17hi_warning_ignore_msvc(26472);
22hi_warning_ignore_msvc(26467);
25hi_warning_ignore_msvc(26496);
27namespace hi::inline
v1 {
29[[nodiscard]]
constexpr T
copy(T value)
noexcept
36template<
typename Out, std::derived_from<std::remove_po
inter_t<Out>> In>
37[[nodiscard]]
constexpr Out
up_cast(In *rhs)
noexcept
38 requires std::is_pointer_v<Out> and (std::is_const_v<std::remove_pointer_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_pointer_t<Out>>)
40 return static_cast<Out
>(rhs);
46[[nodiscard]]
constexpr Out
up_cast(nullptr_t)
noexcept
47 requires std::is_pointer_v<Out>
54template<
typename Out, std::derived_from<std::remove_reference_t<Out>> In>
55[[nodiscard]]
constexpr Out
up_cast(In& rhs)
noexcept
56 requires std::is_reference_v<Out> and (std::is_const_v<std::remove_reference_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_reference_t<Out>>)
58 return static_cast<Out
>(rhs);
68template<
typename Out, base_of<std::remove_po
inter_t<Out>> In>
69[[nodiscard]]
constexpr Out
down_cast(In *rhs)
noexcept
70 requires std::is_pointer_v<Out> and (std::is_const_v<std::remove_pointer_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_pointer_t<Out>>)
72 hi_axiom(rhs ==
nullptr or
dynamic_cast<Out
>(rhs) !=
nullptr);
73 return static_cast<Out
>(rhs);
81[[nodiscard]]
constexpr Out
down_cast(nullptr_t)
noexcept
82 requires std::is_pointer_v<Out>
93template<
typename Out, base_of<std::remove_reference_t<Out>> In>
94[[nodiscard]]
constexpr Out
down_cast(In& rhs)
noexcept
95 requires std::is_reference_v<Out> and (
96 std::is_const_v<std::remove_reference_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_reference_t<Out>>)
99 return static_cast<Out
>(rhs);
104template<arithmetic Out, arithmetic In>
105[[nodiscard]]
constexpr Out
wide_cast(In rhs)
noexcept requires(type_in_range_v<Out, In>)
107 return static_cast<Out
>(rhs);
112template<arithmetic Out>
115 return static_cast<Out
>(rhs);
120template<arithmetic Out, arithmetic In>
121[[nodiscard]]
constexpr bool narrow_validate(Out out, In in)
noexcept
124 auto r = (in ==
static_cast<In
>(out));
129 r &= (in < In{}) == (out < Out{});
139template<std::
unsigned_
integral Out, std::
unsigned_
integral In>
144 r =
static_cast<Out
>(rhs);
157template<arithmetic Out, arithmetic In>
160 if constexpr (type_in_range_v<Out, In>) {
161 return static_cast<Out
>(rhs);
163 hilet r =
static_cast<Out
>(rhs);
164 hi_axiom(detail::narrow_validate(r, rhs));
169template<std::
integral Out, arithmetic In>
170[[nodiscard]]
constexpr Out truncate(In rhs)
noexcept
172 return static_cast<Out
>(rhs);
185template<std::
integral Out, std::
integral In>
188 using in_unsigned_type = std::make_unsigned_t<In>;
189 using out_unsigned_type = std::make_unsigned_t<Out>;
192 auto in_unsigned =
static_cast<in_unsigned_type
>(rhs);
193 auto out_unsigned = narrow_cast<out_unsigned_type>(in_unsigned);
194 return static_cast<Out
>(out_unsigned);
197template<std::
integral Out>
198[[nodiscard]]
constexpr Out char_cast(std::byte rhs)
noexcept
200 return char_cast<Out>(
static_cast<uint8_t
>(rhs));
205template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
208 static_assert(
sizeof(OutType) * 2 ==
sizeof(InType),
"Return value of low_bit_cast must be half the size of the input");
209 return static_cast<OutType
>(value);
214template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
217 static_assert(
sizeof(OutType) * 2 ==
sizeof(InType),
"Return value of high_bit_cast must be half the size of the input");
218 return static_cast<OutType
>(value >>
sizeof(OutType) * CHAR_BIT);
223template<std::
signed_
integral OutType, std::
signed_
integral InType>
224[[nodiscard]]
constexpr OutType low_bit_cast(InType value)
noexcept
226 using UInType = std::make_unsigned_t<InType>;
227 using UOutType = std::make_unsigned_t<OutType>;
228 return static_cast<OutType
>(low_bit_cast<UOutType>(
static_cast<UInType
>(value)));
233template<std::
signed_
integral OutType, std::
signed_
integral InType>
234[[nodiscard]]
constexpr OutType
high_bit_cast(InType value)
noexcept
236 using UInType = std::make_unsigned_t<InType>;
237 using UOutType = std::make_unsigned_t<OutType>;
238 return static_cast<OutType
>(high_bit_cast<UOutType>(
static_cast<UInType
>(value)));
243template<std::
unsigned_
integral OutType, std::
signed_
integral InType>
244[[nodiscard]]
constexpr OutType
low_bit_cast(InType value)
noexcept
246 using UInType = std::make_unsigned_t<InType>;
247 return low_bit_cast<OutType>(
static_cast<UInType
>(value));
252template<std::
unsigned_
integral OutType, std::
signed_
integral InType>
253[[nodiscard]]
constexpr OutType
high_bit_cast(InType value)
noexcept
255 using UInType = std::make_unsigned_t<InType>;
256 return high_bit_cast<OutType>(
static_cast<UInType
>(value));
261template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
264 static_assert(
sizeof(OutType) ==
sizeof(InType) * 2,
"Return value of merge_bit_cast must be double the size of the input");
266 OutType r =
static_cast<OutType
>(
hi);
267 r <<=
sizeof(InType) * CHAR_BIT;
268 r |=
static_cast<OutType
>(lo);
274template<std::
signed_
integral OutType, std::
signed_
integral InType>
275[[nodiscard]]
constexpr OutType merge_bit_cast(InType
hi, InType lo)
noexcept
277 using UInType = std::make_unsigned_t<InType>;
278 using UOutType = std::make_unsigned_t<OutType>;
279 return static_cast<OutType
>(merge_bit_cast<UOutType>(
static_cast<UInType
>(
hi),
static_cast<UInType
>(lo)));
284template<std::
signed_
integral OutType, std::
unsigned_
integral InType>
285[[nodiscard]]
constexpr OutType
merge_bit_cast(InType
hi, InType lo)
noexcept
287 using UOutType = std::make_unsigned_t<OutType>;
288 return narrow_cast<OutType>(merge_bit_cast<UOutType>(
hi, lo));
291[[nodiscard]]
constexpr auto to_underlying(scoped_enum
auto rhs)
noexcept
293 return static_cast<std::underlying_type_t<decltype(rhs)
>>(rhs);
297[[nodiscard]]
constexpr bool to_bool(T&& rhs)
noexcept requires(
requires(T&& x) {
static_cast<bool>(std::forward<T>(x)); })
299 return static_cast<bool>(std::forward<T>(rhs));
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:262
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:105
constexpr OutType high_bit_cast(InType value) noexcept
Return the upper half of the input value.
Definition cast.hpp:215
constexpr Out saturate_cast(In rhs) noexcept
Cast an unsigned number and saturate on overflow.
Definition cast.hpp:140
constexpr Out up_cast(In *rhs) noexcept
Cast a pointer to a class to its base class or itself.
Definition cast.hpp:37
constexpr Out char_cast(In rhs) noexcept
Cast a character.
Definition cast.hpp:186
constexpr OutType low_bit_cast(InType value) noexcept
Return the low half of the input value.
Definition cast.hpp:206
constexpr Out down_cast(In *rhs) noexcept
Cast a pointer to a class to its derived class or itself.
Definition cast.hpp:69
constexpr Out narrow_cast(In rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:158
The HikoGUI namespace.
Definition ascii.hpp:19