1 #ifndef TTG_UTIL_META_H
2 #define TTG_UTIL_META_H
16 #if __cplusplus >= 201703L
31 template <
typename T,
typename Enabler =
void>
34 template <
typename... Ts>
36 using type = std::tuple<typename std::remove_reference<Ts>::type...>;
39 template <
typename Tuple>
42 template <
typename... TupleTs>
45 template <
typename... Ts>
47 using type = std::tuple<Ts...>;
50 template <
typename... Ts,
typename... Us,
typename... R>
53 decltype(std::tuple_cat(std::declval<std::tuple<Ts...>>(), std::declval<std::tuple<Us...>>())), R...>
::type;
56 template <
typename... TupleTs>
60 template <
typename Tuple,
template <
typename>
typename Predicate>
67 using type = std::tuple<E>;
77 template <
template <
typename>
typename Pred,
typename... Es>
79 using type = decltype(std::tuple_cat(
83 template <
typename Tuple,
template <
typename>
typename Pred>
92 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
95 template <
template <
typename>
typename Predicate,
bool Default>
96 struct probe_last<Predicate, Default> :
public std::bool_constant<Default> {};
98 template <
template <
typename>
typename Predicate,
bool Default,
typename T>
99 struct probe_last<Predicate, Default, T> :
public std::bool_constant<Predicate<T>::value> {};
101 template <
template <
typename>
typename Predicate,
bool Default,
typename T1,
typename... Ts>
104 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
107 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
116 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
125 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
128 template <
template <
typename>
typename Predicate,
bool Default>
129 struct probe_first<Predicate, Default> :
public std::bool_constant<Default> {};
131 template <
template <
typename>
typename Predicate,
bool Default,
typename T1,
typename... Ts>
132 struct probe_first<Predicate, Default, T1, Ts...> :
public std::bool_constant<Predicate<T1>::value> {};
134 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
137 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
146 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
154 template <
template <
typename>
typename Predicate,
typename... Ts>
155 struct probe_any : std::bool_constant<(Predicate<Ts>::value || ...)> {};
157 template <
template <
typename>
typename Predicate,
typename... Ts>
160 template <
template <
typename>
typename Predicate,
typename... Ts>
168 template <
template <
typename>
typename Predicate,
typename... Ts>
176 template <
template <
typename>
typename Predicate,
typename... Ts>
177 struct probe_all : std::bool_constant<(Predicate<Ts>::value && ...)> {};
179 template <
template <
typename>
typename Predicate,
typename... Ts>
182 template <
template <
typename>
typename Predicate,
typename... Ts>
190 template <
template <
typename>
typename Predicate,
typename... Ts>
202 template <
typename T>
205 template <
typename T>
206 constexpr
bool is_void_v = is_Void_v<T> || std::is_void_v<T>;
208 template <
typename T>
209 struct is_void : std::bool_constant<is_void_v<T>> {};
211 template <
typename T>
214 template <
typename T>
217 template <
typename... Ts>
220 template <
typename... Ts>
223 template <
typename... Ts>
226 template <
typename... Ts>
229 template <
typename... Ts>
232 template <
typename... Ts>
235 template <
typename... Ts>
238 template <
typename... Ts>
241 template <
typename... Ts>
244 template <
typename... Ts>
247 template <
typename... Ts>
250 template <
typename... Ts>
253 template <
typename... Ts>
256 template <
typename... Ts>
259 template <
typename T>
267 template <
typename T>
270 template <
typename T>
272 std::is_lvalue_reference_v<T> &&std::is_const_v<std::remove_reference_t<T>>;
274 template <
typename T>
277 template <
typename T>
279 std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>;
281 template <
typename T>
284 template <
typename... Ts>
287 template <
typename... Ts>
290 template <
typename... Ts>
332 template <
typename Typelist, std::
size_t N,
typename Enabler =
void>
335 template <
typename... Ts>
337 using type = std::tuple<Ts...>;
340 template <
typename... Ts>
345 template <
typename T,
typename... Ts, std::size_t N>
346 struct drop_first_n<std::tuple<T, Ts...>, N, std::enable_if_t<N != 0>> {
350 template <
typename T,
typename... Ts, std::size_t N>
356 template <
typename Typelist, std::
size_t N>
359 template <
typename ResultTuple,
typename InputTuple, std::
size_t N,
typename Enabler =
void>
362 template <
typename... Ts,
typename... Us>
364 using type = std::tuple<Ts...>;
366 template <
typename... Ts,
typename... Us>
371 template <
typename... Ts,
typename U,
typename... Us, std::size_t N>
375 template <
typename... Ts,
typename U,
typename... Us, std::size_t N>
380 template <
typename... Ts, std::size_t N>
385 template <
typename... Ts, std::size_t N>
391 template <
typename Typelist, std::
size_t N,
typename Enabler =
void>
394 template <
typename... Ts, std::size_t N>
395 struct drop_last_n<std::tuple<Ts...>, N, std::enable_if_t<N <= sizeof...(Ts)>> {
396 using type =
typename take_first_n<std::tuple<Ts...>, (
sizeof...(Ts) - N)>::type;
398 template <
typename... Ts, std::size_t N>
403 template <
typename... Ts, std::size_t N>
404 struct drop_last_n<std::tuple<Ts...>, N, std::enable_if_t<!(N <= sizeof...(Ts))>> {
405 using type = std::tuple<>;
407 template <
typename... Ts, std::size_t N>
408 struct drop_last_n<
typelist<Ts...>, N, std::enable_if_t<!(N <= sizeof...(Ts))>> {
409 using type = typelist<>;
413 template <
typename T,
typename Enabler =
void>
414 struct decayed_typelist;
416 template <
typename... Ts>
417 struct decayed_typelist<std::tuple<Ts...>> {
418 using type = std::tuple<std::decay_t<Ts>...>;
420 template <
typename... Ts>
421 struct decayed_typelist<
typelist<Ts...>> {
422 using type = typelist<std::decay_t<Ts>...>;
425 template <
typename Tuple>
426 using decayed_typelist_t =
typename decayed_typelist<Tuple>::type;
429 template <
typename T,
template <
typename...>
typename Pred>
432 template <
typename FilteredTypelist,
template <
typename...>
typename Pred,
typename... ToBeFilteredTs>
435 template <
typename... FilteredTs,
template <
typename...>
typename Pred>
436 struct filter_impl<
typelist<FilteredTs...>, Pred> {
437 using type =
typelist<FilteredTs...>;
439 template <
typename... FilteredTs,
template <
typename...>
typename Pred>
440 struct filter_impl<std::tuple<FilteredTs...>, Pred> {
441 using type = std::tuple<FilteredTs...>;
444 template <
typename... FilteredTs,
template <
typename...>
typename Pred,
typename U,
typename... RestOfUs>
445 struct filter_impl<
typelist<FilteredTs...>, Pred, U, RestOfUs...>
446 : std::conditional_t<Pred<U>::value, filter_impl<typelist<FilteredTs..., U>, Pred, RestOfUs...>,
447 filter_impl<typelist<FilteredTs...>, Pred, RestOfUs...>> {};
448 template <
typename... FilteredTs,
template <
typename...>
typename Pred,
typename U,
typename... RestOfUs>
449 struct filter_impl<std::tuple<FilteredTs...>, Pred, U, RestOfUs...>
450 : std::conditional_t<Pred<U>::value, filter_impl<std::tuple<FilteredTs..., U>, Pred, RestOfUs...>,
451 filter_impl<std::tuple<FilteredTs...>, Pred, RestOfUs...>> {};
453 template <
typename... Ts,
template <
typename...>
typename Pred>
454 struct filter<
typelist<Ts...>, Pred> : filter_impl<typelist<>, Pred, Ts...> {};
455 template <
typename... Ts,
template <
typename...>
typename Pred>
456 struct filter<std::tuple<Ts...>, Pred> : filter_impl<std::tuple<>, Pred, Ts...> {};
458 template <
typename T,
template <
typename...>
typename Pred>
459 using filter_t =
typename filter<T, Pred>::type;
461 template <
typename T>
462 using drop_void = filter<T, is_nonvoid>;
464 template <
typename T>
465 using drop_void_t =
typename drop_void<T>::type;
467 template <
typename T,
typename S,
typename U>
468 struct replace_nonvoid_helper;
471 template <
typename... Ts,
typename S,
typename... Ss,
typename U,
typename... Us>
478 template <
typename... Ts,
typename... Ss,
typename U,
typename... Us>
485 template <
typename... Ts,
typename... Us>
491 template <
typename... Ts,
typename... Ss>
497 template <
typename... Ts>
503 template <
typename T,
typename U>
504 struct replace_nonvoid;
506 template <
typename... T,
typename... U>
511 template <
typename... T,
typename... U>
512 struct replace_nonvoid<std::tuple<T...>, std::tuple<U...>> {
517 template <
typename T,
typename U>
518 using replace_nonvoid_t =
typename replace_nonvoid<T, U>::type;
524 template <
typename T>
525 struct void_to_Void_tuple;
527 template <
typename... Ts>
528 struct void_to_Void_tuple<std::tuple<Ts...>> {
529 using type = std::tuple<void_to_Void_t<Ts>...>;
532 template <
typename tupleT>
533 using void_to_Void_tuple_t =
typename void_to_Void_tuple<std::decay_t<tupleT>>::type;
535 template <
typename T>
536 struct add_lvalue_reference_tuple;
538 template <
typename... Ts>
539 struct add_lvalue_reference_tuple<std::tuple<Ts...>> {
540 using type = std::tuple<std::add_lvalue_reference_t<Ts>...>;
543 template <
typename tupleT>
544 using add_lvalue_reference_tuple_t =
typename add_lvalue_reference_tuple<tupleT>::type;
546 template <
typename T>
547 struct add_glvalue_reference_tuple;
549 template <
typename... Ts>
550 struct add_glvalue_reference_tuple<std::tuple<Ts...>> {
551 using type = std::tuple<std::conditional_t<std::is_const_v<Ts>, std::add_lvalue_reference_t<Ts>,
552 std::add_rvalue_reference_t<std::remove_const_t<Ts>>>...>;
555 template <
typename tupleT>
556 using add_glvalue_reference_tuple_t =
typename add_glvalue_reference_tuple<tupleT>::type;
558 template <
typename T,
typename... Ts>
559 struct none_has_reference {
560 static constexpr
bool value = !std::is_reference_v<T> && none_has_reference<Ts...>::value;
563 template <
typename T>
564 struct none_has_reference<T> {
565 static constexpr
bool value = !std::is_reference_v<T>;
568 template <
typename... T>
569 struct none_has_reference<
ttg::
typelist<T...>> : none_has_reference<T...> {};
572 struct none_has_reference<
ttg::
typelist<>> : std::true_type {};
574 template <
typename... T>
575 constexpr
bool none_has_reference_v = none_has_reference<T...>::value;
577 template <
typename T>
578 struct is_tuple : std::integral_constant<bool, false> {};
580 template <
typename... Ts>
581 struct is_tuple<std::tuple<Ts...>> : std::integral_constant<bool, true> {};
583 template <
typename T>
584 constexpr
bool is_tuple_v = is_tuple<T>::value;
587 struct is_span : std::false_type {};
589 template <
typename T, std::
size_t S>
590 struct is_span<
ttg::span<T, S>> : std::true_type {};
592 template <
typename T>
593 constexpr
bool is_span_v = is_span<T>::value;
595 template <
template <
class>
class Pred,
typename TupleT, std::size_t I, std::size_t... Is>
596 struct predicate_index_seq_helper;
598 template <
template <
class>
class Pred,
typename T,
typename... Ts, std::size_t I, std::size_t... Is>
599 struct predicate_index_seq_helper<Pred, std::tuple<T, Ts...>, I, Is...> {
600 using seq = std::conditional_t<Pred<T>::value,
601 typename predicate_index_seq_helper<Pred, std::tuple<Ts...>, I + 1, Is..., I>::seq,
602 typename predicate_index_seq_helper<Pred, std::tuple<Ts...>, I + 1, Is...>::seq>;
605 template <
template <
class>
class Pred, std::size_t I, std::size_t... Is>
606 struct predicate_index_seq_helper<Pred, std::tuple<>, I, Is...> {
607 using seq = std::index_sequence<Is...>;
610 template <
typename T>
611 struct is_none_void_pred : std::integral_constant<bool, is_none_void_v<T>> {};
616 template <
typename TupleT>
617 using nonvoid_index_seq =
typename predicate_index_seq_helper<is_none_void_pred, TupleT, 0>::seq;
619 template <
typename T>
620 struct is_void_pred : std::integral_constant<bool, is_void_v<T>> {};
625 template <
typename TupleT>
626 using void_index_seq =
typename predicate_index_seq_helper<is_void_pred, TupleT, 0>::seq;
634 template <
typename T,
typename Enabler =
void>
635 struct is_empty_tuple : std::false_type {};
637 template <
typename... Ts>
638 struct is_empty_tuple<std::tuple<Ts...>, std::enable_if_t<(is_Void_v<Ts> && ...)>> : std::true_type {};
640 template <
typename Tuple>
641 inline constexpr
bool is_empty_tuple_v = is_empty_tuple<Tuple>::value;
643 static_assert(!is_empty_tuple_v<std::tuple<int>>,
"ouch");
644 static_assert(is_empty_tuple_v<std::tuple<>>,
"ouch");
645 static_assert(is_empty_tuple_v<std::tuple<Void>>,
"ouch");
646 static_assert(is_empty_tuple_v<std::tuple<Void, Void, Void>>,
"ouch");
653 ~nonesuch() =
delete;
654 nonesuch(nonesuch
const &) =
delete;
655 void operator=(nonesuch
const &) =
delete;
665 template <
class Default,
class Enabler,
template <
class...>
class TT,
class... Args>
667 using value_t = std::false_type;
668 using type = Default;
671 template <
class Default,
template <
class...>
class TT,
class... Args>
672 struct detector<Default,
void_t<TT<Args...>>, TT, Args...> {
673 using value_t = std::true_type;
674 using type = TT<Args...>;
679 template <
template <
class...>
class TT,
class... Args>
680 using is_detected =
typename detail::detector<nonesuch, void, TT, Args...>::value_t;
682 template <
template <
class...>
class TT,
class... Args>
683 using detected_t =
typename detail::detector<nonesuch, void, TT, Args...>::type;
685 template <
class Default,
template <
class...>
class TT,
class... Args>
686 using detected_or = detail::detector<Default, void, TT, Args...>;
688 template <
template <
class...>
class TT,
class... Args>
689 constexpr
bool is_detected_v = is_detected<TT, Args...>::value;
691 template <
class Default,
template <
class...>
class TT,
class... Args>
692 using detected_or_t =
typename detected_or<Default, TT, Args...>::type;
694 template <
class Expected,
template <
class...>
class TT,
class... Args>
695 using is_detected_exact = std::is_same<Expected, detected_t<TT, Args...>>;
697 template <
class Expected,
template <
class...>
class TT,
class... Args>
698 constexpr
bool is_detected_exact_v = is_detected_exact<Expected, TT, Args...>::value;
700 template <
class To,
template <
class...>
class TT,
class... Args>
701 using is_detected_convertible = std::is_convertible<detected_t<TT, Args...>, To>;
703 template <
class To,
template <
class...>
class TT,
class... Args>
704 constexpr
bool is_detected_convertible_v = is_detected_convertible<To, TT, Args...>::value;
710 template <
typename T>
716 template <
typename T,
typename Enabler =
void>
717 struct has_std_hash_specialization : std::false_type {};
718 template <
typename T>
719 struct has_std_hash_specialization<
720 T,
ttg::
meta::void_t<decltype(std::declval<std::hash<T>>()(std::declval<const T &>()))>> : std::true_type {};
721 template <
typename T>
722 constexpr
bool has_std_hash_specialization_v = has_std_hash_specialization<T>::value;
729 template <
typename Key,
typename Value,
typename Enabler =
void>
730 struct send_callback;
731 template <
typename Key,
typename Value>
732 struct send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
733 using type = std::function<void(
const Key &,
const Value &)>;
735 template <
typename Key,
typename Value>
736 struct send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
737 using type = std::function<void(
const Key &)>;
739 template <
typename Key,
typename Value>
740 struct send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
741 using type = std::function<void(
const Value &)>;
743 template <
typename Key,
typename Value>
744 struct send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
745 using type = std::function<void()>;
747 template <
typename Key,
typename Value>
748 using send_callback_t =
typename send_callback<Key, Value>::type;
753 template <
typename Key,
typename Value,
typename Enabler =
void>
754 struct move_callback;
755 template <
typename Key,
typename Value>
756 struct move_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
757 using type = std::function<void(
const Key &, Value &&)>;
759 template <
typename Key,
typename Value>
760 struct move_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
761 using type = std::function<void(
const Key &)>;
763 template <
typename Key,
typename Value>
764 struct move_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
765 using type = std::function<void(Value &&)>;
767 template <
typename Key,
typename Value>
768 struct move_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
769 using type = std::function<void()>;
771 template <
typename Key,
typename Value>
772 using move_callback_t =
typename move_callback<Key, Value>::type;
777 template <
typename Key,
typename Value,
typename Enabler =
void>
778 struct broadcast_callback;
779 template <
typename Key,
typename Value>
780 struct broadcast_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
781 using type = std::function<void(
const ttg::span<const Key> &,
const Value &)>;
783 template <
typename Key,
typename Value>
784 struct broadcast_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
785 using type = std::function<void(
const ttg::span<const Key> &)>;
787 template <
typename Key,
typename Value>
788 struct broadcast_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
789 using type = std::function<void(
const Value &)>;
791 template <
typename Key,
typename Value>
792 struct broadcast_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
793 using type = std::function<void()>;
795 template <
typename Key,
typename Value>
796 using broadcast_callback_t =
typename broadcast_callback<Key, Value>::type;
803 template <
typename Key,
typename Enabler =
void>
804 struct setsize_callback;
805 template <
typename Key>
806 struct setsize_callback<Key, std::enable_if_t<!is_void_v<Key>>> {
807 using type = std::function<void(
const Key &, std::size_t)>;
809 template <
typename Key>
810 struct setsize_callback<Key, std::enable_if_t<is_void_v<Key>>> {
811 using type = std::function<void(std::size_t)>;
813 template <
typename Key>
814 using setsize_callback_t =
typename setsize_callback<Key>::type;
819 template <
typename Key,
typename Enabler =
void>
820 struct finalize_callback;
821 template <
typename Key>
822 struct finalize_callback<Key, std::enable_if_t<!is_void_v<Key>>> {
823 using type = std::function<void(
const Key &)>;
825 template <
typename Key>
826 struct finalize_callback<Key, std::enable_if_t<is_void_v<Key>>> {
827 using type = std::function<void()>;
829 template <
typename Key>
830 using finalize_callback_t =
typename finalize_callback<Key>::type;
835 template <
typename Key,
typename Return,
typename Enabler =
void>
837 template <
typename Key,
typename Return>
838 struct keymap<Key, Return, std::enable_if_t<!is_void_v<Key>>> {
839 using type = std::function<Return(
const Key &)>;
841 template <
typename Key,
typename Return>
842 struct keymap<Key, Return, std::enable_if_t<is_void_v<Key>>> {
843 using type = std::function<Return()>;
845 template <
typename Key,
typename Return =
int>
846 using keymap_t =
typename keymap<Key, Return>::type;
854 template <
typename T,
typename Enabler =
void>
855 struct input_reducer_type;
856 template <
typename T>
857 struct input_reducer_type<T, std::enable_if_t<!is_void_v<T>>> {
858 using type = std::function<void(std::decay_t<T> &,
const std::decay_t<T> &)>;
860 template <
typename T>
861 struct input_reducer_type<T, std::enable_if_t<is_void_v<T>>> {
862 using type = std::function<void()>;
864 template <
typename... valueTs>
865 struct input_reducers {
866 using type = std::tuple<typename input_reducer_type<valueTs>::type...>;
868 template <
typename... valueTs>
869 struct input_reducers<std::tuple<valueTs...>> {
870 using type = std::tuple<typename input_reducer_type<valueTs>::type...>;
872 template <
typename... valueTs>
873 using input_reducers_t =
typename input_reducers<valueTs...>::type;
878 template <
typename Key,
typename Value,
typename Enabler =
void>
879 struct prepare_send_callback;
880 template <
typename Key,
typename Value>
881 struct prepare_send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
882 using type = std::function<void(
const ttg::span<const Key> &,
const Value &)>;
884 template <
typename Key,
typename Value>
885 struct prepare_send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
886 using type = std::function<void(
const ttg::span<const Key> &)>;
888 template <
typename Key,
typename Value>
889 struct prepare_send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
890 using type = std::function<void(
const Value &)>;
892 template <
typename Key,
typename Value>
893 struct prepare_send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
894 using type = std::function<void()>;
896 template <
typename Key,
typename Value>
897 using prepare_send_callback_t =
typename prepare_send_callback<Key, Value>::type;
899 template<
typename Key,
typename Enabler =
void>
900 struct constraint_callback;
902 template<
typename Key>
903 struct constraint_callback<Key, std::enable_if_t<!is_void_v<Key>>> {
904 using type = std::function<bool(
const Key&)>;
907 template<
typename Key>
908 struct constraint_callback<Key, std::enable_if_t<is_void_v<Key>>> {
909 using type = std::function<bool()>;
912 template<
typename Key>
913 using constraint_callback_t =
typename constraint_callback<Key>::type;
921 template <
typename T,
typename =
void>
922 struct is_iterable : std::false_type {};
925 template <
typename T>
926 struct is_iterable<T, std::
void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>>
929 template <
typename T>
930 constexpr
bool is_iterable_v = is_iterable<T>::value;
935 template <
typename Callable,
typename Typelist>
936 constexpr
bool is_invocable_typelist_v =
false;
937 template <
typename Callable,
typename... Args>
939 template <
typename ReturnType,
typename Callable,
typename Typelist>
940 constexpr
bool is_invocable_typelist_r_v =
false;
941 template <
typename ReturnType,
typename Callable,
typename... Args>
942 constexpr
bool is_invocable_typelist_r_v<ReturnType, Callable,
ttg::typelist<Args...>> =
948 template <
typename Callable,
typename Typelist>
949 struct invoke_result_typelist {};
950 template <
typename Callable,
typename... Args>
951 struct invoke_result_typelist<Callable,
ttg::
typelist<Args...>> : std::invoke_result<Callable, Args...> {};
952 template <
class F,
class... ArgTypes>
953 using invoke_result_typelist_t =
typename invoke_result_typelist<F, ArgTypes...>::type;
A complete version of void.
std::integral_constant< bool,(Flags &const_) !=0 > is_const
constexpr BOOST_CLBL_TRAITS_INLINE_VAR bool is_invocable_r_v
constexpr BOOST_CLBL_TRAITS_INLINE_VAR bool is_invocable_v
top-level TTG namespace contains runtime-neutral functionality
meta::typelist< Ts... > typelist