]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/outcome/basic_result.hpp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / boost / outcome / basic_result.hpp
CommitLineData
92f5a8d4 1/* A very simple result type
1e59de90 2(C) 2017-2022 Niall Douglas <http://www.nedproductions.biz/> (14 commits)
92f5a8d4
TL
3File Created: June 2017
4
5
6Boost Software License - Version 1.0 - August 17th, 2003
7
8Permission is hereby granted, free of charge, to any person or organization
9obtaining a copy of the software and accompanying documentation covered by
10this license (the "Software") to use, reproduce, display, distribute,
11execute, and transmit the Software, and to prepare derivative works of the
12Software, and to permit third-parties to whom the Software is furnished to
13do so, all subject to the following:
14
15The copyright notices in the Software and this entire statement, including
16the above license grant, this restriction and the following disclaimer,
17must be included in all copies of the Software, in whole or in part, and
18all derivative works of the Software, unless such copies or derivative
19works are solely in the form of machine-executable object code generated by
20a source language processor.
21
22THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
25SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
26FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
27ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28DEALINGS IN THE SOFTWARE.
29*/
30
31#ifndef BOOST_OUTCOME_BASIC_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
46BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
47
f67539c2 48template <class R, class S, class NoValuePolicy> //
92f5a8d4
TL
49class basic_result;
50
51namespace detail
52{
53 // These are reused by basic_outcome to save load on the compiler
54 template <class value_type, class error_type> struct result_predicates
55 {
56 // Predicate for the implicit constructors to be available. Weakened to allow result<int, C enum>.
f67539c2
TL
57 static constexpr bool implicit_constructors_enabled = //
58 !(trait::is_error_type<std::decay_t<value_type>>::value &&
59 trait::is_error_type<std::decay_t<error_type>>::value) // both value and error types are not whitelisted error types
60 && ((!detail::is_implicitly_constructible<value_type, error_type> &&
61 !detail::is_implicitly_constructible<error_type, value_type>) // if value and error types cannot be constructed into one another
62 || (trait::is_error_type<std::decay_t<error_type>>::value // if error type is a whitelisted error type
63 && !detail::is_implicitly_constructible<error_type, value_type> // AND which cannot be constructed from the value type
64 && std::is_integral<value_type>::value)); // AND the value type is some integral type
92f5a8d4
TL
65
66 // Predicate for the value converting constructor to be available. Weakened to allow result<int, C enum>.
67 template <class T>
68 static constexpr bool enable_value_converting_constructor = //
69 implicit_constructors_enabled //
70 && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
71 && !trait::is_error_type_enum<error_type, std::decay_t<T>>::value // not an enum valid for my error type
72 && ((detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T>) // is unambiguously for value type
73 || (std::is_same<value_type, std::decay_t<T>>::value // OR is my value type exactly
f67539c2 74 && detail::is_implicitly_constructible<value_type, T>) ); // and my value type is constructible from this ref form of T
92f5a8d4
TL
75
76
77 // Predicate for the error converting constructor to be available. Weakened to allow result<int, C enum>.
78 template <class T>
79 static constexpr bool enable_error_converting_constructor = //
80 implicit_constructors_enabled //
81 && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
82 && !trait::is_error_type_enum<error_type, std::decay_t<T>>::value // not an enum valid for my error type
83 && ((!detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T>) // is unambiguously for error type
84 || (std::is_same<error_type, std::decay_t<T>>::value // OR is my error type exactly
f67539c2 85 && detail::is_implicitly_constructible<error_type, T>) ); // and my error type is constructible from this ref form of T
92f5a8d4
TL
86
87 // Predicate for the error condition converting constructor to be available.
88 template <class ErrorCondEnum>
f67539c2
TL
89 static constexpr bool enable_error_condition_converting_constructor = //
90 !is_in_place_type_t<std::decay_t<ErrorCondEnum>>::value // not in place construction
91 && trait::is_error_type_enum<error_type, std::decay_t<ErrorCondEnum>>::value // is an error condition enum
92 /*&& !detail::is_implicitly_constructible<value_type, ErrorCondEnum> && !detail::is_implicitly_constructible<error_type, ErrorCondEnum>*/; // not
93 // constructible
94 // via any other
95 // means
92f5a8d4
TL
96
97 // Predicate for the converting constructor from a compatible input to be available.
98 template <class T, class U, class V>
f67539c2
TL
99 static constexpr bool enable_compatible_conversion = //
100 (std::is_void<T>::value ||
101 detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // if our value types are constructible
102 &&(std::is_void<U>::value ||
103 detail::is_explicitly_constructible<error_type, typename basic_result<T, U, V>::error_type>) // if our error types are constructible
92f5a8d4
TL
104 ;
105
106 // Predicate for the converting constructor from a make_error_code() of the input to be available.
107 template <class T, class U, class V>
f67539c2
TL
108 static constexpr bool enable_make_error_code_compatible_conversion = //
109 trait::is_error_code_available<std::decay_t<error_type>>::value // if error type has an error code
110 && !enable_compatible_conversion<T, U, V> // and the normal compatible conversion is not available
111 && (std::is_void<T>::value ||
112 detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // and if our value types are constructible
113 &&detail::is_explicitly_constructible<error_type,
114 typename trait::is_error_code_available<U>::type>; // and our error type is constructible from a make_error_code()
92f5a8d4
TL
115
116 // Predicate for the converting constructor from a make_exception_ptr() of the input to be available.
117 template <class T, class U, class V>
f67539c2
TL
118 static constexpr bool enable_make_exception_ptr_compatible_conversion = //
119 trait::is_exception_ptr_available<std::decay_t<error_type>>::value // if error type has an exception ptr
120 && !enable_compatible_conversion<T, U, V> // and the normal compatible conversion is not available
121 && (std::is_void<T>::value ||
122 detail::is_explicitly_constructible<value_type, typename basic_result<T, U, V>::value_type>) // and if our value types are constructible
123 &&detail::is_explicitly_constructible<error_type, typename trait::is_exception_ptr_available<U>::type>; // and our error type is constructible from a
124 // make_exception_ptr()
92f5a8d4
TL
125
126 // Predicate for the implicit converting inplace constructor from a compatible input to be available.
127 struct disable_inplace_value_error_constructor;
128 template <class... Args>
20effc67
TL
129 using choose_inplace_value_error_constructor = std::conditional_t< //
130 detail::is_constructible<value_type, Args...> && detail::is_constructible<error_type, Args...>, //
131 disable_inplace_value_error_constructor, //
132 std::conditional_t< //
133 detail::is_constructible<value_type, Args...>, //
134 value_type, //
135 std::conditional_t< //
136 detail::is_constructible<error_type, Args...>, //
137 error_type, //
92f5a8d4
TL
138 disable_inplace_value_error_constructor>>>;
139 template <class... Args>
f67539c2
TL
140 static constexpr bool enable_inplace_value_error_constructor =
141 implicit_constructors_enabled //
142 && !std::is_same<choose_inplace_value_error_constructor<Args...>, disable_inplace_value_error_constructor>::value;
92f5a8d4
TL
143 };
144
145 template <class T, class U> constexpr inline const U &extract_value_from_success(const success_type<U> &v) { return v.value(); }
146 template <class T, class U> constexpr inline U &&extract_value_from_success(success_type<U> &&v) { return static_cast<success_type<U> &&>(v).value(); }
147 template <class T> constexpr inline T extract_value_from_success(const success_type<void> & /*unused*/) { return T{}; }
148
149 template <class T, class U, class V> constexpr inline const U &extract_error_from_failure(const failure_type<U, V> &v) { return v.error(); }
f67539c2
TL
150 template <class T, class U, class V> constexpr inline U &&extract_error_from_failure(failure_type<U, V> &&v)
151 {
152 return static_cast<failure_type<U, V> &&>(v).error();
153 }
92f5a8d4
TL
154 template <class T, class V> constexpr inline T extract_error_from_failure(const failure_type<void, V> & /*unused*/) { return T{}; }
155
156 template <class T> struct is_basic_result
157 {
158 static constexpr bool value = false;
159 };
160 template <class R, class S, class T> struct is_basic_result<basic_result<R, S, T>>
161 {
162 static constexpr bool value = true;
163 };
164} // namespace detail
165
166/*! AWAITING HUGO JSON CONVERSION TOOL
167type alias template <class T> is_basic_result. Potential doc page: `is_basic_result<T>`
168*/
169template <class T> using is_basic_result = detail::is_basic_result<std::decay_t<T>>;
170/*! AWAITING HUGO JSON CONVERSION TOOL
171SIGNATURE NOT RECOGNISED
172*/
173template <class T> static constexpr bool is_basic_result_v = detail::is_basic_result<std::decay_t<T>>::value;
174
20effc67
TL
175namespace concepts
176{
177#if defined(__cpp_concepts)
178 /* The `basic_result` concept.
179 \requires That `U` matches a `basic_result`.
180 */
181 template <class U>
182 concept BOOST_OUTCOME_GCC6_CONCEPT_BOOL basic_result =
183 BOOST_OUTCOME_V2_NAMESPACE::is_basic_result<U>::value ||
184 (requires(U v) { BOOST_OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>(v); } && //
185 detail::convertible<U, BOOST_OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>> && //
186 detail::base_of<BOOST_OUTCOME_V2_NAMESPACE::basic_result<typename U::value_type, typename U::error_type, typename U::no_value_policy_type>, U>);
187#else
188 namespace detail
189 {
190 inline no_match match_basic_result(...);
191 template <class R, class S, class NVP, class T, //
192 typename = typename T::value_type, //
193 typename = typename T::error_type, //
194 typename = typename T::no_value_policy_type, //
195 typename std::enable_if_t<std::is_convertible<T, BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP>>::value && //
196 std::is_base_of<BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP>, T>::value,
197 bool> = true>
198 inline BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP> match_basic_result(BOOST_OUTCOME_V2_NAMESPACE::basic_result<R, S, NVP> &&, T &&);
199
200 template <class U>
201 static constexpr bool basic_result = BOOST_OUTCOME_V2_NAMESPACE::is_basic_result<U>::value ||
202 !std::is_same<no_match, decltype(match_basic_result(std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>(),
203 std::declval<BOOST_OUTCOME_V2_NAMESPACE::detail::devoid<U>>()))>::value;
204 } // namespace detail
205 /* The `basic_result` concept.
206 \requires That `U` matches a `basic_result`.
207 */
208 template <class U> static constexpr bool basic_result = detail::basic_result<U>;
209#endif
210} // namespace concepts
211
92f5a8d4
TL
212/*! AWAITING HUGO JSON CONVERSION TOOL
213SIGNATURE NOT RECOGNISED
214*/
215namespace hooks
216{
217 /*! AWAITING HUGO JSON CONVERSION TOOL
218SIGNATURE NOT RECOGNISED
92f5a8d4 219*/
20effc67 220 template <class R, class S, class NoValuePolicy> constexpr inline uint16_t spare_storage(const detail::basic_result_storage<R, S, NoValuePolicy> *r) noexcept
f67539c2
TL
221 {
222 return r->_state._status.spare_storage_value;
223 }
92f5a8d4
TL
224 /*! AWAITING HUGO JSON CONVERSION TOOL
225SIGNATURE NOT RECOGNISED
226*/
f67539c2 227 template <class R, class S, class NoValuePolicy>
20effc67 228 constexpr inline void set_spare_storage(detail::basic_result_storage<R, S, NoValuePolicy> *r, uint16_t v) noexcept
f67539c2
TL
229 {
230 r->_state._status.spare_storage_value = v;
231 }
92f5a8d4
TL
232} // namespace hooks
233
234/*! AWAITING HUGO JSON CONVERSION TOOL
235type definition template <class R, class S, class NoValuePolicy> basic_result. Potential doc page: `basic_result<T, E, NoValuePolicy>`
236*/
f67539c2 237template <class R, class S, class NoValuePolicy> //
92f5a8d4
TL
238class BOOST_OUTCOME_NODISCARD basic_result : public detail::basic_result_final<R, S, NoValuePolicy>
239{
240 static_assert(trait::type_can_be_used_in_basic_result<R>, "The type R cannot be used in a basic_result");
241 static_assert(trait::type_can_be_used_in_basic_result<S>, "The type S cannot be used in a basic_result");
92f5a8d4
TL
242
243 using base = detail::basic_result_final<R, S, NoValuePolicy>;
244
245 struct implicit_constructors_disabled_tag
246 {
247 };
248 struct value_converting_constructor_tag
249 {
250 };
251 struct error_converting_constructor_tag
252 {
253 };
254 struct error_condition_converting_constructor_tag
255 {
256 };
257 struct explicit_valueornone_converting_constructor_tag
258 {
259 };
260 struct explicit_valueorerror_converting_constructor_tag
261 {
262 };
263 struct explicit_compatible_copy_conversion_tag
264 {
265 };
266 struct explicit_compatible_move_conversion_tag
267 {
268 };
269 struct explicit_make_error_code_compatible_copy_conversion_tag
270 {
271 };
272 struct explicit_make_error_code_compatible_move_conversion_tag
273 {
274 };
275 struct explicit_make_exception_ptr_compatible_copy_conversion_tag
276 {
277 };
278 struct explicit_make_exception_ptr_compatible_move_conversion_tag
279 {
280 };
281
282public:
283 using value_type = R;
284 using error_type = S;
20effc67 285 using no_value_policy_type = NoValuePolicy;
92f5a8d4
TL
286
287 using value_type_if_enabled = typename base::_value_type;
288 using error_type_if_enabled = typename base::_error_type;
289
290 template <class T, class U = S, class V = NoValuePolicy> using rebind = basic_result<T, U, V>;
291
292protected:
293 // Requirement predicates for result.
294 struct predicate
295 {
296 using base = detail::result_predicates<value_type, error_type>;
297
298 // Predicate for any constructors to be available at all
299 static constexpr bool constructors_enabled = !std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value;
300
301 // Predicate for implicit constructors to be available at all
302 static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
303
304 // Predicate for the value converting constructor to be available.
305 template <class T>
306 static constexpr bool enable_value_converting_constructor = //
307 constructors_enabled //
308 && !std::is_same<std::decay_t<T>, basic_result>::value // not my type
309 && base::template enable_value_converting_constructor<T>;
310
311 // Predicate for the error converting constructor to be available.
312 template <class T>
313 static constexpr bool enable_error_converting_constructor = //
314 constructors_enabled //
315 && !std::is_same<std::decay_t<T>, basic_result>::value // not my type
316 && base::template enable_error_converting_constructor<T>;
317
318 // Predicate for the error condition converting constructor to be available.
319 template <class ErrorCondEnum>
320 static constexpr bool enable_error_condition_converting_constructor = //
321 constructors_enabled //
322 && !std::is_same<std::decay_t<ErrorCondEnum>, basic_result>::value // not my type
323 && base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
324
325 // Predicate for the converting constructor from a compatible input to be available.
326 template <class T, class U, class V>
327 static constexpr bool enable_compatible_conversion = //
328 constructors_enabled //
329 && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
330 && base::template enable_compatible_conversion<T, U, V>;
331
332 // Predicate for the converting constructor from a make_error_code() of the input to be available.
333 template <class T, class U, class V>
334 static constexpr bool enable_make_error_code_compatible_conversion = //
335 constructors_enabled //
336 && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
337 && base::template enable_make_error_code_compatible_conversion<T, U, V>;
338
339 // Predicate for the converting constructor from a make_exception_ptr() of the input to be available.
340 template <class T, class U, class V>
341 static constexpr bool enable_make_exception_ptr_compatible_conversion = //
342 constructors_enabled //
343 && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
344 && base::template enable_make_exception_ptr_compatible_conversion<T, U, V>;
345
346 // Predicate for the inplace construction of value to be available.
347 template <class... Args>
348 static constexpr bool enable_inplace_value_constructor = //
349 constructors_enabled //
350 && (std::is_void<value_type>::value //
20effc67 351 || detail::is_constructible<value_type, Args...>);
92f5a8d4
TL
352
353 // Predicate for the inplace construction of error to be available.
354 template <class... Args>
355 static constexpr bool enable_inplace_error_constructor = //
356 constructors_enabled //
357 && (std::is_void<error_type>::value //
20effc67 358 || detail::is_constructible<error_type, Args...>);
92f5a8d4
TL
359
360 // Predicate for the implicit converting inplace constructor to be available.
361 template <class... Args>
362 static constexpr bool enable_inplace_value_error_constructor = //
363 constructors_enabled //
364 &&base::template enable_inplace_value_error_constructor<Args...>;
365 template <class... Args> using choose_inplace_value_error_constructor = typename base::template choose_inplace_value_error_constructor<Args...>;
366 };
367
368public:
369 /*! AWAITING HUGO JSON CONVERSION TOOL
370SIGNATURE NOT RECOGNISED
371*/
372 basic_result() = delete;
373 /*! AWAITING HUGO JSON CONVERSION TOOL
374SIGNATURE NOT RECOGNISED
375*/
376 basic_result(basic_result && /*unused*/) = default; // NOLINT
377 /*! AWAITING HUGO JSON CONVERSION TOOL
378SIGNATURE NOT RECOGNISED
379*/
380 basic_result(const basic_result & /*unused*/) = default;
381 /*! AWAITING HUGO JSON CONVERSION TOOL
382SIGNATURE NOT RECOGNISED
383*/
384 basic_result &operator=(basic_result && /*unused*/) = default; // NOLINT
385 /*! AWAITING HUGO JSON CONVERSION TOOL
386SIGNATURE NOT RECOGNISED
387*/
388 basic_result &operator=(const basic_result & /*unused*/) = default;
389 ~basic_result() = default;
390
391 /*! AWAITING HUGO JSON CONVERSION TOOL
392SIGNATURE NOT RECOGNISED
393*/
394 BOOST_OUTCOME_TEMPLATE(class Arg, class... Args)
395 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!predicate::constructors_enabled && (sizeof...(Args) >= 0)))
396 basic_result(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_result<T, T> is NOT SUPPORTED, see docs!
397
398 /*! AWAITING HUGO JSON CONVERSION TOOL
399SIGNATURE NOT RECOGNISED
400*/
401 BOOST_OUTCOME_TEMPLATE(class T)
402 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled //
403 && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T>) )))
f67539c2
TL
404 basic_result(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) =
405 delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs!
92f5a8d4
TL
406
407 /*! AWAITING HUGO JSON CONVERSION TOOL
408SIGNATURE NOT RECOGNISED
409*/
410 BOOST_OUTCOME_TEMPLATE(class T)
411 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
f67539c2 412 constexpr basic_result(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept(
20effc67 413 detail::is_nothrow_constructible<value_type, T>) // NOLINT
92f5a8d4
TL
414 : base{in_place_type<typename base::value_type>, static_cast<T &&>(t)}
415 {
1e59de90 416 no_value_policy_type::on_result_construction(this, static_cast<T &&>(t));
92f5a8d4
TL
417 }
418 /*! AWAITING HUGO JSON CONVERSION TOOL
419SIGNATURE NOT RECOGNISED
420*/
421 BOOST_OUTCOME_TEMPLATE(class T)
422 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>))
f67539c2 423 constexpr basic_result(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept(
20effc67 424 detail::is_nothrow_constructible<error_type, T>) // NOLINT
92f5a8d4
TL
425 : base{in_place_type<typename base::error_type>, static_cast<T &&>(t)}
426 {
1e59de90 427 no_value_policy_type::on_result_construction(this, static_cast<T &&>(t));
92f5a8d4
TL
428 }
429 /*! AWAITING HUGO JSON CONVERSION TOOL
430SIGNATURE NOT RECOGNISED
431*/
432 BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum)
433 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), //
434 BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
f67539c2
TL
435 constexpr basic_result(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept(
436 noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT
92f5a8d4
TL
437 : base{in_place_type<typename base::error_type>, make_error_code(t)}
438 {
1e59de90 439 no_value_policy_type::on_result_construction(this, static_cast<ErrorCondEnum &&>(t));
92f5a8d4
TL
440 }
441
442 /*! AWAITING HUGO JSON CONVERSION TOOL
443SIGNATURE NOT RECOGNISED
444*/
445 BOOST_OUTCOME_TEMPLATE(class T)
20effc67 446 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_result, std::decay_t<T>>::enable_result_inputs || !concepts::basic_result<T>), //
92f5a8d4 447 BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_result, std::decay_t<T>>{}(std::declval<T>())))
f67539c2
TL
448 constexpr explicit basic_result(T &&o,
449 explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT
92f5a8d4
TL
450 : basic_result{convert::value_or_error<basic_result, std::decay_t<T>>{}(static_cast<T &&>(o))}
451 {
452 }
453 /*! AWAITING HUGO JSON CONVERSION TOOL
454SIGNATURE NOT RECOGNISED
455*/
456 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
457 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>))
f67539c2
TL
458 constexpr explicit basic_result(
459 const basic_result<T, U, V> &o,
460 explicit_compatible_copy_conversion_tag /*unused*/ =
20effc67 461 explicit_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>)
92f5a8d4
TL
462 : base{typename base::compatible_conversion_tag(), o}
463 {
1e59de90 464 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
465 }
466 /*! AWAITING HUGO JSON CONVERSION TOOL
467SIGNATURE NOT RECOGNISED
468*/
469 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
470 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>))
f67539c2
TL
471 constexpr explicit basic_result(
472 basic_result<T, U, V> &&o,
473 explicit_compatible_move_conversion_tag /*unused*/ =
20effc67 474 explicit_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T> &&detail::is_nothrow_constructible<error_type, U>)
92f5a8d4
TL
475 : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
476 {
1e59de90 477 no_value_policy_type::on_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
92f5a8d4
TL
478 }
479 /*! AWAITING HUGO JSON CONVERSION TOOL
480SIGNATURE NOT RECOGNISED
481*/
482 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
483 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
f67539c2
TL
484 constexpr explicit basic_result(const basic_result<T, U, V> &o,
485 explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
20effc67 486 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
f67539c2 487 &&noexcept(make_error_code(std::declval<U>())))
92f5a8d4
TL
488 : base{typename base::make_error_code_compatible_conversion_tag(), o}
489 {
1e59de90 490 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
491 }
492 /*! AWAITING HUGO JSON CONVERSION TOOL
493SIGNATURE NOT RECOGNISED
494*/
495 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
496 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
f67539c2
TL
497 constexpr explicit basic_result(basic_result<T, U, V> &&o,
498 explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
20effc67 499 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
f67539c2 500 &&noexcept(make_error_code(std::declval<U>())))
92f5a8d4
TL
501 : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
502 {
1e59de90 503 no_value_policy_type::on_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
92f5a8d4
TL
504 }
505 /*! AWAITING HUGO JSON CONVERSION TOOL
506SIGNATURE NOT RECOGNISED
507*/
508 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
509 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
f67539c2
TL
510 constexpr explicit basic_result(const basic_result<T, U, V> &o,
511 explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ =
20effc67 512 explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
f67539c2 513 &&noexcept(make_exception_ptr(std::declval<U>())))
92f5a8d4
TL
514 : base{typename base::make_exception_ptr_compatible_conversion_tag(), o}
515 {
1e59de90 516 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
517 }
518 /*! AWAITING HUGO JSON CONVERSION TOOL
519SIGNATURE NOT RECOGNISED
520*/
521 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
522 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
f67539c2
TL
523 constexpr explicit basic_result(basic_result<T, U, V> &&o,
524 explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ =
20effc67 525 explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(detail::is_nothrow_constructible<value_type, T>
f67539c2 526 &&noexcept(make_exception_ptr(std::declval<U>())))
92f5a8d4
TL
527 : base{typename base::make_exception_ptr_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
528 {
1e59de90 529 no_value_policy_type::on_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
92f5a8d4
TL
530 }
531
532 /*! AWAITING HUGO JSON CONVERSION TOOL
533SIGNATURE NOT RECOGNISED
534*/
535 BOOST_OUTCOME_TEMPLATE(class... Args)
536 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
20effc67 537 constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, Args...>)
92f5a8d4
TL
538 : base{_, static_cast<Args &&>(args)...}
539 {
1e59de90 540 no_value_policy_type::on_result_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
92f5a8d4
TL
541 }
542 /*! AWAITING HUGO JSON CONVERSION TOOL
543SIGNATURE NOT RECOGNISED
544*/
545 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
546 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
f67539c2 547 constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il,
20effc67 548 Args &&... args) noexcept(detail::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>)
92f5a8d4
TL
549 : base{_, il, static_cast<Args &&>(args)...}
550 {
1e59de90 551 no_value_policy_type::on_result_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
92f5a8d4
TL
552 }
553 /*! AWAITING HUGO JSON CONVERSION TOOL
554SIGNATURE NOT RECOGNISED
555*/
556 BOOST_OUTCOME_TEMPLATE(class... Args)
557 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
20effc67 558 constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, Args...>)
92f5a8d4
TL
559 : base{_, static_cast<Args &&>(args)...}
560 {
1e59de90 561 no_value_policy_type::on_result_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
92f5a8d4
TL
562 }
563 /*! AWAITING HUGO JSON CONVERSION TOOL
564SIGNATURE NOT RECOGNISED
565*/
566 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
567 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
f67539c2 568 constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il,
20effc67 569 Args &&... args) noexcept(detail::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>)
92f5a8d4
TL
570 : base{_, il, static_cast<Args &&>(args)...}
571 {
1e59de90 572 no_value_policy_type::on_result_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
92f5a8d4
TL
573 }
574 /*! AWAITING HUGO JSON CONVERSION TOOL
575SIGNATURE NOT RECOGNISED
576*/
577 BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args)
578 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_constructor<A1, A2, Args...>))
f67539c2
TL
579 constexpr basic_result(A1 &&a1, A2 &&a2, Args &&... args) noexcept(noexcept(
580 typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(), std::declval<Args>()...)))
581 : basic_result(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1),
582 static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
92f5a8d4 583 {
92f5a8d4
TL
584 }
585
586 /*! AWAITING HUGO JSON CONVERSION TOOL
587SIGNATURE NOT RECOGNISED
588*/
589 constexpr basic_result(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT
590 : base{in_place_type<value_type_if_enabled>}
591 {
1e59de90
TL
592 hooks::set_spare_storage(this, o.spare_storage());
593 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
594 }
595 /*! AWAITING HUGO JSON CONVERSION TOOL
596SIGNATURE NOT RECOGNISED
597*/
598 BOOST_OUTCOME_TEMPLATE(class T)
599 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, void, void>))
20effc67 600 constexpr basic_result(const success_type<T> &o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
92f5a8d4
TL
601 : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(o)}
602 {
1e59de90
TL
603 hooks::set_spare_storage(this, o.spare_storage());
604 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
605 }
606 /*! AWAITING HUGO JSON CONVERSION TOOL
607SIGNATURE NOT RECOGNISED
608*/
609 BOOST_OUTCOME_TEMPLATE(class T)
610 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void>))
20effc67 611 constexpr basic_result(success_type<T> &&o) noexcept(detail::is_nothrow_constructible<value_type, T>) // NOLINT
92f5a8d4
TL
612 : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
613 {
1e59de90
TL
614 hooks::set_spare_storage(this, o.spare_storage());
615 no_value_policy_type::on_result_move_construction(this, static_cast<success_type<T> &&>(o));
92f5a8d4
TL
616 }
617 /*! AWAITING HUGO JSON CONVERSION TOOL
618SIGNATURE NOT RECOGNISED
619*/
620 BOOST_OUTCOME_TEMPLATE(class T)
621 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
f67539c2 622 constexpr basic_result(const failure_type<T> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(
20effc67 623 detail::is_nothrow_constructible<error_type, T>) // NOLINT
92f5a8d4
TL
624 : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(o)}
625 {
1e59de90
TL
626 hooks::set_spare_storage(this, o.spare_storage());
627 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
628 }
629 /*! AWAITING HUGO JSON CONVERSION TOOL
630SIGNATURE NOT RECOGNISED
631*/
632 BOOST_OUTCOME_TEMPLATE(class T)
633 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
f67539c2 634 constexpr basic_result(failure_type<T> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(
20effc67 635 detail::is_nothrow_constructible<error_type, T>) // NOLINT
92f5a8d4
TL
636 : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
637 {
1e59de90
TL
638 hooks::set_spare_storage(this, o.spare_storage());
639 no_value_policy_type::on_result_move_construction(this, static_cast<failure_type<T> &&>(o));
92f5a8d4
TL
640 }
641 /*! AWAITING HUGO JSON CONVERSION TOOL
642SIGNATURE NOT RECOGNISED
643*/
644 BOOST_OUTCOME_TEMPLATE(class T)
645 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
f67539c2
TL
646 constexpr basic_result(const failure_type<T> &o,
647 explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
648 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
92f5a8d4
TL
649 : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
650 {
1e59de90
TL
651 hooks::set_spare_storage(this, o.spare_storage());
652 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
653 }
654 /*! AWAITING HUGO JSON CONVERSION TOOL
655SIGNATURE NOT RECOGNISED
656*/
657 BOOST_OUTCOME_TEMPLATE(class T)
658 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
f67539c2
TL
659 constexpr basic_result(failure_type<T> &&o,
660 explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
661 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
92f5a8d4
TL
662 : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
663 {
1e59de90
TL
664 hooks::set_spare_storage(this, o.spare_storage());
665 no_value_policy_type::on_result_move_construction(this, static_cast<failure_type<T> &&>(o));
92f5a8d4
TL
666 }
667 /*! AWAITING HUGO JSON CONVERSION TOOL
668SIGNATURE NOT RECOGNISED
669*/
670 BOOST_OUTCOME_TEMPLATE(class T)
671 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
f67539c2
TL
672 constexpr basic_result(const failure_type<T> &o,
673 explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ =
674 explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT
92f5a8d4
TL
675 : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(o))}
676 {
1e59de90
TL
677 hooks::set_spare_storage(this, o.spare_storage());
678 no_value_policy_type::on_result_copy_construction(this, o);
92f5a8d4
TL
679 }
680 /*! AWAITING HUGO JSON CONVERSION TOOL
681SIGNATURE NOT RECOGNISED
682*/
683 BOOST_OUTCOME_TEMPLATE(class T)
684 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
f67539c2
TL
685 constexpr basic_result(failure_type<T> &&o,
686 explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ =
687 explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT
92f5a8d4
TL
688 : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
689 {
1e59de90
TL
690 hooks::set_spare_storage(this, o.spare_storage());
691 no_value_policy_type::on_result_move_construction(this, static_cast<failure_type<T> &&>(o));
92f5a8d4
TL
692 }
693
694 /*! AWAITING HUGO JSON CONVERSION TOOL
695SIGNATURE NOT RECOGNISED
696*/
697 constexpr void swap(basic_result &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) //
698 && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value))
699 {
1e59de90 700 this->_state.swap(o._state);
92f5a8d4
TL
701 }
702
703 /*! AWAITING HUGO JSON CONVERSION TOOL
704SIGNATURE NOT RECOGNISED
705*/
1e59de90 706 auto as_failure() const & { return failure(this->assume_error(), hooks::spare_storage(this)); }
92f5a8d4
TL
707 /*! AWAITING HUGO JSON CONVERSION TOOL
708SIGNATURE NOT RECOGNISED
709*/
1e59de90
TL
710 auto as_failure() &&
711 {
712 this->_state._status.set_have_moved_from(true);
713 return failure(static_cast<basic_result &&>(*this).assume_error(), hooks::spare_storage(this));
714 }
20effc67
TL
715
716#ifdef __APPLE__
717 failure_type<error_type> _xcode_workaround_as_failure() &&;
718#endif
92f5a8d4
TL
719};
720
721/*! AWAITING HUGO JSON CONVERSION TOOL
722SIGNATURE NOT RECOGNISED
723*/
724template <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)))
725{
726 a.swap(b);
727}
728
729#if !defined(NDEBUG)
730// Check is trivial in all ways except default constructibility
731// static_assert(std::is_trivial<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivial!");
f67539c2
TL
732// static_assert(std::is_trivially_default_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially default
733// constructible!");
92f5a8d4 734static_assert(std::is_trivially_copyable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copyable!");
f67539c2
TL
735static_assert(std::is_trivially_assignable<basic_result<int, long, policy::all_narrow>, basic_result<int, long, policy::all_narrow>>::value,
736 "result<int> is not trivially assignable!");
92f5a8d4
TL
737static_assert(std::is_trivially_destructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially destructible!");
738static_assert(std::is_trivially_copy_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy constructible!");
739static_assert(std::is_trivially_move_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move constructible!");
740static_assert(std::is_trivially_copy_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy assignable!");
741static_assert(std::is_trivially_move_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move assignable!");
742// Also check is standard layout
743static_assert(std::is_standard_layout<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not a standard layout type!");
744#endif
745
746BOOST_OUTCOME_V2_NAMESPACE_END
747
748#ifdef __clang__
749#pragma clang diagnostic pop
750#endif
751
752#endif