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");
37 constexpr extent(extent
const&)
noexcept =
default;
38 constexpr extent(extent&&)
noexcept =
default;
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>};
51 [[nodiscard]]
constexpr extent(extent<value_type, E>
const&
other) noexcept : _v(
static_cast<array_type
>(
other))
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;
248 [[nodiscard]]
constexpr friend extent
operator+(extent
const& lhs, extent
const& rhs)
noexcept
250 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
251 return extent{lhs._v + rhs._v};
259 [[nodiscard]]
constexpr friend extent
operator-(extent
const& lhs, extent
const& rhs)
noexcept
261 hi_axiom(lhs.holds_invariant() && rhs.holds_invariant());
262 return extent{lhs._v - rhs._v};
272 [[nodiscard]]
constexpr friend extent
operator*(extent
const& lhs, value_type
const& rhs)
noexcept
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)};
301 [[nodiscard]]
constexpr friend extent
operator+(extent
const& lhs, value_type
const& rhs)
noexcept
307 r._v[i] = lhs._v[i] + rhs;
318 [[nodiscard]]
constexpr friend extent
operator*(value_type
const& lhs, extent
const& rhs)
noexcept
321 return extent{lhs * rhs._v};
329 [[nodiscard]]
constexpr friend bool operator==(extent
const& lhs, extent
const& rhs)
noexcept
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
365 constexpr std::size_t mask = 0b11;
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;
393 [[nodiscard]] hi_force_inline
constexpr friend value_type
squared_hypot(extent
const& rhs)
noexcept
403 [[nodiscard]]
constexpr friend value_type
hypot(extent
const& rhs)
noexcept
413 [[nodiscard]]
constexpr friend value_type
rcp_hypot(extent
const& rhs)
noexcept
423 [[nodiscard]]
constexpr friend extent
normalize(extent
const& rhs)
noexcept
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))};
460 [[nodiscard]]
constexpr friend extent clamp(extent
const& value, extent
const& min, extent
const& max)
noexcept
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());
486 friend std::ostream& operator<<(std::ostream& lhs, extent
const& rhs)
noexcept
488 return lhs << to_string(rhs);
494 static constexpr std::size_t element_mask = (1_uz << D) - 1;
511template<
typename CharT>
512struct std::formatter<
hi::geo::extent<float, 2>, CharT> {
518 auto format(hi::geo::extent<float, 2>
const& t,
auto& fc)
520 return std::vformat_to(fc.out(),
"[{}, {}]", std::make_format_args(t.width(), t.height()));
524template<
typename CharT>
525struct std::formatter<
hi::geo::extent<float, 3>, CharT> {
531 auto format(hi::geo::extent<float, 3>
const& t,
auto& fc)
533 return std::vformat_to(fc.out(),
"[{}, {}, {}]", std::make_format_args(t.width(), t.height(), t.depth()));
537template<
typename CharT>
538struct std::formatter<
hi::geo::extent<int, 2>, CharT> {
544 auto format(hi::geo::extent<int, 2>
const& t,
auto& fc)
546 return std::vformat_to(fc.out(),
"[{}, {}]", std::make_format_args(t.width(), t.height()));
550template<
typename CharT>
551struct std::formatter<
hi::geo::extent<int, 3>, CharT> {
557 auto format(hi::geo::extent<int, 3>
const& t,
auto& fc)
559 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:323
#define hi_no_default(...)
This part of the code should not be reachable, unless a programming bug.
Definition assert.hpp:279
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:253
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
constexpr std::string to_string(std::u32string_view rhs) noexcept
Conversion from UTF-32 to UTF-8.
Definition to_string.hpp:215
geo::extent< float, 3 > extent3
A 3D extent.
Definition extent.hpp:507
geo::extent< float, 2 > extent2
A 2D extent.
Definition extent.hpp:502
@ other
The gui_event does not have associated data.
Definition gui_event_variant.hpp:21
geometry/margins.hpp
Definition cache.hpp:11
The HikoGUI API version 1.
Definition cache.hpp:11
HikoGUI geometry types.
Definition axis_aligned_rectangle.hpp:22
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 value_type & width() noexcept
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
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 extent(extent< value_type, E > const &other) noexcept
Construct a extent from a lower dimension extent.
Definition extent.hpp:51
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
Definition extent.hpp:177
T signaling_NaN(T... args)