Dune Core Modules (2.7.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#include <utility>
9#include <vector>
10
12
13namespace 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>
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>
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>
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>
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
constexpr AutonomousValue< T > autoCopy(T &&v)
Autonomous copy of an expression's value for use in auto type deduction.
Definition: typetraits.hh:723
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
Dune namespace.
Definition: alignedallocator.hh:14
STL namespace.
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.111.3 (Jul 15, 22:36, 2024)