8#include "../rapid/numeric_array.hpp"
11namespace hi::inline v1 {
25 static_assert(D == 2 || D == 3,
"Only 2D or 3D extents are supported");
29 constexpr extent &operator=(
extent const &)
noexcept =
default;
30 constexpr extent &operator=(
extent &&)
noexcept =
default;
35 requires(E < D) [[nodiscard]]
constexpr extent(
extent<E> const &other) noexcept : _v(
static_cast<f32x4>(other))
37 hi_axiom(holds_invariant());
42 [[nodiscard]]
constexpr explicit operator f32x4() const noexcept
47 [[nodiscard]]
constexpr explicit extent(
f32x4 const &other) noexcept : _v(other) {}
49 [[nodiscard]]
constexpr explicit operator bool() const noexcept
51 if constexpr (D == 2) {
52 return _v.x() != 0.0f or _v.y() != 0.0f;
53 }
else if constexpr (D == 3) {
54 return _v.x() != 0.0f or _v.y() != 0.0f or _v.z() != 0.0f;
61 [[nodiscard]]
constexpr explicit operator vector<E>() const noexcept requires(E >= D)
63 hi_axiom(holds_invariant());
64 return vector<E>{
static_cast<f32x4
>(*this)};
69 [[nodiscard]]
constexpr extent() noexcept : _v(0.0f, 0.0f, 0.0f, 0.0f)
71 hi_axiom(holds_invariant());
78 [[nodiscard]]
constexpr extent(
float width,
float height)
noexcept requires(D == 2) : _v(width, height, 0.0f, 0.0f)
80 hi_axiom(holds_invariant());
88 [[nodiscard]]
constexpr extent(
float width,
float height,
float depth = 0.0f) noexcept requires(D == 3) :
89 _v(width, height, depth, 0.0f)
91 hi_axiom(holds_invariant());
94 [[nodiscard]]
static constexpr extent infinity() noexcept requires(D == 2)
99 [[nodiscard]]
static constexpr extent infinity() noexcept requires(D == 3)
107 [[nodiscard]]
static constexpr extent large() noexcept requires(D == 2)
109 return extent{32767.0f, 32767.0f};
112 [[nodiscard]]
static constexpr extent large() noexcept requires(D == 3)
114 return extent{32767.0f, 32767.0f, 32767.0f};
117 [[nodiscard]]
static constexpr extent
nan() noexcept requires(D == 2)
125 [[nodiscard]]
static constexpr extent
nan() noexcept requires(D == 3)
140 [[nodiscard]]
constexpr float &
width() noexcept
151 [[nodiscard]]
constexpr float &
height() noexcept
162 [[nodiscard]]
constexpr float &
depth() noexcept requires(D == 3)
173 [[nodiscard]]
constexpr float const &
width() const noexcept
184 [[nodiscard]]
constexpr float const &
height() const noexcept
195 [[nodiscard]]
constexpr float const &
depth() const noexcept requires(D == 3)
200 [[nodiscard]]
constexpr vector<D> right() const noexcept
205 [[nodiscard]]
constexpr vector<D> up() const noexcept
207 return vector<D>{_v._0y00()};
210 constexpr extent &operator+=(extent
const &rhs)
noexcept
212 return *
this = *
this + rhs;
222 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
223 return extent{lhs._v + rhs._v};
233 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
234 return extent{lhs._v - rhs._v};
246 hi_axiom(lhs.holds_invariant());
247 return extent{lhs._v * rhs};
251 [[nodiscard]]
constexpr friend auto operator+(
extent const &lhs,
vector<E> const &rhs)
noexcept
253 hi_axiom(lhs.holds_invariant());
254 hi_axiom(rhs.holds_invariant());
260 [[nodiscard]]
constexpr friend auto operator+(vector<E>
const &lhs, extent
const &rhs)
noexcept
262 hi_axiom(lhs.holds_invariant());
263 hi_axiom(rhs.holds_invariant());
265 return vector<
std::max(D, E)>{
static_cast<f32x4
>(lhs) +
static_cast<f32x4
>(rhs)};
275 hi_axiom(lhs.holds_invariant());
279 r._v[i] = lhs._v[i] + rhs;
292 hi_axiom(rhs.holds_invariant());
293 return extent{lhs * rhs._v};
303 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
304 return lhs._v == rhs._v;
307 [[nodiscard]]
constexpr friend std::partial_ordering operator<=>(
extent const &lhs,
extent const &rhs)
noexcept
312 hilet equal = eq(lhs._v, rhs._v) & mask;
315 return std::partial_ordering::equivalent;
318 hilet less = lt(lhs._v, rhs._v) & mask;
319 if ((less | equal) == mask) {
321 return std::partial_ordering::less;
324 hilet greater = lt(lhs._v, rhs._v) & mask;
325 if ((greater | equal) == mask) {
327 return std::partial_ordering::greater;
331 return std::partial_ordering::unordered;
334 [[nodiscard]]
constexpr friend std::partial_ordering operator<=>(extent
const &lhs, extent
const &rhs)
noexcept
342 return std::partial_ordering::equivalent;
345 hilet less = lt(lhs._v, rhs._v) & mask;
346 if ((less | equal) == mask) {
348 return std::partial_ordering::less;
351 hilet greater = lt(lhs._v, rhs._v) & mask;
352 if ((greater | equal) == mask) {
354 return std::partial_ordering::greater;
358 return std::partial_ordering::unordered;
367 hi_axiom(rhs.holds_invariant());
368 return squared_hypot<element_mask>(rhs._v);
375 [[nodiscard]]
constexpr friend float hypot(
extent const &rhs)
noexcept
377 hi_axiom(rhs.holds_invariant());
378 return hypot<element_mask>(rhs._v);
387 hi_axiom(rhs.holds_invariant());
388 return rcp_hypot<element_mask>(rhs._v);
397 hi_axiom(rhs.holds_invariant());
398 return extent{normalize<element_mask>(rhs._v)};
401 [[nodiscard]]
constexpr friend extent ceil(
extent const &rhs)
noexcept
403 hi_axiom(rhs.holds_invariant());
407 [[nodiscard]]
constexpr friend extent
floor(extent
const &rhs)
noexcept
409 hi_axiom(rhs.holds_invariant());
410 return extent{
floor(
static_cast<f32x4
>(rhs))};
413 [[nodiscard]]
constexpr friend extent
round(extent
const &rhs)
noexcept
415 hi_axiom(rhs.holds_invariant());
416 return extent{
round(
static_cast<f32x4
>(rhs))};
419 [[nodiscard]]
constexpr friend extent
min(extent
const &lhs, extent
const &rhs)
noexcept
421 return extent{
min(
static_cast<f32x4
>(lhs),
static_cast<f32x4
>(rhs))};
424 [[nodiscard]]
constexpr friend extent
max(extent
const &lhs, extent
const &rhs)
noexcept
426 return extent{
max(
static_cast<f32x4
>(lhs),
static_cast<f32x4
>(rhs))};
429 [[nodiscard]]
constexpr friend extent clamp(extent
const &value, extent
const &min, extent
const &max)
noexcept
431 return extent{clamp(
static_cast<f32x4
>(value),
static_cast<f32x4
>(min),
static_cast<f32x4
>(max))};
440 return _v.x() >= 0.0f && _v.y() >= 0.0f && _v.z() >= 0.0f && _v.w() == 0.0f && (D == 3 || _v.z() == 0.0f);
445 if constexpr (D == 2) {
446 return std::format(
"[{}, {}]", rhs._v.x(), rhs._v.y());
447 }
else if constexpr (D == 3) {
448 return std::format(
"[{}, {}, {}]", rhs._v.x(), rhs._v.y(), rhs._v.z());
450 hi_static_no_default();
462 static constexpr std::size_t element_mask = (1_uz << D) - 1;
467using extent2 = geo::extent<2>;
468using extent3 = geo::extent<3>;
472template<
typename CharT>
473struct std::formatter<hi::geo::extent<2>, CharT> {
479 auto format(hi::geo::extent<2>
const &t,
auto &fc)
481 return std::vformat_to(fc.out(),
"[{}, {}]", std::make_format_args(t.width(), t.height()));
485template<
typename CharT>
486struct std::formatter<hi::geo::extent<3>, CharT> : formatter<float, CharT> {
492 auto format(hi::geo::extent<3>
const &t,
auto &fc)
494 return std::vformat_to(fc.out(),
"[{}, {}, {}]", std::make_format_args(t.width(), t.height(), t.depth()));
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23
A high-level geometric extent.
Definition extent.hpp:23
constexpr extent() noexcept
Construct a empty extent / zero length.
Definition extent.hpp:69
constexpr extent(extent< E > const &other) noexcept
Construct a extent from a lower dimension extent.
Definition extent.hpp:35
constexpr friend extent operator*(float const &lhs, extent const &rhs) noexcept
Scale the extent by a scaler.
Definition extent.hpp:290
constexpr bool holds_invariant() const noexcept
Check if the extent is valid.
Definition extent.hpp:438
constexpr friend extent operator-(extent const &lhs, extent const &rhs) noexcept
Subtract two extents from each other.
Definition extent.hpp:231
constexpr friend extent operator*(extent const &lhs, float const &rhs) noexcept
Scale the extent by a scaler.
Definition extent.hpp:244
constexpr friend float rcp_hypot(extent const &rhs) noexcept
Get the length of the extent.
Definition extent.hpp:385
constexpr float & depth() noexcept
Access the z-as-depth element from the extent.
Definition extent.hpp:162
constexpr friend extent normalize(extent const &rhs) noexcept
Normalize a extent to a unit extent.
Definition extent.hpp:395
constexpr float const & depth() const noexcept
Access the z-as-depth element from the extent.
Definition extent.hpp:195
constexpr friend float hypot(extent const &rhs) noexcept
Get the length of the extent.
Definition extent.hpp:375
constexpr friend extent operator+(extent const &lhs, float const &rhs) noexcept
Add a scaler to the extent.
Definition extent.hpp:273
constexpr float const & height() const noexcept
Access the y-as-height element from the extent.
Definition extent.hpp:184
hi_force_inline constexpr friend float squared_hypot(extent const &rhs) noexcept
Get the squared length of the extent.
Definition extent.hpp:365
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent.hpp:151
constexpr extent(float width, float height) noexcept
Construct a 2D extent from x and y elements.
Definition extent.hpp:78
constexpr friend bool operator==(extent const &lhs, extent const &rhs) noexcept
Compare if two extents are equal.
Definition extent.hpp:301
constexpr float const & width() const noexcept
Access the x-as-width element from the extent.
Definition extent.hpp:173
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent.hpp:140
constexpr friend extent operator+(extent const &lhs, extent const &rhs) noexcept
Add two extents from each other.
Definition extent.hpp:220
constexpr extent(float width, float height, float depth=0.0f) noexcept
Construct a 3D extent from x, y and z elements.
Definition extent.hpp:88
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:20
T signaling_NaN(T... args)