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