18hi_warning_ignore_msvc(26472);
23hi_warning_ignore_msvc(26467);
26hi_warning_ignore_msvc(26496);
28namespace hi::inline
v1 {
30[[nodiscard]]
constexpr T
copy(T value)
noexcept
37template<
typename Out, std::derived_from<std::remove_po
inter_t<Out>> In>
38[[nodiscard]]
constexpr Out
up_cast(In *rhs)
noexcept
39 requires std::is_pointer_v<Out> and
40 (std::is_const_v<std::remove_pointer_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_pointer_t<Out>>)
42 return static_cast<Out
>(rhs);
48[[nodiscard]]
constexpr Out
up_cast(nullptr_t)
noexcept
49 requires std::is_pointer_v<Out>
56template<
typename Out, std::derived_from<std::remove_reference_t<Out>> In>
57[[nodiscard]]
constexpr Out
up_cast(In& rhs)
noexcept
58 requires std::is_reference_v<Out> and
59 (std::is_const_v<std::remove_reference_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_reference_t<Out>>)
61 return static_cast<Out
>(rhs);
71template<
typename Out, base_of<std::remove_po
inter_t<Out>> In>
72[[nodiscard]]
constexpr Out
down_cast(In *rhs)
noexcept
73 requires std::is_pointer_v<Out> and
74 (std::is_const_v<std::remove_pointer_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_pointer_t<Out>>)
76 hi_axiom(rhs ==
nullptr or
dynamic_cast<Out
>(rhs) !=
nullptr);
77 return static_cast<Out
>(rhs);
85[[nodiscard]]
constexpr Out
down_cast(nullptr_t)
noexcept
86 requires std::is_pointer_v<Out>
97template<
typename Out, base_of<std::remove_reference_t<Out>> In>
98[[nodiscard]]
constexpr Out
down_cast(In& rhs)
noexcept
99 requires std::is_reference_v<Out> and
100 (std::is_const_v<std::remove_reference_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_reference_t<Out>>)
103 return static_cast<Out
>(rhs);
108template<arithmetic Out, arithmetic In>
110 requires(type_in_range_v<Out, In>)
112 return static_cast<Out
>(rhs);
117template<arithmetic Out>
120 return static_cast<Out
>(rhs);
125template<arithmetic Out, arithmetic In>
126[[nodiscard]]
constexpr bool narrow_validate(Out out, In in)
noexcept
129 auto r = (in ==
static_cast<In
>(out));
134 r &= (in < In{}) == (out < Out{});
148template<std::
integral Out, arithmetic In>
151 if constexpr (std::is_floating_point_v<In>) {
162 return static_cast<Out
>(rhs);
174template<
typename Out,
typename In>
175[[nodiscard]]
constexpr Out narrow_cast(In
const &rhs)
noexcept;
177template<arithmetic Out, arithmetic In>
180 if constexpr (type_in_range_v<Out, In>) {
181 return static_cast<Out
>(rhs);
183 hilet r =
static_cast<Out
>(rhs);
184 hi_axiom(detail::narrow_validate(r, rhs));
189template<arithmetic Out, arithmetic In>
190[[nodiscard]]
constexpr Out round_cast(In rhs)
noexcept
192 if constexpr (std::is_floating_point_v<In>) {
195 return narrow_cast<Out>(rhs);
199template<arithmetic Out, arithmetic In>
200[[nodiscard]]
constexpr Out floor_cast(In rhs)
noexcept
202 if constexpr (std::is_floating_point_v<In>) {
205 return narrow_cast<Out>(rhs);
209template<arithmetic Out, arithmetic In>
210[[nodiscard]]
constexpr Out ceil_cast(In rhs)
noexcept
212 if constexpr (std::is_floating_point_v<In>) {
215 return narrow_cast<Out>(rhs);
219template<std::
integral Out, arithmetic In>
220[[nodiscard]]
constexpr Out truncate(In rhs)
noexcept
222 return static_cast<Out
>(rhs);
235template<std::
integral Out, std::
integral In>
238 using in_unsigned_type = std::make_unsigned_t<In>;
239 using out_unsigned_type = std::make_unsigned_t<Out>;
242 auto in_unsigned =
static_cast<in_unsigned_type
>(rhs);
243 auto out_unsigned = narrow_cast<out_unsigned_type>(in_unsigned);
244 return static_cast<Out
>(out_unsigned);
247template<std::
integral Out>
248[[nodiscard]]
constexpr Out char_cast(std::byte rhs)
noexcept
250 return char_cast<Out>(
static_cast<uint8_t
>(rhs));
255template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
258 static_assert(
sizeof(OutType) * 2 ==
sizeof(InType),
"Return value of low_bit_cast must be half the size of the input");
259 return static_cast<OutType
>(value);
264template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
267 static_assert(
sizeof(OutType) * 2 ==
sizeof(InType),
"Return value of high_bit_cast must be half the size of the input");
268 return static_cast<OutType
>(value >>
sizeof(OutType) * CHAR_BIT);
273template<std::
signed_
integral OutType, std::
signed_
integral InType>
274[[nodiscard]]
constexpr OutType low_bit_cast(InType value)
noexcept
276 using UInType = std::make_unsigned_t<InType>;
277 using UOutType = std::make_unsigned_t<OutType>;
278 return static_cast<OutType
>(low_bit_cast<UOutType>(
static_cast<UInType
>(value)));
283template<std::
signed_
integral OutType, std::
signed_
integral InType>
284[[nodiscard]]
constexpr OutType
high_bit_cast(InType value)
noexcept
286 using UInType = std::make_unsigned_t<InType>;
287 using UOutType = std::make_unsigned_t<OutType>;
288 return static_cast<OutType
>(high_bit_cast<UOutType>(
static_cast<UInType
>(value)));
293template<std::
unsigned_
integral OutType, std::
signed_
integral InType>
294[[nodiscard]]
constexpr OutType
low_bit_cast(InType value)
noexcept
296 using UInType = std::make_unsigned_t<InType>;
297 return low_bit_cast<OutType>(
static_cast<UInType
>(value));
302template<std::
unsigned_
integral OutType, std::
signed_
integral InType>
303[[nodiscard]]
constexpr OutType
high_bit_cast(InType value)
noexcept
305 using UInType = std::make_unsigned_t<InType>;
306 return high_bit_cast<OutType>(
static_cast<UInType
>(value));
311template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
314 static_assert(
sizeof(OutType) ==
sizeof(InType) * 2,
"Return value of merge_bit_cast must be double the size of the input");
316 OutType r =
static_cast<OutType
>(
hi);
317 r <<=
sizeof(InType) * CHAR_BIT;
318 r |=
static_cast<OutType
>(lo);
324template<std::
signed_
integral OutType, std::
signed_
integral InType>
325[[nodiscard]]
constexpr OutType merge_bit_cast(InType
hi, InType lo)
noexcept
327 using UInType = std::make_unsigned_t<InType>;
328 using UOutType = std::make_unsigned_t<OutType>;
329 return static_cast<OutType
>(merge_bit_cast<UOutType>(
static_cast<UInType
>(
hi),
static_cast<UInType
>(lo)));
334template<std::
signed_
integral OutType, std::
unsigned_
integral InType>
335[[nodiscard]]
constexpr OutType
merge_bit_cast(InType
hi, InType lo)
noexcept
337 using UOutType = std::make_unsigned_t<OutType>;
338 return narrow_cast<OutType>(merge_bit_cast<UOutType>(
hi, lo));
341[[nodiscard]]
constexpr auto to_underlying(scoped_enum
auto rhs)
noexcept
343 return static_cast<std::underlying_type_t<decltype(rhs)
>>(rhs);
347[[nodiscard]]
constexpr bool to_bool(T&& rhs)
noexcept
348 requires(
requires(T&& x) {
static_cast<bool>(std::forward<T>(x)); })
350 return static_cast<bool>(std::forward<T>(rhs));
355 requires std::is_pointer_v<T>
357 return reinterpret_cast<T
>(value);
Utilities to assert and bound check.
#define hi_axiom(expression,...)
Specify an axiom; an expression that is true.
Definition assert.hpp:133
Utilities used by the HikoGUI library itself.
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:15
constexpr OutType merge_bit_cast(InType hi, InType lo) noexcept
Return the upper half of the input value.
Definition cast.hpp:312
constexpr Out wide_cast(In rhs) noexcept
Cast a number to a type that will be able to represent all values without loss of precision.
Definition cast.hpp:109
constexpr OutType high_bit_cast(InType value) noexcept
Return the upper half of the input value.
Definition cast.hpp:265
constexpr Out saturate_cast(In rhs) noexcept
Cast a numeric value to an integer saturating on overflow.
Definition cast.hpp:149
constexpr Out up_cast(In *rhs) noexcept
Cast a pointer to a class to its base class or itself.
Definition cast.hpp:38
constexpr Out char_cast(In rhs) noexcept
Cast a character.
Definition cast.hpp:236
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:178
constexpr OutType low_bit_cast(InType value) noexcept
Return the low half of the input value.
Definition cast.hpp:256
constexpr Out down_cast(In *rhs) noexcept
Cast a pointer to a class to its derived class or itself.
Definition cast.hpp:72
geometry/margins.hpp
Definition assert.hpp:18
constexpr auto three_way_compare(Lhs const &lhs, Rhs const &rhs) noexcept
Safely compare two arithmetic values to each other.
Definition compare.hpp:123