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_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
53template<
typename Out, std::derived_from<std::remove_reference_t<Out>> In>
54[[nodiscard]]
constexpr Out up_cast(In& rhs)
noexcept requires(
55 std::is_const_v<std::remove_reference_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_reference_t<Out>>)
57 return static_cast<Out
>(rhs);
67template<
typename Out, base_of<std::remove_po
inter_t<Out>> In>
68[[nodiscard]]
constexpr Out down_cast(In *rhs)
noexcept
69 requires(std::is_const_v<std::remove_pointer_t<Out>> == std::is_const_v<In> or std::is_const_v<std::remove_pointer_t<Out>>)
71 hi_axiom(rhs ==
nullptr or
dynamic_cast<Out
>(rhs) !=
nullptr);
72 return static_cast<Out
>(rhs);
83[[nodiscard]]
constexpr Out down_cast(nullptr_t)
noexcept
94template<
typename Out, base_of<std::remove_reference_t<Out>> In>
95[[nodiscard]]
constexpr Out down_cast(In& rhs)
noexcept requires(
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>>)
98 return static_cast<Out
>(rhs);
103template<arithmetic Out, arithmetic In>
104[[nodiscard]]
constexpr Out wide_cast(In rhs)
noexcept requires(type_in_range_v<Out, In>)
106 return static_cast<Out
>(rhs);
111template<arithmetic Out>
112[[nodiscard]]
constexpr Out wide_cast(
bool rhs)
noexcept
114 return static_cast<Out
>(rhs);
119template<arithmetic Out, arithmetic In>
120[[nodiscard]]
constexpr bool narrow_validate(Out out, In in)
noexcept
123 auto r = (in ==
static_cast<In
>(out));
128 r &= (in < In{}) == (out < Out{});
144template<arithmetic Out, arithmetic In>
145[[nodiscard]]
constexpr Out narrow(In rhs)
noexcept(type_in_range_v<Out, In>)
147 if constexpr (type_in_range_v<Out, In>) {
148 return static_cast<Out
>(rhs);
150 hilet r =
static_cast<Out
>(rhs);
152 if (not detail::narrow_validate(r, rhs)) {
168template<arithmetic Out, arithmetic In>
169[[nodiscard]]
constexpr Out narrow_cast(In rhs)
noexcept
171 if constexpr (type_in_range_v<Out, In>) {
172 return static_cast<Out
>(rhs);
174 hilet r =
static_cast<Out
>(rhs);
175 hi_axiom(detail::narrow_validate(r, rhs));
180template<std::
integral Out, arithmetic In>
181[[nodiscard]]
constexpr Out truncate(In rhs)
noexcept
183 return static_cast<Out
>(rhs);
196template<std::
integral Out, std::
integral In>
197[[nodiscard]]
constexpr Out char_cast(In rhs)
noexcept
199 using in_unsigned_type = std::make_unsigned_t<In>;
200 using out_unsigned_type = std::make_unsigned_t<Out>;
203 auto in_unsigned =
static_cast<in_unsigned_type
>(rhs);
204 auto out_unsigned = narrow_cast<out_unsigned_type>(in_unsigned);
205 return static_cast<Out
>(out_unsigned);
210template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
211[[nodiscard]]
constexpr OutType low_bit_cast(InType value)
noexcept
213 static_assert(
sizeof(OutType) * 2 ==
sizeof(InType),
"Return value of low_bit_cast must be half the size of the input");
214 return static_cast<OutType
>(value);
219template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
220[[nodiscard]]
constexpr OutType high_bit_cast(InType value)
noexcept
222 static_assert(
sizeof(OutType) * 2 ==
sizeof(InType),
"Return value of high_bit_cast must be half the size of the input");
223 return static_cast<OutType
>(value >>
sizeof(OutType) * CHAR_BIT);
228template<std::
signed_
integral OutType, std::
signed_
integral InType>
229[[nodiscard]]
constexpr OutType low_bit_cast(InType value)
noexcept
231 using UInType = std::make_unsigned_t<InType>;
232 using UOutType = std::make_unsigned_t<OutType>;
233 return static_cast<OutType
>(low_bit_cast<UOutType>(
static_cast<UInType
>(value)));
238template<std::
signed_
integral OutType, std::
signed_
integral InType>
239[[nodiscard]]
constexpr OutType high_bit_cast(InType value)
noexcept
241 using UInType = std::make_unsigned_t<InType>;
242 using UOutType = std::make_unsigned_t<OutType>;
243 return static_cast<OutType
>(high_bit_cast<UOutType>(
static_cast<UInType
>(value)));
248template<std::
unsigned_
integral OutType, std::
signed_
integral InType>
249[[nodiscard]]
constexpr OutType low_bit_cast(InType value)
noexcept
251 using UInType = std::make_unsigned_t<InType>;
252 return low_bit_cast<OutType>(
static_cast<UInType
>(value));
257template<std::
unsigned_
integral OutType, std::
signed_
integral InType>
258[[nodiscard]]
constexpr OutType high_bit_cast(InType value)
noexcept
260 using UInType = std::make_unsigned_t<InType>;
261 return high_bit_cast<OutType>(
static_cast<UInType
>(value));
266template<std::
unsigned_
integral OutType, std::
unsigned_
integral InType>
267[[nodiscard]]
constexpr OutType merge_bit_cast(InType hi, InType lo)
noexcept
269 static_assert(
sizeof(OutType) ==
sizeof(InType) * 2,
"Return value of merge_bit_cast must be double the size of the input");
271 OutType r =
static_cast<OutType
>(hi);
272 r <<=
sizeof(InType) * CHAR_BIT;
273 r |=
static_cast<OutType
>(lo);
279template<std::
signed_
integral OutType, std::
signed_
integral InType>
280[[nodiscard]]
constexpr OutType merge_bit_cast(InType hi, InType lo)
noexcept
282 using UInType = std::make_unsigned_t<InType>;
283 using UOutType = std::make_unsigned_t<OutType>;
284 return static_cast<OutType
>(merge_bit_cast<UOutType>(
static_cast<UInType
>(hi),
static_cast<UInType
>(lo)));
289template<std::
signed_
integral OutType, std::
unsigned_
integral InType>
290[[nodiscard]]
constexpr OutType merge_bit_cast(InType hi, InType lo)
noexcept
292 using UOutType = std::make_unsigned_t<OutType>;
293 return narrow_cast<OutType>(merge_bit_cast<UOutType>(hi, lo));
296[[nodiscard]]
constexpr auto to_underlying(scoped_enum
auto rhs)
noexcept
298 return static_cast<std::underlying_type_t<decltype(rhs)
>>(rhs);
302[[nodiscard]]
constexpr bool to_bool(T&& rhs)
noexcept requires(
requires(T&& x) {
static_cast<bool>(std::forward<T>(x)); })
304 return static_cast<bool>(std::forward<T>(rhs));
This file includes required definitions.
#define hilet
Invariant should be the default for variables.
Definition required.hpp:23