[nostalgia/geo] Simplify Vec2

This commit is contained in:
Gary Talent 2022-02-16 20:16:16 -06:00
parent 8927f0e9c8
commit 72ce8ea4d9
2 changed files with 194 additions and 193 deletions

View File

@ -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

View File

@ -18,38 +18,18 @@
namespace nostalgia::geo {
template<typename T = float>
struct Vec2Base {
template<typename T>
struct Vec {
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(<imgui.h>)
explicit inline operator ImVec2() const noexcept {
return {x, y};
}
#endif
protected:
constexpr T *start() noexcept {
return &x;
}
};
template<typename Base>
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;
T x = 0;
T y = 0;
template<typename RefType = value_type&, typename PtrType = value_type*, bool reverse = false>
struct iterator: public std::iterator<std::bidirectional_iterator_tag, value_type> {
private:
@ -158,77 +138,98 @@ struct Vec: Base {
constexpr Vec() noexcept = default;
constexpr Vec(value_type pX, value_type pY) noexcept: Base(pX, pY) {
template<typename ...Args>
constexpr Vec(T pX, T pY) noexcept: x(pX), y(pY) {
}
#if __has_include(<imgui.h>)
explicit constexpr Vec(const ImVec2 &v) noexcept: Base(v.x, v.y) {
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 {Base::start(), 0, size()};
return {start(), 0, size()};
}
[[nodiscard]]
constexpr iterator<> end() noexcept {
return {Base::start(), size(), size()};
return {start(), size(), size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*> begin() const noexcept {
return {Base::start(), 0, size()};
return {start(), 0, size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*> end() const noexcept {
return {Base::start(), size(), size()};
return {start(), size(), size()};
}
[[nodiscard]]
constexpr iterator<value_type&, value_type*, true> rbegin() noexcept {
return {Base::start(), size() - 1, size()};
return {start(), size() - 1, size()};
}
[[nodiscard]]
constexpr iterator<value_type&, value_type*, true> rend() noexcept {
return {Base::start(), ox::MaxValue<size_type>, size()};
return {start(), ox::MaxValue<size_type>, size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*, true> rbegin() const noexcept {
return {Base::start(), size() - 1, size()};
return {start(), size() - 1, size()};
}
[[nodiscard]]
constexpr iterator<const value_type&, const value_type*, true> rend() const noexcept {
return {Base::start(), ox::MaxValue<size_type>, size()};
return {start(), ox::MaxValue<size_type>, size()};
}
constexpr auto &operator[](std::size_t i) noexcept {
return Base::start()[i];
return start()[i];
}
constexpr const auto &operator[](std::size_t i) const noexcept {
return Base::start()[i];
return start()[i];
}
constexpr auto operator==(const Vec &v) const noexcept {
return Base::x == v.x && Base::y == v.y;
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 Base::x != v.x || Base::y != v.y;
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;
}
};
using Vec2 = Vec<Vec2Base<float>>;
using Vec2 = Vec<float>;
oxModelBegin(Vec2)
oxModelField(x)