diff --git a/src/nostalgia/geo/vec.cpp b/src/nostalgia/geo/vec.cpp index 31d4a0c3..95a500f3 100644 --- a/src/nostalgia/geo/vec.cpp +++ b/src/nostalgia/geo/vec.cpp @@ -11,7 +11,7 @@ namespace nostalgia::geo { #ifndef OX_OS_BareMetal // doesn't compile in devKitPro for some reason static_assert([] { Vec2 v(1, 2); - return v.x == 1 && v.y == 2 && v[0] == 1 && v[1] == 2; + return v.x == 1 && v.y == 2 && v[0] == 1 && v[1] == 2 && v.size() == 2; }); #endif diff --git a/src/nostalgia/geo/vec.hpp b/src/nostalgia/geo/vec.hpp index 714b2efd..e79ea698 100644 --- a/src/nostalgia/geo/vec.hpp +++ b/src/nostalgia/geo/vec.hpp @@ -18,221 +18,222 @@ namespace nostalgia::geo { -template -struct Vec2Base { +template +struct Vec { public: using value_type = T; + using size_type = std::size_t; + + static constexpr auto TypeName = "net.drinkingtea.nostalgia.geo.Point"; + static constexpr auto TypeVersion = 1; + T x = 0; T y = 0; - constexpr Vec2Base() noexcept = default; + template + struct iterator: public std::iterator { + private: + PtrType m_t = nullptr; + size_type m_offset = 0; + size_type m_max = 0; - constexpr Vec2Base(T pX, T pY) noexcept: x(pX), y(pY) { + 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(m_offset - s, 0), m_max); + } else { + return iterator(m_t, ox::min(m_offset + s, m_max), m_max); + } + } + + constexpr typename std::iterator::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(m_offset + s, m_max), m_max); + } else { + return iterator(m_t, ox::max(m_offset - s, 0), m_max); + } + } + + constexpr iterator &operator+=(size_type s) noexcept { + if constexpr(reverse) { + m_offset = ox::max(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(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; + } + + }; + + constexpr Vec() noexcept = default; + + template + constexpr Vec(T pX, T pY) noexcept: x(pX), y(pY) { } #if __has_include() + explicit constexpr Vec(const ImVec2 &v) noexcept: Vec(v.x, v.y) { + } + explicit inline operator ImVec2() const noexcept { return {x, y}; } #endif + [[nodiscard]] + constexpr iterator<> begin() noexcept { + return {start(), 0, size()}; + } + + [[nodiscard]] + constexpr iterator<> end() noexcept { + return {start(), size(), size()}; + } + + [[nodiscard]] + constexpr iterator begin() const noexcept { + return {start(), 0, size()}; + } + + [[nodiscard]] + constexpr iterator end() const noexcept { + return {start(), size(), size()}; + } + + [[nodiscard]] + constexpr iterator rbegin() noexcept { + return {start(), size() - 1, size()}; + } + + [[nodiscard]] + constexpr iterator rend() noexcept { + return {start(), ox::MaxValue, size()}; + } + + [[nodiscard]] + constexpr iterator rbegin() const noexcept { + return {start(), size() - 1, size()}; + } + + [[nodiscard]] + constexpr iterator rend() const noexcept { + return {start(), ox::MaxValue, size()}; + } + + constexpr auto &operator[](std::size_t i) noexcept { + return start()[i]; + } + + constexpr const auto &operator[](std::size_t i) const noexcept { + return start()[i]; + } + + constexpr auto operator==(const Vec &v) const noexcept { + for (auto i = 0u; i < v.size(); ++i) { + if ((*this)[i] != v[i]) { + return false; + } + } + return true; + } + + constexpr auto operator!=(const Vec &v) const noexcept { + return !operator==(v); + } + + [[nodiscard]] + constexpr std::size_t size() const noexcept { + return 2; + } + protected: + [[nodiscard]] constexpr T *start() noexcept { return &x; } + + [[nodiscard]] + constexpr const T *start() const noexcept { + return &x; + } }; -template -struct Vec: Base { - using value_type = typename Base::value_type; - using size_type = std::size_t; - - static constexpr auto TypeName = "net.drinkingtea.nostalgia.geo.Point"; - static constexpr auto TypeVersion = 1; - - template - struct iterator: public std::iterator { - 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(m_offset - s, 0), m_max); - } else { - return iterator(m_t, ox::min(m_offset + s, m_max), m_max); - } - } - - constexpr typename std::iterator::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(m_offset + s, m_max), m_max); - } else { - return iterator(m_t, ox::max(m_offset - s, 0), m_max); - } - } - - constexpr iterator &operator+=(size_type s) noexcept { - if constexpr(reverse) { - m_offset = ox::max(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(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; - } - - }; - - constexpr Vec() noexcept = default; - - constexpr Vec(value_type pX, value_type pY) noexcept: Base(pX, pY) { - } - -#if __has_include() - explicit constexpr Vec(const ImVec2 &v) noexcept: Base(v.x, v.y) { - } -#endif - - [[nodiscard]] - constexpr iterator<> begin() noexcept { - return {Base::start(), 0, size()}; - } - - [[nodiscard]] - constexpr iterator<> end() noexcept { - return {Base::start(), size(), size()}; - } - - [[nodiscard]] - constexpr iterator begin() const noexcept { - return {Base::start(), 0, size()}; - } - - [[nodiscard]] - constexpr iterator end() const noexcept { - return {Base::start(), size(), size()}; - } - - [[nodiscard]] - constexpr iterator rbegin() noexcept { - return {Base::start(), size() - 1, size()}; - } - - [[nodiscard]] - constexpr iterator rend() noexcept { - return {Base::start(), ox::MaxValue, size()}; - } - - [[nodiscard]] - constexpr iterator rbegin() const noexcept { - return {Base::start(), size() - 1, size()}; - } - - [[nodiscard]] - constexpr iterator rend() const noexcept { - return {Base::start(), ox::MaxValue, size()}; - } - - constexpr auto &operator[](std::size_t i) noexcept { - return Base::start()[i]; - } - - constexpr const auto &operator[](std::size_t i) const noexcept { - return Base::start()[i]; - } - - constexpr auto operator==(const Vec &v) const noexcept { - return Base::x == v.x && Base::y == v.y; - } - - constexpr auto operator!=(const Vec &v) const noexcept { - return Base::x != v.x || Base::y != v.y; - } - - [[nodiscard]] - constexpr std::size_t size() const noexcept { - return 2; - } -}; - -using Vec2 = Vec>; +using Vec2 = Vec; oxModelBegin(Vec2) oxModelField(x) oxModelField(y) oxModelEnd() -} \ No newline at end of file +}