]>
Commit | Line | Data |
---|---|---|
92f5a8d4 | 1 | /* Says how to convert value, error and exception types |
f67539c2 | 2 | (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (12 commits) |
92f5a8d4 TL |
3 | File Created: Nov 2017 |
4 | ||
5 | ||
6 | Boost Software License - Version 1.0 - August 17th, 2003 | |
7 | ||
8 | Permission is hereby granted, free of charge, to any person or organization | |
9 | obtaining a copy of the software and accompanying documentation covered by | |
10 | this license (the "Software") to use, reproduce, display, distribute, | |
11 | execute, and transmit the Software, and to prepare derivative works of the | |
12 | Software, and to permit third-parties to whom the Software is furnished to | |
13 | do so, all subject to the following: | |
14 | ||
15 | The copyright notices in the Software and this entire statement, including | |
16 | the above license grant, this restriction and the following disclaimer, | |
17 | must be included in all copies of the Software, in whole or in part, and | |
18 | all derivative works of the Software, unless such copies or derivative | |
19 | works are solely in the form of machine-executable object code generated by | |
20 | a source language processor. | |
21 | ||
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
24 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT | |
25 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE | |
26 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, | |
27 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
28 | DEALINGS IN THE SOFTWARE. | |
29 | */ | |
30 | ||
31 | #ifndef BOOST_OUTCOME_CONVERT_HPP | |
32 | #define BOOST_OUTCOME_CONVERT_HPP | |
33 | ||
34 | #include "detail/basic_result_storage.hpp" | |
35 | ||
36 | BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN | |
37 | ||
20effc67 | 38 | namespace concepts |
92f5a8d4 TL |
39 | { |
40 | #if defined(__cpp_concepts) | |
20effc67 | 41 | #if !defined(_MSC_VER) && !defined(__clang__) && (__GNUC__ < 9 || __cplusplus < 202000L) |
92f5a8d4 TL |
42 | #define BOOST_OUTCOME_GCC6_CONCEPT_BOOL bool |
43 | #else | |
44 | #define BOOST_OUTCOME_GCC6_CONCEPT_BOOL | |
45 | #endif | |
46 | namespace detail | |
47 | { | |
48 | template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL SameHelper = std::is_same<T, U>::value; | |
49 | template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL same_as = detail::SameHelper<T, U> &&detail::SameHelper<U, T>; | |
20effc67 TL |
50 | template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL convertible = std::is_convertible<T, U>::value; |
51 | template <class T, class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL base_of = std::is_base_of<T, U>::value; | |
92f5a8d4 TL |
52 | } // namespace detail |
53 | ||
54 | ||
20effc67 | 55 | /* The `value_or_none` concept. |
92f5a8d4 TL |
56 | \requires That `U::value_type` exists and that `std::declval<U>().has_value()` returns a `bool` and `std::declval<U>().value()` exists. |
57 | */ | |
20effc67 | 58 | template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL value_or_none = requires(U a) |
92f5a8d4 TL |
59 | { |
60 | { | |
61 | a.has_value() | |
62 | } | |
63 | ->detail::same_as<bool>; | |
64 | {a.value()}; | |
65 | }; | |
20effc67 | 66 | /* The `value_or_error` concept. |
92f5a8d4 TL |
67 | \requires That `U::value_type` and `U::error_type` exist; |
68 | that `std::declval<U>().has_value()` returns a `bool`, `std::declval<U>().value()` and `std::declval<U>().error()` exists. | |
69 | */ | |
20effc67 | 70 | template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL value_or_error = requires(U a) |
92f5a8d4 TL |
71 | { |
72 | { | |
73 | a.has_value() | |
74 | } | |
75 | ->detail::same_as<bool>; | |
76 | {a.value()}; | |
77 | {a.error()}; | |
78 | }; | |
20effc67 | 79 | |
92f5a8d4 TL |
80 | #else |
81 | namespace detail | |
82 | { | |
83 | struct no_match | |
84 | { | |
85 | }; | |
86 | inline no_match match_value_or_none(...); | |
87 | inline no_match match_value_or_error(...); | |
88 | BOOST_OUTCOME_TEMPLATE(class U) | |
89 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<U>().has_value()), BOOST_OUTCOME_TEXPR(std::declval<U>().value())) | |
90 | inline U match_value_or_none(U &&); | |
91 | BOOST_OUTCOME_TEMPLATE(class U) | |
92 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<U>().has_value()), BOOST_OUTCOME_TEXPR(std::declval<U>().value()), BOOST_OUTCOME_TEXPR(std::declval<U>().error())) | |
93 | inline U match_value_or_error(U &&); | |
94 | ||
20effc67 TL |
95 | template <class U> |
96 | static constexpr bool value_or_none = | |
97 | !std::is_same<no_match, decltype(match_value_or_none(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value; | |
98 | template <class U> | |
99 | static constexpr bool value_or_error = | |
100 | !std::is_same<no_match, decltype(match_value_or_error(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value; | |
92f5a8d4 | 101 | } // namespace detail |
20effc67 | 102 | /* The `value_or_none` concept. |
92f5a8d4 TL |
103 | \requires That `U::value_type` exists and that `std::declval<U>().has_value()` returns a `bool` and `std::declval<U>().value()` exists. |
104 | */ | |
20effc67 TL |
105 | template <class U> static constexpr bool value_or_none = detail::value_or_none<U>; |
106 | /* The `value_or_error` concept. | |
92f5a8d4 TL |
107 | \requires That `U::value_type` and `U::error_type` exist; |
108 | that `std::declval<U>().has_value()` returns a `bool`, `std::declval<U>().value()` and `std::declval<U>().error()` exists. | |
109 | */ | |
20effc67 TL |
110 | template <class U> static constexpr bool value_or_error = detail::value_or_error<U>; |
111 | #endif | |
112 | } // namespace concepts | |
113 | ||
114 | namespace convert | |
115 | { | |
116 | #if BOOST_OUTCOME_ENABLE_LEGACY_SUPPORT_FOR < 220 | |
117 | #if defined(__cpp_concepts) | |
118 | template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL ValueOrNone = concepts::value_or_none<U>; | |
119 | template <class U> concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL ValueOrError = concepts::value_or_error<U>; | |
120 | #else | |
121 | template <class U> static constexpr bool ValueOrNone = concepts::value_or_none<U>; | |
122 | template <class U> static constexpr bool ValueOrError = concepts::value_or_error<U>; | |
123 | #endif | |
92f5a8d4 TL |
124 | #endif |
125 | ||
126 | namespace detail | |
127 | { | |
128 | template <class T, class X> struct make_type | |
129 | { | |
130 | template <class U> static constexpr T value(U &&v) { return T{in_place_type<typename T::value_type>, static_cast<U &&>(v).value()}; } | |
131 | template <class U> static constexpr T error(U &&v) { return T{in_place_type<typename T::error_type>, static_cast<U &&>(v).error()}; } | |
132 | static constexpr T error() { return T{in_place_type<typename T::error_type>}; } | |
133 | }; | |
134 | template <class T> struct make_type<T, void> | |
135 | { | |
136 | template <class U> static constexpr T value(U && /*unused*/) { return T{in_place_type<typename T::value_type>}; } | |
137 | template <class U> static constexpr T error(U && /*unused*/) { return T{in_place_type<typename T::error_type>}; } | |
138 | static constexpr T error() { return T{in_place_type<typename T::error_type>}; } | |
139 | }; | |
140 | } // namespace detail | |
141 | ||
142 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
143 | type definition value_or_error. Potential doc page: NOT FOUND | |
144 | */ | |
145 | template <class T, class U> struct value_or_error | |
146 | { | |
147 | static constexpr bool enable_result_inputs = false; | |
148 | static constexpr bool enable_outcome_inputs = false; | |
149 | BOOST_OUTCOME_TEMPLATE(class X) | |
20effc67 TL |
150 | BOOST_OUTCOME_TREQUIRES( |
151 | BOOST_OUTCOME_TPRED(std::is_same<U, std::decay_t<X>>::value // | |
152 | &&concepts::value_or_error<U> // | |
153 | && (std::is_void<typename std::decay_t<X>::value_type>::value || | |
154 | BOOST_OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::value_type, typename std::decay_t<X>::value_type>) // | |
155 | &&(std::is_void<typename std::decay_t<X>::error_type>::value || | |
156 | BOOST_OUTCOME_V2_NAMESPACE::detail::is_explicitly_constructible<typename T::error_type, typename std::decay_t<X>::error_type>) )) | |
157 | constexpr T operator()(X &&v) | |
158 | { | |
159 | return v.has_value() ? detail::make_type<T, typename T::value_type>::value(static_cast<X &&>(v)) : | |
160 | detail::make_type<T, typename U::error_type>::error(static_cast<X &&>(v)); | |
161 | } | |
92f5a8d4 TL |
162 | }; |
163 | } // namespace convert | |
164 | ||
165 | BOOST_OUTCOME_V2_NAMESPACE_END | |
166 | ||
167 | #endif |