DUNE-ACFEM (unstable)

access.hh
1#ifndef __DUNE_ACFEM_MPL_ACCESS_HH__
2#define __DUNE_ACFEM_MPL_ACCESS_HH__
3
4#include <tuple>
5#include <array>
6
7#include <dune/common/hybridutilities.hh>
8#include "../common/types.hh"
9#include "generators.hh"
10#include "size.hh"
11#include "typepackelement.hh"
12
13namespace Dune {
14
15 namespace ACFem {
16
41 template<std::size_t N, class Seq>
42 struct Get;
43
44#if DUNE_ACFEM_IS_CLANG(5,99)
45# define DUNE_ACFEM_GET_IS_FAST true
46 static_assert(__has_builtin(__type_pack_element), "");
47
48 template<std::size_t N, class I, I... Is>
49 struct Get<N, Sequence<I, Is...> >
50 : __type_pack_element<N, Constant<I, Is>...>
51 {};
52#else
53 template<std::size_t N, class I, I I0, I... IRest>
54 struct Get<N, Sequence<I, I0, IRest...> >
55 : Get<N-1, Sequence<I, IRest...> >
56 {};
57
58 template<class I, I I0, I... IRest>
59 struct Get<0, Sequence<I, I0, IRest...> >
60 : Constant<I, I0>
61 {};
62
63#if 0
64 template<class I, I I0, I I1, I... IRest>
65 struct Get<1, Sequence<I, I0, I1, IRest...> >
66 : Constant<I, I1>
67 {};
68
69 template<class I, I I0, I I1, I I2, I... IRest>
70 struct Get<2, Sequence<I, I0, I1, I2, IRest...> >
71 : Constant<I, I2>
72 {};
73
74 template<class I, I I0, I I1, I I2, I I3, I... IRest>
75 struct Get<3, Sequence<I, I0, I1, I2, I3, IRest...> >
76 : Constant<I, I3>
77 {};
78
79 template<class I, I I0, I I1, I I2, I I3, I I4, I... IRest>
80 struct Get<4, Sequence<I, I0, I1, I2, I3, I4, IRest...> >
81 : Constant<I, I4>
82 {};
83
84 template<class I, I I0, I I1, I I2, I I3, I I4, I I5, I... IRest>
85 struct Get<5, Sequence<I, I0, I1, I2, I3, I4, I5, IRest...> >
86 : Constant<I, I5>
87 {};
88
89 template<class I, I I0, I I1, I I2, I I3, I I4, I I5, I I6, I... IRest>
90 struct Get<6, Sequence<I, I0, I1, I2, I3, I4, I5, I6, IRest...> >
91 : Constant<I, I6>
92 {};
93
94 template<class I, I I0, I I1, I I2, I I3, I I4, I I5, I I6, I I7, I... IRest>
95 struct Get<7, Sequence<I, I0, I1, I2, I3, I4, I5, I6, I7, IRest...> >
96 : Constant<I, I7>
97 {};
98
99 template<class I, I I0, I I1, I I2, I I3, I I4, I I5, I I6, I I7, I I8, I... IRest>
100 struct Get<8, Sequence<I, I0, I1, I2, I3, I4, I5, I6, I7, I8, IRest...> >
101 : Constant<I, I8>
102 {};
103
104 template<class I, I I0, I I1, I I2, I I3, I I4, I I5, I I6, I I7, I I8, I I9, I... IRest>
105 struct Get<9, Sequence<I, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, IRest...> >
106 : Constant<I, I9>
107 {};
108#endif
109
110#endif
111
112 template<class I>
113 struct Get<0, Sequence<I> >
114 {
115 // To static_assert or not to static_assert ...
116 };
117
118 template<class I, I I0>
119 struct Get<0, Constant<I, I0> >
120 : Constant<I, I0>
121 {};
122
124 template<std::size_t N, class TupleLike>
125 using TupleElement = std::tuple_element_t<N, std::decay_t<TupleLike> >;
126
128 template<std::size_t I, class T, std::enable_if_t<IsTupleLike<T>::value, int> = 0>
129 constexpr decltype(auto) get(T&& t, IndexConstant<I> = IndexConstant<I>{})
130 {
131 return std::get<I>(std::forward<T>(t));
132 }
133
135 template<std::size_t I, class T, std::size_t N, std::enable_if_t<std::is_integral<T>::value, int> = 0>
136 constexpr decltype(auto) get(const T (&t)[N], IndexConstant<I> = IndexConstant<I>{})
137 {
138 return t[I];
139 }
140
142 template<std::size_t I, class T, T... V>
144 {
145 return Get<I, Sequence<T, V...> >::value;
146 }
147
149 template<std::size_t I, class T, T V>
151 {
152 static_assert(I == 0, "Integral constants only have one value.");
153 return V;
154 }
155
156 template<class T, class SFINAE = void>
157 struct AllowsGet
158 : FalseType
159 {};
160
161 template<class T>
162 struct AllowsGet<T, std::enable_if_t<(size<T>() != size<void>())> >
163 : TrueType
164 {};
165
166 /*Obtain type of first tuple element, define to void if empty tuple. */
167 template<class SequenceLike>
168 using Head = Get<0, SequenceLike>;
169
170 /*Obtain type of a last tuple element.*/
171 template<class SequenceLike>
172 using Tail = Get<SequenceLike::size()-1, SequenceLike>;
173
174 namespace {
175
176 // helpers for GetPart template which extracts a consecutive
177 // part of an integer_sequence starting at a given position.
178
179 template<std::size_t Skip, class Sequence, class SFINAE = void>
180 struct GetTailPartHelper;
181
182 template<class Seq>
183 struct GetTailPartHelper<0, Seq>
184 {
185 using Type = Seq;
186 };
187
188 template<std::size_t Skip, class T, T I0, T... I>
189 struct GetTailPartHelper<Skip, Sequence<T, I0, I...>, std::enable_if_t<(Skip > 0)> >
190 {
191 using Type = typename GetTailPartHelper<Skip-1, Sequence<T, I...> >::Type;
192 };
193
194 template<std::size_t Cnt, class Input, class Output = Sequence<typename Input::value_type>, class SFINAE = void>
195 struct GetHeadPartHelper;
196
197 template<class Input, class Output>
198 struct GetHeadPartHelper<0, Input, Output>
199 {
200 using Type = Output;
201 };
202
203 template<std::size_t Cnt, class T, T I0, T... I, T... O>
204 struct GetHeadPartHelper<Cnt, Sequence<T, I0, I...>, Sequence<T, O...>, std::enable_if_t<(Cnt > 0)> >
205 {
206 using Type = typename GetHeadPartHelper<Cnt-1, Sequence<T, I...>, Sequence<T, O..., I0> >::Type;
207 };
208
209 }
210
212 template<std::size_t Skip, std::size_t Cnt, class Seq>
213 using GetPart = typename GetHeadPartHelper<Cnt, typename GetTailPartHelper<Skip, Seq>::Type>::Type;
214
216 template<std::size_t Cnt, class Seq>
217 using HeadPart = typename GetHeadPartHelper<Cnt, Seq>::Type;
218
220 template<std::size_t Cnt, class Seq>
221 using TailPart = typename GetTailPartHelper<Seq::size()-Cnt, Seq>::Type;
222
223 namespace {
224 // helper templates for IndexIn template.
225
226 // default is "infinity".
227 template<std::size_t HeadSize, class T, T V, class Seq>
228 struct IndexInHelper
229 {
230 static constexpr std::size_t value = std::numeric_limits<std::size_t>::max();
231 };
232
233 // "diagonal" case: first element is equal to V
234 template<std::size_t HeadSize, class T, T V, T... Ints>
235 struct IndexInHelper<HeadSize, T, V, Sequence<T, V, Ints...> >
236 {
237 static constexpr std::size_t value = HeadSize;
238 };
239
240 // Recurse until
241 template<std::size_t HeadSize, class T, T V, T I, T... Ints>
242 struct IndexInHelper<HeadSize, T, V, Sequence<T, I, Ints...> >
243 {
244 static constexpr std::size_t value =
245 IndexInHelper<HeadSize+1, T, V, Sequence<T, Ints...> >::value;
246 };
247
248 }
249
250 template<class T, T... I, T V>
251 constexpr auto multiplicity(Sequence<T, I...>, Constant<T, V>)
252 {
253 return IndexConstant<((std::size_t)(I == V) + ... + 0)>::value;
254 }
255
256 template<class T, T... I>
257 constexpr bool containsValue(Sequence<T, I...>, T V)
258 {
259 return (... || (I == V));
260 }
261
262#if 0
263 template<class T, T... I, T V, std::size_t... Idx>
264 constexpr auto indexInHelper(Sequence<T, I...>, Constant<T, V>, IndexSequence<Idx...>)
265 {
266 return IndexConstant<((std::size_t)((I == V)*Idx) + ... + 0)>::value;
267 }
268
269 template<class T, T... I, T V>
270 constexpr auto indexIn(Sequence<T, I...>, Constant<T, V>)
271 {
272 if constexpr (
273 return IndexConstant<((std::size_t)((I == V)*Idx) + ... + 0)>::value;
274 }
275#endif
276
278 template<class Seq, typename Seq::value_type V>
280
281#if 0
283 template<class Seq, typename Seq::value_type V>
284 using ContainsValue = BoolConstant<IndexIn<Seq, V>::value < std::numeric_limits<std::size_t>::max()>;
285#else
286 template<class Seq, typename Seq::value_type V>
287 constexpr inline bool ContainsValueV = containsValue(Seq{}, V);
288
289 template<class Seq, typename Seq::value_type V>
290 using ContainsValue = BoolConstant<containsValue(Seq{}, V)>;
291#endif
292
294 template<std::ptrdiff_t V, class T, T... I>
296 {
297 return Sequence<T, V, I...>{};
298 }
299
301 template<std::ptrdiff_t V, class T, T... I>
303 {
304 return Sequence<T, I..., V>{};
305 }
306
308 template<std::ptrdiff_t V, class Seq>
309 using PushFront = decltype(pushFront<V>(Seq{}));
310
312 template<std::ptrdiff_t V, class Seq>
313 using PushBack = decltype(pushBack<V>(Seq{}));
314
315 namespace {
316 template<std::size_t V, std::size_t N, class Head, class Tail>
317 struct PutHelper;
318
319 template<std::size_t V, std::size_t N, std::size_t... Head, std::size_t Tail0, std::size_t... Tail>
320 struct PutHelper<V, N, IndexSequence<Head...>, IndexSequence<Tail0, Tail...> >
321 {
322 using Type = typename PutHelper<V, N-1, IndexSequence<Head..., Tail0>, IndexSequence<Tail...> >::Type;
323 };
324
325 template<std::size_t V, std::size_t... Head, std::size_t Tail0, std::size_t... Tail>
326 struct PutHelper<V, 0, IndexSequence<Head...>, IndexSequence<Tail0, Tail...> >
327 {
328 using Type = IndexSequence<Head..., V, Tail...>;
329 };
330 }
331
333 template<std::size_t V, std::size_t N, class Input>
334 using Put = typename PutHelper<V, N, IndexSequence<>, Input>::Type;
335
337
339
341
342 } // ACFem::
343
344} // Dune::
345
346#endif // __DUNE_ACFEM_MPL_ACCESS_HH__
constexpr decltype(auto) get(T &&t, IndexConstant< I >=IndexConstant< I >{})
Access to the i-the element.
Definition: access.hh:129
constexpr auto pushBack(Sequence< T, I... >, IntConstant< V >=IntConstant< V >{})
Add V at the end of the sequece.
Definition: access.hh:302
typename PutHelper< V, N, IndexSequence<>, Input >::Type Put
Replace value at position N with V.
Definition: access.hh:334
typename GetHeadPartHelper< Cnt, Seq >::Type HeadPart
Extract Cnt many consecutive elements from the front of Seq.
Definition: access.hh:217
std::tuple_element_t< N, std::decay_t< TupleLike > > TupleElement
Forward to std::tuple_element<N, std::decay_t<T> >
Definition: access.hh:125
decltype(pushFront< V >(Seq{})) PushFront
Add value to start of integer-sequence.
Definition: access.hh:309
typename GetHeadPartHelper< Cnt, typename GetTailPartHelper< Skip, Seq >::Type >::Type GetPart
Extract Cnt many consecutive elements from Seq starting at position N.
Definition: access.hh:213
typename GetTailPartHelper< Seq::size() -Cnt, Seq >::Type TailPart
Extract Cnt many consecutive elements from the end of Seq.
Definition: access.hh:221
constexpr std::size_t size()
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:73
IndexConstant< IndexInHelper< 0, typename Seq::value_type, V, Seq >::value > IndexIn
Find the index of a given value in a sequence.
Definition: access.hh:279
constexpr auto pushFront(Sequence< T, I... >, IntConstant< V >=IntConstant< V >{})
Add V at the front of the sequence.
Definition: access.hh:295
decltype(pushBack< V >(Seq{})) PushBack
Add value to end of integer-sequence.
Definition: access.hh:313
Constant< std::ptrdiff_t, V > IntConstant
Short-for integral constant of type std::p0trdiff_t.
Definition: types.hh:52
Sequence< std::size_t, V... > IndexSequence
Sequence of std::size_t values.
Definition: types.hh:64
integral_constant< T, V > Constant
Short-cut for any integral constant.
Definition: types.hh:40
Constant< bool, V > BoolConstant
Short-cut for integral constant of type bool.
Definition: types.hh:48
std::integer_sequence< T, V... > Sequence
Sequence of any type of integer values.
Definition: types.hh:56
Constant< std::size_t, V > IndexConstant
Short-cut for integral constant of type std::size_t.
Definition: types.hh:44
BoolConstant< false > FalseType
Alias for std::false_type.
Definition: types.hh:110
BoolConstant< true > TrueType
Alias for std::true_type.
Definition: types.hh:107
STL namespace.
Gets the type of the n-th element of a tuple-like or the std::integral_constant corresponding to the ...
Definition: access.hh:42
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)