Dune Core Modules (2.4.2)

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 #ifndef DUNE_TYPETRAITS_HH
4 #define DUNE_TYPETRAITS_HH
5 
6 #include <type_traits>
7 
9 #include <dune/common/std/utility.hh>
10 
11 namespace Dune
12 {
13 
27  struct Empty {};
28 
39  template <typename T>
40  class TypeTraits
41  {
42  private:
43  template <class U>
44  struct PointerTraits {
45  enum { result = false };
46  typedef Empty PointeeType;
47  };
48 
49  template <class U>
50  struct PointerTraits<U*> {
51  enum { result = true };
52  typedef U PointeeType;
53  };
54 
55  template <class U> struct ReferenceTraits
56  {
57  enum { result = false };
58  typedef U ReferredType;
59  };
60 
61  template <class U> struct ReferenceTraits<U&>
62  {
63  enum { result = true };
64  typedef U ReferredType;
65  };
66 
67  public:
68  enum { isPointer = PointerTraits<T>::result };
69  typedef typename PointerTraits<T>::PointeeType PointeeType DUNE_DEPRECATED_MSG("Use remove_pointer instead!");
70 
71  enum { isReference = ReferenceTraits<T>::result };
72  typedef typename ReferenceTraits<T>::ReferredType ReferredType DUNE_DEPRECATED_MSG("Use remove_reference instead!");
73  };
74 
79  template<typename T>
81  {
82  enum {
84  isVolatile=false,
86  isConst=false
87  };
88 
90  typedef T UnqualifiedType;
92  typedef const T ConstType;
94  typedef const volatile T ConstVolatileType;
95  };
96 
97  template<typename T>
98  struct ConstantVolatileTraits<const T>
99  {
100  enum {
101  isVolatile=false, isConst=true
102  };
103  typedef T UnqualifiedType;
104  typedef const UnqualifiedType ConstType;
105  typedef const volatile UnqualifiedType ConstVolatileType;
106  };
107 
108 
109  template<typename T>
110  struct ConstantVolatileTraits<volatile T>
111  {
112  enum {
113  isVolatile=true, isConst=false
114  };
115  typedef T UnqualifiedType;
116  typedef const UnqualifiedType ConstType;
117  typedef const volatile UnqualifiedType ConstVolatileType;
118  };
119 
120  template<typename T>
121  struct ConstantVolatileTraits<const volatile T>
122  {
123  enum {
124  isVolatile=true, isConst=true
125  };
126  typedef T UnqualifiedType;
127  typedef const UnqualifiedType ConstType;
128  typedef const volatile UnqualifiedType ConstVolatileType;
129  };
130 
132  template<typename T>
133  struct IsVolatile
134  {
135  enum {
138  };
139  };
140 
142  template<typename T>
143  struct IsConst
144  {
145  enum {
148  };
149  };
150 
151  template<typename T, bool isVolatile>
152  struct RemoveConstHelper
153  {
154  typedef typename ConstantVolatileTraits<T>::UnqualifiedType Type;
155  };
156 
157  template<typename T>
158  struct RemoveConstHelper<T,true>
159  {
160  typedef volatile typename ConstantVolatileTraits<T>::UnqualifiedType Type;
161  };
162 
163  using std::remove_const;
164  using std::remove_reference;
165 
175  template<class From, class To>
177  {
178  typedef char Small;
179  struct Big {char dummy[2];};
180  static Small test(To);
181  static Big test(...);
182  static typename remove_reference< From >::type &makeFrom ();
183 
184  public:
185  enum {
187  exists = sizeof(test(makeFrom())) == sizeof(Small),
191  sameType = false
192  };
193  Conversion(){}
194 
195  };
196 
197  template <class From>
198  class Conversion<From, void>
199  {
200  public:
201  enum {
202  exists = false,
203  isTwoWay = false,
204  sameType = false
205  };
206  };
207 
208  template <class To>
209  class Conversion<void, To>
210  {
211  public:
212  enum {
213  exists = false,
214  isTwoWay = false,
215  sameType = false
216  };
217  };
218 
219  template<>
220  class Conversion< int, double >
221  {
222  public:
223  enum {
224  exists = true,
225  isTwoWay = false,
226  sameType = false
227  };
228  };
229 
230  template<class T>
231  class Conversion<T,T>{
232  public:
233  enum { exists=true, isTwoWay=true, sameType=true};
234  };
235 
245  template <class Base, class Derived>
246  class IsBaseOf
247  {
248  typedef typename ConstantVolatileTraits< typename remove_reference< Base >::type >::UnqualifiedType RawBase;
249  typedef typename ConstantVolatileTraits< typename remove_reference< Derived >::type >::UnqualifiedType RawDerived;
250  typedef char Small;
251  struct Big {char dummy[2];};
252  static Small test(RawBase*);
253  static Big test(...);
254  static RawDerived* &makePtr ();
255  public:
256  enum {
258  value = sizeof(test(makePtr())) == sizeof(Small)
259  };
260  IsBaseOf(){}
261 
262  };
263 
270  template<class T1, class T2>
272  {
273  enum {
279  };
280  };
281 
282  using std::enable_if;
283 
289  template<class T1, class T2, class Type>
291  : public enable_if<IsInteroperable<T1,T2>::value, Type>
292  {};
293 
294  // pull in default implementation
295  using std::is_same;
296  using std::conditional;
297  using std::integral_constant;
298  using std::true_type;
299  using std::false_type;
300 
301 
302  template<typename>
303  struct __is_pointer_helper
304  : public false_type { };
305 
306  template<typename T>
307  struct __is_pointer_helper<T*>
308  : public true_type { };
309 
311  template<typename T>
312  struct is_pointer
313  : public integral_constant<bool, (__is_pointer_helper<T>::value)>
314  { };
315 
316  // Helper class for is_lvalue_reference
317  template<typename>
318  struct __is_lvalue_reference_helper
319  : public false_type { };
320 
321  template<typename T>
322  struct __is_lvalue_reference_helper<T&>
323  : public true_type { };
324 
326  template<typename T>
328  : public integral_constant<bool, (__is_lvalue_reference_helper<T>::value)>
329  { };
330 
331  template<typename _Tp>
332  struct __remove_pointer_helper
333  { typedef _Tp type; };
334 
335  template<typename _Tp>
336  struct __remove_pointer_helper<_Tp*>
337  { typedef _Tp type; };
338 
344  template<typename _Tp>
346  : public __remove_pointer_helper<typename remove_const<_Tp>::type >
347  { };
348 
366 
382 
389  template<typename T>
390  struct AlwaysFalse {
392  static const bool value = false;
393  };
394 
402  template<typename T>
403  struct AlwaysTrue {
405  static const bool value = true;
406  };
407 
408 
409 #if defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
410 
411 #ifndef DOXYGEN
412 
413  namespace detail {
414 
415  template<typename T, typename I, typename = int>
416  struct _is_indexable
417  : public std::false_type
418  {};
419 
420  template<typename T, typename I>
421  struct _is_indexable<T,I,typename std::enable_if<(sizeof(Std::declval<T>()[Std::declval<I>()]) > 0),int>::type>
422  : public std::true_type
423  {};
424 
425  }
426 
427 #endif // DOXYGEN
428 
431 
435  template<typename T, typename I = std::size_t>
437  : public detail::_is_indexable<T,I>
438  {};
439 
440 
441 #else // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
442 
443 
444  // okay, here follows a mess of compiler bug workarounds...
445  // GCC 4.4 dies if we try to subscript a simple type like int and
446  // both GCC 4.4 and 4.5 don't like using arbitrary types as subscripts
447  // for macros.
448  // So we make sure to only ever attempt the SFINAE for operator[] for
449  // class types, and to make sure the compiler doesn't become overly eager
450  // we have to do some lazy evaluation tricks with nested templates and
451  // stuff.
452  // Let's get rid of GCC 4.4 ASAP!
453 
454 
455  namespace detail {
456 
457  // simple wrapper template to support the lazy evaluation required
458  // in _is_indexable
459  template<typename T>
460  struct _lazy
461  {
462  template<typename U>
463  struct evaluate
464  {
465  typedef T type;
466  };
467  };
468 
469  // default version, gets picked if SFINAE fails
470  template<typename T, typename = int>
471  struct _is_indexable
472  : public std::false_type
473  {};
474 
475  // version for types supporting the subscript operation
476  template<typename T>
477  struct _is_indexable<T,decltype(Std::declval<T>()[0],0)>
478  : public std::true_type
479  {};
480 
481  // helper struct for delaying the evaluation until we are sure
482  // that T is a class (i.e. until we are outside std::conditional
483  // below)
484  struct _check_for_index_operator
485  {
486 
487  template<typename T>
488  struct evaluate
489  : public _is_indexable<T>
490  {};
491 
492  };
493 
494  }
495 
496  // The rationale here is as follows:
497  // 1) If we have an array, we assume we can index into it. That isn't
498  // true if I isn't an integral type, but that's why we have the static assertion
499  // in the body - we could of course try and check whether I is integral, but I
500  // can't be arsed and want to provide a motivation to switch to a newer compiler...
501  // 2) If we have a class, we use SFINAE to check for operator[]
502  // 3) Otherwise, we assume that T does not support indexing
503  //
504  // In order to make sure that the compiler doesn't accidentally try the SFINAE evaluation
505  // on an array or a scalar, we have to resort to lazy evaluation.
506  template<typename T, typename I = std::size_t>
507  struct is_indexable
508  : public std::conditional<
509  std::is_array<T>::value,
510  detail::_lazy<std::true_type>,
511  typename std::conditional<
512  std::is_class<T>::value,
513  detail::_check_for_index_operator,
514  detail::_lazy<std::false_type>
515  >::type
516  >::type::template evaluate<T>::type
517  {
518  static_assert(std::is_same<I,std::size_t>::value,"Your compiler is broken and does not support checking for arbitrary index types");
519  };
520 
521 
522 #endif // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
523 
524 
526 }
527 #endif
Checks wether a type is convertible to another.
Definition: typetraits.hh:177
@ sameType
True if To and From are the same type.
Definition: typetraits.hh:191
@ exists
True if the conversion exists.
Definition: typetraits.hh:187
@ isTwoWay
Whether the conversion exists in both ways.
Definition: typetraits.hh:189
Checks wether a type is derived from another.
Definition: typetraits.hh:247
@ value
True if Base is a base class of Derived.
Definition: typetraits.hh:258
General type traits class to check whether type is reference or pointer type.
Definition: typetraits.hh:41
Definition of the DUNE_DEPRECATED macro for the case that config.h is not available.
#define DUNE_DEPRECATED_MSG(text)
Mark some entity as deprecated.
Definition: deprecated.hh:169
Dune namespace.
Definition: alignment.hh:10
template which always yields a false value
Definition: typetraits.hh:390
static const bool value
always a false value
Definition: typetraits.hh:392
template which always yields a true value
Definition: typetraits.hh:403
static const bool value
always a true value
Definition: typetraits.hh:405
Determines wether a type is const or volatile and provides the unqualified types.
Definition: typetraits.hh:81
const volatile T ConstVolatileType
The const volatile type.
Definition: typetraits.hh:94
T UnqualifiedType
The unqualified type.
Definition: typetraits.hh:90
@ isConst
True if T has a const qualifier.
Definition: typetraits.hh:86
@ isVolatile
True if T has a volatile specifier.
Definition: typetraits.hh:84
const T ConstType
The const type.
Definition: typetraits.hh:92
Just an empty class.
Definition: typetraits.hh:27
Enable typedef if two types are interoperable.
Definition: typetraits.hh:292
Tests wether a type is constant.
Definition: typetraits.hh:144
@ value
True if The type is constant.
Definition: typetraits.hh:147
Checks wether two types are interoperable.
Definition: typetraits.hh:272
@ value
True if either a conversion from T1 to T2 or vice versa exists.
Definition: typetraits.hh:278
Tests wether a type is volatile.
Definition: typetraits.hh:134
@ value
True if The type is volatile.
Definition: typetraits.hh:137
Definition: typetraits.hh:438
Determine whether a type is a lvalue reference type.
Definition: typetraits.hh:329
is_pointer
Definition: typetraits.hh:314
Return the type a pointer type points to.
Definition: typetraits.hh:347
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 13, 22:30, 2024)