Dune Core Modules (2.9.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// SPDX-FileCopyrightInfo: Copyright (C) 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
401 template<typename... T>
402 struct SizeOf
403 : public std::integral_constant<std::size_t,sizeof...(T)>
404 {};
405
406
407#ifndef DOXYGEN
408
409 namespace Impl {
410
411 template<class T, T...>
412 struct IntegerSequenceHelper;
413
414 // Helper struct to compute the i-th entry of a std::integer_sequence
415 //
416 // This could also be implemented using std::get<index>(std::make_tuple(t...)).
417 // However, the gcc-6 implementation of std::make_tuple increases the instantiation
418 // depth by 15 levels for each argument, such that the maximal instantiation depth
419 // is easily hit, especially with clang where it is set to 256.
420 template<class T, T head, T... tail>
421 struct IntegerSequenceHelper<T, head, tail...>
422 {
423
424 // get first entry
425 static constexpr auto get(std::integral_constant<std::size_t, 0>)
426 {
427 return std::integral_constant<T, head>();
428 }
429
430 // call get with first entry cut off and decremented index
431 template<std::size_t index,
432 std::enable_if_t<(index > 0) and (index < sizeof...(tail)+1), int> = 0>
433 static constexpr auto get(std::integral_constant<std::size_t, index>)
434 {
435 return IntegerSequenceHelper<T, tail...>::get(std::integral_constant<std::size_t, index-1>());
436 }
437
438 // use static assertion if index exceeds size
439 template<std::size_t index,
440 std::enable_if_t<(index >= sizeof...(tail)+1), int> = 0>
441 static constexpr auto get(std::integral_constant<std::size_t, index>)
442 {
443 static_assert(index < sizeof...(tail)+1, "index used in IntegerSequenceEntry exceed size");
444 }
445 };
446
447 } // end namespace Impl
448
449#endif // DOXYGEN
450
451
461 template<class T, T... t, std::size_t index>
462 constexpr auto integerSequenceEntry(std::integer_sequence<T, t...> /*seq*/, std::integral_constant<std::size_t, index> i)
463 {
464 static_assert(index < sizeof...(t), "index used in IntegerSequenceEntry exceed size");
465 return Impl::IntegerSequenceHelper<T, t...>::get(i);
466 }
467
468
475 template<class IntegerSequence, std::size_t index>
477
478#ifndef DOXYGEN
479
480 template<class T, T... t, std::size_t i>
481 struct IntegerSequenceEntry<std::integer_sequence<T, t...>, i>
482 : public decltype(Impl::IntegerSequenceHelper<T, t...>::get(std::integral_constant<std::size_t, i>()))
483 {};
484
485#endif // DOXYGEN
486
500 template<class T>
501 struct AutonomousValueType { using type = T; };
502
504 template<class T>
506
508 template<class T>
510
512 template<class T>
514
516 template<class T>
517 struct AutonomousValueType<volatile T> : AutonomousValueType<T> {};
518
520 template<>
521 struct AutonomousValueType<std::vector<bool>::reference>
522 {
523 using type = bool;
524 };
525
527 template<class T>
528 struct AutonomousValueType<volatile const T> : AutonomousValueType<T> {};
529
557 template<class T>
558 using AutonomousValue = typename AutonomousValueType<T>::type;
559
641 template<class T>
643 {
644 return v;
645 }
646
648}
649#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:462
typename FieldTraits< Type >::real_type real_t
Convenient access to FieldTraits<Type>::real_type.
Definition: typetraits.hh:301
constexpr AutonomousValue< T > autoCopy(T &&v)
Autonomous copy of an expression's value for use in auto type deduction.
Definition: typetraits.hh:642
typename AutonomousValueType< T >::type AutonomousValue
Type free of internal references that T can be converted to.
Definition: typetraits.hh:558
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
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:501
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:476
Check if a type is callable with ()-operator and given arguments.
Definition: typetraits.hh:162
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:404
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)