dune-fem  2.8-git
tupleutility.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_COMMON_TUPLEUTILITY_HH
2 #define DUNE_FEM_COMMON_TUPLEUTILITY_HH
3 
4 #include <tuple>
5 #include <utility>
6 
7 #include <dune/common/tupleutility.hh>
8 
9 namespace
10 {
11 
12  // CutOutTuple
13  // -----------
14 
15  template< class Tuple,
16  int begin,
17  int length,
18  class StartType = std::tuple<>
19  >
20  class CutOutTuple
21  {
22  static_assert( (begin+length <= std::tuple_size< Tuple >::value), "Can not cut out tuple of given length" );
23  typedef typename Dune::PushBackTuple< StartType, std::tuple_element< begin, Tuple > >::type NextType;
24 
25  public:
26  typedef typename CutOutTuple< Tuple, (begin+1), (length-1), NextType >::type type;
27  };
28 
29  template< class Tuple, int begin, class ResultType >
30  struct CutOutTuple< Tuple, begin, 0, ResultType >
31  {
32  typedef ResultType type;
33  };
34 
35 } // namespace
36 
37 
38 
39 namespace Dune
40 {
41 
42  // PopFrontTuple
43  // -------------
44 
45  template< class Tuple, int size = std::tuple_size< Tuple >::value >
47  {
48  static_assert( (size == std::tuple_size< Tuple >::value),
49  "The \"size\" template parameter of PopFrontTuple "
50  "is an implementation detail and should never be "
51  "set explicitly!" );
52 
53  typedef typename CutOutTuple< Tuple, 1, (std::tuple_size< Tuple >::value - 1) >::type type;
54  };
55 
56  template< class Tuple >
57  struct PopFrontTuple< Tuple, 0 >
58  {
59  typedef Tuple type;
60  };
61 
62 
63 
64  // PopBackTuple
65  // ------------
66 
67  template< class Tuple, int size = std::tuple_size< Tuple >::value >
68  struct PopBackTuple
69  {
70  static_assert( (size == std::tuple_size< Tuple >::value),
71  "The \"size\" template parameter of PopBackTuple "
72  "is an implementation detail and should never be "
73  "set explicitly!" );
74 
75  typedef typename CutOutTuple< Tuple, 0, (std::tuple_size< Tuple >::value - 1) >::type type;
76  };
77 
78  template< class Tuple >
79  struct PopBackTuple< Tuple, 0 >
80  {
81  typedef Tuple type;
82  };
83 
84 
85 
86  // tuple_push_back
87  // ---------------
88 
89  template< typename T, typename... Args >
90  inline std::tuple< Args..., T > tuple_push_back ( const std::tuple< Args... > &tup, T t )
91  {
92  return std::tuple_cat( tup, std::tuple< T > ( t ) );
93  }
94 
95 
96 
97  // tuple_push_front
98  // ----------------
99 
100  template< typename T, typename... Args >
101  inline std::tuple< T, Args... > tuple_push_front ( const std::tuple< Args... > &tup, T t )
102  {
103  return std::tuple_cat( std::tuple< T > ( t ), tup );
104  }
105 
106 
107 
108  // tuple_pop_back
109  // --------------
110 
111  template< typename Tup, std::size_t... I >
112  inline auto tuple_pop_back_impl ( const Tup &tup, const std::index_sequence< I... >& ) ->
113  decltype ( std::make_tuple( std::get< I > ( tup )... ) )
114  {
115  return std::make_tuple ( std::get< I > ( tup )... );
116  }
117 
118  template< typename T, typename... Args >
119  inline auto tuple_pop_back ( const std::tuple< T, Args... > &tup ) ->
120  decltype ( tuple_pop_back_impl ( tup , std::make_index_sequence< sizeof...( Args ) > ( ) ) )
121  {
122  return tuple_pop_back_impl ( tup , std::make_index_sequence< sizeof... ( Args ) > ( ) );
123  }
124 
125 
126 
127  // tuple_pop_front
128  // ---------------
129 
130  template< typename Tup, std::size_t... I >
131  inline auto tuple_pop_front_impl ( const Tup &tup, const std::index_sequence< I... >& ) ->
132  decltype ( std::make_tuple( std::get< I > ( tup )... ) )
133  {
134  return std::make_tuple ( std::get< I + 1 > ( tup )... );
135  }
136 
137  template< typename T, typename... Args >
138  inline auto tuple_pop_front ( const std::tuple< T, Args... > &tup ) ->
139  decltype ( tuple_pop_front_impl ( tup , std::make_index_sequence< sizeof...( Args ) > ( ) ) )
140  {
141  return tuple_pop_front_impl ( tup , std::make_index_sequence< sizeof... ( Args ) > ( ) );
142  }
143 
144 
145 
146  // ContainsType
147  // ------------
148 
149  /*
150  * \brief Check wheter given type is contained in tuple.
151  *
152  * \tparam Tuple tuple
153  * \tparam Type type to search for
154  */
155  template< class Tuple,
156  class Type,
157  int N = std::tuple_size< Tuple >::value
158  >
160  {
161  static const bool value = ( std::is_same< typename std::tuple_element< N-1, Tuple >::type, Type >::value
162  || ContainsType< Tuple, Type, N-1 >::value );
163  };
164 
165  template< class Tuple,
166  class Type
167  >
168  struct ContainsType< Tuple, Type, 0 >
169  {
170  static const bool value = false;
171  };
172 
173 
174 
175  // FirstTypeIndexTuple
176  // -------------------
177 
178  /*
179  * \brief Please doc me.
180  */
181  template< class Tuple,
182  class SubTuple,
183  class Seed = std::tuple<>,
184  int index = 0,
185  int size = std::tuple_size< SubTuple >::value
186  >
188  {
189  static_assert( (index == std::tuple_size< Seed >::value),
190  "The \"index\" template parameter of FirstTypeIndexTuple"
191  "is an implementation detail and should never be "
192  "set explicitly!" );
193 
194  // get element from selector
195  typedef typename std::tuple_element< index, SubTuple >::type Element;
196  // find element in pass id tuple
197  typedef typename Dune::FirstTypeIndex< Tuple, Element >::type Position;
198  // add value to seed
199  typedef typename Dune::PushBackTuple< Seed, Position >::type NextSeed;
200 
201  public:
202  // result type is a tuple of integral constants
203  typedef typename FirstTypeIndexTuple< Tuple, SubTuple, NextSeed, (index+1) >::type type;
204  };
205 
206  template< class Tuple,
207  class SubTuple,
208  class Seed,
209  int size
210  >
211  struct FirstTypeIndexTuple< Tuple, SubTuple, Seed, size, size >
212  {
213  typedef Seed type;
214  };
215 
216 
217 
218  // MakeSubTuple
219  // ------------
220 
221  /*
222  * \brief Please doc me.
223  */
224  template< class Tuple,
225  class Positions,
226  class Seed = std::tuple<>,
227  int index = 0,
228  int size = std::tuple_size< Positions >::value
229  >
231  {
232  template< class, class, class, int, int > friend class MakeSubTuple;
233 
234  // get pass number for element to append from mapping
235  static const int position = std::tuple_element< index, Positions >::type::value;
236 
237  // add type to seed
238  typedef typename std::tuple_element< position, Tuple >::type AppendType;
239 
240  typedef typename Dune::PushBackTuple< Seed, AppendType >::type AccumulatedType;
241 
242  typedef MakeSubTuple< Tuple, Positions, AccumulatedType, (index+1), size > NextType;
243 
244  static typename NextType::type append ( Tuple &tuple, Seed &seed )
245  {
246  AppendType append = std::get< position >( tuple );
247  AccumulatedType next = tuple_push_back( seed, append );
248  return NextType::append( tuple, next );
249  }
250 
251  public:
252  typedef typename NextType::type type;
253 
254  static type apply ( Tuple &tuple )
255  {
256  Seed seed;
257  return append( tuple, seed );
258  }
259  };
260 
261  template< class Tuple,
262  class Positions,
263  class Seed,
264  int size >
265  class MakeSubTuple< Tuple, Positions, Seed, size, size >
266  {
267  template< class, class, class, int, int > friend class MakeSubTuple;
268 
269  static Seed append ( Tuple &tuple, Seed &seed ) { return seed; }
270 
271  public:
272  typedef Seed type;
273 
274  static type apply ( Tuple & ) { return type(); }
275  };
276 
277 
278 
279  // TupleToVectorConverter
280  // ----------------------
281 
285  template< class VectorTupleType, int pos >
287  {
288  public:
290 
291  typedef typename VectorTupleType::value_type TupleType;
292  typedef typename std::tuple_element< pos, TupleType >::type ValueType;
294 
296  explicit TupleToVectorConverter ( VectorTupleType &vector )
297  : vector_( vector )
298  {}
299 
301  ValueType &operator [] ( const size_t i )
302  {
303  using std::get; // for TypeIndexedTuple the function get is in namespace Dune
304  assert( i < size() );
305  return get< pos >( vector_[ i ] );
306  }
307 
309  const ValueType &operator [] ( const size_t i ) const
310  {
311  using std::get; // for TypeIndexedTuple the function get is in namespace Dune
312  assert( i < size() );
313  return get< pos >( vector_[ i ] );
314  }
315 
317  size_t size () const { return vector_.size(); }
318 
319  protected:
320  VectorTupleType &vector_;
321  };
322 
323 
324 
325  // InstantiateTuple
326  // ----------------
327 
342  template< class Tuple,
343  class Key,
344  class Seed = std::tuple<>,
345  int len = std::tuple_size< Tuple >::value
346  >
348  {
353  static Tuple apply ( const Key &key = Key() )
354  {
355  Seed seed;
356  return append( key, seed );
357  }
358 
359  private:
360  template< class, class, class, int > friend struct InstantiateTuple;
361 
362  static Tuple append ( const Key &key, Seed &seed )
363  {
364  static const int index = std::tuple_size< Tuple >::value - len;
365 
366  typedef typename std::tuple_element< index, Tuple >::type AppendType;
367  typedef typename Dune::PushBackTuple< Seed, AppendType >::type AccumulatedType;
368 
369  AccumulatedType next = Dune::tuple_push_back< AppendType >( seed, AppendType( key ) );
371  }
372  };
373 
374  template< class Tuple, class Key, class Seed >
375  struct InstantiateTuple< Tuple, Key, Seed, 0 >
376  {
377  static Tuple apply ( const Key &key = Key() ) { return Tuple(); }
378 
379  private:
380  template< class, class, class, int > friend struct InstantiateTuple;
381 
382  static Seed append ( const Key &key, Seed &seed ) { return seed; }
383  };
384 
385 } // namespace Dune
386 
387 #endif // #ifndef DUNE_FEM_COMMON_TUPLEUTILITY_HH
Definition: bindguard.hh:11
auto tuple_pop_front_impl(const Tup &tup, const std::index_sequence< I... > &) -> decltype(std::make_tuple(std::get< I >(tup)...))
Definition: tupleutility.hh:131
auto tuple_pop_front(const std::tuple< T, Args... > &tup) -> decltype(tuple_pop_front_impl(tup, std::make_index_sequence< sizeof...(Args) >()))
Definition: tupleutility.hh:138
std::tuple< Args..., T > tuple_push_back(const std::tuple< Args... > &tup, T t)
Definition: tupleutility.hh:90
auto tuple_pop_back_impl(const Tup &tup, const std::index_sequence< I... > &) -> decltype(std::make_tuple(std::get< I >(tup)...))
Definition: tupleutility.hh:112
std::tuple< T, Args... > tuple_push_front(const std::tuple< Args... > &tup, T t)
Definition: tupleutility.hh:101
auto tuple_pop_back(const std::tuple< T, Args... > &tup) -> decltype(tuple_pop_back_impl(tup, std::make_index_sequence< sizeof...(Args) >()))
Definition: tupleutility.hh:119
std::tuple_element< i, Tuple >::type & get(Dune::TypeIndexedTuple< Tuple, Types > &tuple)
Definition: typeindexedtuple.hh:122
Definition: tupleutility.hh:47
CutOutTuple< Tuple, 1,(std::tuple_size< Tuple >::value - 1) >::type type
Definition: tupleutility.hh:51
Tuple type
Definition: tupleutility.hh:59
Definition: tupleutility.hh:69
CutOutTuple< Tuple, 0,(std::tuple_size< Tuple >::value - 1) >::type type
Definition: tupleutility.hh:73
Tuple type
Definition: tupleutility.hh:81
Definition: tupleutility.hh:160
static const bool value
Definition: tupleutility.hh:161
Definition: tupleutility.hh:188
FirstTypeIndexTuple< Tuple, SubTuple, NextSeed,(index+1) >::type type
Definition: tupleutility.hh:203
Definition: tupleutility.hh:231
static type apply(Tuple &tuple)
Definition: tupleutility.hh:254
NextType::type type
Definition: tupleutility.hh:252
static type apply(Tuple &)
Definition: tupleutility.hh:274
wrapper class to convert a vector of tuples of RangeTypes into something that behaves like a vector< ...
Definition: tupleutility.hh:287
std::tuple_element< pos, TupleType >::type ValueType
Definition: tupleutility.hh:292
size_t size() const
return size of vector
Definition: tupleutility.hh:317
TupleToVectorConverter(const TupleToVectorConverter &)=delete
VectorTupleType & vector_
Definition: tupleutility.hh:320
TupleToVectorConverter(VectorTupleType &vector)
constructor
Definition: tupleutility.hh:296
ValueType & operator[](const size_t i)
return reference to i-th entry of vector and pos's tuple component
Definition: tupleutility.hh:301
VectorTupleType::value_type TupleType
Definition: tupleutility.hh:291
ValueType value_type
Definition: tupleutility.hh:293
Instantiate a tuple of elements with identical, simple constructors.
Definition: tupleutility.hh:348
static Tuple apply(const Key &key=Key())
create tuple instance
Definition: tupleutility.hh:353
static Tuple apply(const Key &key=Key())
Definition: tupleutility.hh:377