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 
13 namespace 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>
162  struct IsCallable;
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>
248  struct IsIndexable
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>
271  struct IsIterable
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 
391  struct IsCompileTimeConstant
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>
543  struct AutonomousValueType<const T> : AutonomousValueType<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
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
constexpr static 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.80.0 (Apr 26, 22:29, 2024)