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 
10 namespace Dune {
11 
12  // Provide some more C++11 TMP helpers.
13  // These should be upstreamed to dune-common ASAP.
14 
15  // Tests whether the first template argument is a base class of the second one.
16  using std::is_base_of;
17 
18  template<typename... T>
19  struct first_type;
20 
21  template<typename T0, typename... T>
22  struct first_type<T0,T...>
23  {
24  typedef T0 type;
25  };
26 
27  namespace TypeTree {
28 
29  template<typename T>
30  struct has_node_tag
31  {
32  struct yes { char dummy[1]; };
33  struct no { char dummy[2]; };
34 
35  template<typename X>
36  static yes test(typename X::NodeTag *);
37  template<typename X>
38  static no test(...);
39 
40  enum {
42  value = sizeof(test<T>(0)) == sizeof(yes)
43  };
44  };
45 
46  template<typename T, typename V>
48  {
49  template<int N>
50  struct maybe { char dummy[N+1]; };
51  struct yes { char dummy[2]; };
52  struct no { char dummy[1]; };
53 
54  template<typename X>
56  test(typename X::NodeTag * a);
57  template<typename X>
58  static no test(...);
59 
60  enum {
62  value = sizeof(test<T>(0)) == sizeof(yes)
63  };
64  };
65 
66  template<typename T>
68  {
69  struct yes { char dummy[1]; };
70  struct no { char dummy[2]; };
71 
72  template<typename X>
73  static yes test(typename X::ImplementationTag *);
74  template<typename X>
75  static no test(...);
76 
77  enum {
79  value = sizeof(test<T>(0)) == sizeof(yes)
80  };
81  };
82 
83  template<typename T, typename V>
85  {
86  template<int N>
87  struct maybe { char dummy[N+1]; };
88  struct yes { char dummy[2]; };
89  struct no { char dummy[1]; };
90 
91  template<typename X>
93  test(typename X::ImplementationTag * a);
94  template<typename X>
95  static no test(...);
96 
97  enum {
99  value = sizeof(test<T>(0)) == sizeof(yes)
100  };
101  };
102 
103  template<typename>
104  struct AlwaysVoid
105  {
106  typedef void type;
107  };
108 
109 #ifndef DOXYGEN
110 
111 // Make sure we have decltype or a compatible fall back
112 
113 #if HAVE_STD_DECLTYPE
114 #define DUNE_DECLTYPE decltype
115 #elif HAVE_GCC___TYPEOF__
116 #define DUNE_DECLTYPE __typeof__
117 #else
118 #error The TypeTree library requires support for
119 #error C++11 decltype or a compatible fallback in your compiler.
120 #error Neither of those was found, aborting!!!!
121 #endif
122 
123 #endif // DOXYGEN
124 
125 
127  template<typename T>
128  T* declptr();
129 
130 
131  // Support for lazy evaluation of meta functions. This is required when doing
132  // nested tag dispatch without C++11-style typedefs (based on using syntax).
133  // The standard struct-based meta functions cause premature evaluation in a
134  // context that is not SFINAE-compatible. We thus have to return the meta function
135  // without evaluating it, placing that burden on the caller. On the other hand,
136  // the lookup will often directly the target type, so here is some helper code
137  // to automatically do the additional evaluation if necessary.
138  // Too bad that the new syntax is GCC 4.6+...
139 
140 
142 
145  struct meta_function {};
146 
148  template<typename F>
150  {
151  typedef typename F::type type;
152  };
153 
155  template<typename F>
157  {
158  typedef F type;
159  };
160 
162  template<typename F>
164  {
165  typedef typename conditional<
166  is_base_of<meta_function,F>::value,
169  >::type::type type;
170  };
171 
172  } // end namespace TypeTree
173 } // end namespace Dune
174 
175 #endif // DUNE_TYPETREE_TYPETRAITS_HH
Definition: typetraits.hh:30
Definition: typetraits.hh:67
True if class T defines a NodeTag.
Definition: typetraits.hh:42
F type
Definition: typetraits.hh:158
Definition: typetraits.hh:33
char dummy[2]
Definition: typetraits.hh:33
Definition: typetraits.hh:70
Definition: accumulate_static.hh:12
Helper meta function to delay evaluation of F.
Definition: typetraits.hh:149
Definition: typetraits.hh:50
T * declptr()
Helper function for generating a pointer to a value of type T in an unevaluated operand setting...
T0 type
Definition: typetraits.hh:24
Definition: typetraits.hh:52
Meta function that evaluates its argument iff it inherits from meta_function.
Definition: typetraits.hh:163
static yes test(typename X::NodeTag *)
Definition: typetraits.hh:51
Marker tag declaring a meta function.
Definition: typetraits.hh:145
Definition: typetraits.hh:47
Definition: typetraits.hh:19
Definition: typetraits.hh:32
void type
Definition: typetraits.hh:106
conditional< is_base_of< meta_function, F >::value, lazy_evaluate< F >, lazy_identity< F > >::type::type type
Definition: typetraits.hh:169
Identity function.
Definition: typetraits.hh:156
char dummy[1]
Definition: typetraits.hh:32
F::type type
Definition: typetraits.hh:151
Definition: typetraits.hh:104