1 #ifndef TTG_UTIL_META_H
2 #define TTG_UTIL_META_H
19 #if __cplusplus >= 201703L
34 template <
typename T,
typename Enabler =
void>
37 template <
typename... Ts>
39 using type = std::tuple<typename std::remove_reference<Ts>::type...>;
42 template <
typename Tuple>
45 template <
typename... TupleTs>
48 template <
typename... Ts>
50 using type = std::tuple<Ts...>;
53 template <
typename... Ts,
typename... Us,
typename... R>
56 decltype(std::tuple_cat(std::declval<std::tuple<Ts...>>(), std::declval<std::tuple<Us...>>())), R...>
::type;
59 template <
typename... TupleTs>
63 template <
typename Tuple,
template <
typename>
typename Predicate>
70 using type = std::tuple<E>;
80 template <
template <
typename>
typename Pred,
typename... Es>
82 using type = decltype(std::tuple_cat(
86 template <
typename Tuple,
template <
typename>
typename Pred>
95 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
98 template <
template <
typename>
typename Predicate,
bool Default>
99 struct probe_last<Predicate, Default> :
public std::bool_constant<Default> {};
101 template <
template <
typename>
typename Predicate,
bool Default,
typename T>
102 struct probe_last<Predicate, Default, T> :
public std::bool_constant<Predicate<T>::value> {};
104 template <
template <
typename>
typename Predicate,
bool Default,
typename T1,
typename... Ts>
107 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
110 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
119 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
128 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
131 template <
template <
typename>
typename Predicate,
bool Default>
132 struct probe_first<Predicate, Default> :
public std::bool_constant<Default> {};
134 template <
template <
typename>
typename Predicate,
bool Default,
typename T1,
typename... Ts>
135 struct probe_first<Predicate, Default, T1, Ts...> :
public std::bool_constant<Predicate<T1>::value> {};
137 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
140 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
149 template <
template <
typename>
typename Predicate,
bool Default,
typename... Ts>
157 template <
template <
typename>
typename Predicate,
typename... Ts>
158 struct probe_any : std::bool_constant<(Predicate<Ts>::value || ...)> {};
160 template <
template <
typename>
typename Predicate,
typename... Ts>
163 template <
template <
typename>
typename Predicate,
typename... Ts>
171 template <
template <
typename>
typename Predicate,
typename... Ts>
179 template <
template <
typename>
typename Predicate,
typename... Ts>
180 struct probe_all : std::bool_constant<(Predicate<Ts>::value && ...)> {};
182 template <
template <
typename>
typename Predicate,
typename... Ts>
185 template <
template <
typename>
typename Predicate,
typename... Ts>
193 template <
template <
typename>
typename Predicate,
typename... Ts>
205 template <
typename T>
208 template <
typename T>
209 constexpr
bool is_void_v = is_Void_v<T> || std::is_void_v<T>;
211 template <
typename T>
212 struct is_void : std::bool_constant<is_void_v<T>> {};
214 template <
typename T>
217 template <
typename T>
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... Ts>
262 template <
typename T>
270 template <
typename T>
273 template <
typename T>
275 std::is_lvalue_reference_v<T> &&std::is_const_v<std::remove_reference_t<T>>;
277 template <
typename T>
280 template <
typename T>
282 std::is_lvalue_reference_v<T> && !std::is_const_v<std::remove_reference_t<T>>;
284 template <
typename T>
287 template <
typename... Ts>
290 template <
typename... Ts>
293 template <
typename... Ts>
316 template<
typename T,
typename A>
320 template<
typename T,
typename A>
348 template <
typename Typelist, std::
size_t N,
typename Enabler =
void>
351 template <
typename... Ts>
353 using type = std::tuple<Ts...>;
356 template <
typename... Ts>
361 template <
typename T,
typename... Ts, std::size_t N>
362 struct drop_first_n<std::tuple<T, Ts...>, N, std::enable_if_t<N != 0>> {
366 template <
typename T,
typename... Ts, std::size_t N>
372 template <
typename Typelist, std::
size_t N>
375 template <
typename ResultTuple,
typename InputTuple, std::
size_t N,
typename Enabler =
void>
378 template <
typename... Ts,
typename... Us>
380 using type = std::tuple<Ts...>;
382 template <
typename... Ts,
typename... Us>
387 template <
typename... Ts,
typename U,
typename... Us, std::size_t N>
391 template <
typename... Ts,
typename U,
typename... Us, std::size_t N>
396 template <
typename... Ts, std::size_t N>
401 template <
typename... Ts, std::size_t N>
407 template <
typename Typelist, std::
size_t N,
typename Enabler =
void>
410 template <
typename... Ts, std::size_t N>
411 struct drop_last_n<std::tuple<Ts...>, N, std::enable_if_t<N <= sizeof...(Ts)>> {
412 using type =
typename take_first_n<std::tuple<Ts...>, (
sizeof...(Ts) - N)>::type;
414 template <
typename... Ts, std::size_t N>
419 template <
typename... Ts, std::size_t N>
420 struct drop_last_n<std::tuple<Ts...>, N, std::enable_if_t<!(N <= sizeof...(Ts))>> {
421 using type = std::tuple<>;
423 template <
typename... Ts, std::size_t N>
424 struct drop_last_n<
typelist<Ts...>, N, std::enable_if_t<!(N <= sizeof...(Ts))>> {
425 using type = typelist<>;
429 template <
typename T,
typename Enabler =
void>
430 struct decayed_typelist;
432 template <
typename... Ts>
433 struct decayed_typelist<std::tuple<Ts...>> {
434 using type = std::tuple<std::decay_t<Ts>...>;
436 template <
typename... Ts>
437 struct decayed_typelist<
typelist<Ts...>> {
438 using type = typelist<std::decay_t<Ts>...>;
441 template <
typename Tuple>
442 using decayed_typelist_t =
typename decayed_typelist<Tuple>::type;
445 template <
typename T,
template <
typename...>
typename Pred>
448 template <
typename FilteredTypelist,
template <
typename...>
typename Pred,
typename... ToBeFilteredTs>
451 template <
typename... FilteredTs,
template <
typename...>
typename Pred>
452 struct filter_impl<
typelist<FilteredTs...>, Pred> {
453 using type =
typelist<FilteredTs...>;
455 template <
typename... FilteredTs,
template <
typename...>
typename Pred>
456 struct filter_impl<std::tuple<FilteredTs...>, Pred> {
457 using type = std::tuple<FilteredTs...>;
460 template <
typename... FilteredTs,
template <
typename...>
typename Pred,
typename U,
typename... RestOfUs>
461 struct filter_impl<
typelist<FilteredTs...>, Pred, U, RestOfUs...>
462 : std::conditional_t<Pred<U>::value, filter_impl<typelist<FilteredTs..., U>, Pred, RestOfUs...>,
463 filter_impl<typelist<FilteredTs...>, Pred, RestOfUs...>> {};
464 template <
typename... FilteredTs,
template <
typename...>
typename Pred,
typename U,
typename... RestOfUs>
465 struct filter_impl<std::tuple<FilteredTs...>, Pred, U, RestOfUs...>
466 : std::conditional_t<Pred<U>::value, filter_impl<std::tuple<FilteredTs..., U>, Pred, RestOfUs...>,
467 filter_impl<std::tuple<FilteredTs...>, Pred, RestOfUs...>> {};
469 template <
typename... Ts,
template <
typename...>
typename Pred>
470 struct filter<
typelist<Ts...>, Pred> : filter_impl<typelist<>, Pred, Ts...> {};
471 template <
typename... Ts,
template <
typename...>
typename Pred>
472 struct filter<std::tuple<Ts...>, Pred> : filter_impl<std::tuple<>, Pred, Ts...> {};
474 template <
typename T,
template <
typename...>
typename Pred>
475 using filter_t =
typename filter<T, Pred>::type;
477 template <
typename T>
478 using drop_void = filter<T, is_nonvoid>;
480 template <
typename T>
481 using drop_void_t =
typename drop_void<T>::type;
483 template <
typename T,
typename S,
typename U>
484 struct replace_nonvoid_helper;
487 template <
typename... Ts,
typename S,
typename... Ss,
typename U,
typename... Us>
494 template <
typename... Ts,
typename... Ss,
typename U,
typename... Us>
501 template <
typename... Ts,
typename... Us>
507 template <
typename... Ts,
typename... Ss>
513 template <
typename... Ts>
519 template <
typename T,
typename U>
520 struct replace_nonvoid;
522 template <
typename... T,
typename... U>
527 template <
typename... T,
typename... U>
528 struct replace_nonvoid<std::tuple<T...>, std::tuple<U...>> {
533 template <
typename T,
typename U>
534 using replace_nonvoid_t =
typename replace_nonvoid<T, U>::type;
540 template <
typename T>
541 struct void_to_Void_tuple;
543 template <
typename... Ts>
544 struct void_to_Void_tuple<std::tuple<Ts...>> {
545 using type = std::tuple<void_to_Void_t<Ts>...>;
548 template <
typename tupleT>
549 using void_to_Void_tuple_t =
typename void_to_Void_tuple<std::decay_t<tupleT>>::type;
551 template <
typename T>
552 struct add_lvalue_reference_tuple;
554 template <
typename... Ts>
555 struct add_lvalue_reference_tuple<std::tuple<Ts...>> {
556 using type = std::tuple<std::add_lvalue_reference_t<Ts>...>;
559 template <
typename tupleT>
560 using add_lvalue_reference_tuple_t =
typename add_lvalue_reference_tuple<tupleT>::type;
562 template <
typename T>
563 struct add_glvalue_reference_tuple;
565 template <
typename... Ts>
566 struct add_glvalue_reference_tuple<std::tuple<Ts...>> {
567 using type = std::tuple<std::conditional_t<std::is_const_v<Ts>, std::add_lvalue_reference_t<Ts>,
568 std::add_rvalue_reference_t<std::remove_const_t<Ts>>>...>;
571 template <
typename tupleT>
572 using add_glvalue_reference_tuple_t =
typename add_glvalue_reference_tuple<tupleT>::type;
574 template <
typename T,
typename... Ts>
575 struct none_has_reference {
576 static constexpr
bool value = !std::is_reference_v<T> && none_has_reference<Ts...>::value;
579 template <
typename T>
580 struct none_has_reference<T> {
581 static constexpr
bool value = !std::is_reference_v<T>;
584 template <
typename... T>
585 struct none_has_reference<
ttg::
typelist<T...>> : none_has_reference<T...> {};
588 struct none_has_reference<
ttg::
typelist<>> : std::true_type {};
590 template <
typename... T>
591 constexpr
bool none_has_reference_v = none_has_reference<T...>::value;
593 template <
typename T>
594 struct is_tuple : std::integral_constant<bool, false> {};
596 template <
typename... Ts>
597 struct is_tuple<std::tuple<Ts...>> : std::integral_constant<bool, true> {};
599 template <
typename T>
600 constexpr
bool is_tuple_v = is_tuple<T>::value;
603 struct is_span : std::false_type {};
605 template <
typename T, std::
size_t S>
606 struct is_span<
ttg::span<T, S>> : std::true_type {};
608 template <
typename T>
609 constexpr
bool is_span_v = is_span<T>::value;
611 template <
template <
class>
class Pred,
typename TupleT, std::size_t I, std::size_t... Is>
612 struct predicate_index_seq_helper;
614 template <
template <
class>
class Pred,
typename T,
typename... Ts, std::size_t I, std::size_t... Is>
615 struct predicate_index_seq_helper<Pred, std::tuple<T, Ts...>, I, Is...> {
616 using seq = std::conditional_t<Pred<T>::value,
617 typename predicate_index_seq_helper<Pred, std::tuple<Ts...>, I + 1, Is..., I>::seq,
618 typename predicate_index_seq_helper<Pred, std::tuple<Ts...>, I + 1, Is...>::seq>;
621 template <
template <
class>
class Pred, std::size_t I, std::size_t... Is>
622 struct predicate_index_seq_helper<Pred, std::tuple<>, I, Is...> {
623 using seq = std::index_sequence<Is...>;
626 template <
typename T>
627 struct is_none_void_pred : std::integral_constant<bool, is_none_void_v<T>> {};
632 template <
typename TupleT>
633 using nonvoid_index_seq =
typename predicate_index_seq_helper<is_none_void_pred, TupleT, 0>::seq;
635 template <
typename T>
636 struct is_void_pred : std::integral_constant<bool, is_void_v<T>> {};
641 template <
typename TupleT>
642 using void_index_seq =
typename predicate_index_seq_helper<is_void_pred, TupleT, 0>::seq;
650 template <
typename T,
typename Enabler =
void>
651 struct is_empty_tuple : std::false_type {};
653 template <
typename... Ts>
654 struct is_empty_tuple<std::tuple<Ts...>, std::enable_if_t<(is_Void_v<Ts> && ...)>> : std::true_type {};
656 template <
typename Tuple>
657 inline constexpr
bool is_empty_tuple_v = is_empty_tuple<Tuple>::value;
659 static_assert(!is_empty_tuple_v<std::tuple<int>>,
"ouch");
660 static_assert(is_empty_tuple_v<std::tuple<>>,
"ouch");
661 static_assert(is_empty_tuple_v<std::tuple<Void>>,
"ouch");
662 static_assert(is_empty_tuple_v<std::tuple<Void, Void, Void>>,
"ouch");
669 ~nonesuch() =
delete;
670 nonesuch(nonesuch
const &) =
delete;
671 void operator=(nonesuch
const &) =
delete;
681 template <
class Default,
class Enabler,
template <
class...>
class TT,
class... Args>
683 using value_t = std::false_type;
684 using type = Default;
687 template <
class Default,
template <
class...>
class TT,
class... Args>
688 struct detector<Default,
void_t<TT<Args...>>, TT, Args...> {
689 using value_t = std::true_type;
690 using type = TT<Args...>;
695 template <
template <
class...>
class TT,
class... Args>
696 using is_detected =
typename detail::detector<nonesuch, void, TT, Args...>::value_t;
698 template <
template <
class...>
class TT,
class... Args>
699 using detected_t =
typename detail::detector<nonesuch, void, TT, Args...>::type;
701 template <
class Default,
template <
class...>
class TT,
class... Args>
702 using detected_or = detail::detector<Default, void, TT, Args...>;
704 template <
template <
class...>
class TT,
class... Args>
705 constexpr
bool is_detected_v = is_detected<TT, Args...>::value;
707 template <
class Default,
template <
class...>
class TT,
class... Args>
708 using detected_or_t =
typename detected_or<Default, TT, Args...>::type;
710 template <
class Expected,
template <
class...>
class TT,
class... Args>
711 using is_detected_exact = std::is_same<Expected, detected_t<TT, Args...>>;
713 template <
class Expected,
template <
class...>
class TT,
class... Args>
714 constexpr
bool is_detected_exact_v = is_detected_exact<Expected, TT, Args...>::value;
716 template <
class To,
template <
class...>
class TT,
class... Args>
717 using is_detected_convertible = std::is_convertible<detected_t<TT, Args...>, To>;
719 template <
class To,
template <
class...>
class TT,
class... Args>
720 constexpr
bool is_detected_convertible_v = is_detected_convertible<To, TT, Args...>::value;
726 template <
typename T>
732 template <
typename T,
typename Enabler =
void>
733 struct has_std_hash_specialization : std::false_type {};
734 template <
typename T>
735 struct has_std_hash_specialization<
736 T,
ttg::
meta::void_t<decltype(std::declval<std::hash<T>>()(std::declval<const T &>()))>> : std::true_type {};
737 template <
typename T>
738 constexpr
bool has_std_hash_specialization_v = has_std_hash_specialization<T>::value;
745 template <
typename Key,
typename Value,
typename Enabler =
void>
746 struct send_callback;
747 template <
typename Key,
typename Value>
748 struct send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
749 using type = std::function<void(
const Key &,
const Value &)>;
751 template <
typename Key,
typename Value>
752 struct send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
753 using type = std::function<void(
const Key &)>;
755 template <
typename Key,
typename Value>
756 struct send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
757 using type = std::function<void(
const Value &)>;
759 template <
typename Key,
typename Value>
760 struct send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
761 using type = std::function<void()>;
763 template <
typename Key,
typename Value>
764 using send_callback_t =
typename send_callback<Key, Value>::type;
769 template <
typename Key,
typename Value,
typename Enabler =
void>
770 struct move_callback;
771 template <
typename Key,
typename Value>
772 struct move_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
773 using type = std::function<void(
const Key &, Value &&)>;
775 template <
typename Key,
typename Value>
776 struct move_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
777 using type = std::function<void(
const Key &)>;
779 template <
typename Key,
typename Value>
780 struct move_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
781 using type = std::function<void(Value &&)>;
783 template <
typename Key,
typename Value>
784 struct move_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
785 using type = std::function<void()>;
787 template <
typename Key,
typename Value>
788 using move_callback_t =
typename move_callback<Key, Value>::type;
793 template <
typename Key,
typename Value,
typename Enabler =
void>
794 struct broadcast_callback;
795 template <
typename Key,
typename Value>
796 struct broadcast_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
797 using type = std::function<void(
const ttg::span<const Key> &,
const Value &)>;
799 template <
typename Key,
typename Value>
800 struct broadcast_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
801 using type = std::function<void(
const ttg::span<const Key> &)>;
803 template <
typename Key,
typename Value>
804 struct broadcast_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
805 using type = std::function<void(
const Value &)>;
807 template <
typename Key,
typename Value>
808 struct broadcast_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
809 using type = std::function<void()>;
811 template <
typename Key,
typename Value>
812 using broadcast_callback_t =
typename broadcast_callback<Key, Value>::type;
819 template <
typename Key,
typename Enabler =
void>
820 struct setsize_callback;
821 template <
typename Key>
822 struct setsize_callback<Key, std::enable_if_t<!is_void_v<Key>>> {
823 using type = std::function<void(
const Key &, std::size_t)>;
825 template <
typename Key>
826 struct setsize_callback<Key, std::enable_if_t<is_void_v<Key>>> {
827 using type = std::function<void(std::size_t)>;
829 template <
typename Key>
830 using setsize_callback_t =
typename setsize_callback<Key>::type;
835 template <
typename Key,
typename Enabler =
void>
836 struct finalize_callback;
837 template <
typename Key>
838 struct finalize_callback<Key, std::enable_if_t<!is_void_v<Key>>> {
839 using type = std::function<void(
const Key &)>;
841 template <
typename Key>
842 struct finalize_callback<Key, std::enable_if_t<is_void_v<Key>>> {
843 using type = std::function<void()>;
845 template <
typename Key>
846 using finalize_callback_t =
typename finalize_callback<Key>::type;
851 template <
typename Key,
typename Return,
typename Enabler =
void>
853 template <
typename Key,
typename Return>
854 struct keymap<Key, Return, std::enable_if_t<!is_void_v<Key>>> {
855 using type = std::function<Return(
const Key &)>;
857 template <
typename Key,
typename Return>
858 struct keymap<Key, Return, std::enable_if_t<is_void_v<Key>>> {
859 using type = std::function<Return()>;
861 template <
typename Key,
typename Return =
int>
862 using keymap_t =
typename keymap<Key, Return>::type;
870 template <
typename T,
typename Enabler =
void>
871 struct input_reducer_type;
872 template <
typename T>
873 struct input_reducer_type<T, std::enable_if_t<!is_void_v<T>>> {
874 using type = std::function<void(std::decay_t<T> &,
const std::decay_t<T> &)>;
876 template <
typename T>
877 struct input_reducer_type<T, std::enable_if_t<is_void_v<T>>> {
878 using type = std::function<void()>;
880 template <
typename... valueTs>
881 struct input_reducers {
882 using type = std::tuple<typename input_reducer_type<valueTs>::type...>;
884 template <
typename... valueTs>
885 struct input_reducers<std::tuple<valueTs...>> {
886 using type = std::tuple<typename input_reducer_type<valueTs>::type...>;
888 template <
typename... valueTs>
889 using input_reducers_t =
typename input_reducers<valueTs...>::type;
894 template <
typename Key,
typename Value,
typename Enabler =
void>
895 struct prepare_send_callback;
896 template <
typename Key,
typename Value>
897 struct prepare_send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && !is_void_v<Value>>> {
898 using type = std::function<void(
const ttg::span<const Key> &,
const Value &)>;
900 template <
typename Key,
typename Value>
901 struct prepare_send_callback<Key, Value, std::enable_if_t<!is_void_v<Key> && is_void_v<Value>>> {
902 using type = std::function<void(
const ttg::span<const Key> &)>;
904 template <
typename Key,
typename Value>
905 struct prepare_send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && !is_void_v<Value>>> {
906 using type = std::function<void(
const Value &)>;
908 template <
typename Key,
typename Value>
909 struct prepare_send_callback<Key, Value, std::enable_if_t<is_void_v<Key> && is_void_v<Value>>> {
910 using type = std::function<void()>;
912 template <
typename Key,
typename Value>
913 using prepare_send_callback_t =
typename prepare_send_callback<Key, Value>::type;
915 template<
typename Key,
typename Enabler =
void>
916 struct constraint_callback;
918 template<
typename Key>
919 struct constraint_callback<Key, std::enable_if_t<!is_void_v<Key>>> {
920 using type = std::function<bool(
const Key&)>;
923 template<
typename Key>
924 struct constraint_callback<Key, std::enable_if_t<is_void_v<Key>>> {
925 using type = std::function<bool()>;
928 template<
typename Key>
929 using constraint_callback_t =
typename constraint_callback<Key>::type;
937 template <
typename T,
typename =
void>
938 struct is_iterable : std::false_type {};
941 template <
typename T>
942 struct is_iterable<T, std::
void_t<decltype(std::begin(std::declval<T>())), decltype(std::end(std::declval<T>()))>>
945 template <
typename T>
946 constexpr
bool is_iterable_v = is_iterable<T>::value;
951 template <
typename Callable,
typename Typelist>
952 constexpr
bool is_invocable_typelist_v =
false;
953 template <
typename Callable,
typename... Args>
955 template <
typename ReturnType,
typename Callable,
typename Typelist>
956 constexpr
bool is_invocable_typelist_r_v =
false;
957 template <
typename ReturnType,
typename Callable,
typename... Args>
958 constexpr
bool is_invocable_typelist_r_v<ReturnType, Callable,
ttg::typelist<Args...>> =
964 template <
typename Callable,
typename Typelist>
965 struct invoke_result_typelist {};
966 template <
typename Callable,
typename... Args>
967 struct invoke_result_typelist<Callable,
ttg::
typelist<Args...>> : std::invoke_result<Callable, Args...> {};
968 template <
class F,
class... ArgTypes>
969 using invoke_result_typelist_t =
typename invoke_result_typelist<F, ArgTypes...>::type;
A complete version of void.
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