From 4e0ce575944c9e3b8b6a5b5e7d82350a48272e5b Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 30 May 2023 20:32:43 -0500 Subject: [PATCH] [ox/std] Add geo types --- deps/ox/src/ox/std/CMakeLists.txt | 13 +- deps/ox/src/ox/std/bounds.hpp | 135 +++++++++++++++ deps/ox/src/ox/std/point.hpp | 192 +++++++++++++++++++++ deps/ox/src/ox/std/size.hpp | 192 +++++++++++++++++++++ deps/ox/src/ox/std/std.hpp | 6 +- deps/ox/src/ox/std/vec.cpp | 20 +++ deps/ox/src/ox/std/vec.hpp | 268 ++++++++++++++++++++++++++++++ 7 files changed, 823 insertions(+), 3 deletions(-) create mode 100644 deps/ox/src/ox/std/bounds.hpp create mode 100644 deps/ox/src/ox/std/point.hpp create mode 100644 deps/ox/src/ox/std/size.hpp create mode 100644 deps/ox/src/ox/std/vec.cpp create mode 100644 deps/ox/src/ox/std/vec.hpp diff --git a/deps/ox/src/ox/std/CMakeLists.txt b/deps/ox/src/ox/std/CMakeLists.txt index d9d118ac4..181ca125c 100644 --- a/deps/ox/src/ox/std/CMakeLists.txt +++ b/deps/ox/src/ox/std/CMakeLists.txt @@ -38,10 +38,15 @@ add_library( trace.cpp typetraits.cpp uuid.cpp + vec.cpp ) if(NOT MSVC) target_compile_options(OxStd PRIVATE -Wsign-conversion) + if(UNIX AND NOT APPLE) + target_compile_options(OxStd PUBLIC -export-dynamic) + #target_link_options(OxStd PUBLIC -W1,-E) + endif() endif() if(NOT OX_BARE_METAL) @@ -77,14 +82,15 @@ install( array.hpp assert.hpp bit.hpp + bounds.hpp bstring.hpp buffer.hpp buildinfo.hpp byteswap.hpp concepts.hpp def.hpp - defines.hpp defer.hpp + defines.hpp error.hpp fmt.hpp hardware.hpp @@ -96,12 +102,14 @@ install( memory.hpp new.hpp optional.hpp + point.hpp random.hpp ranges.hpp serialize.hpp + size.hpp + stacktrace.hpp std.hpp stddef.hpp - stacktrace.hpp string.hpp stringview.hpp strongint.hpp @@ -112,6 +120,7 @@ install( typetraits.hpp units.hpp uuid.hpp + vec.hpp vector.hpp writer.hpp DESTINATION diff --git a/deps/ox/src/ox/std/bounds.hpp b/deps/ox/src/ox/std/bounds.hpp new file mode 100644 index 000000000..266389c1b --- /dev/null +++ b/deps/ox/src/ox/std/bounds.hpp @@ -0,0 +1,135 @@ +/* + * Copyright 2015 - 2023 gary@drinkingtea.net + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include +#include + +#include "point.hpp" + +namespace ox { + +class Bounds { + + public: + static constexpr auto TypeName = "net.drinkingtea.ox.Bounds"; + static constexpr auto TypeVersion = 1; + int x = 0; + int y = 0; + int width = 0; + int height = 0; + + constexpr Bounds() noexcept = default; + + constexpr Bounds(int x, int y, int w, int h) noexcept; + + constexpr Bounds(const Point &pt1, const Point &pt2) noexcept; + + [[nodiscard]] + constexpr bool intersects(const Bounds &other) const noexcept; + + [[nodiscard]] + constexpr bool contains(int x, int y) const noexcept; + + [[nodiscard]] + constexpr bool contains(const Point &pt) const noexcept; + + [[nodiscard]] + constexpr int x2() const noexcept; + + [[nodiscard]] + constexpr int y2() const noexcept; + + [[nodiscard]] + constexpr Point pt1() const noexcept; + + [[nodiscard]] + constexpr Point pt2() const noexcept; + + constexpr void setPt2(const Point &pt) noexcept; + + private: + constexpr void set(const Point &pt1, const Point &pt2) noexcept; + +}; + +constexpr Bounds::Bounds(int x, int y, int w, int h) noexcept { + this->x = x; + this->y = y; + this->width = w; + this->height = h; +} + +constexpr Bounds::Bounds(const Point &pt1, const Point &pt2) noexcept { + set(pt1, pt2); +} + +constexpr bool Bounds::intersects(const Bounds &o) const noexcept { + return o.x2() >= x && x2() >= o.x && o.y2() >= y && y2() >= o.y; +} + +constexpr bool Bounds::contains(int x, int y) const noexcept { + return x >= this->x && y >= this->y && x <= x2() && y <= y2(); +} + +constexpr bool Bounds::contains(const Point &pt) const noexcept { + return contains(pt.x, pt.y); +} + +constexpr int Bounds::x2() const noexcept { + return x + width; +} + +constexpr int Bounds::y2() const noexcept { + return y + height; +} + +constexpr Point Bounds::pt1() const noexcept { + return {x, y}; +} + +constexpr Point Bounds::pt2() const noexcept { + return {x2(), y2()}; +} + +constexpr void Bounds::setPt2(const Point &pt) noexcept { + set(pt1(), pt); +} + +constexpr void Bounds::set(const Point &pt1, const Point &pt2) noexcept { + int x1 = 0, x2 = 0, y1 = 0, y2 = 0; + if (pt1.x <= pt2.x) { + x1 = pt1.x; + x2 = pt2.x; + } else { + x1 = pt2.x; + x2 = pt1.x; + } + if (pt1.y <= pt2.y) { + y1 = pt1.y; + y2 = pt2.y; + } else { + y1 = pt2.y; + y2 = pt1.y; + } + this->x = x1; + this->y = y1; + this->width = x2 - x1; + this->height = y2 - y1; +} + +oxModelBegin(Bounds) + oxModelField(x) + oxModelField(y) + oxModelField(width) + oxModelField(height) +oxModelEnd() + +} diff --git a/deps/ox/src/ox/std/point.hpp b/deps/ox/src/ox/std/point.hpp new file mode 100644 index 000000000..942692519 --- /dev/null +++ b/deps/ox/src/ox/std/point.hpp @@ -0,0 +1,192 @@ +/* + * Copyright 2015 - 2023 gary@drinkingtea.net + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include + +namespace ox { + +class Point { + public: + static constexpr auto TypeName = "net.drinkingtea.ox.Point"; + static constexpr auto TypeVersion = 1; + int x = 0; + int y = 0; + + constexpr Point() noexcept = default; + + constexpr Point(int x, int y) noexcept; + + constexpr Point operator+(const Point &p) const noexcept; + + constexpr Point operator-(const Point &p) const noexcept; + + constexpr Point operator*(const Point &p) const noexcept; + + constexpr Point operator/(const Point &p) const noexcept; + + + constexpr Point operator+=(const Point &p) noexcept; + + constexpr Point operator-=(const Point &p) noexcept; + + constexpr Point operator*=(const Point &p) noexcept; + + constexpr Point operator/=(const Point &p) noexcept; + + + constexpr Point operator+(int i) const noexcept; + + constexpr Point operator-(int i) const noexcept; + + constexpr Point operator*(int i) const noexcept; + + constexpr Point operator/(int i) const noexcept; + + + constexpr Point operator+=(int i) noexcept; + + constexpr Point operator-=(int i) noexcept; + + constexpr Point operator*=(int i) noexcept; + + constexpr Point operator/=(int i) noexcept; + + + constexpr bool operator==(const Point&) const noexcept; + + constexpr bool operator!=(const Point&) const noexcept; + +}; + +constexpr Point::Point(int x, int y) noexcept { + this->x = x; + this->y = y; +} + +constexpr Point Point::operator+(const Point &p) const noexcept { + auto out = *this; + out.x += p.x; + out.y += p.y; + return out; +} + +constexpr Point Point::operator-(const Point &p) const noexcept { + auto out = *this; + out.x -= p.x; + out.y -= p.y; + return out; +} + +constexpr Point Point::operator*(const Point &p) const noexcept { + auto out = *this; + out.x *= p.x; + out.y *= p.y; + return out; +} + +constexpr Point Point::operator/(const Point &p) const noexcept { + auto out = *this; + out.x /= p.x; + out.y /= p.y; + return out; +} + +constexpr Point Point::operator+=(const Point &p) noexcept { + x += p.x; + y += p.y; + return *this; +} + +constexpr Point Point::operator-=(const Point &p) noexcept { + x -= p.x; + y -= p.y; + return *this; +} + +constexpr Point Point::operator*=(const Point &p) noexcept { + x *= p.x; + y *= p.y; + return *this; +} + +constexpr Point Point::operator/=(const Point &p) noexcept { + x /= p.x; + y /= p.y; + return *this; +} + + +constexpr Point Point::operator+(int i) const noexcept { + auto out = *this; + out.x += i; + out.y += i; + return out; +} + +constexpr Point Point::operator-(int i) const noexcept { + auto out = *this; + out.x -= i; + out.y -= i; + return out; +} + +constexpr Point Point::operator*(int i) const noexcept { + auto out = *this; + out.x *= i; + out.y *= i; + return out; +} + +constexpr Point Point::operator/(int i) const noexcept { + auto out = *this; + out.x /= i; + out.y /= i; + return out; +} + +constexpr Point Point::operator+=(int i) noexcept { + x += i; + y += i; + return *this; +} + +constexpr Point Point::operator-=(int i) noexcept { + x -= i; + y -= i; + return *this; +} + +constexpr Point Point::operator*=(int i) noexcept { + x *= i; + y *= i; + return *this; +} + +constexpr Point Point::operator/=(int i) noexcept { + x /= i; + y /= i; + return *this; +} + +constexpr bool Point::operator==(const Point &p) const noexcept { + return x == p.x && y == p.y; +} + +constexpr bool Point::operator!=(const Point &p) const noexcept { + return x != p.x || y != p.y; +} + +oxModelBegin(Point) + oxModelField(x) + oxModelField(y) +oxModelEnd() + +} diff --git a/deps/ox/src/ox/std/size.hpp b/deps/ox/src/ox/std/size.hpp new file mode 100644 index 000000000..b4071974f --- /dev/null +++ b/deps/ox/src/ox/std/size.hpp @@ -0,0 +1,192 @@ +/* + * Copyright 2015 - 2023 gary@drinkingtea.net + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include + +namespace ox { + +class Size { + public: + static constexpr auto TypeName = "net.drinkingtea.ox.Size"; + static constexpr auto TypeVersion = 1; + int width = 0; + int height = 0; + + constexpr Size() noexcept = default; + + constexpr Size(int width, int height) noexcept; + + constexpr Size operator+(Size p) const noexcept; + + constexpr Size operator-(Size p) const noexcept; + + constexpr Size operator*(Size p) const noexcept; + + constexpr Size operator/(Size p) const noexcept; + + + constexpr Size operator+=(Size p) noexcept; + + constexpr Size operator-=(Size p) noexcept; + + constexpr Size operator*=(Size p) noexcept; + + constexpr Size operator/=(Size p) noexcept; + + + constexpr Size operator+(int i) const noexcept; + + constexpr Size operator-(int i) const noexcept; + + constexpr Size operator*(int i) const noexcept; + + constexpr Size operator/(int i) const noexcept; + + + constexpr Size operator+=(int i) noexcept; + + constexpr Size operator-=(int i) noexcept; + + constexpr Size operator*=(int i) noexcept; + + constexpr Size operator/=(int i) noexcept; + + + constexpr bool operator==(const Size&) const noexcept; + + constexpr bool operator!=(const Size&) const noexcept; + +}; + +constexpr Size::Size(int width, int height) noexcept { + this->width = width; + this->height = height; +} + +constexpr Size Size::operator+(Size p) const noexcept { + p.width += width; + p.height += height; + return p; +} + +constexpr Size Size::operator-(Size p) const noexcept { + auto out = *this; + out.width -= p.width; + out.height -= p.height; + return out; +} + +constexpr Size Size::operator*(Size p) const noexcept { + p.width *= width; + p.height *= height; + return p; +} + +constexpr Size Size::operator/(Size p) const noexcept { + auto out = *this; + out.width /= p.width; + out.height /= p.height; + return out; +} + +constexpr Size Size::operator+=(Size p) noexcept { + width += p.width; + height += p.height; + return *this; +} + +constexpr Size Size::operator-=(Size p) noexcept { + width -= p.width; + height -= p.height; + return *this; +} + +constexpr Size Size::operator*=(Size p) noexcept { + width *= p.width; + height *= p.height; + return *this; +} + +constexpr Size Size::operator/=(Size p) noexcept { + width /= p.width; + height /= p.height; + return *this; +} + + +constexpr Size Size::operator+(int i) const noexcept { + auto out = *this; + out.width += i; + out.height += i; + return out; +} + +constexpr Size Size::operator-(int i) const noexcept { + auto out = *this; + out.width -= i; + out.height -= i; + return out; +} + +constexpr Size Size::operator*(int i) const noexcept { + auto out = *this; + out.width *= i; + out.height *= i; + return out; +} + +constexpr Size Size::operator/(int i) const noexcept { + auto out = *this; + out.width /= i; + out.height /= i; + return out; +} + + +constexpr Size Size::operator+=(int i) noexcept { + width += i; + height += i; + return *this; +} + +constexpr Size Size::operator-=(int i) noexcept { + width -= i; + height -= i; + return *this; +} + +constexpr Size Size::operator*=(int i) noexcept { + width *= i; + height *= i; + return *this; +} + +constexpr Size Size::operator/=(int i) noexcept { + width /= i; + height /= i; + return *this; +} + + +constexpr bool Size::operator==(const Size &p) const noexcept { + return width == p.width && height == p.height; +} + +constexpr bool Size::operator!=(const Size &p) const noexcept { + return width != p.width || height != p.height; +} + + +oxModelBegin(Size) + oxModelField(width) + oxModelField(height) +oxModelEnd() + +} diff --git a/deps/ox/src/ox/std/std.hpp b/deps/ox/src/ox/std/std.hpp index 96bdcb67e..227dfc790 100644 --- a/deps/ox/src/ox/std/std.hpp +++ b/deps/ox/src/ox/std/std.hpp @@ -11,11 +11,12 @@ #include "array.hpp" #include "assert.hpp" #include "bit.hpp" +#include "bounds.hpp" #include "bstring.hpp" #include "byteswap.hpp" #include "concepts.hpp" -#include "defer.hpp" #include "def.hpp" +#include "defer.hpp" #include "defines.hpp" #include "error.hpp" #include "fmt.hpp" @@ -28,9 +29,11 @@ #include "memory.hpp" #include "new.hpp" #include "optional.hpp" +#include "point.hpp" #include "random.hpp" #include "realstd.hpp" #include "serialize.hpp" +#include "size.hpp" #include "stacktrace.hpp" #include "stddef.hpp" #include "string.hpp" @@ -43,4 +46,5 @@ #include "typetraits.hpp" #include "units.hpp" #include "uuid.hpp" +#include "vec.hpp" #include "vector.hpp" diff --git a/deps/ox/src/ox/std/vec.cpp b/deps/ox/src/ox/std/vec.cpp new file mode 100644 index 000000000..dc3993ae5 --- /dev/null +++ b/deps/ox/src/ox/std/vec.cpp @@ -0,0 +1,20 @@ +/* + * Copyright 2015 - 2023 gary@drinkingtea.net + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include + +#include "vec.hpp" + +namespace ox { + +static_assert([] { + Vec2 v(1, 2); + return v.x == 1 && v.y == 2 && v[0] == 1 && v[1] == 2 && v.size() == 2; +}()); + +} diff --git a/deps/ox/src/ox/std/vec.hpp b/deps/ox/src/ox/std/vec.hpp new file mode 100644 index 000000000..376f28e06 --- /dev/null +++ b/deps/ox/src/ox/std/vec.hpp @@ -0,0 +1,268 @@ +/* + * Copyright 2015 - 2023 gary@drinkingtea.net + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#if __has_include() +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ox { + +template +struct Vec { + public: + using value_type = T; + using size_type = std::size_t; + + static constexpr auto TypeName = "net.drinkingtea.ox.Point"; + static constexpr auto TypeVersion = 1; + + T x = 0; + T y = 0; + + template + struct iterator: public ox::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 ox::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 { + if (std::is_constant_evaluated()) { + switch (i) { + case 0: + return x; + case 1: + return y; + default: + oxAssert(false, "Read past end of Vec2"); + return y; + } + } else { + return start()[i]; + } + } + + constexpr const auto &operator[](std::size_t i) const noexcept { + if (std::is_constant_evaluated()) { + switch (i) { + case 0: + return x; + case 1: + return y; + default: + oxAssert(false, "Read past end of Vec2"); + return y; + } + } else { + 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; + } +}; + +using Vec2 = Vec; + +oxModelBegin(Vec2) + oxModelField(x) + oxModelField(y) +oxModelEnd() + +}