dune-common 3.0-git
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
11
12namespace Dune
13{
14
28 struct Empty {};
29
34 template<typename T>
35 struct DUNE_DEPRECATED_MSG("Use <type_traits> instead!") ConstantVolatileTraits
36 {
37 enum DUNE_DEPRECATED_MSG("Use std::is_volatile/std::is_const instead!") {
39 isVolatile=std::is_volatile<T>::value,
41 isConst=std::is_const<T>::value
42 };
43
45 typedef DUNE_DEPRECATED_MSG("Use std::remove_const instead!") typename std::remove_cv<T>::type UnqualifiedType;
47 typedef DUNE_DEPRECATED_MSG("Use std::add_const instead!") typename std::add_const<UnqualifiedType>::type ConstType;
49 typedef DUNE_DEPRECATED_MSG("Use std::add_cv instead!") typename std::add_cv<UnqualifiedType>::type ConstVolatileType;
50 };
51
53 template<typename T>
54 struct DUNE_DEPRECATED_MSG("Use std::is_volatile instead!") IsVolatile
55 {
56 enum DUNE_DEPRECATED_MSG("Use std::is_volatile instead!") {
58 value=std::is_volatile<T>::value
59 };
60 };
61
63 template<typename T>
64 struct DUNE_DEPRECATED_MSG("Use std::is_const instead!") IsConst
65 {
66 enum DUNE_DEPRECATED_MSG("Use std::is_const instead!") {
68 value=std::is_const<T>::value
69 };
70 };
71
72 template<typename T>
73 struct DUNE_DEPRECATED_MSG("Use std::remove_const instead!") remove_const
74 {
75 typedef DUNE_DEPRECATED_MSG("Use std::remove_const instead!") typename std::remove_const<T>::type type;
76 };
77
78 template<typename T>
80 {
81 typedef DUNE_DEPRECATED_MSG("Use std::remove_reference instead!") typename std::remove_reference<T>::type type;
82 };
83
90 template<class From, class To>
91 struct DUNE_DEPRECATED_MSG("Use std::is_convertible/std::is_same instead!") Conversion
92 {
93 enum DUNE_DEPRECATED_MSG("Use std::is_convertible/std::is_same instead!") {
95 exists = std::is_convertible<From,To>::value,
97 isTwoWay = std::is_convertible<From,To>::value && std::is_convertible<To,From>::value,
99 sameType = std::is_same<From,To>::value
100 };
101 };
102
109 template <class Base, class Derived>
110 struct DUNE_DEPRECATED_MSG("Use std::is_base_of instead!") IsBaseOf
111 {
112 enum DUNE_DEPRECATED_MSG("Use std::is_base_of instead!") {
114 value = std::is_base_of<Base, Derived>::value
115 };
116 };
117
124 template<class T1, class T2>
126 {
127 enum {
132 value = std::is_convertible<T1,T2>::value || std::is_convertible<T2,T1>::value
133 };
134 };
135
136 template<bool B, class T = void>
138 {};
139
140 template<class T>
141 struct enable_if<true,T>
142 {
143 typedef DUNE_DEPRECATED_MSG("Use std::enable_if instead!") T type;
144 };
145
151 template<class T1, class T2, class Type>
153 : public std::enable_if<IsInteroperable<T1,T2>::value, Type>
154 {};
155
156 // pull in default implementation
157 template<typename T, typename U>
158 struct DUNE_DEPRECATED_MSG("Use std::is_same instead!") is_same
159 {
160 enum DUNE_DEPRECATED_MSG("Use std::is_same instead!") {
161 value = std::is_same<T,U>::value
162 };
163 };
164
165 template<bool B, typename T, typename F>
166 struct DUNE_DEPRECATED_MSG("Use std::conditional instead!") conditional
167 {
168 typedef DUNE_DEPRECATED_MSG("Use std::conditional instead!") typename std::conditional<B,T,F>::type type;
169 };
170
171 template<typename T, T v>
173 {
174 DUNE_DEPRECATED_MSG("Use std::integral_constant instead!")
175 static constexpr T value = v;
176 };
177
179 {
180 enum DUNE_DEPRECATED_MSG("Use std::true_type instead!") {
181 value = true
182 };
183 };
184
185 struct DUNE_DEPRECATED_MSG("Use std::false_type instead!") false_type
186 {
187 enum DUNE_DEPRECATED_MSG("Use std::false_type instead!") {
188 value = false
189 };
190 };
191
192 template<typename T>
193 struct DUNE_DEPRECATED_MSG("Use std::is_pointer instead!") is_pointer
194 {
195 enum DUNE_DEPRECATED_MSG("Use std::is_pointer instead!") {
196 value = std::is_pointer<T>::value
197 };
198 };
199
200 template<typename T>
201 struct DUNE_DEPRECATED_MSG("Use std::is_lvalue_reference instead!") is_lvalue_reference
202 {
203 enum DUNE_DEPRECATED_MSG("Use std::is_lvalue_reference instead!") {
204 value = std::is_lvalue_reference<T>::value
205 };
206 };
207
208 template<typename T>
209 struct DUNE_DEPRECATED_MSG("Use std::remove_pointer instead!") remove_pointer
210 {
211 typedef DUNE_DEPRECATED_MSG("Use std::remove_pointer instead!") typename std::remove_pointer<T>::type type;
212 };
213
231
247
254 template<typename T>
255 struct AlwaysFalse {
257 static const bool value = false;
258 };
259
267 template<typename T>
268 struct AlwaysTrue {
270 static const bool value = true;
271 };
272
273 template <typename T>
274 struct IsNumber
275 : public std::integral_constant<bool, std::is_arithmetic<T>::value> {
276 };
277
278 template <typename T>
279 struct IsNumber<std::complex<T>>
280 : public std::integral_constant<bool, IsNumber<T>::value> {
281 };
282
283 template <typename T>
284 struct has_nan
285 : public std::integral_constant<bool, std::is_floating_point<T>::value> {
286 };
287
288 template <typename T>
289 struct has_nan<std::complex<T>>
290 : public std::integral_constant<bool, std::is_floating_point<T>::value> {
291 };
292
293#if defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
294
295#ifndef DOXYGEN
296
297 namespace detail {
298
299 template<typename T, typename I, typename = int>
300 struct _is_indexable
301 : public std::false_type
302 {};
303
304 template<typename T, typename I>
305 struct _is_indexable<T,I,typename std::enable_if<(sizeof(std::declval<T>()[std::declval<I>()]) > 0),int>::type>
306 : public std::true_type
307 {};
308
309 }
310
311#endif // DOXYGEN
312
315
319 template<typename T, typename I = std::size_t>
321 : public detail::_is_indexable<T,I>
322 {};
323
324
325#else // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
326
327
328 // okay, here follows a mess of compiler bug workarounds...
329 // GCC 4.4 dies if we try to subscript a simple type like int and
330 // both GCC 4.4 and 4.5 don't like using arbitrary types as subscripts
331 // for macros.
332 // So we make sure to only ever attempt the SFINAE for operator[] for
333 // class types, and to make sure the compiler doesn't become overly eager
334 // we have to do some lazy evaluation tricks with nested templates and
335 // stuff.
336 // Let's get rid of GCC 4.4 ASAP!
337
338
339 namespace detail {
340
341 // simple wrapper template to support the lazy evaluation required
342 // in _is_indexable
343 template<typename T>
344 struct _lazy
345 {
346 template<typename U>
347 struct evaluate
348 {
349 typedef T type;
350 };
351 };
352
353 // default version, gets picked if SFINAE fails
354 template<typename T, typename = int>
355 struct _is_indexable
356 : public std::false_type
357 {};
358
359 // version for types supporting the subscript operation
360 template<typename T>
361 struct _is_indexable<T,decltype(std::declval<T>()[0],0)>
362 : public std::true_type
363 {};
364
365 // helper struct for delaying the evaluation until we are sure
366 // that T is a class (i.e. until we are outside std::conditional
367 // below)
368 struct _check_for_index_operator
369 {
370
371 template<typename T>
372 struct evaluate
373 : public _is_indexable<T>
374 {};
375
376 };
377
378 }
379
380 // The rationale here is as follows:
381 // 1) If we have an array, we assume we can index into it. That isn't
382 // true if I isn't an integral type, but that's why we have the static assertion
383 // in the body - we could of course try and check whether I is integral, but I
384 // can't be arsed and want to provide a motivation to switch to a newer compiler...
385 // 2) If we have a class, we use SFINAE to check for operator[]
386 // 3) Otherwise, we assume that T does not support indexing
387 //
388 // In order to make sure that the compiler doesn't accidentally try the SFINAE evaluation
389 // on an array or a scalar, we have to resort to lazy evaluation.
390 template<typename T, typename I = std::size_t>
391 struct is_indexable
392 : public std::conditional<
393 std::is_array<T>::value,
394 detail::_lazy<std::true_type>,
395 typename std::conditional<
396 std::is_class<T>::value,
397 detail::_check_for_index_operator,
398 detail::_lazy<std::false_type>
399 >::type
400 >::type::template evaluate<T>::type
401 {
402 static_assert(std::is_same<I,std::size_t>::value,"Your compiler is broken and does not support checking for arbitrary index types");
403 };
404
405
406#endif // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
407
411 // default version, gets picked if SFINAE fails
412 template<typename T, typename = void, typename = void>
413 struct is_range
414 : public std::false_type
415 {};
416
417#ifndef DOXYGEN
418 // version for types with begin() and end()
419 template<typename T>
420 struct is_range<T,
421 decltype(std::declval<T>().begin()),
422 decltype(std::declval<T>().end())>
423 : public std::true_type
424 {};
425#endif
426
427 namespace detail
428 {
430
439 template <class...>
440 struct voider
441 {
442 using type = void;
443 };
444 }
445
446 template <class> struct FieldTraits;
447
449 template <class... Types>
450 using void_t = typename detail::voider<Types...>::type;
451
453 template <class Type>
455
457 template <class Type>
459
460
461
462 // Implementation of IsTuple
463 namespace Imp {
464
465 template<class T>
466 struct IsTuple : public std::false_type
467 {};
468
469 template<class... T>
470 struct IsTuple<std::tuple<T...>> : public std::true_type
471 {};
472
473 } // namespace Imp
474
480 template<class T>
481 struct IsTuple :
482 public Imp::IsTuple<T>
483 {};
484
485
486
487 // Implementation of IsTupleOrDerived
488 namespace Imp {
489
490 template<class... T, class Dummy>
491 std::true_type isTupleOrDerived(const std::tuple<T...>*, Dummy)
492 { return {}; }
493
494 template<class Dummy>
495 std::false_type isTupleOrDerived(const void*, Dummy)
496 { return {}; }
497
498 } // namespace Imp
499
505 template<class T>
507 public decltype(Imp::isTupleOrDerived(std::declval<T*>(), true))
508 {};
509
510
511
512 // Implementation of is IsIntegralConstant
513 namespace Imp {
514
515 template<class T>
516 struct IsIntegralConstant : public std::false_type
517 {};
518
519 template<class T, T t>
520 struct IsIntegralConstant<std::integral_constant<T, t>> : public std::true_type
521 {};
522
523 } // namespace Imp
524
530 template<class T>
531 struct IsIntegralConstant : public Imp::IsIntegralConstant<std::decay_t<T>>
532 {};
533
535}
536#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:458
#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:454
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:450
STL namespace.
Dune namespace.
Definition alignment.hh:11
std::true_type isTupleOrDerived(const std::tuple< T... > *, Dummy)
Definition typetraits.hh:491
Definition ftraits.hh:24
T field_type
export the type representing the field
Definition ftraits.hh:26
T real_type
export the type representing the real type of the field
Definition ftraits.hh:28
Just an empty class.
Definition typetraits.hh:28
Determines whether a type is const or volatile and provides the unqualified types.
Definition typetraits.hh:36
std::add_cv< UnqualifiedType >::type ConstVolatileType
The const volatile type.
Definition typetraits.hh:49
std::remove_cv< T >::type UnqualifiedType
The unqualified type.
Definition typetraits.hh:45
std::add_const< UnqualifiedType >::type ConstType
The const type.
Definition typetraits.hh:47
Tests whether a type is volatile.
Definition typetraits.hh:55
Tests whether a type is constant.
Definition typetraits.hh:65
Definition typetraits.hh:74
std::remove_const< T >::type type
Definition typetraits.hh:75
Definition typetraits.hh:80
std::remove_reference< T >::type type
Definition typetraits.hh:81
Checks whether a type is convertible to another.
Definition typetraits.hh:92
Checks whether a type is derived from another.
Definition typetraits.hh:111
Checks whether two types are interoperable.
Definition typetraits.hh:126
Definition typetraits.hh:138
T type
Definition typetraits.hh:143
Enable typedef if two types are interoperable.
Definition typetraits.hh:154
Definition typetraits.hh:159
Definition typetraits.hh:167
std::conditional< B, T, F >::type type
Definition typetraits.hh:168
Definition typetraits.hh:173
Definition typetraits.hh:179
Definition typetraits.hh:186
Definition typetraits.hh:194
Definition typetraits.hh:202
Definition typetraits.hh:210
std::remove_pointer< T >::type type
Definition typetraits.hh:211
template which always yields a false value
Definition typetraits.hh:255
template which always yields a true value
Definition typetraits.hh:268
Definition typetraits.hh:275
Definition typetraits.hh:285
Definition typetraits.hh:322
Definition typetraits.hh:415
Definition typetraits.hh:441
void type
Definition typetraits.hh:442
Definition typetraits.hh:467
Check if T is a std::tuple<...>
Definition typetraits.hh:483
Check if T derived from a std::tuple<...>
Definition typetraits.hh:508
Definition typetraits.hh:517
Check if T is an std::integral_constant<I, i>
Definition typetraits.hh:532