dune-common  2.11
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 // 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_COMMON_STD_TYPE_TRAITS_HH
6 #define DUNE_COMMON_STD_TYPE_TRAITS_HH
7 
8 #include <type_traits>
9 #include <dune-common-config.hh> // DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
12 
13 #if DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
14 #include <experimental/type_traits>
15 #endif
16 
17 namespace Dune
18 {
19 
21 
30 namespace Std
31 {
32 
33 #if DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
34 
35  using std::experimental::nonesuch;
39  using std::experimental::is_detected_v;
42  using std::experimental::is_detected_exact_v;
44  using std::experimental::is_detected_convertible_v;
45 
46 #else // DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
47 
48  // fallback version of std::experimental::is_detected et al., heavily scribbled
49  // from cppreference.com (but there is actually not much implementation to the thing)
50 
51 #ifndef DOXYGEN
52 
53  namespace Impl {
54 
55  // default version of detector, this gets matched on failure
56  template<typename Default, typename Void, template<typename...> class Op, typename... Args>
57  struct detector
58  {
59  using value_t = std::false_type;
60  using type = Default;
61  };
62 
63  // specialization of detector that matches if Op<Args...> can be instantiated
64  template<typename Default, template<typename...> class Op, typename... Args>
65  struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
66  {
67  using value_t = std::true_type;
68  using type = Op<Args...>;
69  };
70 
71  }
72 
73 #endif // DOXYGEN
74 
76 
84  struct nonesuch
85  {
86  nonesuch() = delete;
87  ~nonesuch() = delete;
88  nonesuch(const nonesuch&) = delete;
89  void operator=(const nonesuch&) = delete;
90  };
91 
93 
127  template<typename Default, template<typename...> class Op, typename... Args>
128  using detected_or = Impl::detector<Default,void,Op,Args...>;
129 
131 
140  template<template<typename...> class Op, typename... Args>
141  using is_detected = typename detected_or<nonesuch,Op,Args...>::value_t;
142 
143 #ifdef __cpp_variable_templates
144 
154  template<template<typename...> class Op, typename... Args>
155  constexpr bool is_detected_v = is_detected<Op,Args...>::value;
156 #endif // __cpp_variable_templates
157 
159 
169  template<template<typename...> class Op, typename... Args>
170  using detected_t = typename detected_or<nonesuch,Op,Args...>::type;
171 
172 
174 
184  template<typename Default, template<typename...> class Op, typename... Args>
185  using detected_or_t = typename detected_or<Default,Op,Args...>::type;
186 
188 
194  template<typename Expected, template<typename...> class Op, typename... Args>
195  using is_detected_exact = std::is_same<Expected,detected_t<Op,Args...>>;
196 
197 #ifdef __cpp_variable_templates
198 
205  template<typename Expected, template<typename...> class Op, typename... Args>
206  constexpr bool is_detected_exact_v = is_detected_exact<Expected,Op,Args...>::value;
207 #endif // __cpp_variable_templates
208 
210 
216  template<typename Target, template<typename...> class Op, typename... Args>
217  using is_detected_convertible = std::is_convertible<Target,detected_t<Op,Args...>>;
218 
219 #ifdef __cpp_variable_templates
220 
227  template<typename Target, template<typename...> class Op, typename... Args>
228  constexpr bool is_detected_convertible_v = is_detected_convertible<Target,Op,Args...>::value;
229 #endif // __cpp_variable_templates
230 
231 #endif // DUNE_HAVE_CXX_EXPERIMENTAL_IS_DETECTED
232 
233 } // namespace Std
234 
235 
236 namespace detail
237 {
238  template <class Type>
239  [[deprecated("Type extraction of `TargetType` has failed. Inspect the code calling `detected_or_fallback_t` for getting the source of this warning!")]]
240  Type warningIfNotDefined(const Std::nonesuch*);
241 
242  template <class Type, class T>
243  Type warningIfNotDefined(const T*);
244 }
245 
247 template <template<typename...> class Fallback,
248  template<typename...> class TargetType, typename... Args>
250  detail::warningIfNotDefined<Std::detected_t<Fallback, Args...> >(std::declval<const Std::detected_t<TargetType, Args...>*>())),
251  TargetType, Args...>;
252 
253 
254 } // namespace Dune
255 
256 #endif // #ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
typename detected_or< nonesuch, Op, Args... >::value_t is_detected
Detects whether Op<Args...> is valid.
Definition: type_traits.hh:141
void operator=(const nonesuch &)=delete
Type representing a lookup failure by std::detected_or and friends.
Definition: type_traits.hh:84
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:185
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
Dune namespace
Definition: alignedallocator.hh:12
Utilities for type computations, constraining overloads, ...
typename detected_or< nonesuch, Op, Args... >::type detected_t
Returns Op<Args...> if that is valid; otherwise returns nonesuch.
Definition: type_traits.hh:170
Std::detected_or_t< decltype(detail::warningIfNotDefined< Std::detected_t< Fallback, Args... > >(std::declval< const Std::detected_t< TargetType, Args... > * >())), TargetType, Args... > detected_or_fallback_t
This type will be either TargetType<Args...> if it exists, or the Fallback<Args...> type.
Definition: type_traits.hh:251
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...> is invalid.
Definition: type_traits.hh:217
STL namespace.
Traits for type conversions and type information.
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:195
Impl::detector< Default, void, Op, Args... > detected_or
Detects whether Op<Args...> is valid and makes the result available.
Definition: type_traits.hh:128