Dune Core Modules (2.6.0)

type_traits.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
4 #define DUNE_COMMON_STD_TYPE_TRAITS_HH
5 
6 #include <type_traits>
9 
10 #if DUNE_HAVE_HEADER_EXPERIMENTAL_TYPE_TRAITS
11 #include <experimental/type_traits>
12 #endif
13 
14 namespace Dune
15 {
16 
18 
27 namespace Std
28 {
29 
30  // to_false_type
31  // -------------
32 
78  template< typename T >
79  struct to_false_type : public std::false_type {};
80 
81 
82 
83  // to_true_type
84  // ------------
85 
96  template< typename T >
97  struct to_true_type : public std::true_type {};
98 
99 
100 #if DUNE_HAVE_CXX_BOOL_CONSTANT
101 
102  using std::bool_constant;
103 
104 #elif DUNE_HAVE_CXX_EXPERIMENTAL_BOOL_CONSTANT
105 
107 
108 #else
109 
117  template <bool value>
118  using bool_constant = std::integral_constant<bool, value>;
119 
120 #endif
121 
122 
123  namespace Impl {
124 
125  // If R is void we only need to check if F can be called
126  // with given Args... list. If this is not possible
127  // result_of_t is not defined and this overload is disabled.
128  template<class R, class F, class... Args,
129  std::enable_if_t<
130  std::is_same<void_t<std::result_of_t<F(Args...)>>, R>::value
131  , int> = 0>
132  std::true_type is_callable_helper(PriorityTag<2>)
133  { return {}; }
134 
135  // Check if result of F(Args...) can be converted to R.
136  // If F cannot even be called with given Args... then
137  // result_of_t is not defined and this overload is disabled.
138  template<class R, class F, class... Args,
139  std::enable_if_t<
140  std::is_convertible<std::result_of_t<F(Args...)>, R>::value
141  , int> = 0>
142  std::true_type is_callable_helper(PriorityTag<1>)
143  { return {}; }
144 
145  // If none of the above matches, F can either not be called
146  // with given Args..., or the result cannot be converted to
147  // void, or R is not void.
148  template<class R, class F, class... Args>
149  std::false_type is_callable_helper(PriorityTag<0>)
150  { return {}; }
151  }
152 
170  template <class D, class R= void>
171  struct is_callable;
172 
190  template <class F, class... Args, class R>
191  struct is_callable< F(Args...), R> :
192  decltype(Impl::is_callable_helper<R, F, Args...>(PriorityTag<42>()))
193  {};
194 
195 
209  template <class F, class... Args>
210  struct is_invocable :
211  decltype(Impl::is_callable_helper<void, F, Args...>(PriorityTag<42>()))
212  {};
213 
229  template <class R, class F, class... Args>
230  struct is_invocable_r :
231  decltype(Impl::is_callable_helper<R, F, Args...>(PriorityTag<42>()))
232  {};
233 
234 
235 #if DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
236 
237  using std::experimental::nonesuch;
247 
248 #else // DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
249 
250  // fallback version of std::experimental::is_detected et al., heavily scribbled
251  // from cppreference.com (but there is actually not much implementation to the thing)
252 
253 #ifndef DOXYGEN
254 
255  namespace Impl {
256 
257  // default version of detector, this gets matched on failure
258  template<typename Default, typename Void, template<typename...> class Op, typename... Args>
259  struct detector
260  {
261  using value_t = std::false_type;
262  using type = Default;
263  };
264 
265  // specialization of detector that matches if Op<Args...> can be instantiated
266  template<typename Default, template<typename...> class Op, typename... Args>
267  struct detector<Default, void_t<Op<Args...>>, Op, Args...>
268  {
269  using value_t = std::true_type;
270  using type = Op<Args...>;
271  };
272 
273  }
274 
275 #endif // DOXYGEN
276 
278 
286  struct nonesuch
287  {
288  nonesuch() = delete;
289  ~nonesuch() = delete;
290  nonesuch(const nonesuch&) = delete;
291  void operator=(const nonesuch&) = delete;
292  };
293 
295 
326  template<typename Default, template<typename...> class Op, typename... Args>
327  using detected_or = Impl::detector<Default,void,Op,Args...>;
328 
330 
339  template<template<typename...> class Op, typename... Args>
340  using is_detected = typename detected_or<nonesuch,Op,Args...>::value_t;
341 
342 #ifdef __cpp_variable_templates
344 
353  template<template<typename...> class Op, typename... Args>
354  constexpr bool is_detected_v = is_detected<Op,Args...>::value;
355 #endif // __cpp_variable_templates
356 
358 
368  template<template<typename...> class Op, typename... Args>
369  using detected_t = typename detected_or<nonesuch,Op,Args...>::type;
370 
371 
373 
383  template<typename Default, template<typename...> class Op, typename... Args>
384  using detected_or_t = typename detected_or<Default,Op,Args...>::type;
385 
387 
393  template<typename Expected, template<typename...> class Op, typename... Args>
394  using is_detected_exact = std::is_same<Expected,detected_t<Op,Args...>>;
395 
396 #ifdef __cpp_variable_templates
398 
404  template<typename Expected, template<typename...> class Op, typename... Args>
405  constexpr bool is_detected_exact_v = is_detected_exact<Expected,Op,Args...>::value;
406 #endif // __cpp_variable_templates
407 
409 
415  template<typename Target, template<typename...> class Op, typename... Args>
416  using is_detected_convertible = std::is_convertible<Target,detected_t<Op,Args...>>;
417 
418 #ifdef __cpp_variable_templates
420 
426  template<typename Target, template<typename...> class Op, typename... Args>
427  constexpr bool is_detected_convertible_v = is_detected_convertible<Target,Op,Args...>::value;
428 #endif // __cpp_variable_templates
429 
430 #endif // DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
431 
432 
433 
434  // conjunction
435  // -----------
436 
444  template< class... B >
445  struct conjunction;
446 
447  template<>
448  struct conjunction<>
449  : std::true_type
450  {};
451 
452  template< class B >
453  struct conjunction< B >
454  : B
455  {};
456 
457  template< class B1, class... Bn >
458  struct conjunction< B1, Bn... >
459  : std::conditional_t< static_cast< bool >( B1::value ), conjunction< Bn... >, B1 >
460  {};
461 
462 
463 
464  // disjunction
465  // -----------
466 
474  template< class... B >
475  struct disjunction;
476 
477  template<>
478  struct disjunction<>
479  : std::false_type
480  {};
481 
482  template< class B >
483  struct disjunction< B >
484  : B
485  {};
486 
487  template< class B1, class... Bn >
488  struct disjunction< B1, Bn... >
489  : std::conditional_t< static_cast< bool >( B1::value ), B1, disjunction< Bn... > >
490  {};
491 
492 } // namespace Std
493 
494 } // namespace Dune
495 
496 #endif // #ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
constexpr bool is_detected_exact_v
Convenient access to the result value of is_detected_exact.
Definition: type_traits.hh:405
constexpr bool is_detected_convertible_v
Convenient access to the result value of is_detected_convertible.
Definition: type_traits.hh:427
std::integral_constant< bool, value > bool_constant
A template alias for std::integral_constant<bool, value>
Definition: type_traits.hh:118
typename detected_or< Default, Op, Args... >::type detected_or_t
Returns Op<Args...> if that is valid; otherwise returns the fallback type Default.
Definition: type_traits.hh:384
std::is_same< Expected, detected_t< Op, Args... > > is_detected_exact
Checks whether Op<Args...> is Expected without causing an error if Op<Args...> is invalid.
Definition: type_traits.hh:394
typename detected_or< nonesuch, Op, Args... >::type detected_t
Returns Op<Args...> if that is valid; otherwise returns nonesuch.
Definition: type_traits.hh:369
typename Impl::voider< Types... >::type void_t
Is void for all valid input types (see N3911). The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:39
constexpr bool is_detected_v
Detects whether Op<Args...> is valid and makes the result available as a value.
Definition: type_traits.hh:354
typename detected_or< nonesuch, Op, Args... >::value_t is_detected
Detects whether Op<Args...> is valid.
Definition: type_traits.hh:340
Impl::detector< Default, void, Op, Args... > detected_or
Detects whether Op<Args...> is valid and makes the result available.
Definition: type_traits.hh:327
std::is_convertible< Target, detected_t< Op, Args... > > is_detected_convertible
Checks whether Op<Args...> is convertible to Target without causing an error if Op<Args....
Definition: type_traits.hh:416
Dune namespace.
Definition: alignedallocator.hh:10
Helper class for tagging priorities.
Definition: typeutilities.hh:83
Helper class for tagging priorities.
Definition: typeutilities.hh:71
forms the logical conjunction of the type traits B...
Definition: type_traits.hh:445
forms the logical disjunction of the type traits B...
Definition: type_traits.hh:475
Traits class to check if function is callable.
Definition: type_traits.hh:171
Traits class to check if function is invocable and the return type is compatible.
Definition: type_traits.hh:232
Traits class to check if function is invocable.
Definition: type_traits.hh:212
Type representing a lookup failure by std::detected_or and friends.
Definition: type_traits.hh:287
template mapping a type to std::false_type
Definition: type_traits.hh:79
template mapping a type to std::true_type
Definition: type_traits.hh:97
Traits for type conversions and type information.
Utilities for type computations, constraining overloads, ...
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)