HOPS
HOPS class reference
MHO_Meta.hh
Go to the documentation of this file.
1 #ifndef MHO_Meta_HH__
2 #define MHO_Meta_HH__
3 
4 #include <complex>
5 #include <map>
6 #include <tuple>
7 #include <type_traits>
8 
9 namespace hops
10 {
11 
19 //null and empty types
21 {};
22 
27 {};
28 
29 //typelist
33 template< typename... T > struct MHO_Typelist
34 {};
35 
36 //typelist size
40 template< typename L > struct MHO_TypelistSizeImpl;
41 
42 //specialization for typelist
48 template< class... T > struct MHO_TypelistSizeImpl< MHO_Typelist< T... > >
49 {
50  using type = std::integral_constant< size_t, sizeof...(T) >;
51 };
52 
56 template< class L > using MHO_TypelistSize = typename MHO_TypelistSizeImpl< L >::type;
57 
61 template< class T, class U > struct is_same_count
62 {
63  constexpr static size_t value = 0;
64 };
65 
69 template< class T > struct is_same_count< T, T >
70 {
71  constexpr static size_t value = 1;
72 };
73 
77 template< typename XCheckType, size_t N, typename... T > struct count_instances_of_type;
78 
79 //terminating case is N=0
87 template< typename XCheckType, typename... T > struct count_instances_of_type< XCheckType, 0, T... >
88 {
89  using current_type = typename std::tuple_element< 0, std::tuple< T... > >::type;
91 };
92 
93 //N = sizeof...(T) - 1
97 template< typename XCheckType, size_t N, typename... T > struct count_instances_of_type
98 {
99  using current_type = typename std::tuple_element< N, std::tuple< T... > >::type;
100  constexpr static std::size_t value =
102 };
103 
105 
106 //functions needed to stream tuples/////////////////////////////////////////////
117 template< size_t N = 0, typename XStream, typename... T >
118 typename std::enable_if< (N >= sizeof...(T)), XStream& >::type ostream_tuple(XStream& s, const std::tuple< T... >&)
119 {
120  //terminating case, do nothing but return s
121  return s;
122 }
123 
134 template< size_t N = 0, typename XStream, typename... T >
135 typename std::enable_if< (N < sizeof...(T)), XStream& >::type ostream_tuple(XStream& s, const std::tuple< T... >& t)
136 {
137  //dump the element @ N
138  s << std::get< N >(t);
139  //recurse to next
140  return ostream_tuple< N + 1 >(s, t);
141 }
142 
143 //functions needed to stream tuples
154 template< size_t N = 0, typename XStream, typename... T >
155 typename std::enable_if< (N >= sizeof...(T)), XStream& >::type istream_tuple(XStream& s, std::tuple< T... >&)
156 {
157  //terminating case, do nothing but return s
158  return s;
159 }
160 
171 template< size_t N = 0, typename XStream, typename... T >
172 typename std::enable_if< (N < sizeof...(T)), XStream& >::type istream_tuple(XStream& s, std::tuple< T... >& t)
173 {
174  //in stream the element @ N
175  s >> std::get< N >(t);
176  //recurse to next
177  return istream_tuple< N + 1 >(s, t);
178 }
179 
181 
185 template< size_t NTypes > struct indexed_tuple_visit
186 {
193  template< typename XTupleType, typename XFunctorType > static void visit(XTupleType& tup, XFunctorType& functor)
194  {
195  //apply here and then recurse to the next type
196  functor(NTypes - 1, std::get< NTypes - 1 >(tup));
198  }
199 };
200 
201 //base case, terminates the recursion
205 template<> struct indexed_tuple_visit< 0 >
206 {
213  template< typename XTupleType, typename XFunctorType > static void visit(XTupleType& tup, XFunctorType& functor) {}
214 };
215 
217 
221 template< size_t NTypes > struct apply_to_tuple
222 {
233  template< typename XTupleType, typename XFunctorType >
234  static void apply(XTupleType& tup, size_t index, XFunctorType& functor)
235  {
236  //if the index matches the current element, apply the functor
237  if(index == NTypes - 1)
238  {
239  functor(std::get< NTypes - 1 >(tup));
240  }
241  else
242  {
243  //else recurse to the next type
244  apply_to_tuple< NTypes - 1 >::apply(tup, index, functor);
245  }
246  }
247 };
248 
249 //base case, empty tuple with no elements (should never happen)
253 template<> struct apply_to_tuple< 0 >
254 {
265  template< typename XTupleType, typename XFunctorType >
266  static void apply(XTupleType& tup, size_t index, XFunctorType& functor)
267  {}
268 };
269 
270 //const access
279 template< typename XTupleType, typename XFunctorType > void apply_at(const XTupleType& tup, size_t index, XFunctorType& functor)
280 {
281  apply_to_tuple< std::tuple_size< XTupleType >::value >::apply(tup, index, functor);
282 }
283 
284 //non-const access
285 template< typename XTupleType, typename XFunctorType > void apply_at(XTupleType& tup, size_t index, XFunctorType& functor)
286 {
287  apply_to_tuple< std::tuple_size< XTupleType >::value >::apply(tup, index, functor);
288 }
289 
292 //same thing as above, but apply a two argument functor to two tuples of the same type
293 
294 //generic apply functor to tuple (for runtime-indexed access)
295 //XTupleType and XTupleType2 must be the same (except for const)
296 template< size_t NTypes > struct apply_to_tuple2
297 {
298  template< typename XTupleType, typename XTupleType2, typename XFunctorType >
299  static void apply(XTupleType& tup1, XTupleType2& tup2, size_t index, XFunctorType& functor)
300  {
301  //if the index matches the current element, apply the functor
302  if(index == NTypes - 1)
303  {
304  functor(std::get< NTypes - 1 >(tup1), std::get< NTypes - 1 >(tup2));
305  }
306  else
307  {
308  //else recurse to the next type
309  apply_to_tuple2< NTypes - 1 >::apply(tup1, tup2, index, functor);
310  }
311  }
312 };
313 
314 //base case, empty tuple with no elements (should never happen)
315 template<> struct apply_to_tuple2< 0 >
316 {
317  template< typename XTupleType, typename XTupleType2, typename XFunctorType >
318  static void apply(XTupleType& tup1, XTupleType2& tup2, size_t index, XFunctorType& functor)
319  {}
320 };
321 
322 //const access on first parameter
323 template< typename XTupleType, typename XTupleType2, typename XFunctorType >
324 void apply_at2(const XTupleType& tup1, XTupleType& tup2, size_t index, XFunctorType& functor)
325 {
326  apply_to_tuple2< std::tuple_size< XTupleType >::value >::apply(tup1, tup2, index, functor);
327 }
328 
329 //non-const access
330 template< typename XTupleType, typename XTupleType2, typename XFunctorType >
331 void apply_at2(XTupleType& tup1, XTupleType2& tup2, size_t index, XFunctorType& functor)
332 {
333  apply_to_tuple2< std::tuple_size< XTupleType >::value >::apply(tup1, tup2, index, functor);
334 }
335 
337 // C++11 index sequence and tuple-apply
338 // (stand-in for C++14 std::index_sequence and C++17 std::apply)
339 
340 template< size_t... Is > struct mho_index_sequence
341 {};
342 
343 template< size_t N, size_t... Is > struct mho_make_index_sequence: mho_make_index_sequence< N - 1, N - 1, Is... >
344 {};
345 
346 template< size_t... Is > struct mho_make_index_sequence< 0, Is... >
347 {
348  using type = mho_index_sequence< Is... >;
349 };
350 
351 template< typename Func, typename Tuple, size_t... Is >
353  -> decltype(std::forward< Func >(f)(std::get< Is >(std::forward< Tuple >(t))...))
354 {
355  return std::forward< Func >(f)(std::get< Is >(std::forward< Tuple >(t))...);
356 }
357 
358 template< typename Func, typename Tuple >
359 auto mho_tuple_apply(Func&& f, Tuple&& t) -> decltype(mho_tuple_apply_impl(
360  std::forward< Func >(f), std::forward< Tuple >(t),
361  typename mho_make_index_sequence< std::tuple_size< typename std::decay< Tuple >::type >::value >::type{}))
362 {
363  return mho_tuple_apply_impl(
364  std::forward< Func >(f), std::forward< Tuple >(t),
365  typename mho_make_index_sequence< std::tuple_size< typename std::decay< Tuple >::type >::value >::type{});
366 }
367 
369 //check structs for complex floating point types
370 
371 template< typename XValueType > struct is_complex: std::false_type
372 {};
373 
374 template<> struct is_complex< std::complex< float > >: std::true_type
375 {};
376 
377 template<> struct is_complex< std::complex< double > >: std::true_type
378 {};
379 
380 template<> struct is_complex< std::complex< long double > >: std::true_type
381 {};
382 
388 template< typename XContainer1, typename XContainer2 >
389 std::map< typename XContainer1::value_type, typename XContainer2::value_type > zip_into_map(const XContainer1& c1,
390  const XContainer2& c2)
391 {
392  auto it1 = c1.begin();
393  auto it2 = c2.begin();
394  std::map< typename XContainer1::value_type, typename XContainer2::value_type > zip;
395  while(it1 != c1.end() && it2 != c2.end())
396  {
397  zip[*it1] = *it2;
398  ++it1;
399  ++it2;
400  }
401  return zip;
402 }
403 
405 //empty classes for detecting classes derived from container types
406 //only needed for dependent template specializations
408 {};
409 
411 {};
412 
414 {}; //only needed for dependent template specializations
415 
417 {}; //only needed for dependent template specializations
418 
420 
421 } // namespace hops
422 
423 #endif
Definition: MHO_Meta.hh:408
Definition: MHO_Meta.hh:417
Definition: MHO_Meta.hh:411
Definition: MHO_Meta.hh:414
t
Definition: picking_aedit.py:14
Definition: MHO_AdhocFlagging.hh:18
std::enable_if<(N >=sizeof...(T)), XStream & >::type istream_tuple(XStream &s, std::tuple< T... > &)
Returns an XStream& without modification for terminating case.
Definition: MHO_Meta.hh:155
void apply_at2(const XTupleType &tup1, XTupleType &tup2, size_t index, XFunctorType &functor)
Definition: MHO_Meta.hh:324
typename MHO_TypelistSizeImpl< L >::type MHO_TypelistSize
Class MHO_TypelistSize - alias to MHO_TypelistSize, retrieve the value itself with value (element of ...
Definition: MHO_Meta.hh:56
std::map< typename XContainer1::value_type, typename XContainer2::value_type > zip_into_map(const XContainer1 &c1, const XContainer2 &c2)
zip elements of two iterable (probably STL) containers (which define a value_type) into a map which t...
Definition: MHO_Meta.hh:389
std::enable_if<(N >=sizeof...(T)), XStream & >::type ostream_tuple(XStream &s, const std::tuple< T... > &)
Terminating case for ostream_tuple, does nothing and returns s.
Definition: MHO_Meta.hh:118
auto mho_tuple_apply_impl(Func &&f, Tuple &&t, mho_index_sequence< Is... >) -> decltype(std::forward< Func >(f)(std::get< Is >(std::forward< Tuple >(t))...))
Definition: MHO_Meta.hh:352
std::integral_constant< size_t, sizeof...(T) > type
Definition: MHO_Meta.hh:50
void apply_at(const XTupleType &tup, size_t index, XFunctorType &functor)
Applies a functor to an element at a specified index in a tuple.
Definition: MHO_Meta.hh:279
auto mho_tuple_apply(Func &&f, Tuple &&t) -> decltype(mho_tuple_apply_impl(std::forward< Func >(f), std::forward< Tuple >(t), typename mho_make_index_sequence< std::tuple_size< typename std::decay< Tuple >::type >::value >::type{}))
Definition: MHO_Meta.hh:359
Definition: MHO_Meta.hh:21
Class MHO_EmptyType.
Definition: MHO_Meta.hh:27
Class MHO_Typelist.
Definition: MHO_Meta.hh:34
Class MHO_TypelistSizeImpl.
Definition: MHO_Meta.hh:40
Definition: MHO_Meta.hh:341
Definition: MHO_Meta.hh:344
static void apply(XTupleType &tup1, XTupleType2 &tup2, size_t index, XFunctorType &functor)
Definition: MHO_Meta.hh:318
Definition: MHO_Meta.hh:297
static void apply(XTupleType &tup1, XTupleType2 &tup2, size_t index, XFunctorType &functor)
Definition: MHO_Meta.hh:299
static void apply(XTupleType &tup, size_t index, XFunctorType &functor)
Applies a functor to an element of a tuple at a given index.
Definition: MHO_Meta.hh:266
Class apply_to_tuple - generic apply functor to tuple element (for runtime-indexed access)
Definition: MHO_Meta.hh:222
static void apply(XTupleType &tup, size_t index, XFunctorType &functor)
Applies a functor to an element of a tuple at a specified index.
Definition: MHO_Meta.hh:234
typename std::tuple_element< 0, std::tuple< T... > >::type current_type
Definition: MHO_Meta.hh:89
Class count_instances_of_type - utility to count the instances of a particular type in a parameter pa...
Definition: MHO_Meta.hh:98
typename std::tuple_element< N, std::tuple< T... > >::type current_type
Definition: MHO_Meta.hh:99
constexpr static std::size_t value
Definition: MHO_Meta.hh:100
static void visit(XTupleType &tup, XFunctorType &functor)
Recursively applies functor to tuple elements and then itself.
Definition: MHO_Meta.hh:213
Class indexed_tuple_visit - generic apply functor (which takes and index value!) to all elements of a...
Definition: MHO_Meta.hh:186
static void visit(XTupleType &tup, XFunctorType &functor)
Applies a functor to all elements of an XTupleType tuple and recursively visits the next type.
Definition: MHO_Meta.hh:193
Definition: MHO_Meta.hh:372
Class is_same_count - utility to return 1 if two types are the same, zero otherwise.
Definition: MHO_Meta.hh:62
Definition: vex.h:175