32#include <initializer_list>
44namespace device {
struct cpu;
struct gpu; }
49template <
typename Ret>
55 template <
typename Fn,
typename Tuple,
size_t... Idx>
58 return __f(std::get<Idx>(std::forward<Tuple>(__t))...);
64 template <
typename SepT,
typename Arg,
65 enable_if_t<std::is_same<Ret, std::string>::value,
char> = 0>
66 static TIMEMORY_INLINE Ret join_tail(std::stringstream& _ss,
const SepT& _sep,
69 _ss << _sep << std::forward<Arg>(_arg);
76 template <
typename SepT,
typename Arg,
typename... Args,
77 enable_if_t<std::is_same<Ret, std::string>::value,
char> = 0>
78 static TIMEMORY_INLINE Ret join_tail(std::stringstream& _ss,
const SepT& _sep,
79 Arg&& _arg, Args&&... __args)
81 _ss << _sep << std::forward<Arg>(_arg);
82 return join_tail<SepT, Args...>(_ss, _sep, std::forward<Args>(__args)...);
88 template <
typename SepT,
typename Arg,
89 enable_if_t<std::is_same<Ret, std::string>::value,
char> = 0>
90 static TIMEMORY_INLINE Ret
join(std::stringstream& _ss,
const SepT&, Arg&& _arg)
92 _ss << std::forward<Arg>(_arg);
99 template <
typename SepT,
typename Arg,
typename... Args,
100 enable_if_t<std::is_same<Ret, std::string>::value,
char> = 0,
102 static TIMEMORY_INLINE Ret
join(std::stringstream& _ss,
const SepT& _sep, Arg&& _arg,
105 _ss << std::forward<Arg>(_arg);
106 return join_tail<SepT, Args...>(_ss, _sep, std::forward<Args>(__args)...);
121 template <
typename Tp,
typename Tail>
124 template <
typename Tp,
typename... Tail>
125 struct get_index_of<Tp,
std::tuple<Tp, Tail...>>
127 static constexpr int value = 0;
130 template <
typename Tp,
typename... Tail>
131 struct get_index_of<Tp,
std::tuple<Tp*, Tail...>>
133 static constexpr int value = 0;
136 template <
typename Tp,
typename... Tail>
137 struct get_index_of<Tp,
std::tuple<Tp&, Tail...>>
139 static constexpr int value = 0;
142 template <
typename Tp,
typename Head,
typename... Tail>
143 struct get_index_of<Tp,
std::tuple<Head, Tail...>>
145 static constexpr int value = 1 + get_index_of<Tp, std::tuple<Tail...>>::value;
148 template <
typename Tp,
typename... Tail>
149 struct get_index_of<Tp,
std::tuple<Tail...>>
151 static_assert(
sizeof...(Tail) != 0,
"Error! Type not found!");
157 template <
typename Fn,
typename Tuple,
size_t... Idx>
158 static TIMEMORY_INLINE Ret
invoke(Fn&& __f, Tuple&& __t, index_sequence<Idx...>)
160 __f(std::get<Idx>(std::forward<Tuple>(__t))...);
166 template <
typename Type,
typename... Args>
167 static TIMEMORY_INLINE
void construct(Args&&...
_args)
169 Type(std::forward<Args>(
_args)...);
175 template <
typename Type,
typename... Args,
size_t... Idx>
176 static TIMEMORY_INLINE
void construct_tuple(std::tuple<Args...>&&
_args,
177 index_sequence<Idx>...)
179 construct<Type>(std::get<Idx>(
_args)...);
184 template <
template <
typename>
class Access,
typename Tuple,
typename... Args,
186 static TIMEMORY_INLINE
void unroll_access(Tuple&& __t, index_sequence<Idx...>,
190 std::forward<
decltype(std::get<Idx>(__t))>(std::get<Idx>(__t)),
191 std::forward<Args>(__args)...));
196 template <
typename Access,
typename Tuple,
typename... Args,
size_t... Idx>
197 static TIMEMORY_INLINE
void variadic_1d(Tuple&& __t, Args&&...
_args,
198 index_sequence<Idx...>)
201 construct<
typename std::tuple_element<Idx, Access>::type>(
202 std::get<Idx>(__t), std::forward<Args>(
_args)...));
207 template <
typename Access,
typename TupleA,
typename TupleB,
typename... Args,
209 static TIMEMORY_INLINE
void variadic_2d(TupleA&& __a, TupleB&& __b, Args&&...
_args,
210 index_sequence<Idx...>)
213 construct<
typename std::tuple_element<Idx, Access>::type>(
214 std::get<Idx>(__a), std::get<Idx>(__b), std::forward<Args>(
_args)...));
219 template <
template <
typename>
class Access,
typename Tuple,
typename... Args,
221 static TIMEMORY_INLINE
void type_access(index_sequence<Idx...>, Args&&... __args)
224 Access<
decay_t<
typename std::tuple_element<Idx, Tuple>::type>>(
225 std::forward<Args>(__args)...));
230 template <
typename Access,
typename Tuple,
typename... Args,
size_t... Idx>
231 static TIMEMORY_INLINE
void apply_access_with_indices(Tuple&& __t,
232 index_sequence<Idx...>,
238 std::forward<
decltype(std::get<Idx>(__t))>(std::get<Idx>(__t)),
239 std::forward<Args>(__args)...));
244 template <
typename Access,
typename TupleA,
typename TupleB,
typename... Args,
246 static TIMEMORY_INLINE
void apply_access2(TupleA&& __ta, TupleB&& __tb,
247 index_sequence<Idx...>, Args&&... __args)
251 std::forward<
decltype(std::get<Idx>(__ta))>(std::get<Idx>(__ta)),
252 std::forward<
decltype(std::get<Idx>(__tb))>(std::get<Idx>(__tb)),
253 std::forward<Args>(__args)...));
258 template <
size_t N,
typename Device,
typename Func,
typename... Args,
259 typename std::enable_if<
260 (N == 1 && std::is_same<Device, device::gpu>::value),
char>::type = 0>
263 std::forward<Func>(__func)(std::forward<Args>(__args)...);
266 template <
size_t N,
typename Device,
typename Func,
typename... Args,
267 typename std::enable_if<(N > 1 && std::is_same<Device, device::gpu>::value),
271 std::forward<Func>(__func)(std::forward<Args>(__args)...);
272 unroll<N - 1, Device, Func, Args...>(std::forward<Func>(__func),
273 std::forward<Args>(__args)...);
278 template <
size_t N,
typename Device,
typename Func,
typename... Args,
279 typename std::enable_if<
280 (N == 1 && std::is_same<Device, device::cpu>::value),
int>::type = 0>
281 static TIMEMORY_INLINE
void unroll(Func&& __func, Args&&... __args)
283 std::forward<Func>(__func)(std::forward<Args>(__args)...);
286 template <
size_t N,
typename Device,
typename Func,
typename... Args,
287 typename std::enable_if<(N > 1 && std::is_same<Device, device::cpu>::value),
289 static TIMEMORY_INLINE
void unroll(Func&& __func, Args&&... __args)
291 std::forward<Func>(__func)(std::forward<Args>(__args)...);
292 unroll<N - 1, Device, Func, Args...>(std::forward<Func>(__func),
293 std::forward<Args>(__args)...);
311template <
typename Ret>
325 using string_tuple_t = std::tuple<std::string>;
331 template <
typename Tp,
bool _Val =
true,
typename Up = int,
332 typename Dt =
typename std::remove_const<decay_t<Tp>>::type>
337 template <
typename SepT,
typename... Args,
typename ReturnT = Ret,
338 size_t N =
sizeof...(Args),
enable_if_t<(N > 0),
char> = 0>
339 static TIMEMORY_INLINE ReturnT
join(SepT&& separator, Args&&... __args)
noexcept
341 std::stringstream ss;
342 ss << std::boolalpha;
343 return internal::apply<Ret>::template
join<SepT, Args...>(
344 std::ref(ss), std::forward<SepT>(separator), std::forward<Args>(__args)...);
349 template <
typename SepT,
typename Arg, if_
string_t<Arg, true> = 0>
350 static TIMEMORY_INLINE Ret
join(SepT&&, Arg&& _arg)
noexcept
352 return std::forward<Arg>(_arg);
357 template <
typename SepT,
typename Arg, if_
string_t<Arg, false> = 0>
358 static TIMEMORY_INLINE Ret
join(SepT&&, Arg&& _arg)
noexcept
360 std::stringstream ss;
367 static TIMEMORY_INLINE Ret
join(
const string_t&)
noexcept {
return Ret{}; }
368 static TIMEMORY_INLINE Ret
join(
const char)
noexcept {
return Ret{}; }
379template <
typename Ret>
387 template <
typename Fn,
typename... Args,
size_t N =
sizeof...(Args)>
388 static TIMEMORY_INLINE Ret
invoke(Fn&& __f, Args&&... __args)
noexcept
390 return __f(std::forward<Args>(__args)...);
396 template <
typename Fn,
template <
typename...>
class Tuple,
typename... Args,
397 size_t N =
sizeof...(Args)>
398 static TIMEMORY_INLINE Ret
invoke(Fn&& __f, Tuple<Args...>&& __t)
noexcept
400 using Tuple_t = Tuple<Args...>;
401 return internal::apply<Ret>::template invoke<Fn, Tuple_t>(
407 template <
typename SepT,
typename Tuple,
size_t... Idx>
422struct apply<
std::tuple<std::string>>
426 using apply_v = apply<string_t>;
433 template <
typename LabelSep,
typename EntrySep,
typename LabelTup,
434 typename EntryTup,
size_t... Idx>
435 static Ret
join(LabelSep&& _label_sep, EntrySep&& _entry_sep,
436 LabelTup&& _label_tup, EntryTup&& _entry_tup,
441 std::get<Idx>(_label_tup),
442 std::get<Idx>(_entry_tup))...);
449 template <
typename LabelSep,
typename EntrySep,
typename LabelTup,
typename EntryTup,
450 size_t N = std::tuple_size<decay_t<LabelTup>>::value,
452 static TIMEMORY_INLINE Ret
join(LabelSep&& _label_sep, EntrySep&& _entry_sep,
453 LabelTup&& _label_tup, EntryTup&& _entry_tup)
noexcept
456 return impl::join(std::forward<LabelSep>(_label_sep),
457 std::forward<EntrySep>(_entry_sep),
458 std::forward<LabelTup>(_label_tup),
459 std::forward<EntryTup>(_entry_tup),
460 make_index_sequence<N>{});
467 template <
typename LabelSep,
typename EntrySep,
typename LabelTup,
typename EntryTup,
468 size_t N = std::tuple_size<decay_t<LabelTup>>::value,
469 enable_if_t<N == 0, int> = 0>
470 static TIMEMORY_INLINE Ret
join(LabelSep&&, EntrySep&&, LabelTup&&,
492 template <
size_t I,
typename A>
493 using Access_t =
typename std::tuple_element<I, A>::type;
498 template <
typename Fn,
typename... Args,
size_t N =
sizeof...(Args)>
499 static TIMEMORY_INLINE
Ret invoke(Fn&& __f, Args&&... __args)
noexcept
501 __f(std::forward<Args>(__args)...);
507 template <
typename Fn,
template <
typename...>
class Tuple,
typename... Args,
508 size_t N =
sizeof...(Args)>
509 static TIMEMORY_INLINE
Ret invoke(Fn&& __f, Tuple<Args...>&& __t)
noexcept
511 using Tuple_t = Tuple<Args...>;
512 internal::apply<Ret>::template invoke<Fn, Tuple_t>(
519 template <typename Tuple, size_t N = std::tuple_size<Tuple>::value>
520 static TIMEMORY_INLINE
void plus(Tuple& _lhs,
const Tuple& _rhs)
noexcept
528 template <typename Tuple, size_t N = std::tuple_size<Tuple>::value>
529 static TIMEMORY_INLINE
void minus(Tuple& _lhs,
const Tuple& _rhs)
noexcept
536 template <
size_t N,
typename Device,
typename Func,
typename... Args,
540 internal::apply<void>::template unroll<N, Device, Func, Args...>(
541 std::forward<Func>(__func), std::forward<Args>(__args)...);
546 template <
size_t N,
typename Device,
typename Func,
typename... Args,
548 static TIMEMORY_INLINE
void unroll(Func&& __func, Args&&... __args)
noexcept
550 internal::apply<void>::template unroll<N, Device, Func, Args...>(
551 std::forward<Func>(__func), std::forward<Args>(__args)...);
560 template <
typename Tp,
typename Value>
562 ->
decltype(std::forward<Tp>(_t) = std::forward<Value>(_v), void())
564 std::forward<Tp>(_t) = std::forward<Value>(_v);
567 template <
typename Tp,
typename Value>
571 template <
typename Tuple,
typename Value,
size_t... Idx>
576 set_value_fold(std::get<Idx>(_t), 0, std::forward<Value>(_v)));
581 template <
typename Tuple,
typename Value>
582 static TIMEMORY_INLINE
void set_value(Tuple&& _t, Value&& _v)
noexcept
584 constexpr auto N = std::tuple_size<decay_t<Tuple>>::value;
585 set_value_fold(std::forward<Tuple>(_t), std::forward<Value>(_v),
591 template <
typename Access,
typename Tuple,
size_t... Idx,
typename... Args>
601 template <
typename Access,
typename Tuple,
typename... Args>
602 static TIMEMORY_INLINE
void access(Tuple&& __t, Args&&... __args)
noexcept
604 constexpr auto N = std::tuple_size<decay_t<Access>>::value;
605 constexpr auto Nt = std::tuple_size<decay_t<Tuple>>::value;
606 static_assert(N == Nt,
"Cannot fold Access from Tuple because sizes differ");
607 access_fold<Access>(std::forward<Tuple>(__t), std::make_index_sequence<N>{},
608 std::forward<Args>(__args)...);
613 template <
typename Access,
size_t... Idx,
typename... Args>
616 return std::make_tuple(
622 template <
typename Access,
typename... Args>
623 static TIMEMORY_INLINE
auto get(Args&&... __args)
625 constexpr auto N = std::tuple_size<decay_t<Access>>::value;
626 return get_fold<Access>(std::make_index_sequence<N>{},
627 std::forward<Args>(__args)...);
632 template <
typename Access,
typename Tuple,
typename... Args>
634 Args&&... __args)
noexcept
636 constexpr auto N = std::tuple_size<decay_t<Tuple>>::value;
637 internal::apply<void>::template apply_access_with_indices<Access, Tuple, Args...>(
639 std::forward<Args>(__args)...);
644 template <
typename Access,
typename TupleA,
typename TupleB,
typename... Args>
645 static TIMEMORY_INLINE
void access2(TupleA&& __ta, TupleB&& __tb,
646 Args&&... __args)
noexcept
648 constexpr size_t N = std::tuple_size<decay_t<Access>>::value;
649 constexpr size_t Na = std::tuple_size<decay_t<TupleA>>::value;
650 constexpr size_t Nb = std::tuple_size<decay_t<TupleB>>::value;
651 static_assert(Na == Nb,
"tuple A size must match tuple B size");
652 internal::apply<void>::template apply_access2<Access, TupleA, TupleB, Args...>(
653 std::forward<TupleA>(__ta), std::forward<TupleB>(__tb),
659 template <
template <
typename>
class Access,
typename Tuple,
typename... Args>
660 static TIMEMORY_INLINE
void unroll_access(Tuple&& __t, Args&&... __args)
noexcept
662 constexpr size_t N = std::tuple_size<decay_t<Tuple>>::value;
663 internal::apply<void>::template unroll_access<Access, Tuple, Args...>(
665 std::forward<Args>(__args)...);
670 template <
template <
typename>
class Access,
typename Tuple,
typename... Args>
671 static TIMEMORY_INLINE
void type_access(Args&&... __args)
noexcept
673 constexpr size_t N = std::tuple_size<decay_t<Tuple>>::value;
674 internal::apply<void>::template type_access<Access, Tuple, Args...>(
Tp & plus(Tp &, const Up &)
Tp & minus(Tp &, const Up &)
auto join(const char *sep, Arg &&arg, Args &&... args)
Ret invoke(string_view_t &&label, Func &&func, Args &&... args)
std::make_integer_sequence< size_t, Num > make_index_sequence
Alias template make_index_sequence.
std::array< char *, 4 > _args
typename std::decay< T >::type decay_t
Alias template for decay.
typename std::enable_if< B, T >::type enable_if_t
Alias template for enable_if.
tim::mpl::apply< std::string > string
std::integer_sequence< size_t, Idx... > index_sequence
Alias template index_sequence.
static void access_with_indices(Tuple &&__t, Args &&... __args) noexcept
static auto set_value_fold(Tp &&_t, int, Value &&_v) noexcept -> decltype(std::forward< Tp >(_t)=std::forward< Value >(_v), void())
static void unroll_access(Tuple &&__t, Args &&... __args) noexcept
static void access2(TupleA &&__ta, TupleB &&__tb, Args &&... __args) noexcept
static void set_value_fold(Tuple &&_t, Value &&_v, index_sequence< Idx... >) noexcept
static Ret invoke(Fn &&__f, Args &&... __args) noexcept
static void access(Tuple &&__t, Args &&... __args) noexcept
static void set_value_fold(Tp &&, long, Value &&) noexcept
static auto get(Args &&... __args)
typename std::tuple_element< I, A >::type Access_t
static void access_fold(Tuple &&_t, index_sequence< Idx... >, Args &&... _args)
static void set_value(Tuple &&_t, Value &&_v) noexcept
static auto get_fold(index_sequence< Idx... >, Args &&... _args)
static void minus(Tuple &_lhs, const Tuple &_rhs) noexcept
static Ret invoke(Fn &&__f, Tuple< Args... > &&__t) noexcept
static void unroll(Func &&__func, Args &&... __args) noexcept
static void plus(Tuple &_lhs, const Tuple &_rhs) noexcept
static void type_access(Args &&... __args) noexcept
static string_t join(SepT &&separator, Tuple &&__tup, index_sequence< Idx... >) noexcept
static Ret invoke(Fn &&__f, Args &&... __args) noexcept
static Ret invoke(Fn &&__f, Tuple< Args... > &&__t) noexcept
#define TIMEMORY_FOLD_EXPRESSION(...)