17namespace ink::runtime::internal
19template<
typename... Ts>
20constexpr size_t sizeof_largest_type()
23 return ((ret =
sizeof(Ts) > ret ?
sizeof(Ts) : ret), ...);
26template<
unsigned int N,
typename Arg,
typename... Args>
27struct get_ith_type : get_ith_type<N - 1, Args...> {
30template<
typename Arg,
typename... Args>
31struct get_ith_type<0, Arg, Args...> {
37template<
typename T, T v>
39 static constexpr T value = v;
41 typedef constant type;
43 constexpr operator value_type() const noexcept {
return value; }
45 constexpr value_type operator()() const noexcept {
return value; }
48struct false_type : constant<bool, false> {
51struct true_type : constant<bool, true> {
55true_type test_ptr_conv(
const volatile B*);
57false_type test_ptr_conv(
const volatile void*);
58template<
typename B,
typename D>
59auto test_is_base_of(
int) ->
decltype(test_ptr_conv<B>(
static_cast<D*
>(
nullptr)));
64template<
class Base,
class Derived>
65struct is_base_of : constant<bool, decltype(test_is_base_of<Base, Derived>(0))::value> {
68template<
class T,
class U>
69struct is_same : false_type {
73struct is_same<T, T> : true_type {
77struct is_pointer : false_type {
81struct is_pointer<T*> : true_type {
90struct remove_cv<const T> {
95struct remove_cv<volatile T> {
100struct remove_cv<const volatile T> {
106 typedef std::remove_cv_t<std::remove_reference_t<T>> type;
112struct is_string : false_type {
116struct is_string<T&> : is_string<T> {
120struct is_string<const T> : is_string<T> {
124struct is_string<const T*> : is_string<T*> {
128struct string_handler {
132struct string_handler<const T> : string_handler<T> {
136struct string_handler<const T*> : string_handler<T*> {
140struct string_handler<T&> : string_handler<T> {
143#define MARK_AS_STRING(TYPE, LEN, SRC) \
145 struct is_string<TYPE> : constant<bool, true> { \
148 struct string_handler<TYPE> { \
149 static size_t length(const TYPE& x) { return static_cast<size_t>(LEN); } \
150 static void src_copy(const TYPE& x, char* output) \
152 [&output](const char* src) { \
153 while (*src != '\0') \
154 *(output++) = *(src++); \
160inline size_t c_str_len(
const char* c)
168MARK_AS_STRING(
char*, c_str_len(x), x);
170MARK_AS_STRING(std::string, x.size(), x.c_str());
172#ifdef INK_ENABLE_UNREAL
173MARK_AS_STRING(FString, x.Len(), TCHAR_TO_UTF8(*x));
181struct function_traits;
184template<
class R,
class... Args>
185struct function_traits<R (*)(Args...)> :
public function_traits<R(Args...)> {
188template<
class R,
class... Args>
189struct function_traits<R(Args...)> {
190 using return_type = R;
192 static constexpr unsigned int arity =
sizeof...(Args);
194 template<
unsigned int N>
196 static_assert(N < arity,
"error: invalid parameter index.");
197 using type =
typename get_ith_type<N, Args...>::type;
202template<
class C,
class R,
class... Args>
203struct function_traits<R (C::*)(Args...)> :
public function_traits<R(C&, Args...)> {
207template<
class C,
class R,
class... Args>
208struct function_traits<R (C::*)(Args...) const> :
public function_traits<R(C&, Args...)> {
212template<
class C,
class R>
213struct function_traits<R(C::*)> :
public function_traits<R(C&)> {
218struct function_traits {
220 using call_type = function_traits<
decltype(&F::operator())>;
223 using return_type =
typename call_type::return_type;
225 static constexpr unsigned int arity = call_type::arity - 1;
227 template<
unsigned int N>
229 static_assert(N < arity,
"error: invalid parameter index.");
230 using type =
typename call_type::template argument<N + 1>::type;
237using Invoke =
typename T::type;
244template<
class S1,
class S2>
247template<
unsigned... I1,
unsigned... I2>
248struct concat<seq<I1...>, seq<I2...>> : seq<I1..., (sizeof...(I1) + I2)...> {
251template<
class S1,
class S2>
252using Concat = Invoke<concat<S1, S2>>;
257using GenSeq = Invoke<gen_seq<N>>;
260struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> {
264struct gen_seq<0> : seq<> {
268struct gen_seq<1> : seq<0> {