Dune Core Modules (2.7.1)

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
14namespace Dune
15{
16
18
27namespace 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>
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>
211 decltype(Impl::is_callable_helper<void, F, Args...>(PriorityTag<42>()))
212 {};
213
229 template <class R, class F, class... Args>
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 >
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 >
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 // negation
493 // --------
494
502 template<class B>
503 struct negation : public bool_constant<!static_cast<bool>(B::value)>
504 {};
505
506} // namespace Std
507
508} // namespace Dune
509
510#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:40
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:14
Helper class for tagging priorities.
Definition: typeutilities.hh:85
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
forms the logical negation of the type traits B...
Definition: type_traits.hh:504
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.111.3 (Nov 12, 23:30, 2024)