alpaka
Abstraction Library for Parallel Kernel Acceleration
Loading...
Searching...
No Matches
CartesianProduct.hpp
Go to the documentation of this file.
1/* Copyright 2022 Benjamin Worpitz, Bernhard Manfred Gruber
2 * SPDX-License-Identifier: MPL-2.0
3 */
4
5#pragma once
6
8
9namespace alpaka::meta
10{
11 // This is based on code by Patrick Fromberg.
12 // See
13 // http://stackoverflow.com/questions/9122028/how-to-create-the-cartesian-product-of-a-type-list/19611856#19611856
14 namespace detail
15 {
16 template<typename... Ts>
18
19 // Stop condition.
20 template<template<typename...> class TList, typename... Ts>
21 struct CartesianProductImplHelper<TList<Ts...>>
22 {
23 using type = TList<Ts...>;
24 };
25
26 // Catches first empty tuple.
27 template<template<typename...> class TList, typename... Ts>
28 struct CartesianProductImplHelper<TList<TList<>>, Ts...>
29 {
30 using type = TList<>;
31 };
32
33 // Catches any empty tuple except first.
34 template<template<typename...> class TList, typename... Ts, typename... Rests>
35 struct CartesianProductImplHelper<TList<Ts...>, TList<>, Rests...>
36 {
37 using type = TList<>;
38 };
39
40 template<template<typename...> class TList, typename... X, typename H, typename... Rests>
41 struct CartesianProductImplHelper<TList<X...>, TList<H>, Rests...>
42 {
43 using type1 = TList<Concatenate<X, TList<H>>...>;
44 using type = typename CartesianProductImplHelper<type1, Rests...>::type;
45 };
46
47 template<
48 template<typename...>
49 class TList,
50 typename... X,
51 template<typename...>
52 class Head,
53 typename T,
54 typename... Ts,
55 typename... Rests>
56 struct CartesianProductImplHelper<TList<X...>, Head<T, Ts...>, Rests...>
57 {
58 using type1 = TList<Concatenate<X, TList<T>>...>;
59 using type2 = typename CartesianProductImplHelper<TList<X...>, TList<Ts...>>::type;
61 using type = typename CartesianProductImplHelper<type3, Rests...>::type;
62 };
63
64 template<template<typename...> class TList, typename... Ts>
66
67 // The base case for no input returns an empty sequence.
68 template<template<typename...> class TList>
70 {
71 using type = TList<>;
72 };
73
74 // R is the return type, Head<A...> is the first input list
75 template<template<typename...> class TList, template<typename...> class Head, typename... Ts, typename... Tail>
76 struct CartesianProductImpl<TList, Head<Ts...>, Tail...>
77 {
78 using type = typename detail::CartesianProductImplHelper<TList<TList<Ts>...>, Tail...>::type;
79 };
80 } // namespace detail
81
82 template<template<typename...> class TList, typename... Ts>
83 using CartesianProduct = typename detail::CartesianProductImpl<TList, Ts...>::type;
84} // namespace alpaka::meta
typename detail::ConcatenateImpl< T... >::type Concatenate
typename detail::CartesianProductImpl< TList, Ts... >::type CartesianProduct
typename CartesianProductImplHelper< TList< X... >, TList< Ts... > >::type type2
typename detail::CartesianProductImplHelper< TList< TList< Ts >... >, Tail... >::type type