Imported Upstream version 1.72.0
[platform/upstream/boost.git] / boost / outcome / basic_result.hpp
1 /* A very simple result type
2 (C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (14 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_RESULT_HPP
32 #define BOOST_OUTCOME_BASIC_RESULT_HPP
33
34 #include "config.hpp"
35 #include "convert.hpp"
36 #include "detail/basic_result_final.hpp"
37
38 #include "policy/all_narrow.hpp"
39 #include "policy/terminate.hpp"
40
41 #ifdef __clang__
42 #pragma clang diagnostic push
43 #pragma clang diagnostic ignored "-Wdocumentation"  // Standardese markup confuses clang
44 #endif
45
46 BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
47
48 template <class R, class S, class NoValuePolicy>                                                                                                                                  //
49 #if !defined(__GNUC__) || __GNUC__ >= 10                                                                                                                                          // GCC's constraints implementation is buggy
50 BOOST_OUTCOME_REQUIRES(trait::type_can_be_used_in_basic_result<R> &&trait::type_can_be_used_in_basic_result<S> && (std::is_void<S>::value || std::is_default_constructible<S>::value))  //
51 #endif
52 class basic_result;
53
54 namespace detail
55 {
56   // These are reused by basic_outcome to save load on the compiler
57   template <class value_type, class error_type> struct result_predicates
58   {
59     // Predicate for the implicit constructors to be available. Weakened to allow result<int, C enum>.
60     static constexpr bool implicit_constructors_enabled =                                                                               //
61     !(trait::is_error_type<std::decay_t<value_type>>::value && trait::is_error_type<std::decay_t<error_type>>::value)                   // both value and error types are not whitelisted error types
62     && ((!detail::is_implicitly_constructible<value_type, error_type> && !detail::is_implicitly_constructible<error_type, value_type>)  // if value and error types cannot be constructed into one another
63         || (trait::is_error_type<std::decay_t<error_type>>::value                                                                       // if error type is a whitelisted error type
64             && !detail::is_implicitly_constructible<error_type, value_type>                                                             // AND which cannot be constructed from the value type
65             && std::is_integral<value_type>::value));                                                                                   // AND the value type is some integral type
66
67     // Predicate for the value converting constructor to be available. Weakened to allow result<int, C enum>.
68     template <class T>
69     static constexpr bool enable_value_converting_constructor =                                                      //
70     implicit_constructors_enabled                                                                                    //
71     && !is_in_place_type_t<std::decay_t<T>>::value                                                                   // not in place construction
72     && !trait::is_error_type_enum<error_type, std::decay_t<T>>::value                                                // not an enum valid for my error type
73     && ((detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T>)  // is unambiguously for value type
74         || (std::is_same<value_type, std::decay_t<T>>::value                                                         // OR is my value type exactly
75             && detail::is_implicitly_constructible<value_type, T>) );                                                // and my value type is constructible from this ref form of T
76
77
78     // Predicate for the error converting constructor to be available. Weakened to allow result<int, C enum>.
79     template <class T>
80     static constexpr bool enable_error_converting_constructor =                                                      //
81     implicit_constructors_enabled                                                                                    //
82     && !is_in_place_type_t<std::decay_t<T>>::value                                                                   // not in place construction
83     && !trait::is_error_type_enum<error_type, std::decay_t<T>>::value                                                // not an enum valid for my error type
84     && ((!detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T>)  // is unambiguously for error type
85         || (std::is_same<error_type, std::decay_t<T>>::value                                                         // OR is my error type exactly
86             && detail::is_implicitly_constructible<error_type, T>) );                                                // and my error type is constructible from this ref form of T
87
88     // Predicate for the error condition converting constructor to be available.
89     template <class ErrorCondEnum>
90     static constexpr bool enable_error_condition_converting_constructor =                                                                       //
91     !is_in_place_type_t<std::decay_t<ErrorCondEnum>>::value                                                                                     // not in place construction
92     && trait::is_error_type_enum<error_type, std::decay_t<ErrorCondEnum>>::value                                                                // is an error condition enum
93     /*&& !detail::is_implicitly_constructible<value_type, ErrorCondEnum> && !detail::is_implicitly_constructible<error_type, ErrorCondEnum>*/;  // not constructible via any other means
94
95     // Predicate for the converting constructor from a compatible input to be available.
96     template <class T, class U, class V>
97     static constexpr bool enable_compatible_conversion =                                                                       //
98     (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>)    // if our value types are constructible
99     &&(std::is_void<U>::value || detail::is_explicitly_constructible<error_type, typename basic_result<T, U, V>::error_type>)  // if our error types are constructible
100     ;
101
102     // Predicate for the converting constructor from a make_error_code() of the input to be available.
103     template <class T, class U, class V>
104     static constexpr bool enable_make_error_code_compatible_conversion =                                                        //
105     trait::is_error_code_available<std::decay_t<error_type>>::value                                                             // if error type has an error code
106     && !enable_compatible_conversion<T, U, V>                                                                                   // and the normal compatible conversion is not available
107     && (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>)  // and if our value types are constructible
108     &&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()
109
110     // Predicate for the converting constructor from a make_exception_ptr() of the input to be available.
111     template <class T, class U, class V>
112     static constexpr bool enable_make_exception_ptr_compatible_conversion =                                                     //
113     trait::is_exception_ptr_available<std::decay_t<error_type>>::value                                                          // if error type has an exception ptr
114     && !enable_compatible_conversion<T, U, V>                                                                                   // and the normal compatible conversion is not available
115     && (std::is_void<T>::value || detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>)  // and if our value types are constructible
116     &&detail::is_explicitly_constructible<error_type, typename trait::is_exception_ptr_available<U>::type>;                     // and our error type is constructible from a make_exception_ptr()
117
118     // Predicate for the implicit converting inplace constructor from a compatible input to be available.
119     struct disable_inplace_value_error_constructor;
120     template <class... Args>
121     using choose_inplace_value_error_constructor = std::conditional_t<                                       //
122     std::is_constructible<value_type, Args...>::value && std::is_constructible<error_type, Args...>::value,  //
123     disable_inplace_value_error_constructor,                                                                 //
124     std::conditional_t<                                                                                      //
125     std::is_constructible<value_type, Args...>::value,                                                       //
126     value_type,                                                                                              //
127     std::conditional_t<                                                                                      //
128     std::is_constructible<error_type, Args...>::value,                                                       //
129     error_type,                                                                                              //
130     disable_inplace_value_error_constructor>>>;
131     template <class... Args>
132     static constexpr bool enable_inplace_value_error_constructor = implicit_constructors_enabled  //
133                                                                    && !std::is_same<choose_inplace_value_error_constructor<Args...>, disable_inplace_value_error_constructor>::value;
134   };
135
136   template <class T, class U> constexpr inline const U &extract_value_from_success(const success_type<U> &v) { return v.value(); }
137   template <class T, class U> constexpr inline U &&extract_value_from_success(success_type<U> &&v) { return static_cast<success_type<U> &&>(v).value(); }
138   template <class T> constexpr inline T extract_value_from_success(const success_type<void> & /*unused*/) { return T{}; }
139
140   template <class T, class U, class V> constexpr inline const U &extract_error_from_failure(const failure_type<U, V> &v) { return v.error(); }
141   template <class T, class U, class V> constexpr inline U &&extract_error_from_failure(failure_type<U, V> &&v) { return static_cast<failure_type<U, V> &&>(v).error(); }
142   template <class T, class V> constexpr inline T extract_error_from_failure(const failure_type<void, V> & /*unused*/) { return T{}; }
143
144   template <class T> struct is_basic_result
145   {
146     static constexpr bool value = false;
147   };
148   template <class R, class S, class T> struct is_basic_result<basic_result<R, S, T>>
149   {
150     static constexpr bool value = true;
151   };
152 }  // namespace detail
153
154 /*! AWAITING HUGO JSON CONVERSION TOOL
155 type alias template <class T> is_basic_result. Potential doc page: `is_basic_result<T>`
156 */
157 template <class T> using is_basic_result = detail::is_basic_result<std::decay_t<T>>;
158 /*! AWAITING HUGO JSON CONVERSION TOOL
159 SIGNATURE NOT RECOGNISED
160 */
161 template <class T> static constexpr bool is_basic_result_v = detail::is_basic_result<std::decay_t<T>>::value;
162
163 /*! AWAITING HUGO JSON CONVERSION TOOL
164 SIGNATURE NOT RECOGNISED
165 */
166 namespace hooks
167 {
168   /*! AWAITING HUGO JSON CONVERSION TOOL
169 SIGNATURE NOT RECOGNISED
170 */
171   template <class T, class U> constexpr inline void hook_result_construction(T * /*unused*/, U && /*unused*/) noexcept {}
172   /*! AWAITING HUGO JSON CONVERSION TOOL
173 SIGNATURE NOT RECOGNISED
174 */
175   template <class T, class U> constexpr inline void hook_result_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {}
176   /*! AWAITING HUGO JSON CONVERSION TOOL
177 SIGNATURE NOT RECOGNISED
178 */
179   template <class T, class U> constexpr inline void hook_result_move_construction(T * /*unused*/, U && /*unused*/) noexcept {}
180   /*! AWAITING HUGO JSON CONVERSION TOOL
181 SIGNATURE NOT RECOGNISED
182 */
183   template <class T, class U, class... Args> constexpr inline void hook_result_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept {}
184
185   /*! AWAITING HUGO JSON CONVERSION TOOL
186 SIGNATURE NOT RECOGNISED
187 */
188   template <class R, class S, class NoValuePolicy> constexpr inline uint16_t spare_storage(const detail::basic_result_final<R, S, NoValuePolicy> *r) noexcept { return (r->_state._status >> detail::status_2byte_shift) & 0xffff; }
189   /*! AWAITING HUGO JSON CONVERSION TOOL
190 SIGNATURE NOT RECOGNISED
191 */
192   template <class R, class S, class NoValuePolicy> constexpr inline void set_spare_storage(detail::basic_result_final<R, S, NoValuePolicy> *r, uint16_t v) noexcept { r->_state._status |= (v << detail::status_2byte_shift); }
193 }  // namespace hooks
194
195 /*! AWAITING HUGO JSON CONVERSION TOOL
196 type definition template <class R, class S, class NoValuePolicy> basic_result. Potential doc page: `basic_result<T, E, NoValuePolicy>`
197 */
198 template <class R, class S, class NoValuePolicy>                                                                                                                                  //
199 #if !defined(__GNUC__) || __GNUC__ >= 10                                                                                                                                          // GCC's constraints implementation is buggy
200 BOOST_OUTCOME_REQUIRES(trait::type_can_be_used_in_basic_result<R> &&trait::type_can_be_used_in_basic_result<S> && (std::is_void<S>::value || std::is_default_constructible<S>::value))  //
201 #endif
202 class BOOST_OUTCOME_NODISCARD basic_result : public detail::basic_result_final<R, S, NoValuePolicy>
203 {
204   static_assert(trait::type_can_be_used_in_basic_result<R>, "The type R cannot be used in a basic_result");
205   static_assert(trait::type_can_be_used_in_basic_result<S>, "The type S cannot be used in a basic_result");
206   static_assert(std::is_void<S>::value || std::is_default_constructible<S>::value, "The type S must be void or default constructible");
207
208   using base = detail::basic_result_final<R, S, NoValuePolicy>;
209
210   struct implicit_constructors_disabled_tag
211   {
212   };
213   struct value_converting_constructor_tag
214   {
215   };
216   struct error_converting_constructor_tag
217   {
218   };
219   struct error_condition_converting_constructor_tag
220   {
221   };
222   struct explicit_valueornone_converting_constructor_tag
223   {
224   };
225   struct explicit_valueorerror_converting_constructor_tag
226   {
227   };
228   struct explicit_compatible_copy_conversion_tag
229   {
230   };
231   struct explicit_compatible_move_conversion_tag
232   {
233   };
234   struct explicit_make_error_code_compatible_copy_conversion_tag
235   {
236   };
237   struct explicit_make_error_code_compatible_move_conversion_tag
238   {
239   };
240   struct explicit_make_exception_ptr_compatible_copy_conversion_tag
241   {
242   };
243   struct explicit_make_exception_ptr_compatible_move_conversion_tag
244   {
245   };
246
247 public:
248   using value_type = R;
249   using error_type = S;
250
251   using value_type_if_enabled = typename base::_value_type;
252   using error_type_if_enabled = typename base::_error_type;
253
254   template <class T, class U = S, class V = NoValuePolicy> using rebind = basic_result<T, U, V>;
255
256 protected:
257   // Requirement predicates for result.
258   struct predicate
259   {
260     using base = detail::result_predicates<value_type, error_type>;
261
262     // Predicate for any constructors to be available at all
263     static constexpr bool constructors_enabled = !std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value;
264
265     // Predicate for implicit constructors to be available at all
266     static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
267
268     // Predicate for the value converting constructor to be available.
269     template <class T>
270     static constexpr bool enable_value_converting_constructor =  //
271     constructors_enabled                                         //
272     && !std::is_same<std::decay_t<T>, basic_result>::value       // not my type
273     && base::template enable_value_converting_constructor<T>;
274
275     // Predicate for the error converting constructor to be available.
276     template <class T>
277     static constexpr bool enable_error_converting_constructor =  //
278     constructors_enabled                                         //
279     && !std::is_same<std::decay_t<T>, basic_result>::value       // not my type
280     && base::template enable_error_converting_constructor<T>;
281
282     // Predicate for the error condition converting constructor to be available.
283     template <class ErrorCondEnum>
284     static constexpr bool enable_error_condition_converting_constructor =  //
285     constructors_enabled                                                   //
286     && !std::is_same<std::decay_t<ErrorCondEnum>, basic_result>::value     // not my type
287     && base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
288
289     // Predicate for the converting constructor from a compatible input to be available.
290     template <class T, class U, class V>
291     static constexpr bool enable_compatible_conversion =          //
292     constructors_enabled                                          //
293     && !std::is_same<basic_result<T, U, V>, basic_result>::value  // not my type
294     && base::template enable_compatible_conversion<T, U, V>;
295
296     // Predicate for the converting constructor from a make_error_code() of the input to be available.
297     template <class T, class U, class V>
298     static constexpr bool enable_make_error_code_compatible_conversion =  //
299     constructors_enabled                                                  //
300     && !std::is_same<basic_result<T, U, V>, basic_result>::value          // not my type
301     && base::template enable_make_error_code_compatible_conversion<T, U, V>;
302
303     // Predicate for the converting constructor from a make_exception_ptr() of the input to be available.
304     template <class T, class U, class V>
305     static constexpr bool enable_make_exception_ptr_compatible_conversion =  //
306     constructors_enabled                                                     //
307     && !std::is_same<basic_result<T, U, V>, basic_result>::value             // not my type
308     && base::template enable_make_exception_ptr_compatible_conversion<T, U, V>;
309
310     // Predicate for the inplace construction of value to be available.
311     template <class... Args>
312     static constexpr bool enable_inplace_value_constructor =  //
313     constructors_enabled                                      //
314     && (std::is_void<value_type>::value                       //
315         || std::is_constructible<value_type, Args...>::value);
316
317     // Predicate for the inplace construction of error to be available.
318     template <class... Args>
319     static constexpr bool enable_inplace_error_constructor =  //
320     constructors_enabled                                      //
321     && (std::is_void<error_type>::value                       //
322         || std::is_constructible<error_type, Args...>::value);
323
324     // Predicate for the implicit converting inplace constructor to be available.
325     template <class... Args>
326     static constexpr bool enable_inplace_value_error_constructor =  //
327     constructors_enabled                                            //
328     &&base::template enable_inplace_value_error_constructor<Args...>;
329     template <class... Args> using choose_inplace_value_error_constructor = typename base::template choose_inplace_value_error_constructor<Args...>;
330   };
331
332 public:
333   /*! AWAITING HUGO JSON CONVERSION TOOL
334 SIGNATURE NOT RECOGNISED
335 */
336   basic_result() = delete;
337   /*! AWAITING HUGO JSON CONVERSION TOOL
338 SIGNATURE NOT RECOGNISED
339 */
340   basic_result(basic_result && /*unused*/) = default;  // NOLINT
341   /*! AWAITING HUGO JSON CONVERSION TOOL
342 SIGNATURE NOT RECOGNISED
343 */
344   basic_result(const basic_result & /*unused*/) = default;
345   /*! AWAITING HUGO JSON CONVERSION TOOL
346 SIGNATURE NOT RECOGNISED
347 */
348   basic_result &operator=(basic_result && /*unused*/) = default;  // NOLINT
349   /*! AWAITING HUGO JSON CONVERSION TOOL
350 SIGNATURE NOT RECOGNISED
351 */
352   basic_result &operator=(const basic_result & /*unused*/) = default;
353   ~basic_result() = default;
354
355   /*! AWAITING HUGO JSON CONVERSION TOOL
356 SIGNATURE NOT RECOGNISED
357 */
358   BOOST_OUTCOME_TEMPLATE(class Arg, class... Args)
359   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!predicate::constructors_enabled && (sizeof...(Args) >= 0)))
360   basic_result(Arg && /*unused*/, Args &&... /*unused*/) = delete;  // NOLINT basic_result<T, T> is NOT SUPPORTED, see docs!
361
362   /*! AWAITING HUGO JSON CONVERSION TOOL
363 SIGNATURE NOT RECOGNISED
364 */
365   BOOST_OUTCOME_TEMPLATE(class T)
366   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled  //
367                                    && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T>) )))
368   basic_result(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!
369
370   /*! AWAITING HUGO JSON CONVERSION TOOL
371 SIGNATURE NOT RECOGNISED
372 */
373   BOOST_OUTCOME_TEMPLATE(class T)
374   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
375   constexpr basic_result(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value)  // NOLINT
376       : base{in_place_type<typename base::value_type>, static_cast<T &&>(t)}
377   {
378     using namespace hooks;
379     hook_result_construction(this, static_cast<T &&>(t));
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::template enable_error_converting_constructor<T>))
386   constexpr basic_result(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept(std::is_nothrow_constructible<error_type, T>::value)  // NOLINT
387       : base{in_place_type<typename base::error_type>, static_cast<T &&>(t)}
388   {
389     using namespace hooks;
390     hook_result_construction(this, static_cast<T &&>(t));
391   }
392   /*! AWAITING HUGO JSON CONVERSION TOOL
393 SIGNATURE NOT RECOGNISED
394 */
395   BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum)
396   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))),  //
397                     BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
398   constexpr basic_result(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
399       : base{in_place_type<typename base::error_type>, make_error_code(t)}
400   {
401     using namespace hooks;
402     hook_result_construction(this, static_cast<ErrorCondEnum &&>(t));
403   }
404
405   /*! AWAITING HUGO JSON CONVERSION TOOL
406 SIGNATURE NOT RECOGNISED
407 */
408   BOOST_OUTCOME_TEMPLATE(class T)
409   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_result, std::decay_t<T>>::enable_result_inputs || !is_basic_result_v<T>),  //
410                     BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_result, std::decay_t<T>>{}(std::declval<T>())))
411   constexpr explicit basic_result(T &&o, explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag())  // NOLINT
412       : basic_result{convert::value_or_error<basic_result, std::decay_t<T>>{}(static_cast<T &&>(o))}
413   {
414   }
415   /*! AWAITING HUGO JSON CONVERSION TOOL
416 SIGNATURE NOT RECOGNISED
417 */
418   BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
419   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>))
420   constexpr explicit basic_result(const basic_result<T, U, V> &o, 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)
421       : base{typename base::compatible_conversion_tag(), o}
422   {
423     using namespace hooks;
424     hook_result_copy_construction(this, o);
425   }
426   /*! AWAITING HUGO JSON CONVERSION TOOL
427 SIGNATURE NOT RECOGNISED
428 */
429   BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
430   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>))
431   constexpr explicit basic_result(basic_result<T, U, V> &&o, 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)
432       : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
433   {
434     using namespace hooks;
435     hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
436   }
437   /*! AWAITING HUGO JSON CONVERSION TOOL
438 SIGNATURE NOT RECOGNISED
439 */
440   BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
441   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
442   constexpr explicit basic_result(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>())))
443       : base{typename base::make_error_code_compatible_conversion_tag(), o}
444   {
445     using namespace hooks;
446     hook_result_copy_construction(this, o);
447   }
448   /*! AWAITING HUGO JSON CONVERSION TOOL
449 SIGNATURE NOT RECOGNISED
450 */
451   BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
452   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
453   constexpr explicit basic_result(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>())))
454       : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
455   {
456     using namespace hooks;
457     hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
458   }
459   /*! AWAITING HUGO JSON CONVERSION TOOL
460 SIGNATURE NOT RECOGNISED
461 */
462   BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
463   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
464   constexpr explicit basic_result(const basic_result<T, U, V> &o, explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value &&noexcept(make_exception_ptr(std::declval<U>())))
465       : base{typename base::make_exception_ptr_compatible_conversion_tag(), o}
466   {
467     using namespace hooks;
468     hook_result_copy_construction(this, o);
469   }
470   /*! AWAITING HUGO JSON CONVERSION TOOL
471 SIGNATURE NOT RECOGNISED
472 */
473   BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
474   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
475   constexpr explicit basic_result(basic_result<T, U, V> &&o, explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value  &&noexcept(make_exception_ptr(std::declval<U>())))
476       : base{typename base::make_exception_ptr_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
477   {
478     using namespace hooks;
479     hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
480   }
481
482   /*! AWAITING HUGO JSON CONVERSION TOOL
483 SIGNATURE NOT RECOGNISED
484 */
485   BOOST_OUTCOME_TEMPLATE(class... Args)
486   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
487   constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(std::is_nothrow_constructible<value_type, Args...>::value)
488       : base{_, static_cast<Args &&>(args)...}
489   {
490     using namespace hooks;
491     hook_result_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
492   }
493   /*! AWAITING HUGO JSON CONVERSION TOOL
494 SIGNATURE NOT RECOGNISED
495 */
496   BOOST_OUTCOME_TEMPLATE(class U, class... Args)
497   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
498   constexpr explicit basic_result(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)
499       : base{_, il, static_cast<Args &&>(args)...}
500   {
501     using namespace hooks;
502     hook_result_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
503   }
504   /*! AWAITING HUGO JSON CONVERSION TOOL
505 SIGNATURE NOT RECOGNISED
506 */
507   BOOST_OUTCOME_TEMPLATE(class... Args)
508   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
509   constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(std::is_nothrow_constructible<error_type, Args...>::value)
510       : base{_, static_cast<Args &&>(args)...}
511   {
512     using namespace hooks;
513     hook_result_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
514   }
515   /*! AWAITING HUGO JSON CONVERSION TOOL
516 SIGNATURE NOT RECOGNISED
517 */
518   BOOST_OUTCOME_TEMPLATE(class U, class... Args)
519   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
520   constexpr explicit basic_result(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)
521       : base{_, il, static_cast<Args &&>(args)...}
522   {
523     using namespace hooks;
524     hook_result_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
525   }
526   /*! AWAITING HUGO JSON CONVERSION TOOL
527 SIGNATURE NOT RECOGNISED
528 */
529   BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args)
530   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_constructor<A1, A2, Args...>))
531   constexpr basic_result(A1 &&a1, A2 &&a2, Args &&... args) noexcept(noexcept(typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(), std::declval<Args>()...)))
532       : basic_result(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1), static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
533   {
534     /* I was a little surprised that the below is needed given that we forward to another constructor.
535     But it turns out that ADL only fires on the first constructor for some reason.
536     */
537     using namespace hooks;
538     // hook_result_in_place_construction(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, this);
539   }
540
541   /*! AWAITING HUGO JSON CONVERSION TOOL
542 SIGNATURE NOT RECOGNISED
543 */
544   constexpr basic_result(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value)  // NOLINT
545       : base{in_place_type<value_type_if_enabled>}
546   {
547     using namespace hooks;
548     hook_result_copy_construction(this, o);
549   }
550   /*! AWAITING HUGO JSON CONVERSION TOOL
551 SIGNATURE NOT RECOGNISED
552 */
553   BOOST_OUTCOME_TEMPLATE(class T)
554   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, void, void>))
555   constexpr basic_result(const success_type<T> &o) noexcept(std::is_nothrow_constructible<value_type, T>::value)  // NOLINT
556       : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(o)}
557   {
558     using namespace hooks;
559     hook_result_copy_construction(this, o);
560   }
561   /*! AWAITING HUGO JSON CONVERSION TOOL
562 SIGNATURE NOT RECOGNISED
563 */
564   BOOST_OUTCOME_TEMPLATE(class T)
565   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void>))
566   constexpr basic_result(success_type<T> &&o) noexcept(std::is_nothrow_constructible<value_type, T>::value)  // NOLINT
567       : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
568   {
569     using namespace hooks;
570     hook_result_move_construction(this, static_cast<success_type<T> &&>(o));
571   }
572   /*! AWAITING HUGO JSON CONVERSION TOOL
573 SIGNATURE NOT RECOGNISED
574 */
575   BOOST_OUTCOME_TEMPLATE(class T)
576   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
577   constexpr basic_result(const failure_type<T> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<error_type, T>::value)  // NOLINT
578       : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(o)}
579   {
580     using namespace hooks;
581     hook_result_copy_construction(this, o);
582   }
583   /*! AWAITING HUGO JSON CONVERSION TOOL
584 SIGNATURE NOT RECOGNISED
585 */
586   BOOST_OUTCOME_TEMPLATE(class T)
587   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
588   constexpr basic_result(failure_type<T> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<error_type, T>::value)  // NOLINT
589       : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
590   {
591     using namespace hooks;
592     hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
593   }
594   /*! AWAITING HUGO JSON CONVERSION TOOL
595 SIGNATURE NOT RECOGNISED
596 */
597   BOOST_OUTCOME_TEMPLATE(class T)
598   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
599   constexpr basic_result(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
600       : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
601   {
602     using namespace hooks;
603     hook_result_copy_construction(this, o);
604   }
605   /*! AWAITING HUGO JSON CONVERSION TOOL
606 SIGNATURE NOT RECOGNISED
607 */
608   BOOST_OUTCOME_TEMPLATE(class T)
609   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
610   constexpr basic_result(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
611       : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
612   {
613     using namespace hooks;
614     hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
615   }
616   /*! AWAITING HUGO JSON CONVERSION TOOL
617 SIGNATURE NOT RECOGNISED
618 */
619   BOOST_OUTCOME_TEMPLATE(class T)
620   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
621   constexpr basic_result(const failure_type<T> &o, explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>())))  // NOLINT
622       : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(o))}
623   {
624     using namespace hooks;
625     hook_result_copy_construction(this, o);
626   }
627   /*! AWAITING HUGO JSON CONVERSION TOOL
628 SIGNATURE NOT RECOGNISED
629 */
630   BOOST_OUTCOME_TEMPLATE(class T)
631   BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
632   constexpr basic_result(failure_type<T> &&o, explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ = explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>())))  // NOLINT
633       : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
634   {
635     using namespace hooks;
636     hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
637   }
638
639   /*! AWAITING HUGO JSON CONVERSION TOOL
640 SIGNATURE NOT RECOGNISED
641 */
642   constexpr void swap(basic_result &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value)  //
643                                                 && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value))
644   {
645     constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value;
646     constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value;
647     detail::basic_result_storage_swap<value_throws, error_throws>(*this, o);
648   }
649
650   /*! AWAITING HUGO JSON CONVERSION TOOL
651 SIGNATURE NOT RECOGNISED
652 */
653   auto as_failure() const & {
654     return failure(this->assume_error()); }
655   /*! AWAITING HUGO JSON CONVERSION TOOL
656 SIGNATURE NOT RECOGNISED
657 */
658   auto as_failure() && {
659     return failure(static_cast<basic_result &&>(*this).assume_error()); }
660 };
661
662 /*! AWAITING HUGO JSON CONVERSION TOOL
663 SIGNATURE NOT RECOGNISED
664 */
665 template <class R, class S, class P> inline void swap(basic_result<R, S, P> &a, basic_result<R, S, P> &b) noexcept(noexcept(a.swap(b)))
666 {
667   a.swap(b);
668 }
669
670 #if !defined(NDEBUG)
671 // Check is trivial in all ways except default constructibility
672 // static_assert(std::is_trivial<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivial!");
673 // static_assert(std::is_trivially_default_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially default constructible!");
674 static_assert(std::is_trivially_copyable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copyable!");
675 static_assert(std::is_trivially_assignable<basic_result<int, long, policy::all_narrow>, basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially assignable!");
676 static_assert(std::is_trivially_destructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially destructible!");
677 static_assert(std::is_trivially_copy_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy constructible!");
678 static_assert(std::is_trivially_move_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move constructible!");
679 static_assert(std::is_trivially_copy_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy assignable!");
680 static_assert(std::is_trivially_move_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move assignable!");
681 // Also check is standard layout
682 static_assert(std::is_standard_layout<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not a standard layout type!");
683 #endif
684
685 BOOST_OUTCOME_V2_NAMESPACE_END
686
687 #ifdef __clang__
688 #pragma clang diagnostic pop
689 #endif
690
691 #endif