Dune Core Modules (2.5.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 <complex>
7 #include <type_traits>
8 
10 
11 namespace Dune
12 {
13 
14  namespace detail
15  {
17 
26  template <class...>
27  struct voider
28  {
29  using type = void;
30  };
31  }
32 
34  template <class... Types>
35  using void_t = typename detail::voider<Types...>::type;
36 
50  struct Empty {};
51 
56  template<typename T>
57  struct DUNE_DEPRECATED_MSG("Use <type_traits> instead!") ConstantVolatileTraits
58  {
59  enum DUNE_DEPRECATED_MSG("Use std::is_volatile/std::is_const instead!") {
61  isVolatile=std::is_volatile<T>::value,
63  isConst=std::is_const<T>::value
64  };
65 
67  typedef DUNE_DEPRECATED_MSG("Use std::remove_const instead!") typename std::remove_cv<T>::type UnqualifiedType;
69  typedef DUNE_DEPRECATED_MSG("Use std::add_const instead!") typename std::add_const<UnqualifiedType>::type ConstType;
71  typedef DUNE_DEPRECATED_MSG("Use std::add_cv instead!") typename std::add_cv<UnqualifiedType>::type ConstVolatileType;
72  };
73 
75  template<typename T>
76  struct DUNE_DEPRECATED_MSG("Use std::is_volatile instead!") IsVolatile
77  {
78  enum DUNE_DEPRECATED_MSG("Use std::is_volatile instead!") {
80  value=std::is_volatile<T>::value
81  };
82  };
83 
85  template<typename T>
86  struct DUNE_DEPRECATED_MSG("Use std::is_const instead!") IsConst
87  {
88  enum DUNE_DEPRECATED_MSG("Use std::is_const instead!") {
90  value=std::is_const<T>::value
91  };
92  };
93 
94  template<typename T>
95  struct DUNE_DEPRECATED_MSG("Use std::remove_const instead!") remove_const
96  {
97  typedef DUNE_DEPRECATED_MSG("Use std::remove_const instead!") typename std::remove_const<T>::type type;
98  };
99 
100  template<typename T>
101  struct DUNE_DEPRECATED_MSG("Use std::remove_reference instead!") remove_reference
102  {
103  typedef DUNE_DEPRECATED_MSG("Use std::remove_reference instead!") typename std::remove_reference<T>::type type;
104  };
105 
112  template<class From, class To>
113  struct DUNE_DEPRECATED_MSG("Use std::is_convertible/std::is_same instead!") Conversion
114  {
115  enum DUNE_DEPRECATED_MSG("Use std::is_convertible/std::is_same instead!") {
117  exists = std::is_convertible<From,To>::value,
119  isTwoWay = std::is_convertible<From,To>::value && std::is_convertible<To,From>::value,
121  sameType = std::is_same<From,To>::value
122  };
123  };
124 
131  template <class Base, class Derived>
132  struct DUNE_DEPRECATED_MSG("Use std::is_base_of instead!") IsBaseOf
133  {
134  enum DUNE_DEPRECATED_MSG("Use std::is_base_of instead!") {
136  value = std::is_base_of<Base, Derived>::value
137  };
138  };
139 
146  template<class T1, class T2>
148  {
149  enum {
154  value = std::is_convertible<T1,T2>::value || std::is_convertible<T2,T1>::value
155  };
156  };
157 
158  template<bool B, class T = void>
159  struct enable_if
160  {};
161 
162  template<class T>
163  struct enable_if<true,T>
164  {
165  typedef DUNE_DEPRECATED_MSG("Use std::enable_if instead!") T type;
166  };
167 
173  template<class T1, class T2, class Type>
175  : public std::enable_if<IsInteroperable<T1,T2>::value, Type>
176  {};
177 
178  // pull in default implementation
179  template<typename T, typename U>
180  struct DUNE_DEPRECATED_MSG("Use std::is_same instead!") is_same
181  {
182  enum DUNE_DEPRECATED_MSG("Use std::is_same instead!") {
183  value = std::is_same<T,U>::value
184  };
185  };
186 
187  template<bool B, typename T, typename F>
188  struct DUNE_DEPRECATED_MSG("Use std::conditional instead!") conditional
189  {
190  typedef DUNE_DEPRECATED_MSG("Use std::conditional instead!") typename std::conditional<B,T,F>::type type;
191  };
192 
193  template<typename T, T v>
194  struct DUNE_DEPRECATED_MSG("Use std::integral_constant instead!") integral_constant
195  {
196  DUNE_DEPRECATED_MSG("Use std::integral_constant instead!")
197  static constexpr T value = v;
198  };
199 
200  struct DUNE_DEPRECATED_MSG("Use std::true_type instead!") true_type
201  {
202  enum DUNE_DEPRECATED_MSG("Use std::true_type instead!") {
203  value = true
204  };
205  };
206 
207  struct DUNE_DEPRECATED_MSG("Use std::false_type instead!") false_type
208  {
209  enum DUNE_DEPRECATED_MSG("Use std::false_type instead!") {
210  value = false
211  };
212  };
213 
214  template<typename T>
215  struct DUNE_DEPRECATED_MSG("Use std::is_pointer instead!") is_pointer
216  {
217  enum DUNE_DEPRECATED_MSG("Use std::is_pointer instead!") {
218  value = std::is_pointer<T>::value
219  };
220  };
221 
222  template<typename T>
223  struct DUNE_DEPRECATED_MSG("Use std::is_lvalue_reference instead!") is_lvalue_reference
224  {
225  enum DUNE_DEPRECATED_MSG("Use std::is_lvalue_reference instead!") {
226  value = std::is_lvalue_reference<T>::value
227  };
228  };
229 
230  template<typename T>
231  struct DUNE_DEPRECATED_MSG("Use std::remove_pointer instead!") remove_pointer
232  {
233  typedef DUNE_DEPRECATED_MSG("Use std::remove_pointer instead!") typename std::remove_pointer<T>::type type;
234  };
235 
253 
269 
276  template<typename T>
277  struct AlwaysFalse {
279  static const bool value = false;
280  };
281 
289  template<typename T>
290  struct AlwaysTrue {
292  static const bool value = true;
293  };
294 
295  template <typename T>
296  struct IsNumber
297  : public std::integral_constant<bool, std::is_arithmetic<T>::value> {
298  };
299 
300  template <typename T>
301  struct IsNumber<std::complex<T>>
302  : public std::integral_constant<bool, IsNumber<T>::value> {
303  };
304 
305  template <typename T>
306  struct has_nan
307  : public std::integral_constant<bool, std::is_floating_point<T>::value> {
308  };
309 
310  template <typename T>
311  struct has_nan<std::complex<T>>
312  : public std::integral_constant<bool, std::is_floating_point<T>::value> {
313  };
314 
315 #if defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
316 
317 #ifndef DOXYGEN
318 
319  namespace detail {
320 
321  template<typename T, typename I, typename = int>
322  struct _is_indexable
323  : public std::false_type
324  {};
325 
326  template<typename T, typename I>
327  struct _is_indexable<T,I,typename std::enable_if<(sizeof(std::declval<T>()[std::declval<I>()]) > 0),int>::type>
328  : public std::true_type
329  {};
330 
331  }
332 
333 #endif // DOXYGEN
334 
337 
341  template<typename T, typename I = std::size_t>
343  : public detail::_is_indexable<T,I>
344  {};
345 
346 
347 #else // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
348 
349 
350  // okay, here follows a mess of compiler bug workarounds...
351  // GCC 4.4 dies if we try to subscript a simple type like int and
352  // both GCC 4.4 and 4.5 don't like using arbitrary types as subscripts
353  // for macros.
354  // So we make sure to only ever attempt the SFINAE for operator[] for
355  // class types, and to make sure the compiler doesn't become overly eager
356  // we have to do some lazy evaluation tricks with nested templates and
357  // stuff.
358  // Let's get rid of GCC 4.4 ASAP!
359 
360 
361  namespace detail {
362 
363  // simple wrapper template to support the lazy evaluation required
364  // in _is_indexable
365  template<typename T>
366  struct _lazy
367  {
368  template<typename U>
369  struct evaluate
370  {
371  typedef T type;
372  };
373  };
374 
375  // default version, gets picked if SFINAE fails
376  template<typename T, typename = int>
377  struct _is_indexable
378  : public std::false_type
379  {};
380 
381  // version for types supporting the subscript operation
382  template<typename T>
383  struct _is_indexable<T,decltype(std::declval<T>()[0],0)>
384  : public std::true_type
385  {};
386 
387  // helper struct for delaying the evaluation until we are sure
388  // that T is a class (i.e. until we are outside std::conditional
389  // below)
390  struct _check_for_index_operator
391  {
392 
393  template<typename T>
394  struct evaluate
395  : public _is_indexable<T>
396  {};
397 
398  };
399 
400  }
401 
402  // The rationale here is as follows:
403  // 1) If we have an array, we assume we can index into it. That isn't
404  // true if I isn't an integral type, but that's why we have the static assertion
405  // in the body - we could of course try and check whether I is integral, but I
406  // can't be arsed and want to provide a motivation to switch to a newer compiler...
407  // 2) If we have a class, we use SFINAE to check for operator[]
408  // 3) Otherwise, we assume that T does not support indexing
409  //
410  // In order to make sure that the compiler doesn't accidentally try the SFINAE evaluation
411  // on an array or a scalar, we have to resort to lazy evaluation.
412  template<typename T, typename I = std::size_t>
413  struct is_indexable
414  : public std::conditional<
415  std::is_array<T>::value,
416  detail::_lazy<std::true_type>,
417  typename std::conditional<
418  std::is_class<T>::value,
419  detail::_check_for_index_operator,
420  detail::_lazy<std::false_type>
421  >::type
422  >::type::template evaluate<T>::type
423  {
424  static_assert(std::is_same<I,std::size_t>::value,"Your compiler is broken and does not support checking for arbitrary index types");
425  };
426 
427 
428 #endif // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
429 
430  namespace Impl {
431  // This function does nothing.
432  // By passing expressions to this function one can avoid
433  // "value computed is not used" warnings that may show up
434  // in a comma expression.
435  template<class...T>
436  void ignore(T&&... t)
437  {}
438  }
439 
443  // default version, gets picked if SFINAE fails
444  template<typename T, typename = void>
445  struct is_range
446  : public std::false_type
447  {};
448 
449 #ifndef DOXYGEN
450  // version for types with begin() and end()
451  template<typename T>
452  struct is_range<T, decltype(Impl::ignore(
453  std::declval<T>().begin(),
454  std::declval<T>().end(),
455  std::declval<T>().begin() != std::declval<T>().end(),
456  decltype(std::declval<T>().begin()){std::declval<T>().end()},
457  ++(std::declval<std::add_lvalue_reference_t<decltype(std::declval<T>().begin())>>()),
458  *(std::declval<T>().begin())
459  ))>
460  : public std::true_type
461  {};
462 #endif
463 
464  template <class> struct FieldTraits;
465 
467  template <class Type>
468  using field_t = typename FieldTraits<Type>::field_type;
469 
471  template <class Type>
472  using real_t = typename FieldTraits<Type>::real_type;
473 
474 
475 
476  // Implementation of IsTuple
477  namespace Imp {
478 
479  template<class T>
480  struct IsTuple : public std::false_type
481  {};
482 
483  template<class... T>
484  struct IsTuple<std::tuple<T...>> : public std::true_type
485  {};
486 
487  } // namespace Imp
488 
494  template<class T>
495  struct IsTuple :
496  public Imp::IsTuple<T>
497  {};
498 
499 
500 
501  // Implementation of IsTupleOrDerived
502  namespace Imp {
503 
504  template<class... T, class Dummy>
505  std::true_type isTupleOrDerived(const std::tuple<T...>*, Dummy)
506  { return {}; }
507 
508  template<class Dummy>
509  std::false_type isTupleOrDerived(const void*, Dummy)
510  { return {}; }
511 
512  } // namespace Imp
513 
519  template<class T>
521  public decltype(Imp::isTupleOrDerived(std::declval<T*>(), true))
522  {};
523 
524 
525 
526  // Implementation of is IsIntegralConstant
527  namespace Imp {
528 
529  template<class T>
530  struct IsIntegralConstant : public std::false_type
531  {};
532 
533  template<class T, T t>
534  struct IsIntegralConstant<std::integral_constant<T, t>> : public std::true_type
535  {};
536 
537  } // namespace Imp
538 
544  template<class T>
545  struct IsIntegralConstant : public Imp::IsIntegralConstant<std::decay_t<T>>
546  {};
547 
548 
549 
563  template<typename... T>
564  struct SizeOf
565  : public std::integral_constant<std::size_t,sizeof...(T)>
566  {};
567 
568 
569 
571 }
572 #endif
Definition of the DUNE_DEPRECATED macro for the case that config.h is not available.
typename FieldTraits< Type >::real_type real_t
Convenient access to FieldTraits<Type>::real_type.
Definition: typetraits.hh:472
typename FieldTraits< Type >::field_type field_t
Convenient access to FieldTraits<Type>::field_type.
Definition: typetraits.hh:468
struct DUNE_DEPRECATED_MSG("Use <type_traits> instead!") ConstantVolatileTraits
Determines whether a type is const or volatile and provides the unqualified types.
Definition: typetraits.hh:57
Dune namespace.
Definition: alignment.hh:11
typename detail::voider< Types... >::type void_t
Is void for all valid input types (see N3911). The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:35
template which always yields a false value
Definition: typetraits.hh:277
template which always yields a true value
Definition: typetraits.hh:290
Just an empty class.
Definition: typetraits.hh:50
Enable typedef if two types are interoperable.
Definition: typetraits.hh:176
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:546
Checks whether two types are interoperable.
Definition: typetraits.hh:148
Check if T derived from a std::tuple<...>
Definition: typetraits.hh:522
Check if T is a std::tuple<...>
Definition: typetraits.hh:497
Compute size of variadic type list.
Definition: typetraits.hh:566
Helper to make void_t work with gcc versions prior to gcc 5.0.
Definition: typetraits.hh:28
Definition: typetraits.hh:344
Definition: typetraits.hh:447
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 9, 22:29, 2024)