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 
13 namespace 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
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.80.0 (May 6, 22:30, 2024)