]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/outcome/basic_outcome.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / outcome / basic_outcome.hpp
CommitLineData
92f5a8d4 1/* A less simple result type
f67539c2 2(C) 2017-2020 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
229*/
230 template <class T, class... U> constexpr inline void hook_outcome_construction(T * /*unused*/, U &&... /*unused*/) noexcept {}
231 /*! AWAITING HUGO JSON CONVERSION TOOL
232SIGNATURE NOT RECOGNISED
233*/
234 template <class T, class U> constexpr inline void hook_outcome_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {}
235 /*! AWAITING HUGO JSON CONVERSION TOOL
236SIGNATURE NOT RECOGNISED
237*/
238 template <class T, class U> constexpr inline void hook_outcome_move_construction(T * /*unused*/, U && /*unused*/) noexcept {}
239 /*! AWAITING HUGO JSON CONVERSION TOOL
240SIGNATURE NOT RECOGNISED
241*/
f67539c2
TL
242 template <class T, class U, class... Args>
243 constexpr inline void hook_outcome_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept
244 {
245 }
92f5a8d4
TL
246
247 /*! AWAITING HUGO JSON CONVERSION TOOL
248SIGNATURE NOT RECOGNISED
249*/
f67539c2
TL
250 template <class R, class S, class P, class NoValuePolicy, class U>
251 constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept;
92f5a8d4
TL
252} // namespace hooks
253
254/*! AWAITING HUGO JSON CONVERSION TOOL
255type definition template <class R, class S, class P, class NoValuePolicy> basic_outcome. Potential doc page: `basic_outcome<T, EC, EP, NoValuePolicy>`
256*/
f67539c2 257template <class R, class S, class P, class NoValuePolicy> //
92f5a8d4
TL
258class BOOST_OUTCOME_NODISCARD basic_outcome
259#if defined(BOOST_OUTCOME_DOXYGEN_IS_IN_THE_HOUSE) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE)
260 : public detail::basic_outcome_failure_observers<detail::basic_result_final<R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>,
261 public detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>,
262 public detail::basic_result_final<R, S, NoValuePolicy>
263#else
f67539c2
TL
264 : public detail::select_basic_outcome_failure_observers<
265 detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>
92f5a8d4
TL
266#endif
267{
268 static_assert(trait::type_can_be_used_in_basic_result<P>, "The exception_type cannot be used");
269 static_assert(std::is_void<P>::value || std::is_default_constructible<P>::value, "exception_type must be void or default constructible");
f67539c2
TL
270 using base = detail::select_basic_outcome_failure_observers<
271 detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>;
92f5a8d4 272 friend struct policy::base;
f67539c2 273 template <class T, class U, class V, class W> //
92f5a8d4 274 friend class basic_outcome;
f67539c2
TL
275 template <class T, class U, class V, class W, class X>
276 friend constexpr inline void hooks::override_outcome_exception(basic_outcome<T, U, V, W> *o, X &&v) noexcept; // NOLINT
92f5a8d4
TL
277
278 struct implicit_constructors_disabled_tag
279 {
280 };
281 struct value_converting_constructor_tag
282 {
283 };
284 struct error_converting_constructor_tag
285 {
286 };
287 struct error_condition_converting_constructor_tag
288 {
289 };
290 struct exception_converting_constructor_tag
291 {
292 };
293 struct error_exception_converting_constructor_tag
294 {
295 };
296 struct explicit_valueorerror_converting_constructor_tag
297 {
298 };
299 struct explicit_compatible_copy_conversion_tag
300 {
301 };
302 struct explicit_compatible_move_conversion_tag
303 {
304 };
305 struct explicit_make_error_code_compatible_copy_conversion_tag
306 {
307 };
308 struct explicit_make_error_code_compatible_move_conversion_tag
309 {
310 };
311 struct error_failure_tag
312 {
313 };
314 struct exception_failure_tag
315 {
316 };
317
318 struct disable_in_place_value_type
319 {
320 };
321 struct disable_in_place_error_type
322 {
323 };
324 struct disable_in_place_exception_type
325 {
326 };
327
328public:
329 using value_type = R;
330 using error_type = S;
331 using exception_type = P;
20effc67 332 using no_value_policy_type = NoValuePolicy;
92f5a8d4
TL
333
334 template <class T, class U = S, class V = P, class W = NoValuePolicy> using rebind = basic_outcome<T, U, V, W>;
335
336protected:
337 // Requirement predicates for outcome.
338 struct predicate
339 {
340 using base = detail::outcome_predicates<value_type, error_type, exception_type>;
341
342 // Predicate for any constructors to be available at all
f67539c2
TL
343 static constexpr bool constructors_enabled =
344 (!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)) //
345 && (!std::is_same<std::decay_t<value_type>, std::decay_t<exception_type>>::value ||
346 (std::is_void<value_type>::value && std::is_void<exception_type>::value)) //
347 && (!std::is_same<std::decay_t<error_type>, std::decay_t<exception_type>>::value ||
348 (std::is_void<error_type>::value && std::is_void<exception_type>::value)) //
92f5a8d4
TL
349 ;
350
351 // Predicate for implicit constructors to be available at all
352 static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
353
354 // Predicate for the value converting constructor to be available.
355 template <class T>
356 static constexpr bool enable_value_converting_constructor = //
357 constructors_enabled //
358 && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
359 && base::template enable_value_converting_constructor<T>;
360
361 // Predicate for the error converting constructor to be available.
362 template <class T>
363 static constexpr bool enable_error_converting_constructor = //
364 constructors_enabled //
365 && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
366 && base::template enable_error_converting_constructor<T>;
367
368 // Predicate for the error condition converting constructor to be available.
369 template <class ErrorCondEnum>
370 static constexpr bool enable_error_condition_converting_constructor = //
371 constructors_enabled //
372 && !std::is_same<std::decay_t<ErrorCondEnum>, basic_outcome>::value // not my type
373 && base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
374
375 // Predicate for the exception converting constructor to be available.
376 template <class T>
377 static constexpr bool enable_exception_converting_constructor = //
378 constructors_enabled //
379 && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
380 && base::template enable_exception_converting_constructor<T>;
381
382 // Predicate for the error + exception converting constructor to be available.
383 template <class T, class U>
384 static constexpr bool enable_error_exception_converting_constructor = //
385 constructors_enabled //
386 && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
387 && base::template enable_error_exception_converting_constructor<T, U>;
388
389 // Predicate for the converting constructor from a compatible input to be available.
390 template <class T, class U, class V, class W>
391 static constexpr bool enable_compatible_conversion = //
392 constructors_enabled //
393 && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type
394 && base::template enable_compatible_conversion<T, U, V, W>;
395
396 // Predicate for the converting constructor from a make_error_code() of the input to be available.
397 template <class T, class U, class V, class W>
398 static constexpr bool enable_make_error_code_compatible_conversion = //
399 constructors_enabled //
400 && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type
401 && base::template enable_make_error_code_compatible_conversion<T, U, V, W>;
402
403 // Predicate for the inplace construction of value to be available.
404 template <class... Args>
405 static constexpr bool enable_inplace_value_constructor = //
406 constructors_enabled //
407 && (std::is_void<value_type>::value //
20effc67 408 || detail::is_constructible<value_type, Args...>);
92f5a8d4
TL
409
410 // Predicate for the inplace construction of error to be available.
411 template <class... Args>
412 static constexpr bool enable_inplace_error_constructor = //
413 constructors_enabled //
414 && (std::is_void<error_type>::value //
20effc67 415 || detail::is_constructible<error_type, Args...>);
92f5a8d4
TL
416
417 // Predicate for the inplace construction of exception to be available.
418 template <class... Args>
419 static constexpr bool enable_inplace_exception_constructor = //
420 constructors_enabled //
421 && (std::is_void<exception_type>::value //
20effc67 422 || detail::is_constructible<exception_type, Args...>);
92f5a8d4
TL
423
424 // Predicate for the implicit converting inplace constructor to be available.
425 template <class... Args>
426 static constexpr bool enable_inplace_value_error_exception_constructor = //
427 constructors_enabled //
428 &&base::template enable_inplace_value_error_exception_constructor<Args...>;
f67539c2
TL
429 template <class... Args>
430 using choose_inplace_value_error_exception_constructor = typename base::template choose_inplace_value_error_exception_constructor<Args...>;
92f5a8d4
TL
431 };
432
433public:
f67539c2
TL
434 using value_type_if_enabled =
435 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>;
436 using error_type_if_enabled =
437 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>;
438 using exception_type_if_enabled = std::conditional_t<std::is_same<exception_type, value_type>::value || std::is_same<exception_type, error_type>::value,
439 disable_in_place_exception_type, exception_type>;
92f5a8d4
TL
440
441protected:
442 detail::devoid<exception_type> _ptr;
443
444public:
445 /*! AWAITING HUGO JSON CONVERSION TOOL
446SIGNATURE NOT RECOGNISED
447*/
448 BOOST_OUTCOME_TEMPLATE(class Arg, class... Args)
449 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((!predicate::constructors_enabled && sizeof...(Args) >= 0)))
450 basic_outcome(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_outcome<> with any of the same type is NOT SUPPORTED, see docs!
451
452 /*! AWAITING HUGO JSON CONVERSION TOOL
453SIGNATURE NOT RECOGNISED
454*/
455 BOOST_OUTCOME_TEMPLATE(class T)
456 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled //
f67539c2
TL
457 && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T> ||
458 detail::is_implicitly_constructible<exception_type, T>) )))
459 basic_outcome(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) =
460 delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs!
92f5a8d4
TL
461
462 /*! AWAITING HUGO JSON CONVERSION TOOL
463SIGNATURE NOT RECOGNISED
464*/
465 BOOST_OUTCOME_TEMPLATE(class T)
466 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
f67539c2 467 constexpr basic_outcome(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept(
20effc67 468 detail::is_nothrow_constructible<value_type, T>) // NOLINT
92f5a8d4
TL
469 : base{in_place_type<typename base::_value_type>, static_cast<T &&>(t)}
470 , _ptr()
471 {
472 using namespace hooks;
473 hook_outcome_construction(this, static_cast<T &&>(t));
474 }
475 /*! AWAITING HUGO JSON CONVERSION TOOL
476SIGNATURE NOT RECOGNISED
477*/
478 BOOST_OUTCOME_TEMPLATE(class T)
479 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>))
f67539c2 480 constexpr basic_outcome(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept(
20effc67 481 detail::is_nothrow_constructible<error_type, T>) // NOLINT
92f5a8d4
TL
482 : base{in_place_type<typename base::_error_type>, static_cast<T &&>(t)}
483 , _ptr()
484 {
485 using namespace hooks;
486 hook_outcome_construction(this, static_cast<T &&>(t));
487 }
488 /*! AWAITING HUGO JSON CONVERSION TOOL
489SIGNATURE NOT RECOGNISED
490*/
491 BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum)
492 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), //
493 BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
f67539c2
TL
494 constexpr basic_outcome(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept(
495 noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT
92f5a8d4
TL
496 : base{in_place_type<typename base::_error_type>, make_error_code(t)}
497 {
498 using namespace hooks;
499 hook_outcome_construction(this, static_cast<ErrorCondEnum &&>(t));
500 }
501 /*! AWAITING HUGO JSON CONVERSION TOOL
502SIGNATURE NOT RECOGNISED
503*/
504 BOOST_OUTCOME_TEMPLATE(class T)
505 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_exception_converting_constructor<T>))
f67539c2 506 constexpr basic_outcome(T &&t, exception_converting_constructor_tag /*unused*/ = exception_converting_constructor_tag()) noexcept(
20effc67 507 detail::is_nothrow_constructible<exception_type, T>) // NOLINT
92f5a8d4
TL
508 : base()
509 , _ptr(static_cast<T &&>(t))
510 {
511 using namespace hooks;
f67539c2 512 this->_state._status.set_have_exception(true);
92f5a8d4
TL
513 hook_outcome_construction(this, static_cast<T &&>(t));
514 }
515 /*! AWAITING HUGO JSON CONVERSION TOOL
516SIGNATURE NOT RECOGNISED
517*/
518 BOOST_OUTCOME_TEMPLATE(class T, class U)
519 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_exception_converting_constructor<T, U>))
f67539c2 520 constexpr basic_outcome(T &&a, U &&b, error_exception_converting_constructor_tag /*unused*/ = error_exception_converting_constructor_tag()) noexcept(
20effc67 521 detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT
92f5a8d4
TL
522 : base{in_place_type<typename base::_error_type>, static_cast<T &&>(a)}
523 , _ptr(static_cast<U &&>(b))
524 {
525 using namespace hooks;
f67539c2 526 this->_state._status.set_have_exception(true);
92f5a8d4
TL
527 hook_outcome_construction(this, static_cast<T &&>(a), static_cast<U &&>(b));
528 }
529
530 /*! AWAITING HUGO JSON CONVERSION TOOL
531SIGNATURE NOT RECOGNISED
532*/
533 BOOST_OUTCOME_TEMPLATE(class T)
20effc67
TL
534 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>), //
535 BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_outcome_inputs || !concepts::basic_outcome<T>), //
92f5a8d4 536 BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_outcome, std::decay_t<T>>{}(std::declval<T>())))
f67539c2
TL
537 constexpr explicit basic_outcome(T &&o,
538 explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT
92f5a8d4
TL
539 : basic_outcome{convert::value_or_error<basic_outcome, std::decay_t<T>>{}(static_cast<T &&>(o))}
540 {
541 }
542 /*! AWAITING HUGO JSON CONVERSION TOOL
543SIGNATURE NOT RECOGNISED
544*/
545 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
546 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
f67539c2
TL
547 constexpr explicit basic_outcome(
548 const basic_outcome<T, U, V, W> &o,
549 explicit_compatible_copy_conversion_tag /*unused*/ =
20effc67
TL
550 explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
551 &&detail::is_nothrow_constructible<exception_type, V>)
92f5a8d4
TL
552 : base{typename base::compatible_conversion_tag(), o}
553 , _ptr(o._ptr)
554 {
555 using namespace hooks;
556 hook_outcome_copy_construction(this, o);
557 }
558 /*! AWAITING HUGO JSON CONVERSION TOOL
559SIGNATURE NOT RECOGNISED
560*/
561 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
562 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
f67539c2
TL
563 constexpr explicit basic_outcome(
564 basic_outcome<T, U, V, W> &&o,
565 explicit_compatible_move_conversion_tag /*unused*/ =
20effc67
TL
566 explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
567 &&detail::is_nothrow_constructible<exception_type, V>)
92f5a8d4
TL
568 : base{typename base::compatible_conversion_tag(), static_cast<basic_outcome<T, U, V, W> &&>(o)}
569 , _ptr(static_cast<typename basic_outcome<T, U, V, W>::exception_type &&>(o._ptr))
570 {
571 using namespace hooks;
572 hook_outcome_move_construction(this, static_cast<basic_outcome<T, U, V, W> &&>(o));
573 }
574 /*! AWAITING HUGO JSON CONVERSION TOOL
575SIGNATURE NOT RECOGNISED
576*/
577 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
578 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
f67539c2
TL
579 constexpr explicit basic_outcome(
580 const basic_result<T, U, V> &o,
581 explicit_compatible_copy_conversion_tag /*unused*/ =
20effc67
TL
582 explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
583 &&detail::is_nothrow_constructible<exception_type>)
92f5a8d4
TL
584 : base{typename base::compatible_conversion_tag(), o}
585 , _ptr()
586 {
587 using namespace hooks;
588 hook_outcome_copy_construction(this, o);
589 }
590 /*! AWAITING HUGO JSON CONVERSION TOOL
591SIGNATURE NOT RECOGNISED
592*/
593 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
594 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
f67539c2
TL
595 constexpr explicit basic_outcome(
596 basic_result<T, U, V> &&o,
597 explicit_compatible_move_conversion_tag /*unused*/ =
20effc67
TL
598 explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>
599 &&detail::is_nothrow_constructible<exception_type>)
92f5a8d4
TL
600 : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
601 , _ptr()
602 {
603 using namespace hooks;
604 hook_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
605 }
606 /*! AWAITING HUGO JSON CONVERSION TOOL
607SIGNATURE NOT RECOGNISED
608*/
609 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
610 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
611 constexpr explicit basic_outcome(const basic_result<T, U, V> &o,
612 explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
20effc67 613 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
f67539c2 614 &&noexcept(make_error_code(std::declval<U>())) &&
20effc67 615 detail::is_nothrow_constructible<exception_type>)
92f5a8d4
TL
616 : base{typename base::make_error_code_compatible_conversion_tag(), o}
617 , _ptr()
618 {
619 using namespace hooks;
620 hook_outcome_copy_construction(this, o);
621 }
622 /*! AWAITING HUGO JSON CONVERSION TOOL
623SIGNATURE NOT RECOGNISED
624*/
625 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
626 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
627 constexpr explicit basic_outcome(basic_result<T, U, V> &&o,
628 explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
20effc67 629 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
f67539c2 630 &&noexcept(make_error_code(std::declval<U>())) &&
20effc67 631 detail::is_nothrow_constructible<exception_type>)
92f5a8d4
TL
632 : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
633 , _ptr()
634 {
635 using namespace hooks;
636 hook_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
637 }
638
639
640 /*! AWAITING HUGO JSON CONVERSION TOOL
641SIGNATURE NOT RECOGNISED
642*/
643 BOOST_OUTCOME_TEMPLATE(class... Args)
644 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
20effc67 645 constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>)
92f5a8d4
TL
646 : base{_, static_cast<Args &&>(args)...}
647 , _ptr()
648 {
649 using namespace hooks;
650 hook_outcome_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
651 }
652 /*! AWAITING HUGO JSON CONVERSION TOOL
653SIGNATURE NOT RECOGNISED
654*/
655 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
656 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
f67539c2 657 constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il,
20effc67 658 Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>)
92f5a8d4
TL
659 : base{_, il, static_cast<Args &&>(args)...}
660 , _ptr()
661 {
662 using namespace hooks;
663 hook_outcome_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
664 }
665 /*! AWAITING HUGO JSON CONVERSION TOOL
666SIGNATURE NOT RECOGNISED
667*/
668 BOOST_OUTCOME_TEMPLATE(class... Args)
669 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
20effc67 670 constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, Args...>)
92f5a8d4
TL
671 : base{_, static_cast<Args &&>(args)...}
672 , _ptr()
673 {
674 using namespace hooks;
675 hook_outcome_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
676 }
677 /*! AWAITING HUGO JSON CONVERSION TOOL
678SIGNATURE NOT RECOGNISED
679*/
680 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
681 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
f67539c2 682 constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il,
20effc67 683 Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>)
92f5a8d4
TL
684 : base{_, il, static_cast<Args &&>(args)...}
685 , _ptr()
686 {
687 using namespace hooks;
688 hook_outcome_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
689 }
690 /*! AWAITING HUGO JSON CONVERSION TOOL
691SIGNATURE NOT RECOGNISED
692*/
693 BOOST_OUTCOME_TEMPLATE(class... Args)
694 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<Args...>))
f67539c2 695 constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/,
20effc67 696 Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, Args...>)
92f5a8d4
TL
697 : base()
698 , _ptr(static_cast<Args &&>(args)...)
699 {
700 using namespace hooks;
f67539c2 701 this->_state._status.set_have_exception(true);
92f5a8d4
TL
702 hook_outcome_in_place_construction(this, in_place_type<exception_type>, static_cast<Args &&>(args)...);
703 }
704 /*! AWAITING HUGO JSON CONVERSION TOOL
705SIGNATURE NOT RECOGNISED
706*/
707 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
708 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<std::initializer_list<U>, Args...>))
f67539c2 709 constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/, std::initializer_list<U> il,
20effc67 710 Args &&... args) noexcept(detail::is_nothrow_constructible<exception_type, std::initializer_list<U>, Args...>)
92f5a8d4
TL
711 : base()
712 , _ptr(il, static_cast<Args &&>(args)...)
713 {
714 using namespace hooks;
f67539c2 715 this->_state._status.set_have_exception(true);
92f5a8d4
TL
716 hook_outcome_in_place_construction(this, in_place_type<exception_type>, il, static_cast<Args &&>(args)...);
717 }
718 /*! AWAITING HUGO JSON CONVERSION TOOL
719SIGNATURE NOT RECOGNISED
720*/
721 BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args)
722 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_exception_constructor<A1, A2, Args...>))
f67539c2
TL
723 constexpr basic_outcome(A1 &&a1, A2 &&a2, Args &&... args) noexcept(
724 noexcept(typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(),
725 std::declval<Args>()...)))
726 : basic_outcome(in_place_type<typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1),
727 static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
92f5a8d4
TL
728 {
729 }
730
731 /*! AWAITING HUGO JSON CONVERSION TOOL
732SIGNATURE NOT RECOGNISED
733*/
734 constexpr basic_outcome(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT
735 : base{in_place_type<typename base::_value_type>}
736 {
737 using namespace hooks;
738 hook_outcome_copy_construction(this, o);
739 }
740 /*! AWAITING HUGO JSON CONVERSION TOOL
741SIGNATURE NOT RECOGNISED
742*/
743 BOOST_OUTCOME_TEMPLATE(class T)
744 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
20effc67 745 constexpr basic_outcome(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
92f5a8d4
TL
746 : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(o)}
747 {
748 using namespace hooks;
749 hook_outcome_copy_construction(this, o);
750 }
751 /*! AWAITING HUGO JSON CONVERSION TOOL
752SIGNATURE NOT RECOGNISED
753*/
754 BOOST_OUTCOME_TEMPLATE(class T)
755 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
20effc67 756 constexpr basic_outcome(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
92f5a8d4
TL
757 : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
758 {
759 using namespace hooks;
760 hook_outcome_move_construction(this, static_cast<success_type<T> &&>(o));
761 }
762
763 /*! AWAITING HUGO JSON CONVERSION TOOL
764SIGNATURE NOT RECOGNISED
765*/
766 BOOST_OUTCOME_TEMPLATE(class T)
767 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
f67539c2 768 constexpr basic_outcome(const failure_type<T> &o,
20effc67 769 error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT
92f5a8d4
TL
770 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
771 , _ptr()
772 {
773 using namespace hooks;
774 hook_outcome_copy_construction(this, o);
775 }
776 /*! AWAITING HUGO JSON CONVERSION TOOL
777SIGNATURE NOT RECOGNISED
778*/
779 BOOST_OUTCOME_TEMPLATE(class T)
780 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
20effc67
TL
781 constexpr basic_outcome(const failure_type<T> &o,
782 exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT
92f5a8d4
TL
783 : base()
784 , _ptr(detail::extract_exception_from_failure<exception_type>(o))
785 {
f67539c2 786 this->_state._status.set_have_exception(true);
92f5a8d4
TL
787 using namespace hooks;
788 hook_outcome_copy_construction(this, o);
789 }
790 /*! AWAITING HUGO JSON CONVERSION TOOL
791SIGNATURE NOT RECOGNISED
792*/
793 BOOST_OUTCOME_TEMPLATE(class T)
794 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
795 constexpr basic_outcome(const failure_type<T> &o,
796 explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
797 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
92f5a8d4
TL
798 : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
799 , _ptr()
800 {
801 using namespace hooks;
802 hook_outcome_copy_construction(this, o);
803 }
804 /*! AWAITING HUGO JSON CONVERSION TOOL
805SIGNATURE NOT RECOGNISED
806*/
807 BOOST_OUTCOME_TEMPLATE(class T, class U)
808 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
f67539c2 809 constexpr basic_outcome(const failure_type<T, U> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(
20effc67 810 detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT
92f5a8d4
TL
811 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
812 , _ptr(detail::extract_exception_from_failure<exception_type>(o))
813 {
814 if(!o.has_error())
815 {
f67539c2 816 this->_state._status.set_have_error(false);
92f5a8d4
TL
817 }
818 if(o.has_exception())
819 {
f67539c2 820 this->_state._status.set_have_exception(true);
92f5a8d4
TL
821 }
822 using namespace hooks;
823 hook_outcome_copy_construction(this, o);
824 }
825
826 /*! AWAITING HUGO JSON CONVERSION TOOL
827SIGNATURE NOT RECOGNISED
828*/
829 BOOST_OUTCOME_TEMPLATE(class T)
830 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
f67539c2 831 constexpr basic_outcome(failure_type<T> &&o,
20effc67 832 error_failure_tag /*unused*/ = error_failure_tag()) noexcept(detail::is_nothrow_constructible<error_type, T>) // NOLINT
92f5a8d4
TL
833 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
834 , _ptr()
835 {
836 using namespace hooks;
837 hook_outcome_copy_construction(this, o);
838 }
839 /*! AWAITING HUGO JSON CONVERSION TOOL
840SIGNATURE NOT RECOGNISED
841*/
842 BOOST_OUTCOME_TEMPLATE(class T)
843 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
20effc67
TL
844 constexpr basic_outcome(failure_type<T> &&o,
845 exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(detail::is_nothrow_constructible<exception_type, T>) // NOLINT
92f5a8d4
TL
846 : base()
847 , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T> &&>(o)))
848 {
f67539c2 849 this->_state._status.set_have_exception(true);
92f5a8d4
TL
850 using namespace hooks;
851 hook_outcome_copy_construction(this, o);
852 }
853 /*! AWAITING HUGO JSON CONVERSION TOOL
854SIGNATURE NOT RECOGNISED
855*/
856 BOOST_OUTCOME_TEMPLATE(class T)
857 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
858 constexpr basic_outcome(failure_type<T> &&o,
859 explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
860 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
92f5a8d4
TL
861 : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
862 , _ptr()
863 {
864 using namespace hooks;
865 hook_outcome_copy_construction(this, o);
866 }
867 /*! AWAITING HUGO JSON CONVERSION TOOL
868SIGNATURE NOT RECOGNISED
869*/
870 BOOST_OUTCOME_TEMPLATE(class T, class U)
871 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
f67539c2 872 constexpr basic_outcome(failure_type<T, U> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(
20effc67 873 detail::is_nothrow_constructible<error_type, T> &&detail::is_nothrow_constructible<exception_type, U>) // NOLINT
92f5a8d4
TL
874 : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T, U> &&>(o))}
875 , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T, U> &&>(o)))
876 {
877 if(!o.has_error())
878 {
f67539c2 879 this->_state._status.set_have_error(false);
92f5a8d4
TL
880 }
881 if(o.has_exception())
882 {
f67539c2 883 this->_state._status.set_have_exception(true);
92f5a8d4
TL
884 }
885 using namespace hooks;
886 hook_outcome_move_construction(this, static_cast<failure_type<T, U> &&>(o));
887 }
888
889 /*! AWAITING HUGO JSON CONVERSION TOOL
890SIGNATURE NOT RECOGNISED
891*/
892 using base::operator==;
893 using base::operator!=;
894 /*! AWAITING HUGO JSON CONVERSION TOOL
895SIGNATURE NOT RECOGNISED
896*/
897 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
898 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()), //
899 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()), //
900 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
901 constexpr bool operator==(const basic_outcome<T, U, V, W> &o) const noexcept( //
902 noexcept(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()) //
903 && noexcept(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()) //
904 && noexcept(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
905 {
f67539c2 906 if(this->_state._status.have_value() && o._state._status.have_value())
92f5a8d4
TL
907 {
908 return this->_state._value == o._state._value; // NOLINT
909 }
f67539c2
TL
910 if(this->_state._status.have_error() && o._state._status.have_error() //
911 && this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
912 {
913 return this->_error == o._error && this->_ptr == o._ptr;
914 }
f67539c2 915 if(this->_state._status.have_error() && o._state._status.have_error())
92f5a8d4
TL
916 {
917 return this->_error == o._error;
918 }
f67539c2 919 if(this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
920 {
921 return this->_ptr == o._ptr;
922 }
923 return false;
924 }
925 /*! AWAITING HUGO JSON CONVERSION TOOL
926SIGNATURE NOT RECOGNISED
927*/
928 BOOST_OUTCOME_TEMPLATE(class T, class U)
929 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() == std::declval<T>()), //
930 BOOST_OUTCOME_TEXPR(std::declval<exception_type>() == std::declval<U>()))
931 constexpr bool operator==(const failure_type<T, U> &o) const noexcept( //
932 noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>()))
933 {
f67539c2
TL
934 if(this->_state._status.have_error() && o._state._status.have_error() //
935 && this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
936 {
937 return this->_error == o.error() && this->_ptr == o.exception();
938 }
f67539c2 939 if(this->_state._status.have_error() && o._state._status.have_error())
92f5a8d4
TL
940 {
941 return this->_error == o.error();
942 }
f67539c2 943 if(this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
944 {
945 return this->_ptr == o.exception();
946 }
947 return false;
948 }
949 /*! AWAITING HUGO JSON CONVERSION TOOL
950SIGNATURE NOT RECOGNISED
951*/
952 BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
953 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()), //
954 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()), //
955 BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
956 constexpr bool operator!=(const basic_outcome<T, U, V, W> &o) const noexcept( //
957 noexcept(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()) //
958 && noexcept(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()) //
959 && noexcept(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
960 {
f67539c2 961 if(this->_state._status.have_value() && o._state._status.have_value())
92f5a8d4
TL
962 {
963 return this->_state._value != o._state._value; // NOLINT
964 }
f67539c2
TL
965 if(this->_state._status.have_error() && o._state._status.have_error() //
966 && this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
967 {
968 return this->_error != o._error || this->_ptr != o._ptr;
969 }
f67539c2 970 if(this->_state._status.have_error() && o._state._status.have_error())
92f5a8d4
TL
971 {
972 return this->_error != o._error;
973 }
f67539c2 974 if(this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
975 {
976 return this->_ptr != o._ptr;
977 }
978 return true;
979 }
980 /*! AWAITING HUGO JSON CONVERSION TOOL
981SIGNATURE NOT RECOGNISED
982*/
983 BOOST_OUTCOME_TEMPLATE(class T, class U)
984 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() != std::declval<T>()), //
985 BOOST_OUTCOME_TEXPR(std::declval<exception_type>() != std::declval<U>()))
986 constexpr bool operator!=(const failure_type<T, U> &o) const noexcept( //
987 noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>()))
988 {
f67539c2
TL
989 if(this->_state._status.have_error() && o._state._status.have_error() //
990 && this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
991 {
992 return this->_error != o.error() || this->_ptr != o.exception();
993 }
f67539c2 994 if(this->_state._status.have_error() && o._state._status.have_error())
92f5a8d4
TL
995 {
996 return this->_error != o.error();
997 }
f67539c2 998 if(this->_state._status.have_exception() && o._state._status.have_exception())
92f5a8d4
TL
999 {
1000 return this->_ptr != o.exception();
1001 }
1002 return true;
1003 }
1004
1005 /*! AWAITING HUGO JSON CONVERSION TOOL
1006SIGNATURE NOT RECOGNISED
1007*/
1008 constexpr void swap(basic_outcome &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) //
1009 && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value) //
1010 && (std::is_void<exception_type>::value || detail::is_nothrow_swappable<exception_type>::value))
1011 {
1012#ifndef BOOST_NO_EXCEPTIONS
1013 constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value;
1014 constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value;
1015 constexpr bool exception_throws = !std::is_void<exception_type>::value && !detail::is_nothrow_swappable<exception_type>::value;
1016#ifdef _MSC_VER
1017#pragma warning(push)
1018#pragma warning(disable : 4127) // conditional expression is constant
1019#endif
1020 if(!exception_throws && !value_throws && !error_throws)
1021 {
1022 // Simples
1023 detail::basic_result_storage_swap<value_throws, error_throws>(*this, o);
1024 using std::swap;
1025 swap(this->_ptr, o._ptr);
1026 return;
1027 }
1028 struct _
1029 {
1030 basic_outcome &a, &b;
1031 bool exceptioned{false};
1032 bool all_good{false};
1033 ~_()
1034 {
1035 if(!all_good)
1036 {
1037 // We lost one of the values
f67539c2
TL
1038 a._state._status.set_have_lost_consistency(true);
1039 b._state._status.set_have_lost_consistency(true);
92f5a8d4
TL
1040 return;
1041 }
1042 if(exceptioned)
1043 {
1044 // The value + error swap threw an exception. Try to swap back _ptr
1045 try
1046 {
1047 strong_swap(all_good, a._ptr, b._ptr);
1048 }
1049 catch(...)
1050 {
1051 // We lost one of the values
f67539c2
TL
1052 a._state._status.set_have_lost_consistency(true);
1053 b._state._status.set_have_lost_consistency(true);
92f5a8d4
TL
1054 // throw away second exception
1055 }
1056
1057 // Prevent has_value() == has_error() or has_value() == has_exception()
1058 auto check = [](basic_outcome *t) {
1059 if(t->has_value() && (t->has_error() || t->has_exception()))
1060 {
f67539c2
TL
1061 t->_state._status.set_have_error(false).set_have_exception(false);
1062 t->_state._status.set_have_lost_consistency(true);
92f5a8d4
TL
1063 }
1064 if(!t->has_value() && !(t->has_error() || t->has_exception()))
1065 {
1066 // Choose error, for no particular reason
f67539c2 1067 t->_state._status.set_have_error(true).set_have_lost_consistency(true);
92f5a8d4
TL
1068 }
1069 };
1070 check(&a);
1071 check(&b);
1072 }
1073 }
1074 } _{*this, o};
1075 strong_swap(_.all_good, this->_ptr, o._ptr);
1076 _.exceptioned = true;
1077 detail::basic_result_storage_swap<value_throws, error_throws>(*this, o);
1078 _.exceptioned = false;
1079#ifdef _MSC_VER
1080#pragma warning(pop)
1081#endif
1082#else
1083 detail::basic_result_storage_swap<false, false>(*this, o);
1084 using std::swap;
1085 swap(this->_ptr, o._ptr);
1086#endif
1087 }
1088
1089 /*! AWAITING HUGO JSON CONVERSION TOOL
1090SIGNATURE NOT RECOGNISED
1091*/
1092 failure_type<error_type, exception_type> as_failure() const &
1093 {
1094 if(this->has_error() && this->has_exception())
1095 {
1096 return failure_type<error_type, exception_type>(this->assume_error(), this->assume_exception());
1097 }
1098 if(this->has_exception())
1099 {
1100 return failure_type<error_type, exception_type>(in_place_type<exception_type>, this->assume_exception());
1101 }
1102 return failure_type<error_type, exception_type>(in_place_type<error_type>, this->assume_error());
1103 }
1104
1105 /*! AWAITING HUGO JSON CONVERSION TOOL
1106SIGNATURE NOT RECOGNISED
1107*/
1108 failure_type<error_type, exception_type> as_failure() &&
1109 {
1110 if(this->has_error() && this->has_exception())
1111 {
1112 return failure_type<error_type, exception_type>(static_cast<S &&>(this->assume_error()), static_cast<P &&>(this->assume_exception()));
1113 }
1114 if(this->has_exception())
1115 {
1116 return failure_type<error_type, exception_type>(in_place_type<exception_type>, static_cast<P &&>(this->assume_exception()));
1117 }
1118 return failure_type<error_type, exception_type>(in_place_type<error_type>, static_cast<S &&>(this->assume_error()));
1119 }
20effc67
TL
1120
1121#ifdef __APPLE__
1122 failure_type<error_type, exception_type> _xcode_workaround_as_failure() &&;
1123#endif
92f5a8d4
TL
1124};
1125
20effc67
TL
1126// C++ 20 operator== rewriting should take care of this for us, indeed
1127// if we don't disable it, we cause Concept recursion to infinity!
1128#if __cplusplus < 202000L
92f5a8d4
TL
1129/*! AWAITING HUGO JSON CONVERSION TOOL
1130SIGNATURE NOT RECOGNISED
1131*/
1132BOOST_OUTCOME_TEMPLATE(class T, class U, class V, //
1133 class R, class S, class P, class N)
1134BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
1135constexpr inline bool operator==(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
1136noexcept(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
1137{
1138 return b == a;
1139}
20effc67 1140#endif
92f5a8d4
TL
1141/*! AWAITING HUGO JSON CONVERSION TOOL
1142SIGNATURE NOT RECOGNISED
1143*/
1144BOOST_OUTCOME_TEMPLATE(class T, class U, class V, //
1145 class R, class S, class P, class N)
1146BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
1147constexpr inline bool operator!=(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
1148noexcept(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
1149{
1150 return b != a;
1151}
1152/*! AWAITING HUGO JSON CONVERSION TOOL
1153SIGNATURE NOT RECOGNISED
1154*/
1155template <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)))
1156{
1157 a.swap(b);
1158}
1159
1160namespace hooks
1161{
1162 /*! AWAITING HUGO JSON CONVERSION TOOL
1163SIGNATURE NOT RECOGNISED
1164*/
f67539c2
TL
1165 template <class R, class S, class P, class NoValuePolicy, class U>
1166 constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept
92f5a8d4
TL
1167 {
1168 o->_ptr = static_cast<U &&>(v); // NOLINT
f67539c2 1169 o->_state._status.set_have_exception(true);
92f5a8d4
TL
1170 }
1171} // namespace hooks
1172
1173BOOST_OUTCOME_V2_NAMESPACE_END
1174
1175#ifdef __clang__
1176#pragma clang diagnostic pop
1177#endif
1178
1179#include "detail/basic_outcome_exception_observers_impl.hpp"
1180
1181#if !defined(NDEBUG)
1182BOOST_OUTCOME_V2_NAMESPACE_BEGIN
1183// Check is trivial in all ways except default constructibility and standard layout
1184// static_assert(std::is_trivial<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivial!");
f67539c2
TL
1185// static_assert(std::is_trivially_default_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially default
1186// constructible!");
92f5a8d4 1187static_assert(std::is_trivially_copyable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copyable!");
f67539c2
TL
1188static_assert(std::is_trivially_assignable<basic_outcome<int, long, double, policy::all_narrow>, basic_outcome<int, long, double, policy::all_narrow>>::value,
1189 "outcome<int> is not trivially assignable!");
92f5a8d4 1190static_assert(std::is_trivially_destructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially destructible!");
f67539c2
TL
1191static_assert(std::is_trivially_copy_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
1192 "outcome<int> is not trivially copy constructible!");
1193static_assert(std::is_trivially_move_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
1194 "outcome<int> is not trivially move constructible!");
92f5a8d4
TL
1195static_assert(std::is_trivially_copy_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy assignable!");
1196static_assert(std::is_trivially_move_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially move assignable!");
1197// Can't be standard layout as non-static member data is defined in more than one inherited class
1198// static_assert(std::is_standard_layout<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not a standard layout type!");
1199BOOST_OUTCOME_V2_NAMESPACE_END
1200#endif
1201
1202#endif