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 
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 
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>
513  struct AutonomousValueType<const T> : AutonomousValueType<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>
642  constexpr AutonomousValue<T> autoCopy(T &&v)
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
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
constexpr AutonomousValue< T > autoCopy(T &&v)
Autonomous copy of an expression's value for use in auto type deduction.
Definition: typetraits.hh:642
Dune namespace.
Definition: alignedallocator.hh:13
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
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:404
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)