12#include "../SIMD/module.hpp"
13#include "../utility/module.hpp"
16namespace hi {
inline namespace v1 {
29template<
typename T,
int D>
33 using array_type = simd<value_type, 4>;
35 static_assert(D == 2 || D == 3,
"Only 2D or 3D extents are supported");
39 constexpr extent& operator=(
extent const&)
noexcept =
default;
40 constexpr extent& operator=(
extent&&)
noexcept =
default;
42 [[nodiscard]]
constexpr static extent large()
noexcept
44 return {large_number_v<value_type>, large_number_v<value_type>};
58 [[nodiscard]]
constexpr explicit operator array_type() const noexcept
63 [[nodiscard]]
constexpr explicit extent(array_type
const&
other) noexcept : _v(
other) {}
65 [[nodiscard]]
constexpr explicit operator bool() const noexcept
67 if constexpr (D == 2) {
68 return _v.x() != value_type{0} or _v.y() != value_type{0};
69 }
else if constexpr (D == 3) {
70 return _v.x() != value_type{0} or _v.y() != value_type{0} or _v.z() != value_type{0};
77 [[nodiscard]]
constexpr explicit operator vector<value_type, E>() const noexcept
81 return vector<value_type, E>{
static_cast<array_type
>(*this)};
86 [[nodiscard]]
constexpr extent() noexcept : _v(value_type{0}, value_type{0}, value_type{0}, value_type{0})
114 [[nodiscard]]
static constexpr extent infinity() noexcept
120 [[nodiscard]]
static constexpr extent infinity() noexcept
129 [[nodiscard]]
static constexpr extent large() noexcept
132 return extent{value_type{16777216}, value_type{16777216}};
135 [[nodiscard]]
static constexpr extent large() noexcept
138 return extent{value_type{16777216}, value_type{16777216}, value_type{16777216}};
141 [[nodiscard]]
static constexpr extent nan() noexcept
142 requires
std::is_same_v<value_type,
float> and (D == 2)
150 [[nodiscard]]
static constexpr extent nan() noexcept
151 requires
std::is_same_v<value_type,
float> and (D == 3)
166 [[nodiscard]]
constexpr value_type&
width() noexcept
177 [[nodiscard]]
constexpr value_type&
height() noexcept
188 [[nodiscard]]
constexpr value_type&
depth() noexcept
200 [[nodiscard]]
constexpr value_type
width() const noexcept
211 [[nodiscard]]
constexpr value_type
height() const noexcept
222 [[nodiscard]]
constexpr value_type
depth() const noexcept
228 [[nodiscard]]
constexpr vector<value_type, D> right() const noexcept
230 return vector<value_type, D>{_v.x000()};
233 [[nodiscard]]
constexpr vector<value_type, D> up() const noexcept
235 return vector<value_type, D>{_v._0y00()};
238 constexpr extent& operator+=(
extent const& rhs)
noexcept
240 return *
this = *
this + rhs;
250 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
251 return extent{lhs._v + rhs._v};
261 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
262 return extent{lhs._v - rhs._v};
275 return extent{lhs._v * rhs};
279 [[nodiscard]]
constexpr friend auto operator+(
extent const& lhs, vector<value_type, E>
const& rhs)
noexcept
284 return extent<value_type,
std::max(D, E)>{
static_cast<array_type
>(lhs) +
static_cast<array_type
>(rhs)};
288 [[nodiscard]]
constexpr friend auto operator+(vector<value_type, E>
const& lhs,
extent const& rhs)
noexcept
293 return vector<value_type,
std::max(D, E)>{
static_cast<array_type
>(lhs) +
static_cast<array_type
>(rhs)};
307 r._v[i] = lhs._v[i] + rhs;
321 return extent{lhs * rhs._v};
331 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
332 return equal(lhs._v, rhs._v);
335 [[nodiscard]]
constexpr friend std::partial_ordering operator<=>(
extent const& lhs,
extent const& rhs)
noexcept
340 hilet equal = eq(lhs._v, rhs._v) & mask;
343 return std::partial_ordering::equivalent;
346 hilet less = lt(lhs._v, rhs._v) & mask;
347 if ((less | equal) == mask) {
349 return std::partial_ordering::less;
352 hilet greater = lt(lhs._v, rhs._v) & mask;
353 if ((greater | equal) == mask) {
355 return std::partial_ordering::greater;
359 return std::partial_ordering::unordered;
362 [[nodiscard]]
constexpr friend std::partial_ordering operator<=>(
extent const& lhs,
extent const& rhs)
noexcept
367 hilet equal = (lhs._v == rhs._v).mask() & mask;
370 return std::partial_ordering::equivalent;
373 hilet less = (lhs._v < rhs._v).mask() & mask;
374 if ((less | equal) == mask) {
376 return std::partial_ordering::less;
379 hilet greater = (lhs._v > rhs._v).mask() & mask;
380 if ((greater | equal) == mask) {
382 return std::partial_ordering::greater;
386 return std::partial_ordering::unordered;
396 return squared_hypot<element_mask>(rhs._v);
403 [[nodiscard]]
constexpr friend value_type
hypot(
extent const& rhs)
noexcept
406 return hypot<element_mask>(rhs._v);
416 return rcp_hypot<element_mask>(rhs._v);
426 return extent{normalize<element_mask>(rhs._v)};
429 [[nodiscard]]
constexpr friend extent ceil(
extent const& rhs)
noexcept
430 requires std::is_same_v<value_type, float>
433 return extent{ceil(array_type{rhs})};
436 [[nodiscard]]
constexpr friend extent floor(
extent const& rhs)
noexcept
437 requires std::is_same_v<value_type, float>
440 return extent{floor(
static_cast<array_type
>(rhs))};
443 [[nodiscard]]
constexpr friend extent round(
extent const& rhs)
noexcept
444 requires std::is_same_v<value_type, float>
447 return extent{round(
static_cast<array_type
>(rhs))};
450 [[nodiscard]]
constexpr friend extent min(
extent const& lhs,
extent const& rhs)
noexcept
452 return extent{min(
static_cast<array_type
>(lhs),
static_cast<array_type
>(rhs))};
455 [[nodiscard]]
constexpr friend extent max(
extent const& lhs,
extent const& rhs)
noexcept
457 return extent{max(
static_cast<array_type
>(lhs),
static_cast<array_type
>(rhs))};
462 return extent{clamp(
static_cast<array_type
>(value),
static_cast<array_type
>(min),
static_cast<array_type
>(max))};
471 return _v.x() >= value_type{0} && _v.y() >= value_type{0} && _v.z() >= value_type{0} && _v.w() == value_type{0} &&
472 (D == 3 || _v.z() == value_type{0});
477 if constexpr (D == 2) {
478 return std::format(
"[{}, {}]", rhs._v.x(), rhs._v.y());
479 }
else if constexpr (D == 3) {
480 return std::format(
"[{}, {}, {}]", rhs._v.x(), rhs._v.y(), rhs._v.z());
488 return lhs << to_string(rhs);
494 static constexpr std::size_t element_mask = (1_uz << D) - 1;
520[[nodiscard]]
constexpr extent2i narrow_cast(
extent2 const& rhs)
noexcept
522 return {narrow_cast<int>(rhs.width()), narrow_cast<int>(rhs.height())};
526[[nodiscard]]
constexpr extent2 narrow_cast(
extent2i const& rhs)
noexcept
528 return {narrow_cast<float>(rhs.width()), narrow_cast<float>(rhs.height())};
533template<
typename CharT>
534struct std::formatter<
hi::geo::extent<float, 2>, CharT> {
540 auto format(hi::geo::extent<float, 2>
const& t,
auto& fc)
542 return std::vformat_to(fc.out(),
"[{}, {}]", std::make_format_args(t.width(), t.height()));
546template<
typename CharT>
547struct std::formatter<
hi::geo::extent<float, 3>, CharT> {
553 auto format(hi::geo::extent<float, 3>
const& t,
auto& fc)
555 return std::vformat_to(fc.out(),
"[{}, {}, {}]", std::make_format_args(t.width(), t.height(), t.depth()));
559template<
typename CharT>
560struct std::formatter<
hi::geo::extent<int, 2>, CharT> {
566 auto format(hi::geo::extent<int, 2>
const& t,
auto& fc)
568 return std::vformat_to(fc.out(),
"[{}, {}]", std::make_format_args(t.width(), t.height()));
572template<
typename CharT>
573struct std::formatter<
hi::geo::extent<int, 3>, CharT> {
579 auto format(hi::geo::extent<int, 3>
const& t,
auto& fc)
581 return std::vformat_to(fc.out(),
"[{}, {}, {}]", std::make_format_args(t.width(), t.height(), t.depth()));
#define hi_static_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:308
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:264
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:238
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
geo::extent< int, 3 > extent3i
A 3D extent.
Definition extent.hpp:517
geo::extent< float, 3 > extent3
A 3D extent.
Definition extent.hpp:507
geo::extent< int, 2 > extent2i
A 2D extent.
Definition extent.hpp:512
geo::extent< float, 2 > extent2
A 2D extent.
Definition extent.hpp:502
@ other
The gui_event does not have associated data.
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
A high-level geometric extent.
Definition extent.hpp:30
hi_force_inline constexpr friend value_type squared_hypot(extent const &rhs) noexcept
Get the squared length of the extent.
Definition extent.hpp:393
constexpr extent() noexcept
Construct a empty extent / zero length.
Definition extent.hpp:86
constexpr extent(extent< value_type, E > const &other) noexcept
Construct a extent from a lower dimension extent.
Definition extent.hpp:51
constexpr value_type & width() noexcept
Access the x-as-width element from the extent.
Definition extent.hpp:166
constexpr friend extent operator*(value_type const &lhs, extent const &rhs) noexcept
Scale the extent by a scaler.
Definition extent.hpp:318
constexpr bool holds_invariant() const noexcept
Check if the extent is valid.
Definition extent.hpp:469
constexpr friend value_type rcp_hypot(extent const &rhs) noexcept
Get the length of the extent.
Definition extent.hpp:413
constexpr friend extent operator-(extent const &lhs, extent const &rhs) noexcept
Subtract two extents from each other.
Definition extent.hpp:259
constexpr value_type height() const noexcept
Access the y-as-height element from the extent.
Definition extent.hpp:211
constexpr friend extent normalize(extent const &rhs) noexcept
Normalize a extent to a unit extent.
Definition extent.hpp:423
constexpr friend extent operator*(extent const &lhs, value_type const &rhs) noexcept
Scale the extent by a scaler.
Definition extent.hpp:272
constexpr friend value_type hypot(extent const &rhs) noexcept
Get the length of the extent.
Definition extent.hpp:403
constexpr value_type & depth() noexcept
Access the z-as-depth element from the extent.
Definition extent.hpp:188
constexpr value_type width() const noexcept
Access the x-as-width element from the extent.
Definition extent.hpp:200
constexpr value_type depth() const noexcept
Access the z-as-depth element from the extent.
Definition extent.hpp:222
constexpr extent(value_type width, value_type height) noexcept
Construct a 2D extent from the width and height.
Definition extent.hpp:95
constexpr friend bool operator==(extent const &lhs, extent const &rhs) noexcept
Compare if two extents are equal.
Definition extent.hpp:329
constexpr extent(value_type width, value_type height, value_type depth=value_type{0}) noexcept
Construct a 3D extent from width, height and depth.
Definition extent.hpp:107
constexpr friend extent operator+(extent const &lhs, value_type const &rhs) noexcept
Add a scaler to the extent.
Definition extent.hpp:301
constexpr friend extent operator+(extent const &lhs, extent const &rhs) noexcept
Add two extents from each other.
Definition extent.hpp:248
constexpr value_type & height() noexcept
Access the y-as-height element from the extent.
Definition extent.hpp:177
T signaling_NaN(T... args)