[nostalgia/geo] Simplify Vec2
This commit is contained in:
parent
8927f0e9c8
commit
72ce8ea4d9
@ -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
|
||||
|
||||
|
@ -18,221 +18,222 @@
|
||||
|
||||
namespace nostalgia::geo {
|
||||
|
||||
template<typename T = float>
|
||||
struct Vec2Base {
|
||||
template<typename T>
|
||||
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<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;
|
||||
|
||||
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<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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
constexpr Vec() noexcept = default;
|
||||
|
||||
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: 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<const value_type&, const value_type*> begin() const noexcept {
|
||||
return {start(), 0, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*> end() const noexcept {
|
||||
return {start(), size(), size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<value_type&, value_type*, true> rbegin() noexcept {
|
||||
return {start(), size() - 1, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<value_type&, value_type*, true> rend() noexcept {
|
||||
return {start(), ox::MaxValue<size_type>, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*, true> rbegin() const noexcept {
|
||||
return {start(), size() - 1, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*, true> rend() const noexcept {
|
||||
return {start(), ox::MaxValue<size_type>, 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<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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
constexpr Vec() noexcept = default;
|
||||
|
||||
constexpr Vec(value_type pX, value_type pY) noexcept: Base(pX, pY) {
|
||||
}
|
||||
|
||||
#if __has_include(<imgui.h>)
|
||||
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<const value_type&, const value_type*> begin() const noexcept {
|
||||
return {Base::start(), 0, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*> end() const noexcept {
|
||||
return {Base::start(), size(), size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<value_type&, value_type*, true> rbegin() noexcept {
|
||||
return {Base::start(), size() - 1, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<value_type&, value_type*, true> rend() noexcept {
|
||||
return {Base::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()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*, true> rend() const noexcept {
|
||||
return {Base::start(), ox::MaxValue<size_type>, 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<Vec2Base<float>>;
|
||||
using Vec2 = Vec<float>;
|
||||
|
||||
oxModelBegin(Vec2)
|
||||
oxModelField(x)
|
||||
oxModelField(y)
|
||||
oxModelEnd()
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user