VertexCFD  0.0-dev
VertexCFD_Utils_ParameterPack.hpp
1 #ifndef VERTEXCFD_PARAMETERPACK_HPP
2 #define VERTEXCFD_PARAMETERPACK_HPP
3 
4 #include <Kokkos_Core.hpp>
5 
6 #include <type_traits>
7 #include <utility>
8 
9 namespace VertexCFD
10 {
11 namespace Utils
12 {
13 //---------------------------------------------------------------------------//
14 // Parameter pack device capture.
15 //
16 // NOTE: In general this would not be needed but NVCC cannot capture parameter
17 // packs in lambda functions hence we need to wrap them in something that can
18 // be captured.
19 //---------------------------------------------------------------------------//
20 // Get the type at the given index of a paremeter pack.
21 template<std::size_t N, typename T, typename... Types>
22 struct PackTypeAtIndexImpl;
23 
24 template<typename T, typename... Types>
25 struct PackTypeAtIndexImpl<0, T, Types...>
26 {
27  using type = T;
28 };
29 
30 template<std::size_t N, typename T, typename... Types>
32 {
33  using type = typename PackTypeAtIndexImpl<N - 1, Types...>::type;
34 };
35 
36 template<std::size_t N, typename... Types>
38 {
39  using type = typename PackTypeAtIndexImpl<N, Types...>::type;
40  static_assert(N < sizeof...(Types), "Type index out of bounds");
41 };
42 
43 //---------------------------------------------------------------------------//
44 // Parameter pack element.
45 template<std::size_t N, typename T>
47 {
48  T _m;
49 };
50 
51 //---------------------------------------------------------------------------//
52 // Capture a parameter pack. All parameter pack elements must be copyable to
53 // device.
54 template<typename Sequence, typename... Types>
56 
57 template<std::size_t... Indices, typename... Types>
58 struct ParameterPackImpl<std::index_sequence<Indices...>, Types...>
59  : ParameterPackElement<Indices, Types>...
60 {
61 };
62 
63 template<typename... Types>
65  : ParameterPackImpl<std::make_index_sequence<sizeof...(Types)>, Types...>
66 {
67  template<std::size_t N>
68  using value_type = typename PackTypeAtIndex<N, Types...>::type;
69 
70  template<std::size_t N>
71  using const_value_type = typename std::add_const<value_type<N>>::type;
72 
73  template<std::size_t N>
75 
76  static constexpr std::size_t size = sizeof...(Types);
77 };
78 
79 //---------------------------------------------------------------------------//
80 // Static type checker.
81 template<class>
82 struct is_parameter_pack_impl : public std::false_type
83 {
84 };
85 
86 template<typename... Types>
87 struct is_parameter_pack_impl<ParameterPack<Types...>> : public std::true_type
88 {
89 };
90 
91 template<class T>
93  : public is_parameter_pack_impl<typename std::remove_cv<T>::type>::type
94 {
95 };
96 
97 //---------------------------------------------------------------------------//
98 
99 } // end namespace Utils
100 
101 //---------------------------------------------------------------------------//
102 // Get an element from a parameter pack. Note that this has been inserted in
103 // the main VertexCFD namespace as it will be used heavily.
104 template<std::size_t N, class ParameterPack_t>
105 KOKKOS_FORCEINLINE_FUNCTION
106  typename std::enable_if<Utils::is_parameter_pack<ParameterPack_t>::value,
107  typename ParameterPack_t::template value_type<N>&>::type
108  get(ParameterPack_t& pp)
109 {
110  return static_cast<typename ParameterPack_t::template element_type<N>&>(pp)
111  ._m;
112 }
113 
114 template<std::size_t N, class ParameterPack_t>
115 KOKKOS_FORCEINLINE_FUNCTION typename std::enable_if<
116  Utils::is_parameter_pack<ParameterPack_t>::value,
117  typename ParameterPack_t::template const_value_type<N>&>::type
118 get(const ParameterPack_t& pp)
119 {
120  return static_cast<const typename ParameterPack_t::template element_type<N>&>(
121  pp)
122  ._m;
123 }
124 
125 //---------------------------------------------------------------------------//
126 namespace Utils
127 {
128 //---------------------------------------------------------------------------//
129 // Fill a parameter pack. Note the indexing is such that the Nth element of a
130 // parameter pack is the Nth element of the tuple.
131 template<typename ParameterPack_t, typename T, typename... Types>
132 void fillParameterPackImpl(ParameterPack_t& pp,
133  const std::integral_constant<std::size_t, 0>,
134  const T& t,
135  const Types&...)
136 {
137  get<ParameterPack_t::size - 1>(pp) = t;
138 }
139 
140 template<typename ParameterPack_t, std::size_t N, typename T, typename... Types>
141 void fillParameterPackImpl(ParameterPack_t& pp,
142  const std::integral_constant<std::size_t, N>,
143  const T& t,
144  const Types&... ts)
145 {
146  get<ParameterPack_t::size - 1 - N>(pp) = t;
147  fillParameterPackImpl(
148  pp, std::integral_constant<std::size_t, N - 1>(), ts...);
149 }
150 
151 template<typename ParameterPack_t, typename... Types>
152 void fillParameterPack(ParameterPack_t& pp, const Types&... ts)
153 {
154  fillParameterPackImpl(
155  pp,
156  std::integral_constant<std::size_t, ParameterPack_t::size - 1>(),
157  ts...);
158 }
159 
160 // Empty case.
161 template<typename ParameterPack_t>
162 void fillParameterPack(ParameterPack_t&)
163 {
164 }
165 
166 //---------------------------------------------------------------------------//
167 // Create a parameter pack.
168 template<typename... Types>
169 ParameterPack<Types...> makeParameterPack(const Types&... ts)
170 {
171  ParameterPack<Types...> pp;
172  fillParameterPack(pp, ts...);
173  return pp;
174 }
175 
176 //---------------------------------------------------------------------------//
177 
178 } // end namespace Utils
179 
180 //---------------------------------------------------------------------------//
181 
182 } // end namespace VertexCFD
183 
184 #endif // end VERTEXCFD_PARAMETERPACK_HPP
VertexCFD::Utils::is_parameter_pack_impl
Definition: VertexCFD_Utils_ParameterPack.hpp:83
VertexCFD::Utils::ParameterPack
Definition: VertexCFD_Utils_ParameterPack.hpp:66
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23
VertexCFD::Utils::PackTypeAtIndex
Definition: VertexCFD_Utils_ParameterPack.hpp:38
VertexCFD::Utils::ParameterPackElement
Definition: VertexCFD_Utils_ParameterPack.hpp:47
VertexCFD::Utils::is_parameter_pack
Definition: VertexCFD_Utils_ParameterPack.hpp:94
VertexCFD::Utils::ParameterPackImpl
Definition: VertexCFD_Utils_ParameterPack.hpp:55
VertexCFD::Utils::PackTypeAtIndexImpl
Definition: VertexCFD_Utils_ParameterPack.hpp:32