dune-common  2.8.0
type_traits.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 #ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
4 #define DUNE_COMMON_STD_TYPE_TRAITS_HH
5 
6 #include <type_traits>
9 
10 #if __has_include(<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 [[deprecated("Will be removed after release 2.8. Use Dune::AlwaysFalse (from dune/common/typetraits.hh)")]] to_false_type : public std::false_type {};
80 
81 
82 
83  // to_true_type
84  // ------------
85 
96  template< typename T >
97  struct [[deprecated("Will be removed after release 2.8. Use Dune::AlwaysTrue (from dune/common/typetraits.hh)")]] to_true_type : public std::true_type {};
98 
99 
102  using std::bool_constant;
103 
104 
105  namespace Impl {
106 
107  // If R is void we only need to check if F can be called
108  // with given Args... list. If this is not possible
109  // result_of_t is not defined and this overload is disabled.
110  template<class R, class F, class... Args,
111  std::enable_if_t<
112  std::is_same<std::void_t<std::result_of_t<F(Args...)>>, R>::value
113  , int> = 0>
114  std::true_type is_callable_helper(PriorityTag<2>)
115  { return {}; }
116 
117  // Check if result of F(Args...) can be converted to R.
118  // If F cannot even be called with given Args... then
119  // result_of_t is not defined and this overload is disabled.
120  template<class R, class F, class... Args,
121  std::enable_if_t<
122  std::is_convertible<std::result_of_t<F(Args...)>, R>::value
123  , int> = 0>
124  std::true_type is_callable_helper(PriorityTag<1>)
125  { return {}; }
126 
127  // If none of the above matches, F can either not be called
128  // with given Args..., or the result cannot be converted to
129  // void, or R is not void.
130  template<class R, class F, class... Args>
131  std::false_type is_callable_helper(PriorityTag<0>)
132  { return {}; }
133  }
134 
153  template <class D, class R= void>
154  struct is_callable;
155 
174  template <class F, class... Args, class R>
175  struct [[deprecated("Use std::is_invocable from <type_traits>. Will be removed after release 2.8")]] is_callable< F(Args...), R> :
176  decltype(Impl::is_callable_helper<R, F, Args...>(PriorityTag<42>()))
177  {};
178 
179 
194  template <class F, class... Args>
195  struct [[deprecated("Use std::is_invocable from <type_traits>. Will be removed after release 2.8")]] is_invocable :
196  decltype(Impl::is_callable_helper<void, F, Args...>(PriorityTag<42>()))
197  {};
198 
215  template <class R, class F, class... Args>
216  struct [[deprecated("Use std::is_invocable_r from <type_traits>. Will be removed after release 2.8")]] is_invocable_r :
217  decltype(Impl::is_callable_helper<R, F, Args...>(PriorityTag<42>()))
218  {};
219 
220 
221 #if DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
222 
223  using std::experimental::nonesuch;
233 
234 #else // DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
235 
236  // fallback version of std::experimental::is_detected et al., heavily scribbled
237  // from cppreference.com (but there is actually not much implementation to the thing)
238 
239 #ifndef DOXYGEN
240 
241  namespace Impl {
242 
243  // default version of detector, this gets matched on failure
244  template<typename Default, typename Void, template<typename...> class Op, typename... Args>
245  struct detector
246  {
247  using value_t = std::false_type;
248  using type = Default;
249  };
250 
251  // specialization of detector that matches if Op<Args...> can be instantiated
252  template<typename Default, template<typename...> class Op, typename... Args>
253  struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
254  {
255  using value_t = std::true_type;
256  using type = Op<Args...>;
257  };
258 
259  }
260 
261 #endif // DOXYGEN
262 
264 
272  struct nonesuch
273  {
274  nonesuch() = delete;
275  ~nonesuch() = delete;
276  nonesuch(const nonesuch&) = delete;
277  void operator=(const nonesuch&) = delete;
278  };
279 
281 
312  template<typename Default, template<typename...> class Op, typename... Args>
313  using detected_or = Impl::detector<Default,void,Op,Args...>;
314 
316 
325  template<template<typename...> class Op, typename... Args>
326  using is_detected = typename detected_or<nonesuch,Op,Args...>::value_t;
327 
328 #ifdef __cpp_variable_templates
330 
339  template<template<typename...> class Op, typename... Args>
340  constexpr bool is_detected_v = is_detected<Op,Args...>::value;
341 #endif // __cpp_variable_templates
342 
344 
354  template<template<typename...> class Op, typename... Args>
355  using detected_t = typename detected_or<nonesuch,Op,Args...>::type;
356 
357 
359 
369  template<typename Default, template<typename...> class Op, typename... Args>
370  using detected_or_t = typename detected_or<Default,Op,Args...>::type;
371 
373 
379  template<typename Expected, template<typename...> class Op, typename... Args>
380  using is_detected_exact = std::is_same<Expected,detected_t<Op,Args...>>;
381 
382 #ifdef __cpp_variable_templates
384 
390  template<typename Expected, template<typename...> class Op, typename... Args>
391  constexpr bool is_detected_exact_v = is_detected_exact<Expected,Op,Args...>::value;
392 #endif // __cpp_variable_templates
393 
395 
401  template<typename Target, template<typename...> class Op, typename... Args>
402  using is_detected_convertible = std::is_convertible<Target,detected_t<Op,Args...>>;
403 
404 #ifdef __cpp_variable_templates
406 
412  template<typename Target, template<typename...> class Op, typename... Args>
413  constexpr bool is_detected_convertible_v = is_detected_convertible<Target,Op,Args...>::value;
414 #endif // __cpp_variable_templates
415 
416 #endif // DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
417 
418 
419 
420  // conjunction
421  // -----------
422 
430  template< class... B >
431  struct [[deprecated("Will be removed after release 2.8. Use std::conjuction instead.")]] conjunction
432  : std::conjunction<B...>
433  {};
434 
435 
436  // disjunction
437  // -----------
438 
446  template< class... B >
447  struct [[deprecated("Will be removed after release 2.8. Use std::disjunction instead.")]] disjunction
448  : std::disjunction<B...>
449  {};
450 
451 
452  // negation
453  // --------
454 
462  template<class B>
463  struct [[deprecated("Will be removed after release 2.8. Use std::negation instead.")]] negation
464  : std::negation<B>
465  {};
466 
467 } // namespace Std
468 
469 } // namespace Dune
470 
471 #endif // #ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
Traits for type conversions and type information.
Utilities for type computations, constraining overloads, ...
constexpr bool is_detected_exact_v
Convenient access to the result value of is_detected_exact.
Definition: type_traits.hh:391
constexpr bool is_detected_convertible_v
Convenient access to the result value of is_detected_convertible.
Definition: type_traits.hh:413
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:370
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:380
typename detected_or< nonesuch, Op, Args... >::type detected_t
Returns Op<Args...> if that is valid; otherwise returns nonesuch.
Definition: type_traits.hh:355
typename Impl::voider< Types... >::type void_t
Is void for all valid input types. The workhorse for C++11 SFINAE-techniques.
Definition: typetraits.hh:38
constexpr bool is_detected_v
Detects whether Op<Args...> is valid and makes the result available as a value.
Definition: type_traits.hh:340
typename detected_or< nonesuch, Op, Args... >::value_t is_detected
Detects whether Op<Args...> is valid.
Definition: type_traits.hh:326
Impl::detector< Default, void, Op, Args... > detected_or
Detects whether Op<Args...> is valid and makes the result available.
Definition: type_traits.hh:313
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:402
Dune namespace.
Definition: alignedallocator.hh:11
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 class to check if function is callable.
Definition: type_traits.hh:154
Traits class to check if function is invocable.
Definition: type_traits.hh:197
Traits class to check if function is invocable and the return type is compatible.
Definition: type_traits.hh:218
Type representing a lookup failure by std::detected_or and friends.
Definition: type_traits.hh:273
nonesuch(const nonesuch &)=delete
void operator=(const nonesuch &)=delete
forms the logical conjunction of the type traits B...
Definition: type_traits.hh:433
forms the logical disjunction of the type traits B...
Definition: type_traits.hh:449
forms the logical negation of the type traits B...
Definition: type_traits.hh:465
template which always yields a false value
Definition: typetraits.hh:124
template which always yields a true value
Definition: typetraits.hh:134
Helper class for tagging priorities.
Definition: typeutilities.hh:71