dune-common  2.2.1
typetraits.hh
Go to the documentation of this file.
1 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=8 sw=2 sts=2:
3 #ifndef DUNE_TYPETRAITS_HH
4 #define DUNE_TYPETRAITS_HH
5 
6 #if defined HAVE_TYPE_TRAITS
7 #include <type_traits>
8 #elif defined HAVE_TR1_TYPE_TRAITS
9 #include <tr1/type_traits>
10 #endif
11 
12 namespace Dune
13 {
14 
28  struct Empty {};
29 
34  template <typename T>
35  class TypeTraits
36  {
37  private:
38  template <class U>
39  struct PointerTraits {
40  enum { result = false };
41  typedef Empty PointeeType;
42  };
43 
44  template <class U>
45  struct PointerTraits<U*> {
46  enum { result = true };
47  typedef U PointeeType;
48  };
49 
50  template <class U> struct ReferenceTraits
51  {
52  enum { result = false };
53  typedef U ReferredType;
54  };
55 
56  template <class U> struct ReferenceTraits<U&>
57  {
58  enum { result = true };
59  typedef U ReferredType;
60  };
61 
62  public:
63  enum { isPointer = PointerTraits<T>::result };
65 
66  enum { isReference = ReferenceTraits<T>::result };
67  typedef typename ReferenceTraits<T>::ReferredType ReferredType;
68  };
69 
74  template<typename T>
76  {
77  enum{
79  isVolatile=false,
81  isConst=false
82  };
83 
85  typedef T UnqualifiedType;
87  typedef const T ConstType;
89  typedef const volatile T ConstVolatileType;
90  };
91 
92  template<typename T>
93  struct ConstantVolatileTraits<const T>
94  {
95  enum{
96  isVolatile=false, isConst=true
97  };
98  typedef T UnqualifiedType;
99  typedef const UnqualifiedType ConstType;
100  typedef const volatile UnqualifiedType ConstVolatileType;
101  };
102 
103 
104  template<typename T>
105  struct ConstantVolatileTraits<volatile T>
106  {
107  enum{
108  isVolatile=true, isConst=false
109  };
110  typedef T UnqualifiedType;
111  typedef const UnqualifiedType ConstType;
112  typedef const volatile UnqualifiedType ConstVolatileType;
113  };
114 
115  template<typename T>
116  struct ConstantVolatileTraits<const volatile T>
117  {
118  enum{
119  isVolatile=true, isConst=true
120  };
121  typedef T UnqualifiedType;
122  typedef const UnqualifiedType ConstType;
123  typedef const volatile UnqualifiedType ConstVolatileType;
124  };
125 
127  template<typename T>
128  struct IsVolatile
129  {
130  enum{
133  };
134  };
135 
137  template<typename T>
138  struct IsConst
139  {
140  enum{
143  };
144  };
145 
146  template<typename T, bool isVolatile>
148  {
150  };
151 
152  template<typename T>
153  struct RemoveConstHelper<T,true>
154  {
156  };
157 
158 #if defined HAVE_TYPE_TRAITS
159  using std::remove_const;
160 #elif defined HAVE_TR1_TYPE_TRAITS
161  using std::tr1::remove_const;
162 #else
163 
166  template<typename T>
168  {
170  };
171 #endif
172 
173 #if defined HAVE_TYPE_TRAITS
174  using std::remove_reference;
175 #elif defined HAVE_TR1_TYPE_TRAITS
176  using std::tr1::remove_reference;
177 #else
178 
179 
183  template<typename T> struct remove_reference {
185  typedef T type;
186  };
187 # ifndef DOXYGEN
188  template<typename T> struct remove_reference<T&> {
189  typedef T type;
190  };
191 # endif // ! defined(DOXYGEN)
192 #endif
193 
203  template<class From, class To>
205  {
206  typedef char Small;
207  struct Big{char dummy[2];};
208  static Small test(To);
209  static Big test(...);
210  static typename TypeTraits< From >::ReferredType &makeFrom ();
211 
212  public:
213  enum {
215  exists = sizeof(test(makeFrom())) == sizeof(Small),
219  sameType = false
220  };
222 
223  };
224 
225  template <class From>
226  class Conversion<From, void>
227  {
228  public:
229  enum {
230  exists = false,
231  isTwoWay = false,
232  sameType = false
233  };
234  };
235 
236  template <class To>
237  class Conversion<void, To>
238  {
239  public:
240  enum {
241  exists = false,
242  isTwoWay = false,
243  sameType = false
244  };
245  };
246 
247  template<>
248  class Conversion< int, double >
249  {
250  public:
251  enum {
252  exists = true,
253  isTwoWay = false,
254  sameType = false
255  };
256  };
257 
258  template<class T>
259  class Conversion<T,T>{
260  public:
261  enum{ exists=true, isTwoWay=true, sameType=true};
262  };
263 
273  template <class Base, class Derived>
274  class IsBaseOf
275  {
276  typedef typename ConstantVolatileTraits< typename TypeTraits< Base >::ReferredType >::UnqualifiedType RawBase;
277  typedef typename ConstantVolatileTraits< typename TypeTraits< Derived >::ReferredType >::UnqualifiedType RawDerived;
278  typedef char Small;
279  struct Big{char dummy[2];};
280  static Small test(RawBase*);
281  static Big test(...);
282  static RawDerived* &makePtr ();
283  public:
284  enum {
286  value = sizeof(test(makePtr())) == sizeof(Small)
287  };
289 
290  };
291 
298  template<class T1, class T2>
300  {
301  enum{
307  };
308  };
309 
310 #ifdef HAVE_TYPE_TRAITS
311  using std::enable_if;
312 #else
313 
319  template<bool b, typename T=void>
320  struct enable_if
321  {
322  typedef T type;
323  };
324 
325  template<typename T>
326  struct enable_if<false,T>
327  {};
328 #endif
329 
330 
336  template<class T1, class T2, class Type>
338  : public enable_if<IsInteroperable<T1,T2>::value, Type>
339  {};
340 
341 #if defined HAVE_TYPE_TRAITS
342  using std::is_same;
343 #elif defined HAVE_TR1_TYPE_TRAITS
344  using std::tr1::is_same;
345 #else
346 
350  template<typename T1, typename T2>
351  struct is_same
352  {
354  enum{
355  /* @brief Whether T1 is the same type as T2. */
356  value=false
357  };
358  };
359 
360 
361  template<typename T>
362  struct is_same<T,T>
363  {
364  enum{ value=true};
365  };
366 #endif
367 
376  template<bool first, class T1, class T2>
377  struct SelectType
378  {
385  typedef T1 Type;
386  };
387 
388  template<class T1, class T2>
389  struct SelectType<false,T1,T2>
390  {
391  typedef T2 Type;
392  };
393 
395  //
396  // integral_constant (C++0x 20.7.3 "Helper classes")
397  //
398 #if defined HAVE_TYPE_TRAITS
399  using std::integral_constant;
400  using std::true_type;
401  using std::false_type;
402 #elif defined HAVE_TR1_TYPE_TRAITS
403  using std::tr1::integral_constant;
404  using std::tr1::true_type;
405  using std::tr1::false_type;
406 #else
407 
408 
412  template <class T, T v>
415  static const T value = v;
417  typedef T value_type;
421  operator value_type() { return value; }
422  };
423 
428 #endif
429 
431 }
432 #endif