dune-typetree  2.4-dev
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 #ifndef DOXYGEN
112 
113 // Make sure we have decltype or a compatible fall back
114 
115 #if HAVE_STD_DECLTYPE
116 #define DUNE_DECLTYPE decltype
117 #elif HAVE_GCC___TYPEOF__
118 #define DUNE_DECLTYPE __typeof__
119 #else
120 #error The TypeTree library requires support for
121 #error C++11 decltype or a compatible fallback in your compiler.
122 #error Neither of those was found, aborting!!!!
123 #endif
124 
125 #endif // DOXYGEN
126 
127 
129  template<typename T>
130  T* declptr();
131 
132 
133  // Support for lazy evaluation of meta functions. This is required when doing
134  // nested tag dispatch without C++11-style typedefs (based on using syntax).
135  // The standard struct-based meta functions cause premature evaluation in a
136  // context that is not SFINAE-compatible. We thus have to return the meta function
137  // without evaluating it, placing that burden on the caller. On the other hand,
138  // the lookup will often directly the target type, so here is some helper code
139  // to automatically do the additional evaluation if necessary.
140  // Too bad that the new syntax is GCC 4.6+...
141 
142 
144 
147  struct meta_function {};
148 
150  template<typename F>
152  {
153  typedef typename F::type type;
154  };
155 
157  template<typename F>
159  {
160  typedef F type;
161  };
162 
164  template<typename F>
166  {
167  typedef typename conditional<
168  is_base_of<meta_function,F>::value,
171  >::type::type type;
172  };
173 
174  namespace impl {
175 
176  // Check if type is a or is derived from one of the tree path types
177 
178  // Default overload for types not representing a tree path
179  constexpr auto isTreePath(void*)
180  -> std::false_type
181  {
182  return std::false_type();
183  }
184 
185  // Overload for DynamicTreePath
186  constexpr auto isTreePath(const DynamicTreePath*)
187  -> std::true_type
188  {
189  return std::true_type();
190  }
191 
192  // Overload for instances of TreePath<...>
193  template<std::size_t... i>
194  constexpr auto isTreePath(const TreePath<i...>*)
195  -> std::true_type
196  {
197  return std::true_type();
198  }
199 
200  // Overload for instances of HybridTreePath<...>
201  template<class... I>
202  constexpr auto isTreePath(const HybridTreePath<I...>*)
203  -> std::true_type
204  {
205  return std::true_type();
206  }
207 
208  }
209 
220  template<class T>
221  struct IsTreePath :
222  public decltype(impl::isTreePath((typename std::decay<T>::type*)(nullptr)))
223  {};
224 
231  template<class T>
232  constexpr auto isTreePath(const T&)
233  -> IsTreePath<T>
234  {
235  return IsTreePath<T>();
236  }
237 
238 
239  } // end namespace TypeTree
240 } // end namespace Dune
241 
242 #endif // DUNE_TYPETREE_TYPETRAITS_HH
Definition: typetraits.hh:32
Definition: typetraits.hh:69
True if class T defines a NodeTag.
Definition: typetraits.hh:44
T * declptr()
Helper function for generating a pointer to a value of type T in an unevaluated operand setting...
Marker tag declaring a meta function.
Definition: typetraits.hh:147
Definition: typetraits.hh:54
Definition: accumulate_static.hh:12
char dummy[1]
Definition: typetraits.hh:34
F::type type
Definition: typetraits.hh:153
T0 type
Definition: typetraits.hh:26
Definition: typetraits.hh:35
F type
Definition: typetraits.hh:160
Meta function that evaluates its argument iff it inherits from meta_function.
Definition: typetraits.hh:165
constexpr auto isTreePath(const T &) -> IsTreePath< T >
Check if given object represents a tree path.
Definition: typetraits.hh:232
static yes test(typename X::NodeTag *)
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:34
A TreePath that stores the path of a node as runtime information.
Definition: treepath.hh:157
Helper meta function to delay evaluation of F.
Definition: typetraits.hh:151
Definition: typetraits.hh:49
Definition: typetraits.hh:21
Definition: typetraits.hh:53
void type
Definition: typetraits.hh:108
conditional< is_base_of< meta_function, F >::value, lazy_evaluate< F >, lazy_identity< F > >::type::type type
Definition: typetraits.hh:171
Definition: typetraits.hh:72
Identity function.
Definition: typetraits.hh:158
Check if type represents a tree path.
Definition: typetraits.hh:221
Definition: treepath.hh:30
Definition: typetraits.hh:106
char dummy[2]
Definition: typetraits.hh:35