Dune Core Modules (2.7.1)

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 #include <utility>
9 #include <vector>
10 
12 
13 namespace Dune
14 {
15 
16  namespace Impl
17  {
19 
28  template <class...>
29  struct voider
30  {
31  using type = void;
32  };
33  }
34 
36 
39  template <class... Types>
40  using void_t = typename Impl::voider<Types...>::type;
41 
55  struct Empty {};
56 
63  template<class T1, class T2>
65  {
66  enum {
71  value = std::is_convertible<T1,T2>::value || std::is_convertible<T2,T1>::value
72  };
73  };
74 
80  template<class T1, class T2, class Type>
82  : public std::enable_if<IsInteroperable<T1,T2>::value, Type>
83  {};
84 
102 
118 
125  template<typename T>
126  struct AlwaysFalse {
128  static const bool value = false;
129  };
130 
138  template<typename T>
139  struct AlwaysTrue {
141  static const bool value = true;
142  };
143 
146 
161  template <typename T>
162  struct IsNumber
163  : public std::integral_constant<bool, std::is_arithmetic<T>::value> {
164  };
165 
166 #ifndef DOXYGEN
167 
168  template <typename T>
169  struct IsNumber<std::complex<T>>
170  : public std::integral_constant<bool, IsNumber<T>::value> {
171  };
172 
173 #endif // DOXYGEN
174 
176 
179  template <typename T>
180  struct HasNaN
181  : public std::integral_constant<bool, std::is_floating_point<T>::value> {
182  };
183 
184 #ifndef DOXYGEN
185 
186  template <typename T>
187  struct HasNaN<std::complex<T>>
188  : public std::integral_constant<bool, std::is_floating_point<T>::value> {
189  };
190 
191 #endif // DOXYGEN
192 
195 
198  template <typename T>
199  struct DUNE_DEPRECATED_MSG("Has been renamed to 'HasNaN'.") has_nan
200  : HasNaN<T> {};
201 
202 #if defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
203 
204 #ifndef DOXYGEN
205 
206  namespace Impl {
207 
208  template<typename T, typename I, typename = int>
209  struct IsIndexable
210  : public std::false_type
211  {};
212 
213  template<typename T, typename I>
214  struct IsIndexable<T,I,typename std::enable_if<(sizeof(std::declval<T>()[std::declval<I>()]) > 0),int>::type>
215  : public std::true_type
216  {};
217 
218  }
219 
220 #endif // DOXYGEN
221 
223 
227  template<typename T, typename I = std::size_t>
228  struct IsIndexable
229  : public Impl::IsIndexable<T,I>
230  {};
231 
232 #else // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
233 
234 
235  // okay, here follows a mess of compiler bug workarounds...
236  // GCC 4.4 dies if we try to subscript a simple type like int and
237  // both GCC 4.4 and 4.5 don't like using arbitrary types as subscripts
238  // for macros.
239  // So we make sure to only ever attempt the SFINAE for operator[] for
240  // class types, and to make sure the compiler doesn't become overly eager
241  // we have to do some lazy evaluation tricks with nested templates and
242  // stuff.
243  // Let's get rid of GCC 4.4 ASAP!
244 
245 
246  namespace Impl {
247 
248  // simple wrapper template to support the lazy evaluation required
249  // in _is_indexable
250  template<typename T>
251  struct _lazy
252  {
253  template<typename U>
254  struct evaluate
255  {
256  typedef T type;
257  };
258  };
259 
260  // default version, gets picked if SFINAE fails
261  template<typename T, typename = int>
262  struct IsIndexable
263  : public std::false_type
264  {};
265 
266  // version for types supporting the subscript operation
267  template<typename T>
268  struct IsIndexable<T,decltype(std::declval<T>()[0],0)>
269  : public std::true_type
270  {};
271 
272  // helper struct for delaying the evaluation until we are sure
273  // that T is a class (i.e. until we are outside std::conditional
274  // below)
275  struct _check_for_index_operator
276  {
277 
278  template<typename T>
279  struct evaluate
280  : public IsIndexable<T>
281  {};
282 
283  };
284 
285  }
286 
287  // The rationale here is as follows:
288  // 1) If we have an array, we assume we can index into it. That isn't
289  // true if I isn't an integral type, but that's why we have the static assertion
290  // in the body - we could of course try and check whether I is integral, but I
291  // can't be arsed and want to provide a motivation to switch to a newer compiler...
292  // 2) If we have a class, we use SFINAE to check for operator[]
293  // 3) Otherwise, we assume that T does not support indexing
294  //
295  // In order to make sure that the compiler doesn't accidentally try the SFINAE evaluation
296  // on an array or a scalar, we have to resort to lazy evaluation.
297  template<typename T, typename I = std::size_t>
298  struct IsIndexable
299  : public std::conditional<
300  std::is_array<T>::value,
301  Impl::_lazy<std::true_type>,
302  typename std::conditional<
303  std::is_class<T>::value,
304  Impl::_check_for_index_operator,
305  Impl::_lazy<std::false_type>
306  >::type
307  >::type::template evaluate<T>::type
308  {
309  static_assert(std::is_same<I,std::size_t>::value,"Your compiler is broken and does not support checking for arbitrary index types");
310  };
311 
312 
313 #endif // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
314 
317 
321  template<typename T, typename I = std::size_t>
322  struct DUNE_DEPRECATED_MSG("Has been renamed to 'IsIndexable'.") is_indexable
323  : public IsIndexable<T,I> {};
324 
325 #ifndef DOXYGEN
326 
327  namespace Impl {
328  // This function does nothing.
329  // By passing expressions to this function one can avoid
330  // "value computed is not used" warnings that may show up
331  // in a comma expression.
332  template<class...T>
333  void ignore(T&&... /*t*/)
334  {}
335  }
336 
337 #endif // DOXYGEN
338 
342  // default version, gets picked if SFINAE fails
343  template<typename T, typename = void>
344  struct IsIterable
345  : public std::false_type
346  {};
347 
348 #ifndef DOXYGEN
349  // version for types with begin() and end()
350  template<typename T>
351  struct IsIterable<T, decltype(Impl::ignore(
352  std::declval<T>().begin(),
353  std::declval<T>().end(),
354  std::declval<T>().begin() != std::declval<T>().end(),
355  decltype(std::declval<T>().begin()){std::declval<T>().end()},
356  ++(std::declval<std::add_lvalue_reference_t<decltype(std::declval<T>().begin())>>()),
357  *(std::declval<T>().begin())
358  ))>
359  : public std::true_type
360  {};
361 #endif
362 
367  template<typename T, typename = void>
368  struct DUNE_DEPRECATED_MSG("Has been renamed to 'IsIterable'.") is_range
369  : public IsIterable<T> {};
370 
371 #ifndef DOXYGEN
372  // this is just a forward declaration
373  template <class> struct FieldTraits;
374 #endif
375 
377  template <class Type>
378  using field_t = typename FieldTraits<Type>::field_type;
379 
381  template <class Type>
382  using real_t = typename FieldTraits<Type>::real_type;
383 
384 
385 #ifndef DOXYGEN
386 
387  // Implementation of IsTuple
388  namespace Impl {
389 
390  template<class T>
391  struct IsTuple : public std::false_type
392  {};
393 
394  template<class... T>
395  struct IsTuple<std::tuple<T...>> : public std::true_type
396  {};
397 
398  } // namespace Impl
399 
400 #endif // DOXYGEN
401 
407  template<class T>
408  struct IsTuple :
409  public Impl::IsTuple<T>
410  {};
411 
412 
413 #ifndef DOXYGEN
414 
415  // Implementation of IsTupleOrDerived
416  namespace Impl {
417 
418  template<class... T, class Dummy>
419  std::true_type isTupleOrDerived(const std::tuple<T...>*, Dummy)
420  { return {}; }
421 
422  template<class Dummy>
423  std::false_type isTupleOrDerived(const void*, Dummy)
424  { return {}; }
425 
426  } // namespace Impl
427 
428 #endif // DOXYGEN
429 
435  template<class T>
437  public decltype(Impl::isTupleOrDerived(std::declval<T*>(), true))
438  {};
439 
440 
441 #ifndef DOXYGEN
442 
443  // Implementation of is IsIntegralConstant
444  namespace Impl {
445 
446  template<class T>
447  struct IsIntegralConstant : public std::false_type
448  {};
449 
450  template<class T, T t>
451  struct IsIntegralConstant<std::integral_constant<T, t>> : public std::true_type
452  {};
453 
454  } // namespace Impl
455 
456 #endif // DOXYGEN
457 
463  template<class T>
464  struct IsIntegralConstant : public Impl::IsIntegralConstant<std::decay_t<T>>
465  {};
466 
467 
468 
482  template<typename... T>
483  struct SizeOf
484  : public std::integral_constant<std::size_t,sizeof...(T)>
485  {};
486 
487 
488 #ifndef DOXYGEN
489 
490  namespace Impl {
491 
492  template<class T, T...>
493  struct IntegerSequenceHelper;
494 
495  // Helper struct to compute the i-th entry of a std::integer_sequence
496  //
497  // This could also be implemented using std::get<index>(std::make_tuple(t...)).
498  // However, the gcc-6 implementation of std::make_tuple increases the instantiation
499  // depth by 15 levels for each argument, such that the maximal instantiation depth
500  // is easily hit, especially with clang where it is set to 256.
501  template<class T, T head, T... tail>
502  struct IntegerSequenceHelper<T, head, tail...>
503  {
504 
505  // get first entry
506  static constexpr auto get(std::integral_constant<std::size_t, 0>)
507  {
508  return std::integral_constant<T, head>();
509  }
510 
511  // call get with first entry cut off and decremented index
512  template<std::size_t index,
513  std::enable_if_t<(index > 0) and (index < sizeof...(tail)+1), int> = 0>
514  static constexpr auto get(std::integral_constant<std::size_t, index>)
515  {
516  return IntegerSequenceHelper<T, tail...>::get(std::integral_constant<std::size_t, index-1>());
517  }
518 
519  // use static assertion if index exceeds size
520  template<std::size_t index,
521  std::enable_if_t<(index >= sizeof...(tail)+1), int> = 0>
522  static constexpr auto get(std::integral_constant<std::size_t, index>)
523  {
524  static_assert(index < sizeof...(tail)+1, "index used in IntegerSequenceEntry exceed size");
525  }
526  };
527 
528  } // end namespace Impl
529 
530 #endif // DOXYGEN
531 
532 
542  template<class T, T... t, std::size_t index>
543  constexpr auto integerSequenceEntry(std::integer_sequence<T, t...> /*seq*/, std::integral_constant<std::size_t, index> i)
544  {
545  static_assert(index < sizeof...(t), "index used in IntegerSequenceEntry exceed size");
546  return Impl::IntegerSequenceHelper<T, t...>::get(i);
547  }
548 
549 
556  template<class IntegerSequence, std::size_t index>
558 
559 #ifndef DOXYGEN
560 
561  template<class T, T... t, std::size_t i>
562  struct IntegerSequenceEntry<std::integer_sequence<T, t...>, i>
563  : public decltype(Impl::IntegerSequenceHelper<T, t...>::get(std::integral_constant<std::size_t, i>()))
564  {};
565 
566 #endif // DOXYGEN
567 
581  template<class T>
582  struct AutonomousValueType { using type = T; };
583 
585  template<class T>
587 
589  template<class T>
591 
593  template<class T>
594  struct AutonomousValueType<const T> : AutonomousValueType<T> {};
595 
597  template<class T>
598  struct AutonomousValueType<volatile T> : AutonomousValueType<T> {};
599 
601  template<>
602  struct AutonomousValueType<std::vector<bool>::reference>
603  {
604  using type = bool;
605  };
606 
608  template<class T>
609  struct AutonomousValueType<volatile const T> : AutonomousValueType<T> {};
610 
638  template<class T>
639  using AutonomousValue = typename AutonomousValueType<T>::type;
640 
722  template<class T>
723  constexpr AutonomousValue<T> autoCopy(T &&v)
724  {
725  return v;
726  }
727 
729 }
730 #endif
Definition of the DUNE_DEPRECATED macro for the case that config.h is not available.
constexpr auto integerSequenceEntry(std::integer_sequence< T, t... >, std::integral_constant< std::size_t, index > i)
Get entry of std::integer_sequence.
Definition: typetraits.hh:543
typename FieldTraits< Type >::real_type real_t
Convenient access to FieldTraits<Type>::real_type.
Definition: typetraits.hh:382
typename AutonomousValueType< T >::type AutonomousValue
Type free of internal references that T can be converted to.
Definition: typetraits.hh:639
typename Impl::voider< Types... >::type void_t
Is void for all valid input types (see N3911). The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:40
#define DUNE_DEPRECATED_MSG(text)
Mark some entity as deprecated.
Definition: deprecated.hh:169
typename FieldTraits< Type >::field_type field_t
Convenient access to FieldTraits<Type>::field_type.
Definition: typetraits.hh:378
constexpr AutonomousValue< T > autoCopy(T &&v)
Autonomous copy of an expression's value for use in auto type deduction.
Definition: typetraits.hh:723
Dune namespace.
Definition: alignedallocator.hh:14
template which always yields a false value
Definition: typetraits.hh:126
static const bool value
always a false value
Definition: typetraits.hh:128
template which always yields a true value
Definition: typetraits.hh:139
static const bool value
always a true value
Definition: typetraits.hh:141
Type free of internal references that T can be converted to.
Definition: typetraits.hh:582
Just an empty class.
Definition: typetraits.hh:55
Enable typedef if two types are interoperable.
Definition: typetraits.hh:83
Whether this type has a value of NaN.
Definition: typetraits.hh:181
Get entry of std::integer_sequence.
Definition: typetraits.hh:557
Type trait to determine whether an instance of T has an operator[](I), i.e. whether it can be indexed...
Definition: typetraits.hh:230
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:465
Checks whether two types are interoperable.
Definition: typetraits.hh:65
@ value
True if either a conversion from T1 to T2 or vice versa exists.
Definition: typetraits.hh:71
typetrait to check that a class has begin() and end() members
Definition: typetraits.hh:346
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition: typetraits.hh:163
Check if T derived from a std::tuple<...>
Definition: typetraits.hh:438
Check if T is a std::tuple<...>
Definition: typetraits.hh:410
Compute size of variadic type list.
Definition: typetraits.hh:485
Whether this type has a value of NaN.
Definition: typetraits.hh:200
Definition: typetraits.hh:323
typetrait to check that a class has begin() and end() members
Definition: typetraits.hh:369
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 8, 22:30, 2024)