1 /* A very simple result type
2 (C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (14 commits)
3 File Created: June 2017
6 Boost Software License - Version 1.0 - August 17th, 2003
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:
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.
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.
31 #ifndef BOOST_OUTCOME_BASIC_RESULT_HPP
32 #define BOOST_OUTCOME_BASIC_RESULT_HPP
35 #include "convert.hpp"
36 #include "detail/basic_result_final.hpp"
38 #include "policy/all_narrow.hpp"
39 #include "policy/terminate.hpp"
42 #pragma clang diagnostic push
43 #pragma clang diagnostic ignored "-Wdocumentation" // Standardese markup confuses clang
46 BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
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)) //
56 // These are reused by basic_outcome to save load on the compiler
57 template <class value_type, class error_type> struct result_predicates
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
67 // Predicate for the value converting constructor to be available. Weakened to allow result<int, C enum>.
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
78 // Predicate for the error converting constructor to be available. Weakened to allow result<int, C enum>.
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
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
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
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()
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()
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, //
127 std::conditional_t< //
128 std::is_constructible<error_type, Args...>::value, //
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;
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{}; }
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{}; }
144 template <class T> struct is_basic_result
146 static constexpr bool value = false;
148 template <class R, class S, class T> struct is_basic_result<basic_result<R, S, T>>
150 static constexpr bool value = true;
152 } // namespace detail
154 /*! AWAITING HUGO JSON CONVERSION TOOL
155 type alias template <class T> is_basic_result. Potential doc page: `is_basic_result<T>`
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
161 template <class T> static constexpr bool is_basic_result_v = detail::is_basic_result<std::decay_t<T>>::value;
163 /*! AWAITING HUGO JSON CONVERSION TOOL
164 SIGNATURE NOT RECOGNISED
168 /*! AWAITING HUGO JSON CONVERSION TOOL
169 SIGNATURE NOT RECOGNISED
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
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
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
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 {}
185 /*! AWAITING HUGO JSON CONVERSION TOOL
186 SIGNATURE NOT RECOGNISED
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
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); }
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>`
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)) //
202 class BOOST_OUTCOME_NODISCARD basic_result : public detail::basic_result_final<R, S, NoValuePolicy>
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");
208 using base = detail::basic_result_final<R, S, NoValuePolicy>;
210 struct implicit_constructors_disabled_tag
213 struct value_converting_constructor_tag
216 struct error_converting_constructor_tag
219 struct error_condition_converting_constructor_tag
222 struct explicit_valueornone_converting_constructor_tag
225 struct explicit_valueorerror_converting_constructor_tag
228 struct explicit_compatible_copy_conversion_tag
231 struct explicit_compatible_move_conversion_tag
234 struct explicit_make_error_code_compatible_copy_conversion_tag
237 struct explicit_make_error_code_compatible_move_conversion_tag
240 struct explicit_make_exception_ptr_compatible_copy_conversion_tag
243 struct explicit_make_exception_ptr_compatible_move_conversion_tag
248 using value_type = R;
249 using error_type = S;
251 using value_type_if_enabled = typename base::_value_type;
252 using error_type_if_enabled = typename base::_error_type;
254 template <class T, class U = S, class V = NoValuePolicy> using rebind = basic_result<T, U, V>;
257 // Requirement predicates for result.
260 using base = detail::result_predicates<value_type, error_type>;
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;
265 // Predicate for implicit constructors to be available at all
266 static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
268 // Predicate for the value converting constructor to be available.
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>;
275 // Predicate for the error converting constructor to be available.
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>;
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>;
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>;
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>;
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>;
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);
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);
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...>;
333 /*! AWAITING HUGO JSON CONVERSION TOOL
334 SIGNATURE NOT RECOGNISED
336 basic_result() = delete;
337 /*! AWAITING HUGO JSON CONVERSION TOOL
338 SIGNATURE NOT RECOGNISED
340 basic_result(basic_result && /*unused*/) = default; // NOLINT
341 /*! AWAITING HUGO JSON CONVERSION TOOL
342 SIGNATURE NOT RECOGNISED
344 basic_result(const basic_result & /*unused*/) = default;
345 /*! AWAITING HUGO JSON CONVERSION TOOL
346 SIGNATURE NOT RECOGNISED
348 basic_result &operator=(basic_result && /*unused*/) = default; // NOLINT
349 /*! AWAITING HUGO JSON CONVERSION TOOL
350 SIGNATURE NOT RECOGNISED
352 basic_result &operator=(const basic_result & /*unused*/) = default;
353 ~basic_result() = default;
355 /*! AWAITING HUGO JSON CONVERSION TOOL
356 SIGNATURE NOT RECOGNISED
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!
362 /*! AWAITING HUGO JSON CONVERSION TOOL
363 SIGNATURE NOT RECOGNISED
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!
370 /*! AWAITING HUGO JSON CONVERSION TOOL
371 SIGNATURE NOT RECOGNISED
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)}
378 using namespace hooks;
379 hook_result_construction(this, static_cast<T &&>(t));
381 /*! AWAITING HUGO JSON CONVERSION TOOL
382 SIGNATURE NOT RECOGNISED
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)}
389 using namespace hooks;
390 hook_result_construction(this, static_cast<T &&>(t));
392 /*! AWAITING HUGO JSON CONVERSION TOOL
393 SIGNATURE NOT RECOGNISED
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)}
401 using namespace hooks;
402 hook_result_construction(this, static_cast<ErrorCondEnum &&>(t));
405 /*! AWAITING HUGO JSON CONVERSION TOOL
406 SIGNATURE NOT RECOGNISED
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))}
415 /*! AWAITING HUGO JSON CONVERSION TOOL
416 SIGNATURE NOT RECOGNISED
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}
423 using namespace hooks;
424 hook_result_copy_construction(this, o);
426 /*! AWAITING HUGO JSON CONVERSION TOOL
427 SIGNATURE NOT RECOGNISED
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)}
434 using namespace hooks;
435 hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
437 /*! AWAITING HUGO JSON CONVERSION TOOL
438 SIGNATURE NOT RECOGNISED
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}
445 using namespace hooks;
446 hook_result_copy_construction(this, o);
448 /*! AWAITING HUGO JSON CONVERSION TOOL
449 SIGNATURE NOT RECOGNISED
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)}
456 using namespace hooks;
457 hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
459 /*! AWAITING HUGO JSON CONVERSION TOOL
460 SIGNATURE NOT RECOGNISED
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}
467 using namespace hooks;
468 hook_result_copy_construction(this, o);
470 /*! AWAITING HUGO JSON CONVERSION TOOL
471 SIGNATURE NOT RECOGNISED
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)}
478 using namespace hooks;
479 hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
482 /*! AWAITING HUGO JSON CONVERSION TOOL
483 SIGNATURE NOT RECOGNISED
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)...}
490 using namespace hooks;
491 hook_result_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
493 /*! AWAITING HUGO JSON CONVERSION TOOL
494 SIGNATURE NOT RECOGNISED
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)...}
501 using namespace hooks;
502 hook_result_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
504 /*! AWAITING HUGO JSON CONVERSION TOOL
505 SIGNATURE NOT RECOGNISED
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)...}
512 using namespace hooks;
513 hook_result_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
515 /*! AWAITING HUGO JSON CONVERSION TOOL
516 SIGNATURE NOT RECOGNISED
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)...}
523 using namespace hooks;
524 hook_result_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
526 /*! AWAITING HUGO JSON CONVERSION TOOL
527 SIGNATURE NOT RECOGNISED
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)...)
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.
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);
541 /*! AWAITING HUGO JSON CONVERSION TOOL
542 SIGNATURE NOT RECOGNISED
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>}
547 using namespace hooks;
548 hook_result_copy_construction(this, o);
550 /*! AWAITING HUGO JSON CONVERSION TOOL
551 SIGNATURE NOT RECOGNISED
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)}
558 using namespace hooks;
559 hook_result_copy_construction(this, o);
561 /*! AWAITING HUGO JSON CONVERSION TOOL
562 SIGNATURE NOT RECOGNISED
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))}
569 using namespace hooks;
570 hook_result_move_construction(this, static_cast<success_type<T> &&>(o));
572 /*! AWAITING HUGO JSON CONVERSION TOOL
573 SIGNATURE NOT RECOGNISED
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)}
580 using namespace hooks;
581 hook_result_copy_construction(this, o);
583 /*! AWAITING HUGO JSON CONVERSION TOOL
584 SIGNATURE NOT RECOGNISED
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))}
591 using namespace hooks;
592 hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
594 /*! AWAITING HUGO JSON CONVERSION TOOL
595 SIGNATURE NOT RECOGNISED
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))}
602 using namespace hooks;
603 hook_result_copy_construction(this, o);
605 /*! AWAITING HUGO JSON CONVERSION TOOL
606 SIGNATURE NOT RECOGNISED
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)))}
613 using namespace hooks;
614 hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
616 /*! AWAITING HUGO JSON CONVERSION TOOL
617 SIGNATURE NOT RECOGNISED
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))}
624 using namespace hooks;
625 hook_result_copy_construction(this, o);
627 /*! AWAITING HUGO JSON CONVERSION TOOL
628 SIGNATURE NOT RECOGNISED
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)))}
635 using namespace hooks;
636 hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
639 /*! AWAITING HUGO JSON CONVERSION TOOL
640 SIGNATURE NOT RECOGNISED
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))
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);
650 /*! AWAITING HUGO JSON CONVERSION TOOL
651 SIGNATURE NOT RECOGNISED
653 auto as_failure() const & {
654 return failure(this->assume_error()); }
655 /*! AWAITING HUGO JSON CONVERSION TOOL
656 SIGNATURE NOT RECOGNISED
658 auto as_failure() && {
659 return failure(static_cast<basic_result &&>(*this).assume_error()); }
662 /*! AWAITING HUGO JSON CONVERSION TOOL
663 SIGNATURE NOT RECOGNISED
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)))
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!");
685 BOOST_OUTCOME_V2_NAMESPACE_END
688 #pragma clang diagnostic pop