[nostalgia/geo] Add iterators to Vec2

This commit is contained in:
Gary Talent 2022-02-13 12:04:58 -06:00
parent 8774f1c062
commit 90723b718b

View File

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