10 #include <type_traits>    15 #define UNREACHABLE __builtin_unreachable()    17 #define UNREACHABLE __assume(0)    22 template <
typename E, std::enable_if_t<std::is_enum_v<E>, 
int> = 0> constexpr 
inline decltype(
auto) 
to_integral(E e) {
    23     return static_cast<typename std::underlying_type<E>::type
>(e);
    25 template <
typename T, std::enable_if_t<std::is_
integral_v<T>, 
int> = 0> constexpr 
inline decltype(
auto) 
to_integral(T v) { 
return v; }
    35 template <
class... Ts> 
void sink(Ts&&... ts) { (
static_cast<void>(std::move(ts)), ...); }
    37 template <
class Lambda, 
class... Ts> constexpr 
auto test_sfinae(Lambda lambda, Ts&&...) -> decltype(lambda(std::declval<Ts>()...), 
bool{}) {
    42 template <
typename T, 
typename V, 
size_t... I> 
void visit_impl(T&& t, V&& v, std::index_sequence<I...>) { (..., v(std::get<I>(t))); }
    44 template <
typename T, 
typename V> 
void visit(T&& t, V&& v) {
    45     visit_impl(std::forward<T>(t), std::forward<V>(v), std::make_index_sequence<std::tuple_size<
typename std::decay<T>::type>::value>());
    50 template <
typename T> 
inline void freeany(T ptr) {
    51     static_assert(std::is_array_v<T> || std::is_pointer_v<T>, 
"T needs to be a pointer or an array type");
    58     constexpr 
auto& get_underlying(
EHTag) 
const noexcept { 
return static_cast<const CRTP&
>(*this).underlying; }
    59     constexpr 
auto& values() 
const noexcept { 
return static_cast<const CRTP&
>(*this).values; }
    61     constexpr 
static EHTag tag{};
    64     [[nodiscard]] constexpr std::string_view 
to_string() const noexcept { 
return values()[
to_integral(get_underlying(tag))]; }
    66         const auto res = 
cexpr::find(values().cbegin(), values().cend(), v);
    67         return res != values().end() ? std::optional{CRTP{tag, std::distance(values().cbegin(), res)}} : std::nullopt;
    72     constexpr 
auto& get_underlying(
EHTag) 
const noexcept { 
return static_cast<const CRTP&
>(*this).underlying; }
    73     constexpr 
auto& values() 
const noexcept { 
return static_cast<const CRTP&
>(*this).values; }
    75     constexpr 
static EHTag tag{};
    78     [[nodiscard]] constexpr std::string_view 
to_string() const noexcept {
    79         return values()[
sizeof(decltype(
to_integral(get_underlying(tag)))) * 8 - __builtin_clz(
to_integral(get_underlying(tag))) -
    83         const auto res = 
cexpr::find(values().cbegin(), values().end(), v);
    84         return res != values().cend() ? std::optional{CRTP{tag, (1u << std::distance(values().cbegin(), res))}} : std::nullopt;
    88 template <
class E, 
class = std::enable_if_t<std::is_base_of_v<EnumSetHelper<E>, E>>> E 
operator|(E lhs, E rhs) {
    92 template <
class E, 
class = std::enable_if_t<std::is_base_of_v<EnumSetHelper<E>, E>>> E& 
operator|=(E& lhs, E rhs) {
   105         const auto hi1b = 
sizeof(U) * 8 - lz - 1;
   115         const auto hi1b = 
sizeof(U) * 8 - lz - 1;
   123     gsl::owner<char*> ptr{};
   140     [[nodiscard]] 
inline auto begin() const noexcept { 
return std::string_view{ptr}.begin(); }
   141     [[nodiscard]] 
inline auto end() const noexcept { 
return std::string_view{ptr}.end(); }
   142     [[nodiscard]] 
inline auto cbegin() const noexcept { 
return std::string_view{ptr}.cbegin(); }
   143     [[nodiscard]] 
inline auto cend() const noexcept { 
return std::string_view{ptr}.cend(); }
   145     constexpr 
inline explicit operator const char*() 
const noexcept { 
return ptr; }
   146     constexpr 
inline explicit operator char*() noexcept { 
return ptr; }
   148     constexpr 
inline explicit operator bool() const noexcept { 
return ptr; }
   163     static constexpr std::size_t arity = 
sizeof...(Args);
   165     template <std::
size_t N> 
struct Arg {
   166         static_assert(N < arity, 
"error: invalid parameter index.");
   167         using type = 
typename std::tuple_element<N, std::tuple<Args...>>
::type;
   190     static constexpr std::size_t arity = call_type::arity - 1;
   192     template <std::
size_t N> 
struct Arg {
   193         static_assert(N < arity, 
"error: invalid parameter index.");
   196     template <std::
size_t N> 
using Arg_t = 
typename Arg<N>::type;
   205 template <
typename T> 
struct NoallocWFree : 
private std::allocator<gsl::owner<T>> { 
   207     using std::allocator<gsl::owner<T>>::allocate;
   208     using std::allocator<gsl::owner<T>>::deallocate;
   209     constexpr 
inline void construct(gsl::owner<T>* ptr) 
const noexcept {}
   213 template <
typename T, 
typename D> 
struct UniqueSpan : std::unique_ptr<T[], D> {
   214     UniqueSpan(T* p, D d) noexcept : std::unique_ptr<T[], D>(p, d) {}
   215     inline auto begin() const noexcept { 
return this->
get(); }
   216     inline auto end() const noexcept { 
return this->
get() + this->get_deleter()(
nullptr); }
   217     inline auto cbegin() const noexcept { 
return this->
get(); }
   218     inline auto cend() const noexcept { 
return this->
get() + this->get_deleter()(
nullptr); }
   224     inline auto begin() const noexcept { 
return std::basic_string_view<T*>{this->
get()}.
begin(); }
   225     inline auto end() const noexcept { 
return std::basic_string_view<T*>{this->
get()}.
end(); }
   226     inline auto cbegin() const noexcept { 
return std::basic_string_view<T*>{this->
get()}.
cbegin(); }
   227     inline auto cend() const noexcept { 
return std::basic_string_view<T*>{this->
get()}.
cend(); }
   232     static constexpr 
auto false_it(T* arr) {
   241     inline auto begin() const noexcept { 
return this->
get(); }
   242     inline auto end() const noexcept { 
return false_it(this->
get()); }
   243     inline auto cbegin() const noexcept { 
return this->
get(); }
   244     inline auto cend() const noexcept { 
return false_it(this->
get()); }
   248 namespace impl::any {
   254     static_assert(CountFTraits::arity == 1, 
"Counting function requires one argument");
   255     static_assert(std::is_same_v<
typename CountFTraits::template Arg_t<0>, U>, 
"Counting function requires the underlying ptr as argument");
   256     using CountFRet = 
typename CountFTraits::return_type;
   259     static_assert(DataFTraits::arity == 3, 
"Data function requires three arguments");
   260     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<0>, U>, 
"Data function requires the underlying ptr as first argument");
   261     static_assert(std::is_pointer_v<
typename DataFTraits::template Arg_t<0>>, 
"Data function requires a pointer to the array as second argument");
   262     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<2>, CountFRet>,
   263                   "Data function requires counting function return type as third argument");
   264     using T = std::remove_pointer_t<typename DataFTraits::template Arg_t<1>>;
   266     using RetType = std::optional<std::vector<T>>;
   267     std::vector<T> ret{};
   268     ret.resize(count_fcn(underlying));
   270         const auto res = data_fcn(underlying, ret.data(), ret.size());
   272             return RetType{std::nullopt};
   278     static_assert(CountFTraits::arity == 1, 
"Counting function requires one argument");
   279     static_assert(std::is_same_v<
typename CountFTraits::template Arg_t<0>, U>, 
"Counting function requires the underlying ptr as argument");
   280     using CountFRet = 
typename CountFTraits::return_type;
   283     static_assert(DataFTraits::arity == 3, 
"Data function requires three arguments");
   284     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<0>, U>, 
"Data function requires the underlying ptr as first argument");
   285     static_assert(std::is_pointer_v<
typename DataFTraits::template Arg_t<0>>, 
"Data function requires a pointer to the array as second argument");
   286     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<2>, CountFRet>,
   287                   "Data function requires counting function return type as third argument");
   288     using T = std::remove_pointer_t<typename DataFTraits::template Arg_t<1>>;
   291     using RetType = std::optional<std::vector<gsl::owner<T>, LocAlloc>>;
   293     auto& vec = ret.emplace();
   294     vec.resize(count_fcn(underlying));
   296         const auto res = data_fcn(underlying, vec.data(), vec.size());
   298             return RetType{std::nullopt};
   303 template <
typename Conv = void, 
typename U, 
typename CF, 
typename DF, 
typename... DF_Args>
   306     static_assert(CountFTraits::arity == 1, 
"Counting function requires one argument");
   307     static_assert(std::is_same_v<
typename CountFTraits::template Arg_t<0>, U>, 
"Counting function requires the underlying ptr as argument");
   308     using CountFRet = 
typename CountFTraits::return_type;
   311     static_assert(DataFTraits::arity == 3 + 
sizeof...(DF_Args), 
"Data function requires three base arguments");
   312     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<0>, U>, 
"Data function requires the underlying ptr as first argument");
   313     static_assert(std::is_pointer_v<
typename DataFTraits::template Arg_t<0>>, 
"Data function requires a pointer to the array as second argument");
   314     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<2>, CountFRet>,
   315                   "Data function requires counting function return type as third argument");
   316     using DedT = std::remove_pointer_t<typename DataFTraits::template Arg_t<1>>;
   317     if constexpr (!std::is_same_v<Conv, void>)
   318         static_assert(
sizeof(DedT) == 
sizeof(Conv) && 
alignof(DedT) == 
alignof(Conv), 
"Conversion type must have the same size as the source");
   319     using T = std::conditional_t<std::is_same_v<Conv, void>, DedT, Conv>;
   321     using RetType = std::optional<std::vector<T>>;
   323     auto& vec = ret.emplace();
   324     vec.resize(count_fcn(underlying));
   326         const auto res = data_fcn(underlying, reinterpret_cast<DedT*>(vec.data()), vec.size(), df_args...); 
   328             return RetType{std::nullopt};
   333 template <
typename Wrap, 
template <
class, 
class> 
typename Span = 
UniqueSpan, void (*dtroy)(Wrap*) = std::destroy_at<Wrap>, 
typename U,
   334           typename DataFRet, 
typename T, 
typename... DataFArgs>
   337     auto res = data_fcn(underlying, reinterpret_cast<T**>(&lease_arr), data_f_args...);
   338     auto deleter = [=](Wrap* arr) {
   342         for (
auto it = arr; it != arr + res; ++it)
   348                                                   decltype(deleter), void (*)(Wrap*)>>;
   350     if constexpr (std::is_same_v<RetType, 
UniqueSpan<Wrap, decltype(deleter)>>) {
   351         return RetType{res != -1 ? lease_arr : 
nullptr, deleter};
   354             return RetType{
nullptr, 
nullptr};
   355         return RetType{lease_arr, [](
auto arr) {
   365 template <
typename Conv = 
void, 
typename U, 
typename CountFRet, 
typename DataFRet, 
typename T>
   367     std::vector<gsl::owner<T>> ret{};
   368     ret.resize(count_fcn(underlying));
   369     const auto res = data_fcn(underlying, ret.data(), ret.size());
   371         throw std::runtime_error{__func__};
   372     if constexpr (std::is_same_v<void, Conv>)
   374     std::vector<Conv> tret{};
   375     tret.reserve(ret.size());
   376     std::move(ret.begin(), ret.end(), std::back_inserter(tret));
   379 template <
typename Conv = 
void, 
typename U, 
typename CF, 
typename DF>
   382     static_assert(CountFTraits::arity == 1, 
"Counting function requires one argument");
   383     static_assert(std::is_same_v<
typename CountFTraits::template Arg_t<0>, U>, 
"Counting function requires the underlying ptr as argument");
   384     using CountFRet = 
typename CountFTraits::return_type;
   387     static_assert(DataFTraits::arity == 3, 
"Data function requires three arguments");
   388     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<0>, U>, 
"Data function requires the underlying ptr as first argument");
   389     static_assert(std::is_pointer_v<
typename DataFTraits::template Arg_t<0>>, 
"Data function requires a pointer to the array as second argument");
   390     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<2>, CountFRet>,
   391                   "Data function requires counting function return type as third argument");
   392     using T = std::remove_pointer_t<typename DataFTraits::template Arg_t<1>>;
   395     std::vector<gsl::owner<T>, LocAlloc> ret{};
   396     ret.resize(count_fcn(underlying));
   397     const auto res = data_fcn(underlying, ret.data(), ret.size());
   399         throw std::runtime_error{__func__};
   400     if constexpr (std::is_same_v<void, Conv>)
   402     std::vector<Conv> tret{};
   403     tret.reserve(ret.size());
   404     std::move(ret.begin(), ret.end(), std::back_inserter(tret));
   408 template <
typename Conv = 
void, 
typename U, 
typename CF, 
typename DF>
   411     static_assert(CountFTraits::arity == 1, 
"Counting function requires one argument");
   412     static_assert(std::is_same_v<
typename CountFTraits::template Arg_t<0>, U>, 
"Counting function requires the underlying ptr as argument");
   413     using CountFRet = 
typename CountFTraits::return_type;
   416     static_assert(DataFTraits::arity == 3, 
"Data function requires three arguments");
   417     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<0>, U>, 
"Data function requires the underlying ptr as first argument");
   418     static_assert(std::is_pointer_v<
typename DataFTraits::template Arg_t<0>>, 
"Data function requires a pointer to the array as second argument");
   419     static_assert(std::is_same_v<
typename DataFTraits::template Arg_t<2>, CountFRet>,
   420                   "Data function requires counting function return type as third argument");
   421     using DedT = std::remove_pointer_t<typename DataFTraits::template Arg_t<1>>;
   422     using T = std::conditional_t<(sizeof(DedT) == sizeof(Conv) && alignof(DedT) == alignof(Conv)), Conv, DedT>;
   424     std::vector<T> ret{};
   425     ret.resize(count_fcn(underlying));
   426     const auto res = data_fcn(underlying, reinterpret_cast<DedT*>(ret.data()), ret.size()); 
   428         throw std::runtime_error{__func__};
   429     if constexpr (std::is_same_v<void, Conv>)
   431     std::vector<Conv> tret{};
   432     tret.reserve(ret.size());
   433     std::move(ret.begin(), ret.end(), std::back_inserter(tret));
   437 template <
typename Wrap = void, 
typename U, 
typename DataFRet, 
typename T, 
typename... DataFArgs>
   440     auto res = data_fcn(underlying, &ptr, data_f_args...);
   442         throw std::runtime_error{__func__};
   443     using ValueType = std::conditional_t<std::is_void_v<Wrap>, T, Wrap>;
   444     std::vector<ValueType> ret;
   447     const auto end = ptr + res;
   449         ret.emplace_back(*it++);
   459 template <
typename... Base> 
struct Visitor : Base... { 
using Base::operator()...; };
   461 template <
typename... T> 
Visitor(T...)->Visitor<T...>;
 auto cend() const noexcept
Definition: utility.hpp:244
 
void freeany(T ptr)
Definition: utility.hpp:50
 
typename Arg< N >::type Arg_t
Definition: utility.hpp:196
 
void sink(Ts &&...ts)
Definition: utility.hpp:35
 
UniqueFalseTerminatedSpan(T *p, D d) noexcept
Definition: utility.hpp:240
 
UniqueZstring(UniqueZstring &&uz) noexcept
Definition: utility.hpp:129
 
constexpr auto & operator++() noexcept
Definition: utility.hpp:103
 
void destroy(gsl::owner< T > *ptr) const noexcept
Definition: utility.hpp:210
 
Definition: utility.hpp:55
 
UniqueSpan(T *p, D d) noexcept
Definition: utility.hpp:214
 
auto begin() const noexcept
Definition: utility.hpp:241
 
auto begin() const noexcept
Definition: utility.hpp:224
 
auto end() const noexcept
Definition: utility.hpp:141
 
auto end() const noexcept
Definition: utility.hpp:216
 
auto cend() const noexcept
Definition: utility.hpp:143
 
typename Arg< N >::type Arg_t
Definition: utility.hpp:170
 
auto cend() const noexcept
Definition: utility.hpp:218
 
auto cbegin() const noexcept
Definition: utility.hpp:226
 
T passive
Definition: utility.hpp:48
 
Definition: utility.hpp:96
 
gsl::owner< T > value_type
Definition: utility.hpp:206
 
constexpr EnumSetIterator(E e) noexcept
Definition: utility.hpp:101
 
constexpr auto from_string_base(std::string_view v) const noexcept
Definition: utility.hpp:65
 
auto cbegin() const noexcept
Definition: utility.hpp:142
 
constexpr void construct(gsl::owner< T > *ptr) const noexcept
Definition: utility.hpp:209
 
Definition: utility.hpp:230
 
typename call_type::return_type return_type
Definition: utility.hpp:188
 
Definition: utility.hpp:213
 
constexpr auto from_string_base(std::string_view v) const noexcept
Definition: utility.hpp:82
 
Visitor(T...) -> Visitor< T... >
 
UniqueNullTerminatedSpan(T *p, D d) noexcept
Definition: utility.hpp:223
 
R return_type
Definition: utility.hpp:161
 
Definition: utility.hpp:71
 
constexpr auto test_sfinae(Lambda lambda, Ts &&...) -> decltype(lambda(std::declval< Ts >()...), bool
Definition: utility.hpp:37
 
auto end() const noexcept
Definition: utility.hpp:225
 
Definition: utility.hpp:122
 
typename std::tuple_element< N, std::tuple< Args... >>::type type
Definition: utility.hpp:167
 
E & operator|=(E &lhs, E rhs)
Definition: utility.hpp:92
 
Definition: utility.hpp:459
 
~UniqueZstring() noexcept
Definition: utility.hpp:130
 
typename RemoveOptional< OptT >::type RemoveOptional_t
Definition: utility.hpp:33
 
E operator|(E lhs, E rhs)
Definition: utility.hpp:88
 
auto cbegin() const noexcept
Definition: utility.hpp:217
 
constexpr UniqueZstring(gsl::owner< char * > ptr)
Definition: utility.hpp:127
 
auto begin() const noexcept
Definition: utility.hpp:140
 
void visit_impl(T &&t, V &&v, std::index_sequence< I... >)
Definition: utility.hpp:42
 
Definition: utility.hpp:221
 
constexpr std::string_view to_string() const noexcept
Definition: utility.hpp:64
 
Definition: utility.hpp:192
 
constexpr E operator*() const noexcept
Definition: utility.hpp:113
 
constexpr InputIt find(InputIt first, InputIt last, const T &value)
Definition: cexpr_algs.hpp:4
 
UniqueZstring & operator=(UniqueZstring &&uz) noexcept
Definition: utility.hpp:133
 
Definition: utility.hpp:155
 
Definition: utility.hpp:27
 
decltype(auto) constexpr to_integral(E e)
Definition: utility.hpp:22
 
T type
Definition: utility.hpp:31
 
auto begin() const noexcept
Definition: utility.hpp:215
 
constexpr std::string_view to_string() const noexcept
Definition: utility.hpp:78
 
Definition: utility.hpp:205
 
auto cbegin() const noexcept
Definition: utility.hpp:243
 
void visit(T &&t, V &&v)
Definition: utility.hpp:44
 
Definition: utility.hpp:151
 
Definition: utility.hpp:29
 
typename call_type::template Arg< N+1 >::type type
Definition: utility.hpp:194
 
Definition: utility.hpp:57
 
auto cend() const noexcept
Definition: utility.hpp:227
 
auto end() const noexcept
Definition: utility.hpp:242