]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/outcome/basic_outcome.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / boost / outcome / basic_outcome.hpp
CommitLineData
92f5a8d4 1/* A less simple result type
1e59de90 2(C) 2017-2022 Niall Douglas <http://www.nedproductions.biz/> (20 commits)
92f5a8d4
TL
3File Created: June 2017
4
5
6Boost Software License - Version 1.0 - August 17th, 2003
7
8Permission is hereby granted, free of charge, to any person or organization
9obtaining a copy of the software and accompanying documentation covered by
10this license (the "Software") to use, reproduce, display, distribute,
11execute, and transmit the Software, and to prepare derivative works of the
12Software, and to permit third-parties to whom the Software is furnished to
13do so, all subject to the following:
14
15The copyright notices in the Software and this entire statement, including
16the above license grant, this restriction and the following disclaimer,
17must be included in all copies of the Software, in whole or in part, and
18all derivative works of the Software, unless such copies or derivative
19works are solely in the form of machine-executable object code generated by
20a source language processor.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
25SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
26FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
27ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28DEALINGS 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
45BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
46
f67539c2 47template <class R, class S, class P, class NoValuePolicy> //
92f5a8d4
TL
48class basic_outcome;
49
50namespace 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
174type alias template <class T> is_basic_outcome. Potential doc page: `is_basic_outcome<T>`
175*/
176template <class T> using is_basic_outcome = detail::is_basic_outcome<std::decay_t<T>>;
177/*! AWAITING HUGO JSON CONVERSION TOOL
178SIGNATURE NOT RECOGNISED
179*/
180template <class T> static constexpr bool is_basic_outcome_v = detail::is_basic_outcome<std::decay_t<T>>::value;
181
20effc67
TL
182namespace 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
225namespace hooks
226{
227 /*! AWAITING HUGO JSON CONVERSION TOOL
228SIGNATURE 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
235type definition template <class R, class S, class P, class NoValuePolicy> basic_outcome. Potential doc page: `basic_outcome<T, EC, EP, NoValuePolicy>`
236*/
f67539c2 237template <class R, class S, class P, class NoValuePolicy> //
92f5a8d4
TL
238class 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
308public:
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
316protected:
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
413public:
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
421protected:
422 detail::devoid<exception_type> _ptr;
423
424public:
425 /*! AWAITING HUGO JSON CONVERSION TOOL
426SIGNATURE 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
433SIGNATURE 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
443SIGNATURE 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
455SIGNATURE 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
467SIGNATURE 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
479SIGNATURE 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
492SIGNATURE 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
506SIGNATURE 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
518SIGNATURE 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
533SIGNATURE 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
548SIGNATURE 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
563SIGNATURE 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
578SIGNATURE 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
593SIGNATURE 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
610SIGNATURE 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
621SIGNATURE 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
633SIGNATURE 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
644SIGNATURE 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
656SIGNATURE 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
669SIGNATURE 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
682SIGNATURE 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
695SIGNATURE 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
704SIGNATURE 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
715SIGNATURE 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
727SIGNATURE 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
740SIGNATURE 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
754SIGNATURE 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
768SIGNATURE 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
790SIGNATURE 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
803SIGNATURE 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
817SIGNATURE 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
831SIGNATURE 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
853SIGNATURE NOT RECOGNISED
854*/
855 using base::operator==;
856 using base::operator!=;
857 /*! AWAITING HUGO JSON CONVERSION TOOL
858SIGNATURE 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
889SIGNATURE 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
913SIGNATURE 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
944SIGNATURE 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
969SIGNATURE 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
1053SIGNATURE 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
1069SIGNATURE 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
1095SIGNATURE NOT RECOGNISED
1096*/
1097BOOST_OUTCOME_TEMPLATE(class T, class U, class V, //
1098 class R, class S, class P, class N)
1099BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
1100constexpr inline bool operator==(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
1101noexcept(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
1107SIGNATURE NOT RECOGNISED
1108*/
1109BOOST_OUTCOME_TEMPLATE(class T, class U, class V, //
1110 class R, class S, class P, class N)
1111BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
1112constexpr inline bool operator!=(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
1113noexcept(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
1118SIGNATURE NOT RECOGNISED
1119*/
1120template <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
1125namespace hooks
1126{
1127 /*! AWAITING HUGO JSON CONVERSION TOOL
1128SIGNATURE 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
1138BOOST_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)
1147BOOST_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 1152static_assert(std::is_trivially_copyable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copyable!");
f67539c2
TL
1153static_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 1155static_assert(std::is_trivially_destructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially destructible!");
f67539c2
TL
1156static_assert(std::is_trivially_copy_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
1157 "outcome<int> is not trivially copy constructible!");
1158static_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
1160static_assert(std::is_trivially_copy_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy assignable!");
1161static_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!");
1164BOOST_OUTCOME_V2_NAMESPACE_END
1165#endif
1166
1167#endif