]>
Commit | Line | Data |
---|---|---|
92f5a8d4 | 1 | /* A less simple result type |
1e59de90 | 2 | (C) 2017-2022 Niall Douglas <http://www.nedproductions.biz/> (20 commits) |
92f5a8d4 TL |
3 | File Created: June 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_BASIC_OUTCOME_HPP | |
32 | #define BOOST_OUTCOME_BASIC_OUTCOME_HPP | |
33 | ||
34 | #include "config.hpp" | |
35 | ||
36 | #include "basic_result.hpp" | |
37 | #include "detail/basic_outcome_exception_observers.hpp" | |
38 | #include "detail/basic_outcome_failure_observers.hpp" | |
39 | ||
40 | #ifdef __clang__ | |
41 | #pragma clang diagnostic push | |
42 | #pragma clang diagnostic ignored "-Wdocumentation" // Standardese markup confuses clang | |
43 | #endif | |
44 | ||
45 | BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN | |
46 | ||
f67539c2 | 47 | template <class R, class S, class P, class NoValuePolicy> // |
92f5a8d4 TL |
48 | class basic_outcome; |
49 | ||
50 | namespace detail | |
51 | { | |
52 | // May be reused by basic_outcome subclasses to save load on the compiler | |
53 | template <class value_type, class error_type, class exception_type> struct outcome_predicates | |
54 | { | |
55 | using result = result_predicates<value_type, error_type>; | |
56 | ||
57 | // Predicate for the implicit constructors to be available | |
58 | static constexpr bool implicit_constructors_enabled = // | |
59 | result::implicit_constructors_enabled // | |
60 | && !detail::is_implicitly_constructible<value_type, exception_type> // | |
61 | && !detail::is_implicitly_constructible<error_type, exception_type> // | |
62 | && !detail::is_implicitly_constructible<exception_type, value_type> // | |
63 | && !detail::is_implicitly_constructible<exception_type, error_type>; | |
64 | ||
65 | // Predicate for the value converting constructor to be available. | |
66 | template <class T> | |
67 | static constexpr bool enable_value_converting_constructor = // | |
68 | implicit_constructors_enabled // | |
69 | &&result::template enable_value_converting_constructor<T> // | |
70 | && !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition | |
71 | ||
72 | // Predicate for the error converting constructor to be available. | |
73 | template <class T> | |
74 | static constexpr bool enable_error_converting_constructor = // | |
75 | implicit_constructors_enabled // | |
76 | &&result::template enable_error_converting_constructor<T> // | |
77 | && !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition | |
78 | ||
79 | // Predicate for the error condition converting constructor to be available. | |
80 | template <class ErrorCondEnum> | |
81 | static constexpr bool enable_error_condition_converting_constructor = result::template enable_error_condition_converting_constructor<ErrorCondEnum> // | |
82 | && !detail::is_implicitly_constructible<exception_type, ErrorCondEnum>; | |
83 | ||
84 | // Predicate for the exception converting constructor to be available. | |
85 | template <class T> | |
86 | static constexpr bool enable_exception_converting_constructor = // | |
87 | implicit_constructors_enabled // | |
88 | && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction | |
f67539c2 TL |
89 | && !detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T> && |
90 | detail::is_implicitly_constructible<exception_type, T>; | |
92f5a8d4 TL |
91 | |
92 | // Predicate for the error + exception converting constructor to be available. | |
93 | template <class T, class U> | |
94 | static constexpr bool enable_error_exception_converting_constructor = // | |
95 | implicit_constructors_enabled // | |
96 | && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction | |
97 | && !detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T> // | |
98 | && !detail::is_implicitly_constructible<value_type, U> && detail::is_implicitly_constructible<exception_type, U>; | |
99 | ||
100 | // Predicate for the converting copy constructor from a compatible outcome to be available. | |
101 | template <class T, class U, class V, class W> | |
f67539c2 TL |
102 | static constexpr bool enable_compatible_conversion = // |
103 | (std::is_void<T>::value || | |
104 | detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // if our value types are constructible | |
105 | &&(std::is_void<U>::value || | |
106 | detail::is_explicitly_constructible<error_type, typename basic_outcome<T, U, V, W>::error_type>) // if our error types are constructible | |
107 | &&(std::is_void<V>::value || | |
108 | detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>) // if our exception types are constructible | |
92f5a8d4 TL |
109 | ; |
110 | ||
111 | // Predicate for the converting constructor from a make_error_code() of the input to be available. | |
112 | template <class T, class U, class V, class W> | |
f67539c2 TL |
113 | static constexpr bool enable_make_error_code_compatible_conversion = // |
114 | trait::is_error_code_available<std::decay_t<error_type>>::value // if error type has an error code | |
115 | && !enable_compatible_conversion<T, U, V, W> // and the normal compatible conversion is not available | |
116 | && (std::is_void<T>::value || | |
117 | detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // and if our value types are constructible | |
118 | &&detail::is_explicitly_constructible<error_type, | |
119 | typename trait::is_error_code_available<U>::type> // and our error type is constructible from a make_error_code() | |
120 | && (std::is_void<V>::value || | |
121 | detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>); // and our exception types are constructible | |
92f5a8d4 TL |
122 | |
123 | // Predicate for the implicit converting inplace constructor from a compatible input to be available. | |
124 | struct disable_inplace_value_error_exception_constructor; | |
125 | template <class... Args> | |
f67539c2 | 126 | using choose_inplace_value_error_exception_constructor = std::conditional_t< // |
20effc67 TL |
127 | ((static_cast<int>(detail::is_constructible<value_type, Args...>) + static_cast<int>(detail::is_constructible<error_type, Args...>) + |
128 | static_cast<int>(detail::is_constructible<exception_type, Args...>)) > 1), // | |
129 | disable_inplace_value_error_exception_constructor, // | |
130 | std::conditional_t< // | |
131 | detail::is_constructible<value_type, Args...>, // | |
132 | value_type, // | |
133 | std::conditional_t< // | |
134 | detail::is_constructible<error_type, Args...>, // | |
135 | error_type, // | |
136 | std::conditional_t< // | |
137 | detail::is_constructible<exception_type, Args...>, // | |
138 | exception_type, // | |
92f5a8d4 TL |
139 | disable_inplace_value_error_exception_constructor>>>>; |
140 | template <class... Args> | |
141 | static constexpr bool enable_inplace_value_error_exception_constructor = // | |
f67539c2 TL |
142 | implicit_constructors_enabled && |
143 | !std::is_same<choose_inplace_value_error_exception_constructor<Args...>, disable_inplace_value_error_exception_constructor>::value; | |
92f5a8d4 TL |
144 | }; |
145 | ||
146 | // Select whether to use basic_outcome_failure_observers or not | |
147 | template <class Base, class R, class S, class P, class NoValuePolicy> | |
148 | using select_basic_outcome_failure_observers = // | |
f67539c2 TL |
149 | std::conditional_t<trait::is_error_code_available<S>::value && trait::is_exception_ptr_available<P>::value, |
150 | basic_outcome_failure_observers<Base, R, S, P, NoValuePolicy>, Base>; | |
92f5a8d4 TL |
151 | |
152 | template <class T, class U, class V> constexpr inline const V &extract_exception_from_failure(const failure_type<U, V> &v) { return v.exception(); } | |
f67539c2 TL |
153 | template <class T, class U, class V> constexpr inline V &&extract_exception_from_failure(failure_type<U, V> &&v) |
154 | { | |
155 | return static_cast<failure_type<U, V> &&>(v).exception(); | |
156 | } | |
92f5a8d4 | 157 | template <class T, class U> constexpr inline const U &extract_exception_from_failure(const failure_type<U, void> &v) { return v.error(); } |
f67539c2 TL |
158 | template <class T, class U> constexpr inline U &&extract_exception_from_failure(failure_type<U, void> &&v) |
159 | { | |
160 | return static_cast<failure_type<U, void> &&>(v).error(); | |
161 | } | |
92f5a8d4 TL |
162 | |
163 | template <class T> struct is_basic_outcome | |
164 | { | |
165 | static constexpr bool value = false; | |
166 | }; | |
167 | template <class R, class S, class T, class N> struct is_basic_outcome<basic_outcome<R, S, T, N>> | |
168 | { | |
169 | static constexpr bool value = true; | |
170 | }; | |
171 | } // namespace detail | |
172 | ||
173 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
174 | type alias template <class T> is_basic_outcome. Potential doc page: `is_basic_outcome<T>` | |
175 | */ | |
176 | template <class T> using is_basic_outcome = detail::is_basic_outcome<std::decay_t<T>>; | |
177 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
178 | SIGNATURE NOT RECOGNISED | |
179 | */ | |
180 | template <class T> static constexpr bool is_basic_outcome_v = detail::is_basic_outcome<std::decay_t<T>>::value; | |
181 | ||
20effc67 TL |
182 | namespace concepts |
183 | { | |
184 | #if defined(__cpp_concepts) | |
185 | /* The `basic_outcome` concept. | |
186 | \requires That `U` matches a `basic_outcome`. | |
187 | */ | |
188 | template <class U> | |
189 | concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL basic_outcome = | |
190 | BOOST_OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value || | |
191 | (requires(U v) { | |
192 | BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>(v); | |
193 | } && // | |
194 | detail::convertible< | |
195 | U, BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>> && // | |
196 | detail::base_of< | |
197 | BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<typename U::value_type, typename U::error_type, typename U::exception_type, typename U::no_value_policy_type>, U>); | |
198 | #else | |
199 | namespace detail | |
200 | { | |
201 | inline no_match match_basic_outcome(...); | |
202 | template <class R, class S, class P, class NVP, class T, // | |
203 | typename = typename T::value_type, // | |
204 | typename = typename T::error_type, // | |
205 | typename = typename T::exception_type, // | |
206 | typename = typename T::no_value_policy_type, // | |
207 | typename std::enable_if_t<std::is_convertible<T, BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>>::value && // | |
208 | std::is_base_of<BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP>, T>::value, | |
209 | bool> = true> | |
210 | inline BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> match_basic_outcome(BOOST_OUTCOME_V2_NAMESPACE::basic_outcome<R, S, P, NVP> &&, T &&); | |
211 | ||
212 | template <class U> | |
213 | static constexpr bool basic_outcome = | |
214 | BOOST_OUTCOME_V2_NAMESPACE::is_basic_outcome<U>::value || | |
215 | !std::is_same<no_match, decltype(match_basic_outcome(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>(), | |
216 | std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value; | |
217 | } // namespace detail | |
218 | /* The `basic_outcome` concept. | |
219 | \requires That `U` matches a `basic_outcome`. | |
220 | */ | |
221 | template <class U> static constexpr bool basic_outcome = detail::basic_outcome<U>; | |
222 | #endif | |
223 | } // namespace concepts | |
224 | ||
92f5a8d4 TL |
225 | namespace hooks |
226 | { | |
227 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
228 | SIGNATURE NOT RECOGNISED | |
92f5a8d4 | 229 | */ |
f67539c2 TL |
230 | template <class R, class S, class P, class NoValuePolicy, class U> |
231 | constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept; | |
92f5a8d4 TL |
232 | } // namespace hooks |
233 | ||
234 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
235 | type definition template <class R, class S, class P, class NoValuePolicy> basic_outcome. Potential doc page: `basic_outcome<T, EC, EP, NoValuePolicy>` | |
236 | */ | |
f67539c2 | 237 | template <class R, class S, class P, class NoValuePolicy> // |
92f5a8d4 TL |
238 | class BOOST_OUTCOME_NODISCARD basic_outcome |
239 | #if defined(BOOST_OUTCOME_DOXYGEN_IS_IN_THE_HOUSE) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE) | |
240 | : public detail::basic_outcome_failure_observers<detail::basic_result_final<R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>, | |
241 | public detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, | |
242 | public detail::basic_result_final<R, S, NoValuePolicy> | |
243 | #else | |
f67539c2 TL |
244 | : public detail::select_basic_outcome_failure_observers< |
245 | detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy> | |
92f5a8d4 TL |
246 | #endif |
247 | { | |
248 | static_assert(trait::type_can_be_used_in_basic_result<P>, "The exception_type cannot be used"); | |
249 | static_assert(std::is_void<P>::value || std::is_default_constructible<P>::value, "exception_type must be void or default constructible"); | |
f67539c2 TL |
250 | using base = detail::select_basic_outcome_failure_observers< |
251 | detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>; | |
92f5a8d4 | 252 | friend struct policy::base; |
f67539c2 | 253 | template <class T, class U, class V, class W> // |
92f5a8d4 | 254 | friend class basic_outcome; |
f67539c2 TL |
255 | template <class T, class U, class V, class W, class X> |
256 | friend constexpr inline void hooks::override_outcome_exception(basic_outcome<T, U, V, W> *o, X &&v) noexcept; // NOLINT | |
92f5a8d4 TL |
257 | |
258 | struct implicit_constructors_disabled_tag | |
259 | { | |
260 | }; | |
261 | struct value_converting_constructor_tag | |
262 | { | |
263 | }; | |
264 | struct error_converting_constructor_tag | |
265 | { | |
266 | }; | |
267 | struct error_condition_converting_constructor_tag | |
268 | { | |
269 | }; | |
270 | struct exception_converting_constructor_tag | |
271 | { | |
272 | }; | |
273 | struct error_exception_converting_constructor_tag | |
274 | { | |
275 | }; | |
276 | struct explicit_valueorerror_converting_constructor_tag | |
277 | { | |
278 | }; | |
279 | struct explicit_compatible_copy_conversion_tag | |
280 | { | |
281 | }; | |
282 | struct explicit_compatible_move_conversion_tag | |
283 | { | |
284 | }; | |
285 | struct explicit_make_error_code_compatible_copy_conversion_tag | |
286 | { | |
287 | }; | |
288 | struct explicit_make_error_code_compatible_move_conversion_tag | |
289 | { | |
290 | }; | |
291 | struct error_failure_tag | |
292 | { | |
293 | }; | |
294 | struct exception_failure_tag | |
295 | { | |
296 | }; | |
297 | ||
298 | struct disable_in_place_value_type | |
299 | { | |
300 | }; | |
301 | struct disable_in_place_error_type | |
302 | { | |
303 | }; | |
304 | struct disable_in_place_exception_type | |
305 | { | |
306 | }; | |
307 | ||
308 | public: | |
309 | using value_type = R; | |
310 | using error_type = S; | |
311 | using exception_type = P; | |
20effc67 | 312 | using no_value_policy_type = NoValuePolicy; |
92f5a8d4 TL |
313 | |
314 | template <class T, class U = S, class V = P, class W = NoValuePolicy> using rebind = basic_outcome<T, U, V, W>; | |
315 | ||
316 | protected: | |
317 | // Requirement predicates for outcome. | |
318 | struct predicate | |
319 | { | |
320 | using base = detail::outcome_predicates<value_type, error_type, exception_type>; | |
321 | ||
322 | // Predicate for any constructors to be available at all | |
f67539c2 TL |
323 | static constexpr bool constructors_enabled = |
324 | (!std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value || (std::is_void<value_type>::value && std::is_void<error_type>::value)) // | |
325 | && (!std::is_same<std::decay_t<value_type>, std::decay_t<exception_type>>::value || | |
326 | (std::is_void<value_type>::value && std::is_void<exception_type>::value)) // | |
327 | && (!std::is_same<std::decay_t<error_type>, std::decay_t<exception_type>>::value || | |
328 | (std::is_void<error_type>::value && std::is_void<exception_type>::value)) // | |
92f5a8d4 TL |
329 | ; |
330 | ||
331 | // Predicate for implicit constructors to be available at all | |
332 | static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled; | |
333 | ||
334 | // Predicate for the value converting constructor to be available. | |
335 | template <class T> | |
336 | static constexpr bool enable_value_converting_constructor = // | |
337 | constructors_enabled // | |
338 | && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type | |
339 | && base::template enable_value_converting_constructor<T>; | |
340 | ||
341 | // Predicate for the error converting constructor to be available. | |
342 | template <class T> | |
343 | static constexpr bool enable_error_converting_constructor = // | |
344 | constructors_enabled // | |
345 | && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type | |
346 | && base::template enable_error_converting_constructor<T>; | |
347 | ||
348 | // Predicate for the error condition converting constructor to be available. | |
349 | template <class ErrorCondEnum> | |
350 | static constexpr bool enable_error_condition_converting_constructor = // | |
351 | constructors_enabled // | |
352 | && !std::is_same<std::decay_t<ErrorCondEnum>, basic_outcome>::value // not my type | |
353 | && base::template enable_error_condition_converting_constructor<ErrorCondEnum>; | |
354 | ||
355 | // Predicate for the exception converting constructor to be available. | |
356 | template <class T> | |
357 | static constexpr bool enable_exception_converting_constructor = // | |
358 | constructors_enabled // | |
359 | && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type | |
360 | && base::template enable_exception_converting_constructor<T>; | |
361 | ||
362 | // Predicate for the error + exception converting constructor to be available. | |
363 | template <class T, class U> | |
364 | static constexpr bool enable_error_exception_converting_constructor = // | |
365 | constructors_enabled // | |
366 | && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type | |
367 | && base::template enable_error_exception_converting_constructor<T, U>; | |
368 | ||
369 | // Predicate for the converting constructor from a compatible input to be available. | |
370 | template <class T, class U, class V, class W> | |
371 | static constexpr bool enable_compatible_conversion = // | |
372 | constructors_enabled // | |
373 | && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type | |
374 | && base::template enable_compatible_conversion<T, U, V, W>; | |
375 | ||
376 | // Predicate for the converting constructor from a make_error_code() of the input to be available. | |
377 | template <class T, class U, class V, class W> | |
378 | static constexpr bool enable_make_error_code_compatible_conversion = // | |
379 | constructors_enabled // | |
380 | && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type | |
381 | && base::template enable_make_error_code_compatible_conversion<T, U, V, W>; | |
382 | ||
383 | // Predicate for the inplace construction of value to be available. | |
384 | template <class... Args> | |
385 | static constexpr bool enable_inplace_value_constructor = // | |
386 | constructors_enabled // | |
387 | && (std::is_void<value_type>::value // | |
20effc67 | 388 | || detail::is_constructible<value_type, Args...>); |
92f5a8d4 TL |
389 | |
390 | // Predicate for the inplace construction of error to be available. | |
391 | template <class... Args> | |
392 | static constexpr bool enable_inplace_error_constructor = // | |
393 | constructors_enabled // | |
394 | && (std::is_void<error_type>::value // | |
20effc67 | 395 | || detail::is_constructible<error_type, Args...>); |
92f5a8d4 TL |
396 | |
397 | // Predicate for the inplace construction of exception to be available. | |
398 | template <class... Args> | |
399 | static constexpr bool enable_inplace_exception_constructor = // | |
400 | constructors_enabled // | |
401 | && (std::is_void<exception_type>::value // | |
20effc67 | 402 | || detail::is_constructible<exception_type, Args...>); |
92f5a8d4 TL |
403 | |
404 | // Predicate for the implicit converting inplace constructor to be available. | |
405 | template <class... Args> | |
406 | static constexpr bool enable_inplace_value_error_exception_constructor = // | |
407 | constructors_enabled // | |
408 | &&base::template enable_inplace_value_error_exception_constructor<Args...>; | |
f67539c2 TL |
409 | template <class... Args> |
410 | using choose_inplace_value_error_exception_constructor = typename base::template choose_inplace_value_error_exception_constructor<Args...>; | |
92f5a8d4 TL |
411 | }; |
412 | ||
413 | public: | |
f67539c2 TL |
414 | using value_type_if_enabled = |
415 | std::conditional_t<std::is_same<value_type, error_type>::value || std::is_same<value_type, exception_type>::value, disable_in_place_value_type, value_type>; | |
416 | using error_type_if_enabled = | |
417 | std::conditional_t<std::is_same<error_type, value_type>::value || std::is_same<error_type, exception_type>::value, disable_in_place_error_type, error_type>; | |
418 | using exception_type_if_enabled = std::conditional_t<std::is_same<exception_type, value_type>::value || std::is_same<exception_type, error_type>::value, | |
419 | disable_in_place_exception_type, exception_type>; | |
92f5a8d4 TL |
420 | |
421 | protected: | |
422 | detail::devoid<exception_type> _ptr; | |
423 | ||
424 | public: | |
425 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
426 | SIGNATURE NOT RECOGNISED | |
427 | */ | |
428 | BOOST_OUTCOME_TEMPLATE(class Arg, class... Args) | |
429 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((!predicate::constructors_enabled && sizeof...(Args) >= 0))) | |
430 | basic_outcome(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_outcome<> with any of the same type is NOT SUPPORTED, see docs! | |
431 | ||
432 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
433 | SIGNATURE NOT RECOGNISED | |
434 | */ | |
435 | BOOST_OUTCOME_TEMPLATE(class T) | |
436 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled // | |
f67539c2 TL |
437 | && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T> || |
438 | detail::is_implicitly_constructible<exception_type, T>) ))) | |
439 | basic_outcome(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) = | |
440 | delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs! | |
92f5a8d4 TL |
441 | |
442 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
443 | SIGNATURE NOT RECOGNISED | |
444 | */ | |
445 | BOOST_OUTCOME_TEMPLATE(class T) | |
446 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>)) | |
f67539c2 | 447 | constexpr basic_outcome(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept( |
20effc67 | 448 | detail::is_nothrow_constructible<value_type, T>) // NOLINT |
92f5a8d4 TL |
449 | : base{in_place_type<typename base::_value_type>, static_cast<T &&>(t)} |
450 | , _ptr() | |
451 | { | |
1e59de90 | 452 | no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t)); |
92f5a8d4 TL |
453 | } |
454 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
455 | SIGNATURE NOT RECOGNISED | |
456 | */ | |
457 | BOOST_OUTCOME_TEMPLATE(class T) | |
458 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>)) | |
f67539c2 | 459 | constexpr basic_outcome(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept( |
20effc67 | 460 | detail::is_nothrow_constructible<error_type, T>) // NOLINT |
92f5a8d4 TL |
461 | : base{in_place_type<typename base::_error_type>, static_cast<T &&>(t)} |
462 | , _ptr() | |
463 | { | |
1e59de90 | 464 | no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t)); |
92f5a8d4 TL |
465 | } |
466 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
467 | SIGNATURE NOT RECOGNISED | |
468 | */ | |
469 | BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum) | |
470 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), // | |
471 | BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>)) | |
f67539c2 TL |
472 | constexpr basic_outcome(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept( |
473 | noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT | |
92f5a8d4 TL |
474 | : base{in_place_type<typename base::_error_type>, make_error_code(t)} |
475 | { | |
1e59de90 | 476 | no_value_policy_type::on_outcome_construction(this, static_cast<ErrorCondEnum &&>(t)); |
92f5a8d4 TL |
477 | } |
478 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
479 | SIGNATURE NOT RECOGNISED | |
480 | */ | |
481 | BOOST_OUTCOME_TEMPLATE(class T) | |
482 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_exception_converting_constructor<T>)) | |
f67539c2 | 483 | constexpr basic_outcome(T &&t, exception_converting_constructor_tag /*unused*/ = exception_converting_constructor_tag()) noexcept( |
20effc67 | 484 | detail::is_nothrow_constructible<exception_type, T>) // NOLINT |
92f5a8d4 TL |
485 | : base() |
486 | , _ptr(static_cast<T &&>(t)) | |
487 | { | |
f67539c2 | 488 | this->_state._status.set_have_exception(true); |
1e59de90 | 489 | no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(t)); |
92f5a8d4 TL |
490 | } |
491 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
492 | SIGNATURE NOT RECOGNISED | |
493 | */ | |
494 | BOOST_OUTCOME_TEMPLATE(class T, class U) | |
495 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_exception_converting_constructor<T, U>)) | |
f67539c2 | 496 | constexpr basic_outcome(T &&a, U &&b, error_exception_converting_constructor_tag /*unused*/ = error_exception_converting_constructor_tag()) noexcept( |
20effc67 | 497 | detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT |
92f5a8d4 TL |
498 | : base{in_place_type<typename base::_error_type>, static_cast<T &&>(a)} |
499 | , _ptr(static_cast<U &&>(b)) | |
500 | { | |
f67539c2 | 501 | this->_state._status.set_have_exception(true); |
1e59de90 | 502 | no_value_policy_type::on_outcome_construction(this, static_cast<T &&>(a), static_cast<U &&>(b)); |
92f5a8d4 TL |
503 | } |
504 | ||
505 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
506 | SIGNATURE NOT RECOGNISED | |
507 | */ | |
508 | BOOST_OUTCOME_TEMPLATE(class T) | |
20effc67 TL |
509 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>), // |
510 | BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_outcome_inputs || !concepts::basic_outcome<T>), // | |
92f5a8d4 | 511 | BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_outcome, std::decay_t<T>>{}(std::declval<T>()))) |
f67539c2 TL |
512 | constexpr explicit basic_outcome(T &&o, |
513 | explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT | |
92f5a8d4 TL |
514 | : basic_outcome{convert::value_or_error<basic_outcome, std::decay_t<T>>{}(static_cast<T &&>(o))} |
515 | { | |
516 | } | |
517 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
518 | SIGNATURE NOT RECOGNISED | |
519 | */ | |
520 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) | |
521 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>)) | |
f67539c2 TL |
522 | constexpr explicit basic_outcome( |
523 | const basic_outcome<T, U, V, W> &o, | |
524 | explicit_compatible_copy_conversion_tag /*unused*/ = | |
20effc67 TL |
525 | explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> |
526 | &&detail::is_nothrow_constructible<exception_type, V>) | |
92f5a8d4 TL |
527 | : base{typename base::compatible_conversion_tag(), o} |
528 | , _ptr(o._ptr) | |
529 | { | |
1e59de90 | 530 | no_value_policy_type::on_outcome_copy_construction(this, o); |
92f5a8d4 TL |
531 | } |
532 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
533 | SIGNATURE NOT RECOGNISED | |
534 | */ | |
535 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) | |
536 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>)) | |
f67539c2 TL |
537 | constexpr explicit basic_outcome( |
538 | basic_outcome<T, U, V, W> &&o, | |
539 | explicit_compatible_move_conversion_tag /*unused*/ = | |
20effc67 TL |
540 | explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> |
541 | &&detail::is_nothrow_constructible<exception_type, V>) | |
92f5a8d4 TL |
542 | : base{typename base::compatible_conversion_tag(), static_cast<basic_outcome<T, U, V, W> &&>(o)} |
543 | , _ptr(static_cast<typename basic_outcome<T, U, V, W>::exception_type &&>(o._ptr)) | |
544 | { | |
1e59de90 | 545 | no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_outcome<T, U, V, W> &&>(o)); |
92f5a8d4 TL |
546 | } |
547 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
548 | SIGNATURE NOT RECOGNISED | |
549 | */ | |
550 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V) | |
551 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>)) | |
f67539c2 TL |
552 | constexpr explicit basic_outcome( |
553 | const basic_result<T, U, V> &o, | |
554 | explicit_compatible_copy_conversion_tag /*unused*/ = | |
20effc67 TL |
555 | explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> |
556 | &&detail::is_nothrow_constructible<exception_type>) | |
92f5a8d4 TL |
557 | : base{typename base::compatible_conversion_tag(), o} |
558 | , _ptr() | |
559 | { | |
1e59de90 | 560 | no_value_policy_type::on_outcome_copy_construction(this, o); |
92f5a8d4 TL |
561 | } |
562 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
563 | SIGNATURE NOT RECOGNISED | |
564 | */ | |
565 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V) | |
566 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>)) | |
f67539c2 TL |
567 | constexpr explicit basic_outcome( |
568 | basic_result<T, U, V> &&o, | |
569 | explicit_compatible_move_conversion_tag /*unused*/ = | |
20effc67 TL |
570 | explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U> |
571 | &&detail::is_nothrow_constructible<exception_type>) | |
92f5a8d4 TL |
572 | : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)} |
573 | , _ptr() | |
574 | { | |
1e59de90 | 575 | no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o)); |
92f5a8d4 TL |
576 | } |
577 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
578 | SIGNATURE NOT RECOGNISED | |
579 | */ | |
580 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V) | |
581 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>)) | |
f67539c2 TL |
582 | constexpr explicit basic_outcome(const basic_result<T, U, V> &o, |
583 | explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ = | |
20effc67 | 584 | explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> |
f67539c2 | 585 | &&noexcept(make_error_code(std::declval<U>())) && |
20effc67 | 586 | detail::is_nothrow_constructible<exception_type>) |
92f5a8d4 TL |
587 | : base{typename base::make_error_code_compatible_conversion_tag(), o} |
588 | , _ptr() | |
589 | { | |
1e59de90 | 590 | no_value_policy_type::on_outcome_copy_construction(this, o); |
92f5a8d4 TL |
591 | } |
592 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
593 | SIGNATURE NOT RECOGNISED | |
594 | */ | |
595 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V) | |
596 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>)) | |
f67539c2 TL |
597 | constexpr explicit basic_outcome(basic_result<T, U, V> &&o, |
598 | explicit_make_error_code_compatible_move_conversion_tag /*unused*/ = | |
20effc67 | 599 | explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> |
f67539c2 | 600 | &&noexcept(make_error_code(std::declval<U>())) && |
20effc67 | 601 | detail::is_nothrow_constructible<exception_type>) |
92f5a8d4 TL |
602 | : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)} |
603 | , _ptr() | |
604 | { | |
1e59de90 | 605 | no_value_policy_type::on_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o)); |
92f5a8d4 TL |
606 | } |
607 | ||
608 | ||
609 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
610 | SIGNATURE NOT RECOGNISED | |
611 | */ | |
612 | BOOST_OUTCOME_TEMPLATE(class... Args) | |
613 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>)) | |
20effc67 | 614 | constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>) |
92f5a8d4 TL |
615 | : base{_, static_cast<Args &&>(args)...} |
616 | , _ptr() | |
617 | { | |
1e59de90 | 618 | no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...); |
92f5a8d4 TL |
619 | } |
620 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
621 | SIGNATURE NOT RECOGNISED | |
622 | */ | |
623 | BOOST_OUTCOME_TEMPLATE(class U, class... Args) | |
624 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>)) | |
f67539c2 | 625 | constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il, |
20effc67 | 626 | Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>) |
92f5a8d4 TL |
627 | : base{_, il, static_cast<Args &&>(args)...} |
628 | , _ptr() | |
629 | { | |
1e59de90 | 630 | no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...); |
92f5a8d4 TL |
631 | } |
632 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
633 | SIGNATURE NOT RECOGNISED | |
634 | */ | |
635 | BOOST_OUTCOME_TEMPLATE(class... Args) | |
636 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>)) | |
20effc67 | 637 | constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, Args...>) |
92f5a8d4 TL |
638 | : base{_, static_cast<Args &&>(args)...} |
639 | , _ptr() | |
640 | { | |
1e59de90 | 641 | no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...); |
92f5a8d4 TL |
642 | } |
643 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
644 | SIGNATURE NOT RECOGNISED | |
645 | */ | |
646 | BOOST_OUTCOME_TEMPLATE(class U, class... Args) | |
647 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>)) | |
f67539c2 | 648 | constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il, |
20effc67 | 649 | Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>) |
92f5a8d4 TL |
650 | : base{_, il, static_cast<Args &&>(args)...} |
651 | , _ptr() | |
652 | { | |
1e59de90 | 653 | no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...); |
92f5a8d4 TL |
654 | } |
655 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
656 | SIGNATURE NOT RECOGNISED | |
657 | */ | |
658 | BOOST_OUTCOME_TEMPLATE(class... Args) | |
659 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<Args...>)) | |
f67539c2 | 660 | constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/, |
20effc67 | 661 | Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, Args...>) |
92f5a8d4 TL |
662 | : base() |
663 | , _ptr(static_cast<Args &&>(args)...) | |
664 | { | |
f67539c2 | 665 | this->_state._status.set_have_exception(true); |
1e59de90 | 666 | no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<exception_type>, static_cast<Args &&>(args)...); |
92f5a8d4 TL |
667 | } |
668 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
669 | SIGNATURE NOT RECOGNISED | |
670 | */ | |
671 | BOOST_OUTCOME_TEMPLATE(class U, class... Args) | |
672 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<std::initializer_list<U>, Args...>)) | |
f67539c2 | 673 | constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/, std::initializer_list<U> il, |
20effc67 | 674 | Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, std::initializer_list<U>, Args...>) |
92f5a8d4 TL |
675 | : base() |
676 | , _ptr(il, static_cast<Args &&>(args)...) | |
677 | { | |
f67539c2 | 678 | this->_state._status.set_have_exception(true); |
1e59de90 | 679 | no_value_policy_type::on_outcome_in_place_construction(this, in_place_type<exception_type>, il, static_cast<Args &&>(args)...); |
92f5a8d4 TL |
680 | } |
681 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
682 | SIGNATURE NOT RECOGNISED | |
683 | */ | |
684 | BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args) | |
685 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_exception_constructor<A1, A2, Args...>)) | |
f67539c2 TL |
686 | constexpr basic_outcome(A1 &&a1, A2 &&a2, Args &&... args) noexcept( |
687 | noexcept(typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(), | |
688 | std::declval<Args>()...))) | |
689 | : basic_outcome(in_place_type<typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1), | |
690 | static_cast<A2 &&>(a2), static_cast<Args &&>(args)...) | |
92f5a8d4 TL |
691 | { |
692 | } | |
693 | ||
694 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
695 | SIGNATURE NOT RECOGNISED | |
696 | */ | |
697 | constexpr basic_outcome(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT | |
698 | : base{in_place_type<typename base::_value_type>} | |
699 | { | |
1e59de90 TL |
700 | hooks::set_spare_storage(this, o.spare_storage()); |
701 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
702 | } |
703 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
704 | SIGNATURE NOT RECOGNISED | |
705 | */ | |
706 | BOOST_OUTCOME_TEMPLATE(class T) | |
707 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>)) | |
20effc67 | 708 | constexpr basic_outcome(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT |
92f5a8d4 TL |
709 | : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(o)} |
710 | { | |
1e59de90 TL |
711 | hooks::set_spare_storage(this, o.spare_storage()); |
712 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
713 | } |
714 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
715 | SIGNATURE NOT RECOGNISED | |
716 | */ | |
717 | BOOST_OUTCOME_TEMPLATE(class T) | |
718 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>)) | |
20effc67 | 719 | constexpr basic_outcome(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT |
92f5a8d4 TL |
720 | : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))} |
721 | { | |
1e59de90 TL |
722 | hooks::set_spare_storage(this, o.spare_storage()); |
723 | no_value_policy_type::on_outcome_move_construction(this, static_cast<success_type<T> &&>(o)); | |
92f5a8d4 TL |
724 | } |
725 | ||
726 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
727 | SIGNATURE NOT RECOGNISED | |
728 | */ | |
729 | BOOST_OUTCOME_TEMPLATE(class T) | |
730 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>)) | |
f67539c2 | 731 | constexpr basic_outcome(const failure_type<T> &o, |
20effc67 | 732 | error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT |
92f5a8d4 TL |
733 | : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)} |
734 | , _ptr() | |
735 | { | |
1e59de90 TL |
736 | hooks::set_spare_storage(this, o.spare_storage()); |
737 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
738 | } |
739 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
740 | SIGNATURE NOT RECOGNISED | |
741 | */ | |
742 | BOOST_OUTCOME_TEMPLATE(class T) | |
743 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>)) | |
20effc67 TL |
744 | constexpr basic_outcome(const failure_type<T> &o, |
745 | exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT | |
92f5a8d4 TL |
746 | : base() |
747 | , _ptr(detail::extract_exception_from_failure<exception_type>(o)) | |
748 | { | |
f67539c2 | 749 | this->_state._status.set_have_exception(true); |
1e59de90 TL |
750 | hooks::set_spare_storage(this, o.spare_storage()); |
751 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
752 | } |
753 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
754 | SIGNATURE NOT RECOGNISED | |
755 | */ | |
756 | BOOST_OUTCOME_TEMPLATE(class T) | |
757 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>)) | |
f67539c2 TL |
758 | constexpr basic_outcome(const failure_type<T> &o, |
759 | explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ = | |
760 | explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT | |
92f5a8d4 TL |
761 | : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(o))} |
762 | , _ptr() | |
763 | { | |
1e59de90 TL |
764 | hooks::set_spare_storage(this, o.spare_storage()); |
765 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
766 | } |
767 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
768 | SIGNATURE NOT RECOGNISED | |
769 | */ | |
770 | BOOST_OUTCOME_TEMPLATE(class T, class U) | |
771 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>)) | |
f67539c2 | 772 | constexpr basic_outcome(const failure_type<T, U> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept( |
20effc67 | 773 | detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT |
92f5a8d4 TL |
774 | : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)} |
775 | , _ptr(detail::extract_exception_from_failure<exception_type>(o)) | |
776 | { | |
777 | if(!o.has_error()) | |
778 | { | |
f67539c2 | 779 | this->_state._status.set_have_error(false); |
92f5a8d4 TL |
780 | } |
781 | if(o.has_exception()) | |
782 | { | |
f67539c2 | 783 | this->_state._status.set_have_exception(true); |
92f5a8d4 | 784 | } |
1e59de90 TL |
785 | hooks::set_spare_storage(this, o.spare_storage()); |
786 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
787 | } |
788 | ||
789 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
790 | SIGNATURE NOT RECOGNISED | |
791 | */ | |
792 | BOOST_OUTCOME_TEMPLATE(class T) | |
793 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>)) | |
f67539c2 | 794 | constexpr basic_outcome(failure_type<T> &&o, |
20effc67 | 795 | error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT |
92f5a8d4 TL |
796 | : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))} |
797 | , _ptr() | |
798 | { | |
1e59de90 TL |
799 | hooks::set_spare_storage(this, o.spare_storage()); |
800 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
801 | } |
802 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
803 | SIGNATURE NOT RECOGNISED | |
804 | */ | |
805 | BOOST_OUTCOME_TEMPLATE(class T) | |
806 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>)) | |
20effc67 TL |
807 | constexpr basic_outcome(failure_type<T> &&o, |
808 | exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT | |
92f5a8d4 TL |
809 | : base() |
810 | , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T> &&>(o))) | |
811 | { | |
f67539c2 | 812 | this->_state._status.set_have_exception(true); |
1e59de90 TL |
813 | hooks::set_spare_storage(this, o.spare_storage()); |
814 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
815 | } |
816 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
817 | SIGNATURE NOT RECOGNISED | |
818 | */ | |
819 | BOOST_OUTCOME_TEMPLATE(class T) | |
820 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>)) | |
f67539c2 TL |
821 | constexpr basic_outcome(failure_type<T> &&o, |
822 | explicit_make_error_code_compatible_move_conversion_tag /*unused*/ = | |
823 | explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT | |
92f5a8d4 TL |
824 | : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))} |
825 | , _ptr() | |
826 | { | |
1e59de90 TL |
827 | hooks::set_spare_storage(this, o.spare_storage()); |
828 | no_value_policy_type::on_outcome_copy_construction(this, o); | |
92f5a8d4 TL |
829 | } |
830 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
831 | SIGNATURE NOT RECOGNISED | |
832 | */ | |
833 | BOOST_OUTCOME_TEMPLATE(class T, class U) | |
834 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>)) | |
f67539c2 | 835 | constexpr basic_outcome(failure_type<T, U> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept( |
20effc67 | 836 | detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT |
92f5a8d4 TL |
837 | : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T, U> &&>(o))} |
838 | , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T, U> &&>(o))) | |
839 | { | |
840 | if(!o.has_error()) | |
841 | { | |
f67539c2 | 842 | this->_state._status.set_have_error(false); |
92f5a8d4 TL |
843 | } |
844 | if(o.has_exception()) | |
845 | { | |
f67539c2 | 846 | this->_state._status.set_have_exception(true); |
92f5a8d4 | 847 | } |
1e59de90 TL |
848 | hooks::set_spare_storage(this, o.spare_storage()); |
849 | no_value_policy_type::on_outcome_move_construction(this, static_cast<failure_type<T, U> &&>(o)); | |
92f5a8d4 TL |
850 | } |
851 | ||
852 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
853 | SIGNATURE NOT RECOGNISED | |
854 | */ | |
855 | using base::operator==; | |
856 | using base::operator!=; | |
857 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
858 | SIGNATURE NOT RECOGNISED | |
859 | */ | |
860 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) | |
861 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()), // | |
862 | BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()), // | |
863 | BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>())) | |
1e59de90 TL |
864 | constexpr bool operator==(const basic_outcome<T, U, V, W> &o) const noexcept( // |
865 | noexcept(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()) // | |
866 | &&noexcept(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()) // | |
867 | &&noexcept(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>())) | |
92f5a8d4 | 868 | { |
f67539c2 | 869 | if(this->_state._status.have_value() && o._state._status.have_value()) |
92f5a8d4 TL |
870 | { |
871 | return this->_state._value == o._state._value; // NOLINT | |
872 | } | |
f67539c2 TL |
873 | if(this->_state._status.have_error() && o._state._status.have_error() // |
874 | && this->_state._status.have_exception() && o._state._status.have_exception()) | |
92f5a8d4 | 875 | { |
1e59de90 | 876 | return this->_state._error == o._state._error && this->_ptr == o._ptr; |
92f5a8d4 | 877 | } |
f67539c2 | 878 | if(this->_state._status.have_error() && o._state._status.have_error()) |
92f5a8d4 | 879 | { |
1e59de90 | 880 | return this->_state._error == o._state._error; |
92f5a8d4 | 881 | } |
f67539c2 | 882 | if(this->_state._status.have_exception() && o._state._status.have_exception()) |
92f5a8d4 TL |
883 | { |
884 | return this->_ptr == o._ptr; | |
885 | } | |
886 | return false; | |
887 | } | |
888 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
889 | SIGNATURE NOT RECOGNISED | |
890 | */ | |
891 | BOOST_OUTCOME_TEMPLATE(class T, class U) | |
892 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() == std::declval<T>()), // | |
893 | BOOST_OUTCOME_TEXPR(std::declval<exception_type>() == std::declval<U>())) | |
894 | constexpr bool operator==(const failure_type<T, U> &o) const noexcept( // | |
1e59de90 | 895 | noexcept(std::declval<error_type>() == std::declval<T>()) &&noexcept(std::declval<exception_type>() == std::declval<U>())) |
92f5a8d4 | 896 | { |
f67539c2 TL |
897 | if(this->_state._status.have_error() && o._state._status.have_error() // |
898 | && this->_state._status.have_exception() && o._state._status.have_exception()) | |
92f5a8d4 | 899 | { |
1e59de90 | 900 | return this->_state._error == o.error() && this->_ptr == o.exception(); |
92f5a8d4 | 901 | } |
f67539c2 | 902 | if(this->_state._status.have_error() && o._state._status.have_error()) |
92f5a8d4 | 903 | { |
1e59de90 | 904 | return this->_state._error == o.error(); |
92f5a8d4 | 905 | } |
f67539c2 | 906 | if(this->_state._status.have_exception() && o._state._status.have_exception()) |
92f5a8d4 TL |
907 | { |
908 | return this->_ptr == o.exception(); | |
909 | } | |
910 | return false; | |
911 | } | |
912 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
913 | SIGNATURE NOT RECOGNISED | |
914 | */ | |
915 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W) | |
916 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()), // | |
917 | BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()), // | |
918 | BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>())) | |
1e59de90 TL |
919 | constexpr bool operator!=(const basic_outcome<T, U, V, W> &o) const noexcept( // |
920 | noexcept(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()) // | |
921 | &&noexcept(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()) // | |
922 | &&noexcept(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>())) | |
92f5a8d4 | 923 | { |
f67539c2 | 924 | if(this->_state._status.have_value() && o._state._status.have_value()) |
92f5a8d4 TL |
925 | { |
926 | return this->_state._value != o._state._value; // NOLINT | |
927 | } | |
f67539c2 TL |
928 | if(this->_state._status.have_error() && o._state._status.have_error() // |
929 | && this->_state._status.have_exception() && o._state._status.have_exception()) | |
92f5a8d4 | 930 | { |
1e59de90 | 931 | return this->_state._error != o._state._error || this->_ptr != o._ptr; |
92f5a8d4 | 932 | } |
f67539c2 | 933 | if(this->_state._status.have_error() && o._state._status.have_error()) |
92f5a8d4 | 934 | { |
1e59de90 | 935 | return this->_state._error != o._state._error; |
92f5a8d4 | 936 | } |
f67539c2 | 937 | if(this->_state._status.have_exception() && o._state._status.have_exception()) |
92f5a8d4 TL |
938 | { |
939 | return this->_ptr != o._ptr; | |
940 | } | |
941 | return true; | |
942 | } | |
943 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
944 | SIGNATURE NOT RECOGNISED | |
945 | */ | |
946 | BOOST_OUTCOME_TEMPLATE(class T, class U) | |
947 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() != std::declval<T>()), // | |
948 | BOOST_OUTCOME_TEXPR(std::declval<exception_type>() != std::declval<U>())) | |
949 | constexpr bool operator!=(const failure_type<T, U> &o) const noexcept( // | |
1e59de90 | 950 | noexcept(std::declval<error_type>() == std::declval<T>()) &&noexcept(std::declval<exception_type>() == std::declval<U>())) |
92f5a8d4 | 951 | { |
f67539c2 TL |
952 | if(this->_state._status.have_error() && o._state._status.have_error() // |
953 | && this->_state._status.have_exception() && o._state._status.have_exception()) | |
92f5a8d4 | 954 | { |
1e59de90 | 955 | return this->_state._error != o.error() || this->_ptr != o.exception(); |
92f5a8d4 | 956 | } |
f67539c2 | 957 | if(this->_state._status.have_error() && o._state._status.have_error()) |
92f5a8d4 | 958 | { |
1e59de90 | 959 | return this->_state._error != o.error(); |
92f5a8d4 | 960 | } |
f67539c2 | 961 | if(this->_state._status.have_exception() && o._state._status.have_exception()) |
92f5a8d4 TL |
962 | { |
963 | return this->_ptr != o.exception(); | |
964 | } | |
965 | return true; | |
966 | } | |
967 | ||
968 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
969 | SIGNATURE NOT RECOGNISED | |
970 | */ | |
971 | constexpr void swap(basic_outcome &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) // | |
972 | && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value) // | |
973 | && (std::is_void<exception_type>::value || detail::is_nothrow_swappable<exception_type>::value)) | |
974 | { | |
975 | #ifndef BOOST_NO_EXCEPTIONS | |
976 | constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value; | |
977 | constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value; | |
978 | constexpr bool exception_throws = !std::is_void<exception_type>::value && !detail::is_nothrow_swappable<exception_type>::value; | |
979 | #ifdef _MSC_VER | |
980 | #pragma warning(push) | |
981 | #pragma warning(disable : 4127) // conditional expression is constant | |
982 | #endif | |
983 | if(!exception_throws && !value_throws && !error_throws) | |
984 | { | |
985 | // Simples | |
1e59de90 | 986 | this->_state.swap(o._state); |
92f5a8d4 TL |
987 | using std::swap; |
988 | swap(this->_ptr, o._ptr); | |
989 | return; | |
990 | } | |
991 | struct _ | |
992 | { | |
993 | basic_outcome &a, &b; | |
994 | bool exceptioned{false}; | |
995 | bool all_good{false}; | |
996 | ~_() | |
997 | { | |
998 | if(!all_good) | |
999 | { | |
1000 | // We lost one of the values | |
f67539c2 TL |
1001 | a._state._status.set_have_lost_consistency(true); |
1002 | b._state._status.set_have_lost_consistency(true); | |
92f5a8d4 TL |
1003 | return; |
1004 | } | |
1005 | if(exceptioned) | |
1006 | { | |
1007 | // The value + error swap threw an exception. Try to swap back _ptr | |
1008 | try | |
1009 | { | |
1010 | strong_swap(all_good, a._ptr, b._ptr); | |
1011 | } | |
1012 | catch(...) | |
1013 | { | |
1014 | // We lost one of the values | |
f67539c2 TL |
1015 | a._state._status.set_have_lost_consistency(true); |
1016 | b._state._status.set_have_lost_consistency(true); | |
92f5a8d4 TL |
1017 | // throw away second exception |
1018 | } | |
1019 | ||
1020 | // Prevent has_value() == has_error() or has_value() == has_exception() | |
1021 | auto check = [](basic_outcome *t) { | |
1022 | if(t->has_value() && (t->has_error() || t->has_exception())) | |
1023 | { | |
f67539c2 TL |
1024 | t->_state._status.set_have_error(false).set_have_exception(false); |
1025 | t->_state._status.set_have_lost_consistency(true); | |
92f5a8d4 TL |
1026 | } |
1027 | if(!t->has_value() && !(t->has_error() || t->has_exception())) | |
1028 | { | |
1029 | // Choose error, for no particular reason | |
f67539c2 | 1030 | t->_state._status.set_have_error(true).set_have_lost_consistency(true); |
92f5a8d4 TL |
1031 | } |
1032 | }; | |
1033 | check(&a); | |
1034 | check(&b); | |
1035 | } | |
1036 | } | |
1037 | } _{*this, o}; | |
1038 | strong_swap(_.all_good, this->_ptr, o._ptr); | |
1039 | _.exceptioned = true; | |
1e59de90 | 1040 | this->_state.swap(o._state); |
92f5a8d4 TL |
1041 | _.exceptioned = false; |
1042 | #ifdef _MSC_VER | |
1043 | #pragma warning(pop) | |
1044 | #endif | |
1045 | #else | |
1e59de90 | 1046 | this->_state.swap(o._state); |
92f5a8d4 TL |
1047 | using std::swap; |
1048 | swap(this->_ptr, o._ptr); | |
1049 | #endif | |
1050 | } | |
1051 | ||
1052 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
1053 | SIGNATURE NOT RECOGNISED | |
1054 | */ | |
1055 | failure_type<error_type, exception_type> as_failure() const & | |
1056 | { | |
1057 | if(this->has_error() && this->has_exception()) | |
1058 | { | |
1e59de90 | 1059 | return failure_type<error_type, exception_type>(this->assume_error(), this->assume_exception(), hooks::spare_storage(this)); |
92f5a8d4 TL |
1060 | } |
1061 | if(this->has_exception()) | |
1062 | { | |
1e59de90 | 1063 | return failure_type<error_type, exception_type>(in_place_type<exception_type>, this->assume_exception(), hooks::spare_storage(this)); |
92f5a8d4 | 1064 | } |
1e59de90 | 1065 | return failure_type<error_type, exception_type>(in_place_type<error_type>, this->assume_error(), hooks::spare_storage(this)); |
92f5a8d4 TL |
1066 | } |
1067 | ||
1068 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
1069 | SIGNATURE NOT RECOGNISED | |
1070 | */ | |
1071 | failure_type<error_type, exception_type> as_failure() && | |
1072 | { | |
1e59de90 | 1073 | this->_state._status.set_have_moved_from(true); |
92f5a8d4 TL |
1074 | if(this->has_error() && this->has_exception()) |
1075 | { | |
1e59de90 TL |
1076 | return failure_type<error_type, exception_type>(static_cast<S &&>(this->assume_error()), static_cast<P &&>(this->assume_exception()), |
1077 | hooks::spare_storage(this)); | |
92f5a8d4 TL |
1078 | } |
1079 | if(this->has_exception()) | |
1080 | { | |
1e59de90 | 1081 | return failure_type<error_type, exception_type>(in_place_type<exception_type>, static_cast<P &&>(this->assume_exception()), hooks::spare_storage(this)); |
92f5a8d4 | 1082 | } |
1e59de90 | 1083 | return failure_type<error_type, exception_type>(in_place_type<error_type>, static_cast<S &&>(this->assume_error()), hooks::spare_storage(this)); |
92f5a8d4 | 1084 | } |
20effc67 TL |
1085 | |
1086 | #ifdef __APPLE__ | |
1087 | failure_type<error_type, exception_type> _xcode_workaround_as_failure() &&; | |
1088 | #endif | |
92f5a8d4 TL |
1089 | }; |
1090 | ||
20effc67 TL |
1091 | // C++ 20 operator== rewriting should take care of this for us, indeed |
1092 | // if we don't disable it, we cause Concept recursion to infinity! | |
1e59de90 | 1093 | #if __cplusplus < 202000L && !_HAS_CXX20 |
92f5a8d4 TL |
1094 | /*! AWAITING HUGO JSON CONVERSION TOOL |
1095 | SIGNATURE NOT RECOGNISED | |
1096 | */ | |
1097 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V, // | |
1098 | class R, class S, class P, class N) | |
1099 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>())) | |
1100 | constexpr inline bool operator==(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( // | |
1101 | noexcept(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>())) | |
1102 | { | |
1103 | return b == a; | |
1104 | } | |
20effc67 | 1105 | #endif |
92f5a8d4 TL |
1106 | /*! AWAITING HUGO JSON CONVERSION TOOL |
1107 | SIGNATURE NOT RECOGNISED | |
1108 | */ | |
1109 | BOOST_OUTCOME_TEMPLATE(class T, class U, class V, // | |
1110 | class R, class S, class P, class N) | |
1111 | BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>())) | |
1112 | constexpr inline bool operator!=(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( // | |
1113 | noexcept(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>())) | |
1114 | { | |
1115 | return b != a; | |
1116 | } | |
1117 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
1118 | SIGNATURE NOT RECOGNISED | |
1119 | */ | |
1120 | template <class R, class S, class P, class N> inline void swap(basic_outcome<R, S, P, N> &a, basic_outcome<R, S, P, N> &b) noexcept(noexcept(a.swap(b))) | |
1121 | { | |
1122 | a.swap(b); | |
1123 | } | |
1124 | ||
1125 | namespace hooks | |
1126 | { | |
1127 | /*! AWAITING HUGO JSON CONVERSION TOOL | |
1128 | SIGNATURE NOT RECOGNISED | |
1129 | */ | |
f67539c2 TL |
1130 | template <class R, class S, class P, class NoValuePolicy, class U> |
1131 | constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept | |
92f5a8d4 TL |
1132 | { |
1133 | o->_ptr = static_cast<U &&>(v); // NOLINT | |
f67539c2 | 1134 | o->_state._status.set_have_exception(true); |
92f5a8d4 TL |
1135 | } |
1136 | } // namespace hooks | |
1137 | ||
1138 | BOOST_OUTCOME_V2_NAMESPACE_END | |
1139 | ||
1140 | #ifdef __clang__ | |
1141 | #pragma clang diagnostic pop | |
1142 | #endif | |
1143 | ||
1144 | #include "detail/basic_outcome_exception_observers_impl.hpp" | |
1145 | ||
1146 | #if !defined(NDEBUG) | |
1147 | BOOST_OUTCOME_V2_NAMESPACE_BEGIN | |
1148 | // Check is trivial in all ways except default constructibility and standard layout | |
1149 | // static_assert(std::is_trivial<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivial!"); | |
f67539c2 TL |
1150 | // static_assert(std::is_trivially_default_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially default |
1151 | // constructible!"); | |
92f5a8d4 | 1152 | static_assert(std::is_trivially_copyable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copyable!"); |
f67539c2 TL |
1153 | static_assert(std::is_trivially_assignable<basic_outcome<int, long, double, policy::all_narrow>, basic_outcome<int, long, double, policy::all_narrow>>::value, |
1154 | "outcome<int> is not trivially assignable!"); | |
92f5a8d4 | 1155 | static_assert(std::is_trivially_destructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially destructible!"); |
f67539c2 TL |
1156 | static_assert(std::is_trivially_copy_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, |
1157 | "outcome<int> is not trivially copy constructible!"); | |
1158 | static_assert(std::is_trivially_move_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, | |
1159 | "outcome<int> is not trivially move constructible!"); | |
92f5a8d4 TL |
1160 | static_assert(std::is_trivially_copy_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy assignable!"); |
1161 | static_assert(std::is_trivially_move_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially move assignable!"); | |
1162 | // Can't be standard layout as non-static member data is defined in more than one inherited class | |
1163 | // static_assert(std::is_standard_layout<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not a standard layout type!"); | |
1164 | BOOST_OUTCOME_V2_NAMESPACE_END | |
1165 | #endif | |
1166 | ||
1167 | #endif |