Imported Upstream version 1.72.0
[platform/upstream/boost.git] / 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