00001
00002
00003 #ifndef DUNE_TYPETRAITS_HH
00004 #define DUNE_TYPETRAITS_HH
00005
00006 #include <complex>
00007 #include <type_traits>
00008
00009 #include <dune/common/deprecated.hh>
00010
00011 namespace Dune
00012 {
00013
00014 namespace detail
00015 {
00017
00026 template <class...>
00027 struct voider
00028 {
00029 using type = void;
00030 };
00031 }
00032
00034 template <class... Types>
00035 using void_t = typename detail::voider<Types...>::type;
00036
00050 struct Empty {};
00051
00056 template<typename T>
00057 struct DUNE_DEPRECATED_MSG("Use <type_traits> instead!") ConstantVolatileTraits
00058 {
00059 enum DUNE_DEPRECATED_MSG("Use std::is_volatile/std::is_const instead!") {
00061 isVolatile=std::is_volatile<T>::value,
00063 isConst=std::is_const<T>::value
00064 };
00065
00067 typedef DUNE_DEPRECATED_MSG("Use std::remove_const instead!") typename std::remove_cv<T>::type UnqualifiedType;
00069 typedef DUNE_DEPRECATED_MSG("Use std::add_const instead!") typename std::add_const<UnqualifiedType>::type ConstType;
00071 typedef DUNE_DEPRECATED_MSG("Use std::add_cv instead!") typename std::add_cv<UnqualifiedType>::type ConstVolatileType;
00072 };
00073
00075 template<typename T>
00076 struct DUNE_DEPRECATED_MSG("Use std::is_volatile instead!") IsVolatile
00077 {
00078 enum DUNE_DEPRECATED_MSG("Use std::is_volatile instead!") {
00080 value=std::is_volatile<T>::value
00081 };
00082 };
00083
00085 template<typename T>
00086 struct DUNE_DEPRECATED_MSG("Use std::is_const instead!") IsConst
00087 {
00088 enum DUNE_DEPRECATED_MSG("Use std::is_const instead!") {
00090 value=std::is_const<T>::value
00091 };
00092 };
00093
00094 template<typename T>
00095 struct DUNE_DEPRECATED_MSG("Use std::remove_const instead!") remove_const
00096 {
00097 typedef DUNE_DEPRECATED_MSG("Use std::remove_const instead!") typename std::remove_const<T>::type type;
00098 };
00099
00100 template<typename T>
00101 struct DUNE_DEPRECATED_MSG("Use std::remove_reference instead!") remove_reference
00102 {
00103 typedef DUNE_DEPRECATED_MSG("Use std::remove_reference instead!") typename std::remove_reference<T>::type type;
00104 };
00105
00112 template<class From, class To>
00113 struct DUNE_DEPRECATED_MSG("Use std::is_convertible/std::is_same instead!") Conversion
00114 {
00115 enum DUNE_DEPRECATED_MSG("Use std::is_convertible/std::is_same instead!") {
00117 exists = std::is_convertible<From,To>::value,
00119 isTwoWay = std::is_convertible<From,To>::value && std::is_convertible<To,From>::value,
00121 sameType = std::is_same<From,To>::value
00122 };
00123 };
00124
00131 template <class Base, class Derived>
00132 struct DUNE_DEPRECATED_MSG("Use std::is_base_of instead!") IsBaseOf
00133 {
00134 enum DUNE_DEPRECATED_MSG("Use std::is_base_of instead!") {
00136 value = std::is_base_of<Base, Derived>::value
00137 };
00138 };
00139
00146 template<class T1, class T2>
00147 struct IsInteroperable
00148 {
00149 enum {
00154 value = std::is_convertible<T1,T2>::value || std::is_convertible<T2,T1>::value
00155 };
00156 };
00157
00158 template<bool B, class T = void>
00159 struct enable_if
00160 {};
00161
00162 template<class T>
00163 struct enable_if<true,T>
00164 {
00165 typedef DUNE_DEPRECATED_MSG("Use std::enable_if instead!") T type;
00166 };
00167
00173 template<class T1, class T2, class Type>
00174 struct EnableIfInterOperable
00175 : public std::enable_if<IsInteroperable<T1,T2>::value, Type>
00176 {};
00177
00178
00179 template<typename T, typename U>
00180 struct DUNE_DEPRECATED_MSG("Use std::is_same instead!") is_same
00181 {
00182 enum DUNE_DEPRECATED_MSG("Use std::is_same instead!") {
00183 value = std::is_same<T,U>::value
00184 };
00185 };
00186
00187 template<bool B, typename T, typename F>
00188 struct DUNE_DEPRECATED_MSG("Use std::conditional instead!") conditional
00189 {
00190 typedef DUNE_DEPRECATED_MSG("Use std::conditional instead!") typename std::conditional<B,T,F>::type type;
00191 };
00192
00193 template<typename T, T v>
00194 struct DUNE_DEPRECATED_MSG("Use std::integral_constant instead!") integral_constant
00195 {
00196 DUNE_DEPRECATED_MSG("Use std::integral_constant instead!")
00197 static constexpr T value = v;
00198 };
00199
00200 struct DUNE_DEPRECATED_MSG("Use std::true_type instead!") true_type
00201 {
00202 enum DUNE_DEPRECATED_MSG("Use std::true_type instead!") {
00203 value = true
00204 };
00205 };
00206
00207 struct DUNE_DEPRECATED_MSG("Use std::false_type instead!") false_type
00208 {
00209 enum DUNE_DEPRECATED_MSG("Use std::false_type instead!") {
00210 value = false
00211 };
00212 };
00213
00214 template<typename T>
00215 struct DUNE_DEPRECATED_MSG("Use std::is_pointer instead!") is_pointer
00216 {
00217 enum DUNE_DEPRECATED_MSG("Use std::is_pointer instead!") {
00218 value = std::is_pointer<T>::value
00219 };
00220 };
00221
00222 template<typename T>
00223 struct DUNE_DEPRECATED_MSG("Use std::is_lvalue_reference instead!") is_lvalue_reference
00224 {
00225 enum DUNE_DEPRECATED_MSG("Use std::is_lvalue_reference instead!") {
00226 value = std::is_lvalue_reference<T>::value
00227 };
00228 };
00229
00230 template<typename T>
00231 struct DUNE_DEPRECATED_MSG("Use std::remove_pointer instead!") remove_pointer
00232 {
00233 typedef DUNE_DEPRECATED_MSG("Use std::remove_pointer instead!") typename std::remove_pointer<T>::type type;
00234 };
00235
00253
00269
00276 template<typename T>
00277 struct AlwaysFalse {
00279 static const bool value = false;
00280 };
00281
00289 template<typename T>
00290 struct AlwaysTrue {
00292 static const bool value = true;
00293 };
00294
00295 template <typename T>
00296 struct IsNumber
00297 : public std::integral_constant<bool, std::is_arithmetic<T>::value> {
00298 };
00299
00300 template <typename T>
00301 struct IsNumber<std::complex<T>>
00302 : public std::integral_constant<bool, IsNumber<T>::value> {
00303 };
00304
00305 template <typename T>
00306 struct has_nan
00307 : public std::integral_constant<bool, std::is_floating_point<T>::value> {
00308 };
00309
00310 template <typename T>
00311 struct has_nan<std::complex<T>>
00312 : public std::integral_constant<bool, std::is_floating_point<T>::value> {
00313 };
00314
00315 #if defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
00316
00317 #ifndef DOXYGEN
00318
00319 namespace detail {
00320
00321 template<typename T, typename I, typename = int>
00322 struct _is_indexable
00323 : public std::false_type
00324 {};
00325
00326 template<typename T, typename I>
00327 struct _is_indexable<T,I,typename std::enable_if<(sizeof(std::declval<T>()[std::declval<I>()]) > 0),int>::type>
00328 : public std::true_type
00329 {};
00330
00331 }
00332
00333 #endif // DOXYGEN
00334
00337
00341 template<typename T, typename I = std::size_t>
00342 struct is_indexable
00343 : public detail::_is_indexable<T,I>
00344 {};
00345
00346
00347 #else // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 namespace detail {
00362
00363
00364
00365 template<typename T>
00366 struct _lazy
00367 {
00368 template<typename U>
00369 struct evaluate
00370 {
00371 typedef T type;
00372 };
00373 };
00374
00375
00376 template<typename T, typename = int>
00377 struct _is_indexable
00378 : public std::false_type
00379 {};
00380
00381
00382 template<typename T>
00383 struct _is_indexable<T,decltype(std::declval<T>()[0],0)>
00384 : public std::true_type
00385 {};
00386
00387
00388
00389
00390 struct _check_for_index_operator
00391 {
00392
00393 template<typename T>
00394 struct evaluate
00395 : public _is_indexable<T>
00396 {};
00397
00398 };
00399
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 template<typename T, typename I = std::size_t>
00413 struct is_indexable
00414 : public std::conditional<
00415 std::is_array<T>::value,
00416 detail::_lazy<std::true_type>,
00417 typename std::conditional<
00418 std::is_class<T>::value,
00419 detail::_check_for_index_operator,
00420 detail::_lazy<std::false_type>
00421 >::type
00422 >::type::template evaluate<T>::type
00423 {
00424 static_assert(std::is_same<I,std::size_t>::value,"Your compiler is broken and does not support checking for arbitrary index types");
00425 };
00426
00427
00428 #endif // defined(DOXYGEN) or HAVE_IS_INDEXABLE_SUPPORT
00429
00430 namespace Impl {
00431
00432
00433
00434
00435 template<class...T>
00436 void ignore(T&&... t)
00437 {}
00438 }
00439
00443
00444 template<typename T, typename = void>
00445 struct is_range
00446 : public std::false_type
00447 {};
00448
00449 #ifndef DOXYGEN
00450
00451 template<typename T>
00452 struct is_range<T, decltype(Impl::ignore(
00453 std::declval<T>().begin(),
00454 std::declval<T>().end(),
00455 std::declval<T>().begin() != std::declval<T>().end(),
00456 decltype(std::declval<T>().begin()){std::declval<T>().end()},
00457 ++(std::declval<std::add_lvalue_reference_t<decltype(std::declval<T>().begin())>>()),
00458 *(std::declval<T>().begin())
00459 ))>
00460 : public std::true_type
00461 {};
00462 #endif
00463
00464 template <class> struct FieldTraits;
00465
00467 template <class Type>
00468 using field_t = typename FieldTraits<Type>::field_type;
00469
00471 template <class Type>
00472 using real_t = typename FieldTraits<Type>::real_type;
00473
00474
00475
00476
00477 namespace Imp {
00478
00479 template<class T>
00480 struct IsTuple : public std::false_type
00481 {};
00482
00483 template<class... T>
00484 struct IsTuple<std::tuple<T...>> : public std::true_type
00485 {};
00486
00487 }
00488
00494 template<class T>
00495 struct IsTuple :
00496 public Imp::IsTuple<T>
00497 {};
00498
00499
00500
00501
00502 namespace Imp {
00503
00504 template<class... T, class Dummy>
00505 std::true_type isTupleOrDerived(const std::tuple<T...>*, Dummy)
00506 { return {}; }
00507
00508 template<class Dummy>
00509 std::false_type isTupleOrDerived(const void*, Dummy)
00510 { return {}; }
00511
00512 }
00513
00519 template<class T>
00520 struct IsTupleOrDerived :
00521 public decltype(Imp::isTupleOrDerived(std::declval<T*>(), true))
00522 {};
00523
00524
00525
00526
00527 namespace Imp {
00528
00529 template<class T>
00530 struct IsIntegralConstant : public std::false_type
00531 {};
00532
00533 template<class T, T t>
00534 struct IsIntegralConstant<std::integral_constant<T, t>> : public std::true_type
00535 {};
00536
00537 }
00538
00544 template<class T>
00545 struct IsIntegralConstant : public Imp::IsIntegralConstant<std::decay_t<T>>
00546 {};
00547
00548
00549
00563 template<typename... T>
00564 struct SizeOf
00565 : public std::integral_constant<std::size_t,sizeof...(T)>
00566 {};
00567
00568
00569
00571 }
00572 #endif