dune-typetree  2.4.1
typetraits.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
4 #ifndef DUNE_TYPETREE_TYPETRAITS_HH
5 #define DUNE_TYPETREE_TYPETRAITS_HH
6 
7 #include <type_traits>
8 #include <dune/common/typetraits.hh>
9 
11 
12 namespace Dune {
13 
14  // Provide some more C++11 TMP helpers.
15  // These should be upstreamed to dune-common ASAP.
16 
17  // Tests whether the first template argument is a base class of the second one.
18  using std::is_base_of;
19 
20  template<typename... T>
21  struct first_type;
22 
23  template<typename T0, typename... T>
24  struct first_type<T0,T...>
25  {
26  typedef T0 type;
27  };
28 
29  namespace TypeTree {
30 
31  template<typename T>
32  struct has_node_tag
33  {
34  struct yes { char dummy[1]; };
35  struct no { char dummy[2]; };
36 
37  template<typename X>
38  static yes test(typename X::NodeTag *);
39  template<typename X>
40  static no test(...);
41 
42  enum {
44  value = sizeof(test<T>(0)) == sizeof(yes)
45  };
46  };
47 
48  template<typename T, typename V>
50  {
51  template<int N>
52  struct maybe { char dummy[N+1]; };
53  struct yes { char dummy[2]; };
54  struct no { char dummy[1]; };
55 
56  template<typename X>
58  test(typename X::NodeTag * a);
59  template<typename X>
60  static no test(...);
61 
62  enum {
64  value = sizeof(test<T>(0)) == sizeof(yes)
65  };
66  };
67 
68  template<typename T>
70  {
71  struct yes { char dummy[1]; };
72  struct no { char dummy[2]; };
73 
74  template<typename X>
75  static yes test(typename X::ImplementationTag *);
76  template<typename X>
77  static no test(...);
78 
79  enum {
81  value = sizeof(test<T>(0)) == sizeof(yes)
82  };
83  };
84 
85  template<typename T, typename V>
87  {
88  template<int N>
89  struct maybe { char dummy[N+1]; };
90  struct yes { char dummy[2]; };
91  struct no { char dummy[1]; };
92 
93  template<typename X>
95  test(typename X::ImplementationTag * a);
96  template<typename X>
97  static no test(...);
98 
99  enum {
101  value = sizeof(test<T>(0)) == sizeof(yes)
102  };
103  };
104 
105  template<typename>
106  struct AlwaysVoid
107  {
108  typedef void type;
109  };
110 
111 
113  template<typename T>
114  T* declptr();
115 
116 
117  // Support for lazy evaluation of meta functions. This is required when doing
118  // nested tag dispatch without C++11-style typedefs (based on using syntax).
119  // The standard struct-based meta functions cause premature evaluation in a
120  // context that is not SFINAE-compatible. We thus have to return the meta function
121  // without evaluating it, placing that burden on the caller. On the other hand,
122  // the lookup will often directly the target type, so here is some helper code
123  // to automatically do the additional evaluation if necessary.
124  // Too bad that the new syntax is GCC 4.6+...
125 
126 
128 
131  struct meta_function {};
132 
134  template<typename F>
136  {
137  typedef typename F::type type;
138  };
139 
141  template<typename F>
143  {
144  typedef F type;
145  };
146 
148  template<typename F>
150  {
151  typedef typename conditional<
152  is_base_of<meta_function,F>::value,
155  >::type::type type;
156  };
157 
158  namespace impl {
159 
160  // Check if type is a or is derived from one of the tree path types
161 
162  // Default overload for types not representing a tree path
163  constexpr auto isTreePath(void*)
164  -> std::false_type
165  {
166  return std::false_type();
167  }
168 
169  // Overload for DynamicTreePath
170  constexpr auto isTreePath(const DynamicTreePath*)
171  -> std::true_type
172  {
173  return std::true_type();
174  }
175 
176  // Overload for instances of TreePath<...>
177  template<std::size_t... i>
178  constexpr auto isTreePath(const TreePath<i...>*)
179  -> std::true_type
180  {
181  return std::true_type();
182  }
183 
184  // Overload for instances of HybridTreePath<...>
185  template<class... I>
186  constexpr auto isTreePath(const HybridTreePath<I...>*)
187  -> std::true_type
188  {
189  return std::true_type();
190  }
191 
192  }
193 
204  template<class T>
205  struct IsTreePath :
206  public decltype(impl::isTreePath((typename std::decay<T>::type*)(nullptr)))
207  {};
208 
215  template<class T>
216  constexpr auto isTreePath(const T&)
217  -> IsTreePath<T>
218  {
219  return IsTreePath<T>();
220  }
221 
222 
223  } // end namespace TypeTree
224 } // end namespace Dune
225 
226 #endif // DUNE_TYPETREE_TYPETRAITS_HH
constexpr auto isTreePath(const T &) -> IsTreePath< T >
Check if given object represents a tree path.
Definition: typetraits.hh:216
Meta function that evaluates its argument iff it inherits from meta_function.
Definition: typetraits.hh:149
Definition: typetraits.hh:52
A hybrid version of TreePath that supports both compile time and run time indices.
Definition: treepath.hh:322
Definition: typetraits.hh:35
F type
Definition: typetraits.hh:144
Definition: typetraits.hh:69
T0 type
Definition: typetraits.hh:26
A TreePath that stores the path of a node as runtime information.
Definition: treepath.hh:157
Definition: typetraits.hh:49
Definition: typetraits.hh:21
Definition: typetraits.hh:53
Definition: treepath.hh:30
F::type type
Definition: typetraits.hh:137
Definition: typetraits.hh:72
Identity function.
Definition: typetraits.hh:142
Check if type represents a tree path.
Definition: typetraits.hh:205
Definition: typetraits.hh:32
T * declptr()
Helper function for generating a pointer to a value of type T in an unevaluated operand setting...
void type
Definition: typetraits.hh:108
Definition: typetraits.hh:106
conditional< is_base_of< meta_function, F >::value, lazy_evaluate< F >, lazy_identity< F > >::type::type type
Definition: typetraits.hh:155
Definition: typetraits.hh:34
Marker tag declaring a meta function.
Definition: typetraits.hh:131
Definition: typetraits.hh:54
Definition: accumulate_static.hh:12
Helper meta function to delay evaluation of F.
Definition: typetraits.hh:135