[nostalgia/geo] Add iterators to Vec2
This commit is contained in:
		| @@ -8,11 +8,123 @@ | ||||
| #include <imgui.h> | ||||
| #endif | ||||
|  | ||||
| #include <ox/std/bit.hpp> | ||||
| #include <ox/std/iterator.hpp> | ||||
| #include <ox/std/math.hpp> | ||||
| #include <ox/std/types.hpp> | ||||
|  | ||||
| namespace nostalgia::geo { | ||||
|  | ||||
| struct Vec2 { | ||||
| 	using value_type = float; | ||||
| 	using size_type = std::size_t; | ||||
|  | ||||
| 	template<typename RefType = value_type&, typename PtrType = value_type*, bool reverse = false> | ||||
| 	struct iterator: public std::iterator<std::bidirectional_iterator_tag, value_type> { | ||||
| 		private: | ||||
| 			PtrType m_t = nullptr; | ||||
| 			size_type m_offset = 0; | ||||
| 			size_type m_max = 0; | ||||
|  | ||||
| 		public: | ||||
| 			constexpr iterator() noexcept = default; | ||||
|  | ||||
| 			constexpr iterator(PtrType t, size_type offset, size_type max) noexcept { | ||||
| 				m_t = t; | ||||
| 				m_offset = offset; | ||||
| 				m_max = max; | ||||
| 			} | ||||
|  | ||||
| 			[[nodiscard]] | ||||
| 			constexpr auto offset() const noexcept { | ||||
| 				return m_offset; | ||||
| 			} | ||||
|  | ||||
| 			constexpr iterator operator+(size_type s) const noexcept { | ||||
| 				 if constexpr(reverse) { | ||||
| 				 return iterator(m_t, ox::max<size_type>(m_offset - s, 0), m_max); | ||||
| 				 } else { | ||||
| 				 return iterator(m_t, ox::min<size_type>(m_offset + s, m_max), m_max); | ||||
| 				 } | ||||
| 			} | ||||
|  | ||||
| 			constexpr typename std::iterator<std::bidirectional_iterator_tag, value_type>::difference_type | ||||
| 			operator-(const iterator &other) const noexcept { | ||||
| 				if constexpr(reverse) { | ||||
| 					return m_offset + other.m_offset; | ||||
| 				} else { | ||||
| 					return m_offset - other.m_offset; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			constexpr iterator operator-(size_type s) const noexcept { | ||||
| 				if constexpr(reverse) { | ||||
| 					return iterator(m_t, ox::min<size_type>(m_offset + s, m_max), m_max); | ||||
| 				} else { | ||||
| 					return iterator(m_t, ox::max<size_type>(m_offset - s, 0), m_max); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			constexpr iterator &operator+=(size_type s) noexcept { | ||||
| 				if constexpr(reverse) { | ||||
| 					m_offset = ox::max<size_type>(m_offset - s, 0); | ||||
| 				} else { | ||||
| 					m_offset = ox::min(m_offset + s, m_max); | ||||
| 				} | ||||
| 				return *this; | ||||
| 			} | ||||
|  | ||||
| 			constexpr iterator &operator-=(size_type s) noexcept { | ||||
| 				if constexpr(reverse) { | ||||
| 					m_offset = ox::min(m_offset + s, m_max); | ||||
| 				} else { | ||||
| 					m_offset = ox::max<size_type>(m_offset - s, 0); | ||||
| 				} | ||||
| 				return *this; | ||||
| 			} | ||||
|  | ||||
| 			constexpr iterator &operator++() noexcept { | ||||
| 				return operator+=(1); | ||||
| 			} | ||||
|  | ||||
| 			constexpr iterator &operator--() noexcept { | ||||
| 				return operator-=(1); | ||||
| 			} | ||||
|  | ||||
| 			constexpr RefType operator*() const noexcept { | ||||
| 				return m_t[m_offset]; | ||||
| 			} | ||||
|  | ||||
| 			constexpr RefType operator[](size_type s) const noexcept { | ||||
| 				return m_t[s]; | ||||
| 			} | ||||
|  | ||||
| 			constexpr bool operator<(const iterator &other) const noexcept { | ||||
| 				return m_offset < other.m_offset; | ||||
| 			} | ||||
|  | ||||
| 			constexpr bool operator>(const iterator &other) const noexcept { | ||||
| 				return m_offset > other.m_offset; | ||||
| 			} | ||||
|  | ||||
| 			constexpr bool operator<=(const iterator &other) const noexcept { | ||||
| 				return m_offset <= other.m_offset; | ||||
| 			} | ||||
|  | ||||
| 			constexpr bool operator>=(const iterator &other) const noexcept { | ||||
| 				return m_offset >= other.m_offset; | ||||
| 			} | ||||
|  | ||||
| 			constexpr bool operator==(const iterator &other) const noexcept { | ||||
| 				return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max; | ||||
| 			} | ||||
|  | ||||
| 			constexpr bool operator!=(const iterator &other) const noexcept { | ||||
| 				return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max; | ||||
| 			} | ||||
|  | ||||
| 	}; | ||||
|  | ||||
| 	float x = 0; | ||||
| 	float y = 0; | ||||
|  | ||||
| @@ -26,6 +138,46 @@ struct Vec2 { | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<> begin() noexcept { | ||||
| 		return {&x, 0, size()}; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<> end() noexcept { | ||||
| 		return {&x, size(), size()}; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<const value_type&, const value_type*> begin() const noexcept { | ||||
| 		return {&x, 0, size()}; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<const value_type&, const value_type*> end() const noexcept { | ||||
| 		return {&x, size(), size()}; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<value_type&, value_type*, true> rbegin() noexcept { | ||||
| 		return {&x, size() - 1, size()}; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<value_type&, value_type*, true> rend() noexcept { | ||||
| 		return {&x, ox::MaxValue<size_type>, size()}; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<const value_type&, const value_type*, true> rbegin() const noexcept { | ||||
| 		return {&x, size() - 1, size()}; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr iterator<const value_type&, const value_type*, true> rend() const noexcept { | ||||
| 		return {&x, ox::MaxValue<size_type>, size()}; | ||||
| 	} | ||||
|  | ||||
| 	constexpr auto &operator[](std::size_t i) noexcept { | ||||
| 		return (&x)[i]; | ||||
| 	} | ||||
| @@ -34,6 +186,11 @@ struct Vec2 { | ||||
| 		return (&x)[i]; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] | ||||
| 	constexpr std::size_t size() const noexcept { | ||||
| 		return 2; | ||||
| 	} | ||||
|  | ||||
| #if __has_include(<imgui.h>) | ||||
| 	explicit operator ImVec2() const noexcept { | ||||
| 		return {x, y}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user