7#if defined(__cpp_lib_byteswap) && __cpp_lib_byteswap >= 202110L
10#if defined(__cpp_lib_forward_like)
15#include "min-cpp-version/cpp20.h"
20 template <
class T,
class =
void>
21 struct is_complete : std::false_type
26 struct is_complete<T, decltype(void(sizeof(T)))> : std::true_type
31 concept is_complete_v = is_complete<T>::value;
33 template<
class T,
class U>
34 constexpr std::unique_ptr<T> dynamic_pointer_cast(std::unique_ptr<U>&& r)
noexcept
36 if (
auto p =
dynamic_cast<T*
>(r.get()))
37 return (
void)r.release(), std::unique_ptr<T>(p);
42 template<
class T,
class U>
43 constexpr std::unique_ptr<T> dynamic_steal_cast(std::unique_ptr<U>& r)
noexcept
45 if (
auto p =
dynamic_cast<T*
>(r.get()))
46 return (
void)r.release(), std::unique_ptr<T>(p);
51 template<
class T,
class D,
class U>
52 constexpr std::unique_ptr<T, D> dynamic_pointer_cast(std::unique_ptr<U, D>&& r)
noexcept
54 if (
auto p =
dynamic_cast<std::unique_ptr<T, D>::pointer
>(r.get()))
55 return (
void)r.release(), std::unique_ptr<T, D>(p, std::forward<D>(r.get_deleter()));
56 else if constexpr (!std::is_pointer_v<D> && std::is_default_constructible_v<D>)
58 else if constexpr (std::is_copy_constructible_v<D>)
59 return std::unique_ptr<T, D>(
nullptr, r.get_deleter());
62 template<
class T,
class U>
63 constexpr std::unique_ptr<T> static_pointer_cast(std::unique_ptr<U>&& r)
noexcept
65 return std::unique_ptr<T>(
static_cast<T*
>(r.release()));
68 template<
class T,
class D,
class U>
69 constexpr std::unique_ptr<T, D> static_pointer_cast(std::unique_ptr<U, D>&& r)
noexcept
71 return std::unique_ptr<T, D>(r.release(), std::forward<D>(r.get_deleter()));
74#if defined(__cpp_concepts)
78 using with_reference = _Ty&;
81 concept can_reference =
requires {
typename with_reference<T>; };
85 concept dereferenceable =
requires(T & t) {
86 { *t } -> detail::can_reference;
90#if defined(__cpp_lib_forward_like)
91 using std::forward_like;
93 template <
class Ty,
class Uty>
94 [[nodiscard]]
constexpr auto&& forward_like(Uty&& Ux)
noexcept
96 static_assert(detail::can_reference<Ty>,
"forward_like's first template argument must be a referenceable type.");
98 using UnrefT = std::remove_reference_t<Ty>;
99 using UnrefU = std::remove_reference_t<Uty>;
100 if constexpr (std::is_const_v<UnrefT>) {
101 if constexpr (std::is_lvalue_reference_v<Ty>) {
102 return static_cast<const UnrefU&
>(Ux);
105 return static_cast<const UnrefU&&
>(Ux);
109 if constexpr (std::is_lvalue_reference_v<Ty>) {
110 return static_cast<UnrefU&
>(Ux);
113 return static_cast<UnrefU&&
>(Ux);
119#if __cpp_lib_byteswap < 202110L
121 [[nodiscard]]
constexpr unsigned short byteswap_ushort(
const unsigned short val)
noexcept {
122 return static_cast<unsigned short>((val << 8) | (val >> 8));
125 [[nodiscard]]
constexpr unsigned long byteswap_ulong(
const unsigned long val)
noexcept {
126 return (val << 24) | ((val << 8) & 0x00FF'0000) | ((val >> 8) & 0x0000'FF00) | (val >> 24);
129 [[nodiscard]]
constexpr unsigned long long byteswap_uint64(
const unsigned long long val)
noexcept {
130 return (val << 56) | ((val << 40) & 0x00FF'0000'0000'0000) | ((val << 24) & 0x0000'FF00'0000'0000)
131 | ((val << 8) & 0x0000'00FF'0000'0000) | ((val >> 8) & 0x0000'0000'FF00'0000)
132 | ((val >> 24) & 0x0000'0000'00FF'0000) | ((val >> 40) & 0x0000'0000'0000'FF00) | (val >> 56);
135 template <
class T, std::enable_if_t<std::is_
integral_v<T>,
int> = 0>
136 [[nodiscard]]
constexpr T byteswap(
const T val)
noexcept
138 if constexpr (
sizeof(T) == 1)
140 else if constexpr (
sizeof(T) == 2)
141 return static_cast<T
>(byteswap_ushort(
static_cast<unsigned short>(val)));
142 else if constexpr (
sizeof(T) == 4)
143 return static_cast<T
>(byteswap_ulong(
static_cast<unsigned long>(val)));
144 else if constexpr (
sizeof(T) == 8)
145 return static_cast<T
>(byteswap_uint64(
static_cast<unsigned long long>(val)));
147 static_assert(always_false<T>,
"unsupported integer size");
153#if defined(__cpp_lib_unreachable)
154 using std::unreachable;
156 [[noreturn]]
inline void unreachable() noexcept
Primary namespace for everything in this library.