diff --git a/src/nostalgia/geo/vec.hpp b/src/nostalgia/geo/vec.hpp index fc8117aa..714b2efd 100644 --- a/src/nostalgia/geo/vec.hpp +++ b/src/nostalgia/geo/vec.hpp @@ -18,8 +18,33 @@ namespace nostalgia::geo { -struct Vec2 { - using value_type = float; +template +struct Vec2Base { + public: + using value_type = T; + T x = 0; + T y = 0; + + constexpr Vec2Base() noexcept = default; + + constexpr Vec2Base(T pX, T pY) noexcept: x(pX), y(pY) { + } + +#if __has_include() + explicit inline operator ImVec2() const noexcept { + return {x, y}; + } +#endif + + protected: + constexpr T *start() 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"; @@ -131,79 +156,80 @@ struct Vec2 { }; - float x = 0; - float y = 0; + constexpr Vec() noexcept = default; - constexpr Vec2() noexcept = default; - - constexpr Vec2(float pX, float pY) noexcept: x(pX), y(pY) { + constexpr Vec(value_type pX, value_type pY) noexcept: Base(pX, pY) { } #if __has_include() - explicit constexpr Vec2(const ImVec2 &v) noexcept: x(v.x), y(v.y) { + explicit constexpr Vec(const ImVec2 &v) noexcept: Base(v.x, v.y) { } #endif [[nodiscard]] constexpr iterator<> begin() noexcept { - return {&x, 0, size()}; + return {Base::start(), 0, size()}; } [[nodiscard]] constexpr iterator<> end() noexcept { - return {&x, size(), size()}; + return {Base::start(), size(), size()}; } [[nodiscard]] constexpr iterator begin() const noexcept { - return {&x, 0, size()}; + return {Base::start(), 0, size()}; } [[nodiscard]] constexpr iterator end() const noexcept { - return {&x, size(), size()}; + return {Base::start(), size(), size()}; } [[nodiscard]] constexpr iterator rbegin() noexcept { - return {&x, size() - 1, size()}; + return {Base::start(), size() - 1, size()}; } [[nodiscard]] constexpr iterator rend() noexcept { - return {&x, ox::MaxValue, size()}; + return {Base::start(), ox::MaxValue, size()}; } [[nodiscard]] constexpr iterator rbegin() const noexcept { - return {&x, size() - 1, size()}; + return {Base::start(), size() - 1, size()}; } [[nodiscard]] constexpr iterator rend() const noexcept { - return {&x, ox::MaxValue, size()}; + return {Base::start(), ox::MaxValue, size()}; } constexpr auto &operator[](std::size_t i) noexcept { - return (&x)[i]; + return Base::start()[i]; } constexpr const auto &operator[](std::size_t i) const noexcept { - return (&x)[i]; + 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; } - -#if __has_include() - explicit operator ImVec2() const noexcept { - return {x, y}; - } -#endif }; +using Vec2 = Vec>; + oxModelBegin(Vec2) oxModelField(x) oxModelField(y)