dune-common 2.10
Loading...
Searching...
No Matches
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// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5#ifndef DUNE_TYPETRAITS_HH
6#define DUNE_TYPETRAITS_HH
7
8#include <complex>
9#include <type_traits>
10#include <utility>
11#include <vector>
12
13namespace Dune
14{
15
16 namespace Impl
17 {
19
23 template <class...>
24 struct voider
25 {
26 using type = void;
27 };
28 }
29
31
39 template <class... Types>
40 using void_t = typename Impl::voider<Types...>::type;
41
51
55 struct Empty {};
56
63 template<class T1, class T2>
65 {
70 constexpr static bool value = std::is_convertible<T1,T2>::value || std::is_convertible<T2,T1>::value;
71 };
72
78 template<class T1, class T2, class Type>
80 : public std::enable_if<IsInteroperable<T1,T2>::value, Type>
81 {};
82
100 typedef void FrobnicateType;
101 };
102 \endcode
103 This will trigger static_assert() as soon as the compiler reads the
104 definition for the Traits template, since it knows that "false" can
105 never become true, no matter what the template parameters of Traits are.
106 As a workaround you can use AlwaysFalse: replace <tt>false</tt> by
107 <tt>AlwaysFalse<T>::value</tt>, like this:
108 \code
109 template<typename T>
110 struct Traits {
111 static_assert(AlwaysFalse<T>::value,
112 "Instantiating this non-specialized template is an "
113 "error. You should use one of the specializations "
114 "instead.");
116 typedef void FrobnicateType;
117 };
118 \endcode
119 Since there might be an specialization of AlwaysFalse for template
120 parameter T, the compiler cannot trigger static_assert() until the
121 type of T is known, that is, until Traits<T> is instantiated.
122 */
123 template<typename T>
124 struct AlwaysFalse : public std::false_type {};
125
133 template<typename T>
134 struct AlwaysTrue : public std::true_type {};
135
161 template<typename D, typename R = void>
163
168 template<typename R, typename F, typename... Args>
169 struct IsCallable<F(Args...), R>
170 : public std::bool_constant<
171 std::is_invocable_r_v<R, F, Args...>
172 && !std::is_member_pointer_v<std::decay_t<F>>
173 > {};
174
177
192 template <typename T>
193 struct IsNumber
194 : public std::integral_constant<bool, std::is_arithmetic<T>::value> {
195 };
196
197#ifndef DOXYGEN
198
199 template <typename T>
200 struct IsNumber<std::complex<T>>
201 : public std::integral_constant<bool, IsNumber<T>::value> {
202 };
203
204#endif // DOXYGEN
205
207
210 template <typename T>
211 struct HasNaN
212 : public std::integral_constant<bool, std::is_floating_point<T>::value> {
213 };
214
215#ifndef DOXYGEN
216
217 template <typename T>
218 struct HasNaN<std::complex<T>>
219 : public std::integral_constant<bool, std::is_floating_point<T>::value> {
220 };
221
222#endif // DOXYGEN
223
224#ifndef DOXYGEN
225
226 namespace Impl {
227
228 template<typename T, typename I, typename = int>
229 struct IsIndexable
230 : public std::false_type
231 {};
232
233 template<typename T, typename I>
234 struct IsIndexable<T,I,typename std::enable_if<(sizeof(std::declval<T>()[std::declval<I>()]) > 0),int>::type>
235 : public std::true_type
236 {};
237
238 }
239
240#endif // DOXYGEN
241
243
247 template<typename T, typename I = std::size_t>
249 : public Impl::IsIndexable<T,I>
250 {};
251
252#ifndef DOXYGEN
253
254 namespace Impl {
255 // This function does nothing.
256 // By passing expressions to this function one can avoid
257 // "value computed is not used" warnings that may show up
258 // in a comma expression.
259 template<class...T>
260 void ignore(T&&... /*t*/)
261 {}
262 }
263
264#endif // DOXYGEN
265
269 // default version, gets picked if SFINAE fails
270 template<typename T, typename = void>
272 : public std::false_type
273 {};
274
275#ifndef DOXYGEN
276 // version for types with begin() and end()
277 template<typename T>
278 struct IsIterable<T, decltype(Impl::ignore(
279 std::declval<T>().begin(),
280 std::declval<T>().end(),
281 std::declval<T>().begin() != std::declval<T>().end(),
282 decltype(std::declval<T>().begin()){std::declval<T>().end()},
283 ++(std::declval<std::add_lvalue_reference_t<decltype(std::declval<T>().begin())>>()),
284 *(std::declval<T>().begin())
285 ))>
286 : public std::true_type
287 {};
288#endif
289
290#ifndef DOXYGEN
291 // this is just a forward declaration
292 template <class> struct FieldTraits;
293#endif
294
296 template <class Type>
298
300 template <class Type>
302
303
304#ifndef DOXYGEN
305
306 // Implementation of IsTuple
307 namespace Impl {
308
309 template<class T>
310 struct IsTuple : public std::false_type
311 {};
312
313 template<class... T>
314 struct IsTuple<std::tuple<T...>> : public std::true_type
315 {};
316
317 } // namespace Impl
318
319#endif // DOXYGEN
320
326 template<class T>
327 struct IsTuple :
328 public Impl::IsTuple<T>
329 {};
330
331
332#ifndef DOXYGEN
333
334 // Implementation of IsTupleOrDerived
335 namespace Impl {
336
337 template<class... T, class Dummy>
338 std::true_type isTupleOrDerived(const std::tuple<T...>*, Dummy)
339 { return {}; }
340
341 template<class Dummy>
342 std::false_type isTupleOrDerived(const void*, Dummy)
343 { return {}; }
344
345 } // namespace Impl
346
347#endif // DOXYGEN
348
354 template<class T>
356 public decltype(Impl::isTupleOrDerived(std::declval<T*>(), true))
357 {};
358
359
360#ifndef DOXYGEN
361
362 // Implementation of is IsIntegralConstant
363 namespace Impl {
364
365 template<class T>
366 struct IsIntegralConstant : public std::false_type
367 {};
368
369 template<class T, T t>
370 struct IsIntegralConstant<std::integral_constant<T, t>> : public std::true_type
371 {};
372
373 } // namespace Impl
374
375#endif // DOXYGEN
376
382 template<class T>
383 struct IsIntegralConstant : public Impl::IsIntegralConstant<std::decay_t<T>>
384 {};
385
386
387#ifndef DOXYGEN
388
389 namespace Impl {
390
392 {
393 template <class T, T value>
394 static std::true_type check(std::integral_constant<T,value>);
395 static std::false_type check(...);
396 };
397
398 } // namespace Impl
399
400#endif // DOXYGEN
401
408 template<class T>
410 : public decltype(Impl::IsCompileTimeConstant::check(std::declval<T>()))
411 {};
412
413
414
430 template<typename... T>
431 struct
432 [[deprecated("This class is deprecated and will be removed after Dune 2.10. Use sizeof...(T) instead.")]]
433 SizeOf
434 : public std::integral_constant<std::size_t,sizeof...(T)>
435 {};
436
437
438#ifndef DOXYGEN
439
440 namespace Impl {
441
442 template<class T, T...>
443 struct IntegerSequenceHelper;
444
445 // Helper struct to compute the i-th entry of a std::integer_sequence
446 //
447 // This could also be implemented using std::get<index>(std::make_tuple(t...)).
448 // However, the gcc-6 implementation of std::make_tuple increases the instantiation
449 // depth by 15 levels for each argument, such that the maximal instantiation depth
450 // is easily hit, especially with clang where it is set to 256.
451 template<class T, T head, T... tail>
452 struct IntegerSequenceHelper<T, head, tail...>
453 {
454
455 // get first entry
456 static constexpr auto get(std::integral_constant<std::size_t, 0>)
457 {
458 return std::integral_constant<T, head>();
459 }
460
461 // call get with first entry cut off and decremented index
462 template<std::size_t index,
463 std::enable_if_t<(index > 0) and (index < sizeof...(tail)+1), int> = 0>
464 static constexpr auto get(std::integral_constant<std::size_t, index>)
465 {
466 return IntegerSequenceHelper<T, tail...>::get(std::integral_constant<std::size_t, index-1>());
467 }
468
469 // use static assertion if index exceeds size
470 template<std::size_t index,
471 std::enable_if_t<(index >= sizeof...(tail)+1), int> = 0>
472 static constexpr auto get(std::integral_constant<std::size_t, index>)
473 {
474 static_assert(index < sizeof...(tail)+1, "index used in IntegerSequenceEntry exceed size");
475 }
476 };
477
478 } // end namespace Impl
479
480#endif // DOXYGEN
481
482
491 template<class T, T... t, std::size_t index>
492 constexpr auto integerSequenceEntry(std::integer_sequence<T, t...> /*seq*/, std::integral_constant<std::size_t, index> i)
493 {
494 static_assert(index < sizeof...(t), "index used in IntegerSequenceEntry exceed size");
495 return Impl::IntegerSequenceHelper<T, t...>::get(i);
496 }
497
498
505 template<class IntegerSequence, std::size_t index>
507
508#ifndef DOXYGEN
509
510 template<class T, T... t, std::size_t i>
511 struct IntegerSequenceEntry<std::integer_sequence<T, t...>, i>
512 : public decltype(Impl::IntegerSequenceHelper<T, t...>::get(std::integral_constant<std::size_t, i>()))
513 {};
514
515#endif // DOXYGEN
516
530 template<class T>
531 struct AutonomousValueType { using type = T; };
532
534 template<class T>
536
538 template<class T>
540
542 template<class T>
544
546 template<class T>
547 struct AutonomousValueType<volatile T> : AutonomousValueType<T> {};
548
550 template<>
551 struct AutonomousValueType<std::vector<bool>::reference>
552 {
553 using type = bool;
554 };
555
557 template<class T>
558 struct AutonomousValueType<volatile const T> : AutonomousValueType<T> {};
559
587 template<class T>
589
671 template<class T>
673 {
674 return v;
675 }
676
678}
679#endif
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:492
typename Impl::voider< Types... >::type void_t
Is void for all valid input types. The workhorse for C++11 SFINAE-techniques.
Definition typetraits.hh:40
typename FieldTraits< Type >::real_type real_t
Convenient access to FieldTraits<Type>::real_type.
Definition typetraits.hh:301
typename FieldTraits< Type >::field_type field_t
Convenient access to FieldTraits<Type>::field_type.
Definition typetraits.hh:297
constexpr AutonomousValue< T > autoCopy(T &&v)
Autonomous copy of an expression's value for use in auto type deduction.
Definition typetraits.hh:672
typename AutonomousValueType< T >::type AutonomousValue
Type free of internal references that T can be converted to.
Definition typetraits.hh:588
MPI_Datatype MPITraits< ParallelLocalIndex< T > >::type
Definition plocalindex.hh:317
STL namespace.
Dune namespace.
Definition alignedallocator.hh:13
constexpr std::integer_sequence< T, II... > tail(std::integer_sequence< T, I0, II... >)
For a sequence [head,tail...) return the tail sequence.
Definition integersequence.hh:58
constexpr std::integral_constant< T, I0 > head(std::integer_sequence< T, I0, II... >)
For a sequence [head,tail...) return the single head element.
Definition integersequence.hh:53
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition integersequence.hh:22
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition typetraits.hh:194
T field_type
export the type representing the field
Definition ftraits.hh:28
T real_type
export the type representing the real type of the field
Definition ftraits.hh:30
Just an empty class.
Definition typetraits.hh:55
Checks whether two types are interoperable.
Definition typetraits.hh:65
static constexpr bool value
True if either a conversion from T1 to T2 or vice versa exists.
Definition typetraits.hh:70
Enable typedef if two types are interoperable.
Definition typetraits.hh:81
template which always yields a false value
Definition typetraits.hh:124
template which always yields a true value
Definition typetraits.hh:134
Check if a type is callable with ()-operator and given arguments.
Definition typetraits.hh:162
Whether this type has a value of NaN.
Definition typetraits.hh:212
Type trait to determine whether an instance of T has an operator[](I), i.e. whether it can be indexed...
Definition typetraits.hh:250
typetrait to check that a class has begin() and end() members
Definition typetraits.hh:273
Check if T is a std::tuple<...>.
Definition typetraits.hh:329
Check if T derived from a std::tuple<...>.
Definition typetraits.hh:357
Check if T is an std::integral_constant<I, i>.
Definition typetraits.hh:384
Check if T is an integral constant or any type derived from std::integral_constant.
Definition typetraits.hh:411
Compute size of variadic type list.
Definition typetraits.hh:435
Get entry of std::integer_sequence.
Definition typetraits.hh:506
Type free of internal references that T can be converted to.
Definition typetraits.hh:531
T type
Definition typetraits.hh:531