18 #include "cudf_gtest.hpp"
80 using ::testing::Types;
83 template <
class T,
int D>
85 static_assert(D == 0,
"Out of bounds");
89 template <
class... T,
int D>
90 struct GetTypeImpl<Types<T...>, D> {
91 static_assert(D <
sizeof...(T),
"Out of bounds");
93 using raw_type = decltype(std::get<D>(std::declval<std::tuple<T...>>()));
94 using type = std::decay_t<raw_type>;
96 template <
class T,
class... ARGS>
97 struct GetTypeImpl<Types<T, ARGS...>, 0> {
114 template <
class TUPLE,
int D>
115 using GetType =
typename GetTypeImpl<TUPLE, D>::type;
119 template <
class TUPLE>
122 template <
class... TYPES>
123 struct GetSizeImpl<Types<TYPES...>> {
124 static constexpr
auto value =
sizeof...(TYPES);
136 template <
class TUPLE>
137 constexpr
auto GetSize = GetSizeImpl<TUPLE>::value;
142 template <
class A,
class B>
145 template <
class... T,
class... U>
146 struct Concat2<Types<T...>, Types<U...>> {
147 using type = Types<T..., U...>;
151 template <
class... T>
154 template <
class HEAD1,
class HEAD2,
class... TAIL>
155 struct ConcatImpl<HEAD1, HEAD2, TAIL...> {
156 using type =
typename ConcatImpl<typename detail::Concat2<HEAD1, HEAD2>::type, TAIL...>::type;
160 struct ConcatImpl<A> {
164 template <
class... A>
165 struct ConcatImpl<Types<A...>> {
166 using type = Types<A...>;
170 struct ConcatImpl<> {
171 using type = Types<>;
184 template <
class... T>
185 using Concat =
typename ConcatImpl<T...>::type;
193 struct FlattenImpl<Types<>> {
194 using type = Types<>;
197 template <
class HEAD,
class... TAIL>
198 struct FlattenImpl<Types<HEAD, TAIL...>> {
199 using type = Concat<Types<HEAD>,
typename FlattenImpl<Types<TAIL...>>::type>;
202 template <
class... HEAD,
class... TAIL>
203 struct FlattenImpl<Types<Types<HEAD...>, TAIL...>> {
204 using type =
typename FlattenImpl<Types<HEAD..., TAIL...>>::type;
220 using Flatten =
typename FlattenImpl<T>::type;
226 template <
class T,
class TUPLE>
229 template <
class T,
class... ARGS>
230 struct Prepend1<T, Types<ARGS...>> {
231 using type =
Flatten<Types<T, ARGS...>>;
234 template <
class T,
class TUPLES>
238 template <
class T,
class... TUPLES>
239 struct Prepend<T, Types<TUPLES...>> {
240 using type = Types<typename Prepend1<T, TUPLES>::type...>;
244 template <
class T,
class... TUPLES>
245 struct Prepend<T, Types<Types<>, TUPLES...>> : Prepend<T, Types<TUPLES...>> {};
248 template <
class... ARGS>
249 struct CrossProductImpl;
252 struct CrossProductImpl<> {
253 using type = Types<>;
256 template <
class... ARGS>
257 struct CrossProductImpl<Types<ARGS...>> {
258 using type = Types<Types<ARGS>...>;
261 template <
class... AARGS,
class... TAIL>
262 struct CrossProductImpl<Types<AARGS...>, TAIL...> {
264 Concat<
typename detail::Prepend<AARGS,
typename CrossProductImpl<TAIL...>::type>::type...>;
268 template <
class T,
class... TAIL>
269 struct CrossProductImpl<T, TAIL...> : CrossProductImpl<Types<T>, TAIL...> {};
287 template <
class... ARGS>
293 template <
class... ITEMS>
294 struct AllSame : std::false_type {};
298 struct AllSame<A> : std::true_type {};
301 struct AllSame<A, A> : std::true_type {};
303 template <
class HEAD,
class... TAIL>
306 template <
class... ITEMS>
334 template <
class... ITEMS>
335 using Call = detail::AllSame<ITEMS...>;
341 template <
class NEEDLE,
class HAYSACK>
345 template <
class NEEDLE>
346 struct ExistsImpl<NEEDLE, Types<>> : std::false_type {};
349 template <
class NEEDLE,
class... TAIL>
350 struct ExistsImpl<NEEDLE, Types<NEEDLE, TAIL...>> : std::true_type {};
353 template <
class NEEDLE,
class HEAD,
class... TAIL>
354 struct ExistsImpl<NEEDLE, Types<HEAD, TAIL...>> : ExistsImpl<NEEDLE, Types<TAIL...>> {};
368 template <
class NEEDLE,
class HAYSACK>
369 constexpr
bool Exists = ExistsImpl<NEEDLE, HAYSACK>::value;
392 template <
class HAYSACK>
399 template <
class NEEDLE>
400 using Call = ExistsImpl<NEEDLE, HAYSACK>;
405 template <
class PRED,
class TUPLE>
408 template <
class PRED>
409 struct RemoveIfImpl<PRED, Types<>> {
410 using type = Types<>;
413 template <
class PRED,
class HEAD,
class... TAIL>
414 struct RemoveIfImpl<PRED, Types<HEAD, TAIL...>> {
416 Concat<typename std::conditional<PRED::template Call<HEAD>::value, Types<>, Types<HEAD>>::type,
417 typename RemoveIfImpl<PRED, Types<TAIL...>>::type>;
440 template <
class PRED,
class TUPLE>
441 using RemoveIf =
typename RemoveIfImpl<PRED, TUPLE>::type;
445 template <
class XFORM,
class TYPES>
446 struct TransformImpl;
448 template <
class XFORM,
class... ITEMS>
449 struct TransformImpl<XFORM, Types<ITEMS...>> {
450 using type = Types<typename XFORM::template Call<ITEMS>...>;
469 template <
class XFORM,
class TYPES>
470 using Transform =
typename TransformImpl<XFORM, TYPES>::type;
475 template <
class T,
int N,
class RES>
478 template <
class T,
int N,
class... ITEMS>
479 struct Repeat<T, N, Types<ITEMS...>> {
480 using type =
typename Repeat<T, N - 1, Types<T, ITEMS...>>::type;
483 template <
class T,
class... ITEMS>
484 struct Repeat<T, 0, Types<ITEMS...>> {
485 using type = Types<ITEMS...>;
512 using Call =
typename detail::Repeat<T, N, Types<>>::type;
517 template <
class TYPES,
class... ITEMS>
520 template <
class... HEAD,
class... TAIL>
521 struct AppendImpl<Types<HEAD...>, TAIL...> {
522 using type = Types<HEAD..., TAIL...>;
538 template <
class TYPES,
class... ITEMS>
539 using Append =
typename AppendImpl<TYPES, ITEMS...>::type;
545 template <
class TUPLE,
int CUR,
int... IDXs>
549 template <
class... ITEMS,
int CUR>
550 struct Remove<Types<ITEMS...>, CUR> {
551 using type = Types<ITEMS...>;
555 template <
class HEAD,
class... TAIL,
int CUR,
int... IDXTAIL>
556 struct Remove<Types<HEAD, TAIL...>, CUR, CUR, IDXTAIL...> {
558 using type =
typename Remove<Types<TAIL...>, CUR + 1, IDXTAIL...>::type;
562 template <
class HEAD,
class... TAIL,
int CUR,
int IDXHEAD,
int... IDXTAIL>
563 struct Remove<Types<HEAD, TAIL...>, CUR, IDXHEAD, IDXTAIL...> {
564 static_assert(
sizeof...(TAIL) + 1 > IDXHEAD - CUR,
"Index out of bounds");
572 template <
class TUPLE,
int... IDXs>
574 using type =
typename detail::Remove<TUPLE, 0, IDXs...>::type;
584 template <
class TUPLE,
int... IDXs>
585 using Remove =
typename RemoveImpl<TUPLE, IDXs...>::type;
590 template <
class... ITEMS>
595 using type = Types<>;
598 template <
class HEAD,
class... TAIL>
599 struct Unique<HEAD, TAIL...> {
600 using type =
Concat<std::conditional_t<
Exists<HEAD, Types<TAIL...>>, Types<>, Types<HEAD>>,
601 typename Unique<TAIL...>::type>;
605 template <
class TYPES>
608 template <
class... ITEMS>
609 struct UniqueImpl<Types<ITEMS...>> {
610 using type =
typename detail::Unique<ITEMS...>::type;
625 template <
class TYPES>
626 using Unique =
typename UniqueImpl<TYPES>::type;
Indicates if all types in a list are identical.
detail::AllSame< ITEMS... > Call
Invoked as predicate for RemoveIf.
Indicates if a type exists within a type list.
ExistsImpl< NEEDLE, HAYSACK > Call
Invoked as predicate for RemoveIf.
Transformation that repeats a type for a specified count.
typename detail::Repeat< T, N, Types<> >::type Call
Invoked as predicate for Transform.
typename FlattenImpl< T >::type Flatten
Flattens nested compile-time lists of types into a single list of types.
constexpr bool Exists
Indicates if a type exists within a type list.
typename ConcatImpl< T... >::type Concat
Concatenates compile-time lists of types into a single type list.
typename RemoveIfImpl< PRED, TUPLE >::type RemoveIf
Removes types from a type list that satisfy a predicate.
typename CrossProductImpl< ARGS... >::type CrossProduct
Creates a new type list from the cross product (cartesian product) of two type lists.
typename RemoveImpl< TUPLE, IDXs... >::type Remove
Removes types at specified indices from a type list.
constexpr auto GetSize
Returns the size (number of elements) in a type list.
typename AppendImpl< TYPES, ITEMS... >::type Append
Appends types to a type list.
typename UniqueImpl< TYPES >::type Unique
Removes duplicate types from a type list.
typename TransformImpl< XFORM, TYPES >::type Transform
Applies a transformation to every type in a type list.
typename GetTypeImpl< TUPLE, D >::type GetType
Gives the specified type from a type list.