You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.6 KiB
88 lines
2.6 KiB
#pragma once
|
|
|
|
#include <limits>
|
|
#include <vector>
|
|
#include <new>
|
|
#include <utility>
|
|
#include <memory>
|
|
|
|
#include <utils/no_unique_address_emulation.hpp>
|
|
|
|
namespace detail
|
|
{
|
|
template <std::size_t _Np, typename... _Types>
|
|
struct __nth__ {
|
|
};
|
|
|
|
template <typename _Tp0, typename... _Rest>
|
|
struct __nth__<0, _Tp0, _Rest...> {
|
|
using type = _Tp0;
|
|
};
|
|
|
|
template <typename _Tp0, typename _Tp1, typename... _Rest>
|
|
struct __nth__<1, _Tp0, _Tp1, _Rest...> {
|
|
using type = _Tp1;
|
|
};
|
|
|
|
template <typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
|
|
struct __nth__<2, _Tp0, _Tp1, _Tp2, _Rest...> {
|
|
using type = _Tp2;
|
|
};
|
|
|
|
template <const std::size_t _Np, typename _Tp0, typename _Tp1, typename _Tp2, typename... _Rest>
|
|
struct __nth__<_Np, _Tp0, _Tp1, _Tp2, _Rest...> : __nth__<_Np - 3, _Rest...> {
|
|
};
|
|
|
|
template <const std::size_t _Idx, typename... _Types>
|
|
using _Select_nth_type = typename __nth__<_Idx, _Types...>::type;
|
|
|
|
template <unsigned long long _Val, typename... _Ints>
|
|
struct _Select_int_base;
|
|
|
|
template <unsigned long long _Val, typename _IntType, typename... _Ints>
|
|
struct _Select_int_base<_Val, _IntType, _Ints...> : std::conditional_t<(_Val <= std::numeric_limits<_IntType>::max()),
|
|
std::integral_constant<_IntType, (_IntType)_Val>,
|
|
_Select_int_base<_Val, _Ints...>> {
|
|
};
|
|
|
|
template <unsigned long long _Val>
|
|
struct _Select_int_base<_Val> {
|
|
};
|
|
|
|
template <unsigned long long _Val>
|
|
using _Select_int =
|
|
typename _Select_int_base<_Val, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>::type::
|
|
value_type;
|
|
} // namespace detail
|
|
|
|
namespace impl::variadic
|
|
{
|
|
#pragma packed(push, 1)
|
|
|
|
template <typename _Index_type>
|
|
struct _Index_base {
|
|
_Index_type __this_;
|
|
_Index_type __next_;
|
|
|
|
constexpr _Index_base(const _Index_type __i, const _Index_type __j) noexcept : __this_{__i}, __next_{__j} {}
|
|
};
|
|
|
|
#pragma packed(pop)
|
|
|
|
template <typename _Ty, typename _Index_type>
|
|
struct _Element : public _Index_base<_Index_type>,
|
|
public no_unique_address_emulation<_Ty> {
|
|
template <typename... _Args>
|
|
explicit constexpr _Element(const std::size_t __i, _Args &&...__ctors) //
|
|
noexcept(std::is_nothrow_constructible_v<_Ty, _Args...>)
|
|
: _Index_base<_Index_type>{static_cast<_Index_type>(__i), std::numeric_limits<_Index_type>::max()},
|
|
no_unique_address_emulation<_Ty>(std::forward<_Args>(__ctors)...)
|
|
{
|
|
}
|
|
};
|
|
|
|
template <typename _Allocator, typename... _Types>
|
|
struct variadic {
|
|
|
|
};
|
|
} // namespace impl::variadic
|