Dune Core Modules (2.5.0)

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
11namespace 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
STL namespace.
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.111.3 (Jul 15, 22:36, 2024)