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> {
105struct remove_reference {
110struct remove_reference<T&> {
115struct remove_reference<T&&> {
121 typedef typename remove_cv<typename remove_reference<T>::type>::type type;
127struct is_string : false_type {
131struct is_string<T&> : is_string<T> {
135struct is_string<const T> : is_string<T> {
139struct is_string<const T*> : is_string<T*> {
143struct string_handler {
147struct string_handler<const T> : string_handler<T> {
151struct string_handler<const T*> : string_handler<T*> {
155struct string_handler<T&> : string_handler<T> {
158#define MARK_AS_STRING(TYPE, LEN, SRC) \
160 struct is_string<TYPE> : constant<bool, true> { \
163 struct string_handler<TYPE> { \
164 static size_t length(const TYPE& x) { return static_cast<size_t>(LEN); } \
165 static void src_copy(const TYPE& x, char* output) \
167 [&output](const char* src) { \
168 while (*src != '\0') \
169 *(output++) = *(src++); \
175inline size_t c_str_len(
const char* c)
183MARK_AS_STRING(
char*, c_str_len(x), x);
185MARK_AS_STRING(std::string, x.size(), x.c_str());
187#ifdef INK_ENABLE_UNREAL
188MARK_AS_STRING(FString, x.Len(), TCHAR_TO_UTF8(*x));
196struct function_traits;
199template<
class R,
class... Args>
200struct function_traits<R (*)(Args...)> :
public function_traits<R(Args...)> {
203template<
class R,
class... Args>
204struct function_traits<R(Args...)> {
205 using return_type = R;
207 static constexpr unsigned int arity =
sizeof...(Args);
209 template<
unsigned int N>
211 static_assert(N < arity,
"error: invalid parameter index.");
212 using type =
typename get_ith_type<N, Args...>::type;
217template<
class C,
class R,
class... Args>
218struct function_traits<R (C::*)(Args...)> :
public function_traits<R(C&, Args...)> {
222template<
class C,
class R,
class... Args>
223struct function_traits<R (C::*)(Args...) const> :
public function_traits<R(C&, Args...)> {
227template<
class C,
class R>
228struct function_traits<R(C::*)> :
public function_traits<R(C&)> {
233struct function_traits {
235 using call_type = function_traits<
decltype(&F::operator())>;
238 using return_type =
typename call_type::return_type;
240 static constexpr unsigned int arity = call_type::arity - 1;
242 template<
unsigned int N>
244 static_assert(N < arity,
"error: invalid parameter index.");
245 using type =
typename call_type::template argument<N + 1>::type;
252using Invoke =
typename T::type;
259template<
class S1,
class S2>
262template<
unsigned... I1,
unsigned... I2>
263struct concat<seq<I1...>, seq<I2...>> : seq<I1..., (sizeof...(I1) + I2)...> {
266template<
class S1,
class S2>
267using Concat = Invoke<concat<S1, S2>>;
272using GenSeq = Invoke<gen_seq<N>>;
275struct gen_seq : Concat<GenSeq<N / 2>, GenSeq<N - N / 2>> {
279struct gen_seq<0> : seq<> {
283struct gen_seq<1> : seq<0> {