Dune Core Modules (unstable)

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
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
116
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>
297 using field_t = typename FieldTraits<Type>::field_type;
298
300 template <class Type>
301 using real_t = typename FieldTraits<Type>::real_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>
588 using AutonomousValue = typename AutonomousValueType<T>::type;
589
671 template<class T>
672 constexpr AutonomousValue<T> autoCopy(T &&v)
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 FieldTraits< Type >::real_type real_t
Convenient access to FieldTraits<Type>::real_type.
Definition: typetraits.hh:301
typename AutonomousValueType< T >::type AutonomousValue
Type free of internal references that T can be converted to.
Definition: typetraits.hh:588
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 >::field_type field_t
Convenient access to FieldTraits<Type>::field_type.
Definition: typetraits.hh:297
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
STL namespace.
template which always yields a false value
Definition: typetraits.hh:124
template which always yields a true value
Definition: typetraits.hh:134
Type free of internal references that T can be converted to.
Definition: typetraits.hh:531
Just an empty class.
Definition: typetraits.hh:55
Enable typedef if two types are interoperable.
Definition: typetraits.hh:81
Whether this type has a value of NaN.
Definition: typetraits.hh:212
Get entry of std::integer_sequence.
Definition: typetraits.hh:506
Check if a type is callable with ()-operator and given arguments.
Definition: typetraits.hh:162
Check if T is an integral constant or any type derived from std::integral_constant.
Definition: typetraits.hh:411
Type trait to determine whether an instance of T has an operator[](I), i.e. whether it can be indexed...
Definition: typetraits.hh:250
Check if T is an std::integral_constant<I, i>
Definition: typetraits.hh:384
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
typetrait to check that a class has begin() and end() members
Definition: typetraits.hh:273
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition: typetraits.hh:194
Check if T derived from a std::tuple<...>
Definition: typetraits.hh:357
Check if T is a std::tuple<...>
Definition: typetraits.hh:329
Compute size of variadic type list.
Definition: typetraits.hh:435
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 21, 23:30, 2024)