]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/outcome/basic_result.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / outcome / basic_result.hpp
1 /* A very simple result type
2 (C) 2017-2020 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 class basic_result;
50
51 namespace 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>.
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
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
74 && detail::is_implicitly_constructible<value_type, T>) ); // and my value type is constructible from this ref form of T
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
85 && detail::is_implicitly_constructible<error_type, T>) ); // and my error type is constructible from this ref form of T
86
87 // Predicate for the error condition converting constructor to be available.
88 template <class ErrorCondEnum>
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
96
97 // Predicate for the converting constructor from a compatible input to be available.
98 template <class T, class U, class V>
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
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>
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()
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>
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()
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>
129 using choose_inplace_value_error_constructor = std::conditional_t< //
130 std::is_constructible<value_type, Args...>::value && std::is_constructible<error_type, Args...>::value, //
131 disable_inplace_value_error_constructor, //
132 std::conditional_t< //
133 std::is_constructible<value_type, Args...>::value, //
134 value_type, //
135 std::conditional_t< //
136 std::is_constructible<error_type, Args...>::value, //
137 error_type, //
138 disable_inplace_value_error_constructor>>>;
139 template <class... Args>
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;
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(); }
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 }
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
167 type alias template <class T> is_basic_result. Potential doc page: `is_basic_result<T>`
168 */
169 template <class T> using is_basic_result = detail::is_basic_result<std::decay_t<T>>;
170 /*! AWAITING HUGO JSON CONVERSION TOOL
171 SIGNATURE NOT RECOGNISED
172 */
173 template <class T> static constexpr bool is_basic_result_v = detail::is_basic_result<std::decay_t<T>>::value;
174
175 /*! AWAITING HUGO JSON CONVERSION TOOL
176 SIGNATURE NOT RECOGNISED
177 */
178 namespace hooks
179 {
180 /*! AWAITING HUGO JSON CONVERSION TOOL
181 SIGNATURE NOT RECOGNISED
182 */
183 template <class T, class U> constexpr inline void hook_result_construction(T * /*unused*/, U && /*unused*/) noexcept {}
184 /*! AWAITING HUGO JSON CONVERSION TOOL
185 SIGNATURE NOT RECOGNISED
186 */
187 template <class T, class U> constexpr inline void hook_result_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {}
188 /*! AWAITING HUGO JSON CONVERSION TOOL
189 SIGNATURE NOT RECOGNISED
190 */
191 template <class T, class U> constexpr inline void hook_result_move_construction(T * /*unused*/, U && /*unused*/) noexcept {}
192 /*! AWAITING HUGO JSON CONVERSION TOOL
193 SIGNATURE NOT RECOGNISED
194 */
195 template <class T, class U, class... Args>
196 constexpr inline void hook_result_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept
197 {
198 }
199
200 /*! AWAITING HUGO JSON CONVERSION TOOL
201 SIGNATURE NOT RECOGNISED
202 */
203 template <class R, class S, class NoValuePolicy> constexpr inline uint16_t spare_storage(const detail::basic_result_final<R, S, NoValuePolicy> *r) noexcept
204 {
205 return r->_state._status.spare_storage_value;
206 }
207 /*! AWAITING HUGO JSON CONVERSION TOOL
208 SIGNATURE NOT RECOGNISED
209 */
210 template <class R, class S, class NoValuePolicy>
211 constexpr inline void set_spare_storage(detail::basic_result_final<R, S, NoValuePolicy> *r, uint16_t v) noexcept
212 {
213 r->_state._status.spare_storage_value = v;
214 }
215 } // namespace hooks
216
217 /*! AWAITING HUGO JSON CONVERSION TOOL
218 type definition template <class R, class S, class NoValuePolicy> basic_result. Potential doc page: `basic_result<T, E, NoValuePolicy>`
219 */
220 template <class R, class S, class NoValuePolicy> //
221 class BOOST_OUTCOME_NODISCARD basic_result : public detail::basic_result_final<R, S, NoValuePolicy>
222 {
223 static_assert(trait::type_can_be_used_in_basic_result<R>, "The type R cannot be used in a basic_result");
224 static_assert(trait::type_can_be_used_in_basic_result<S>, "The type S cannot be used in a basic_result");
225 static_assert(std::is_void<S>::value || std::is_default_constructible<S>::value, "The type S must be void or default constructible");
226
227 using base = detail::basic_result_final<R, S, NoValuePolicy>;
228
229 struct implicit_constructors_disabled_tag
230 {
231 };
232 struct value_converting_constructor_tag
233 {
234 };
235 struct error_converting_constructor_tag
236 {
237 };
238 struct error_condition_converting_constructor_tag
239 {
240 };
241 struct explicit_valueornone_converting_constructor_tag
242 {
243 };
244 struct explicit_valueorerror_converting_constructor_tag
245 {
246 };
247 struct explicit_compatible_copy_conversion_tag
248 {
249 };
250 struct explicit_compatible_move_conversion_tag
251 {
252 };
253 struct explicit_make_error_code_compatible_copy_conversion_tag
254 {
255 };
256 struct explicit_make_error_code_compatible_move_conversion_tag
257 {
258 };
259 struct explicit_make_exception_ptr_compatible_copy_conversion_tag
260 {
261 };
262 struct explicit_make_exception_ptr_compatible_move_conversion_tag
263 {
264 };
265
266 public:
267 using value_type = R;
268 using error_type = S;
269
270 using value_type_if_enabled = typename base::_value_type;
271 using error_type_if_enabled = typename base::_error_type;
272
273 template <class T, class U = S, class V = NoValuePolicy> using rebind = basic_result<T, U, V>;
274
275 protected:
276 // Requirement predicates for result.
277 struct predicate
278 {
279 using base = detail::result_predicates<value_type, error_type>;
280
281 // Predicate for any constructors to be available at all
282 static constexpr bool constructors_enabled = !std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value;
283
284 // Predicate for implicit constructors to be available at all
285 static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
286
287 // Predicate for the value converting constructor to be available.
288 template <class T>
289 static constexpr bool enable_value_converting_constructor = //
290 constructors_enabled //
291 && !std::is_same<std::decay_t<T>, basic_result>::value // not my type
292 && base::template enable_value_converting_constructor<T>;
293
294 // Predicate for the error converting constructor to be available.
295 template <class T>
296 static constexpr bool enable_error_converting_constructor = //
297 constructors_enabled //
298 && !std::is_same<std::decay_t<T>, basic_result>::value // not my type
299 && base::template enable_error_converting_constructor<T>;
300
301 // Predicate for the error condition converting constructor to be available.
302 template <class ErrorCondEnum>
303 static constexpr bool enable_error_condition_converting_constructor = //
304 constructors_enabled //
305 && !std::is_same<std::decay_t<ErrorCondEnum>, basic_result>::value // not my type
306 && base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
307
308 // Predicate for the converting constructor from a compatible input to be available.
309 template <class T, class U, class V>
310 static constexpr bool enable_compatible_conversion = //
311 constructors_enabled //
312 && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
313 && base::template enable_compatible_conversion<T, U, V>;
314
315 // Predicate for the converting constructor from a make_error_code() of the input to be available.
316 template <class T, class U, class V>
317 static constexpr bool enable_make_error_code_compatible_conversion = //
318 constructors_enabled //
319 && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
320 && base::template enable_make_error_code_compatible_conversion<T, U, V>;
321
322 // Predicate for the converting constructor from a make_exception_ptr() of the input to be available.
323 template <class T, class U, class V>
324 static constexpr bool enable_make_exception_ptr_compatible_conversion = //
325 constructors_enabled //
326 && !std::is_same<basic_result<T, U, V>, basic_result>::value // not my type
327 && base::template enable_make_exception_ptr_compatible_conversion<T, U, V>;
328
329 // Predicate for the inplace construction of value to be available.
330 template <class... Args>
331 static constexpr bool enable_inplace_value_constructor = //
332 constructors_enabled //
333 && (std::is_void<value_type>::value //
334 || std::is_constructible<value_type, Args...>::value);
335
336 // Predicate for the inplace construction of error to be available.
337 template <class... Args>
338 static constexpr bool enable_inplace_error_constructor = //
339 constructors_enabled //
340 && (std::is_void<error_type>::value //
341 || std::is_constructible<error_type, Args...>::value);
342
343 // Predicate for the implicit converting inplace constructor to be available.
344 template <class... Args>
345 static constexpr bool enable_inplace_value_error_constructor = //
346 constructors_enabled //
347 &&base::template enable_inplace_value_error_constructor<Args...>;
348 template <class... Args> using choose_inplace_value_error_constructor = typename base::template choose_inplace_value_error_constructor<Args...>;
349 };
350
351 public:
352 /*! AWAITING HUGO JSON CONVERSION TOOL
353 SIGNATURE NOT RECOGNISED
354 */
355 basic_result() = delete;
356 /*! AWAITING HUGO JSON CONVERSION TOOL
357 SIGNATURE NOT RECOGNISED
358 */
359 basic_result(basic_result && /*unused*/) = default; // NOLINT
360 /*! AWAITING HUGO JSON CONVERSION TOOL
361 SIGNATURE NOT RECOGNISED
362 */
363 basic_result(const basic_result & /*unused*/) = default;
364 /*! AWAITING HUGO JSON CONVERSION TOOL
365 SIGNATURE NOT RECOGNISED
366 */
367 basic_result &operator=(basic_result && /*unused*/) = default; // NOLINT
368 /*! AWAITING HUGO JSON CONVERSION TOOL
369 SIGNATURE NOT RECOGNISED
370 */
371 basic_result &operator=(const basic_result & /*unused*/) = default;
372 ~basic_result() = default;
373
374 /*! AWAITING HUGO JSON CONVERSION TOOL
375 SIGNATURE NOT RECOGNISED
376 */
377 BOOST_OUTCOME_TEMPLATE(class Arg, class... Args)
378 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!predicate::constructors_enabled && (sizeof...(Args) >= 0)))
379 basic_result(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_result<T, T> is NOT SUPPORTED, see docs!
380
381 /*! AWAITING HUGO JSON CONVERSION TOOL
382 SIGNATURE NOT RECOGNISED
383 */
384 BOOST_OUTCOME_TEMPLATE(class T)
385 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((predicate::constructors_enabled && !predicate::implicit_constructors_enabled //
386 && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T>) )))
387 basic_result(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) =
388 delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs!
389
390 /*! AWAITING HUGO JSON CONVERSION TOOL
391 SIGNATURE NOT RECOGNISED
392 */
393 BOOST_OUTCOME_TEMPLATE(class T)
394 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
395 constexpr basic_result(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept(
396 std::is_nothrow_constructible<value_type, T>::value) // NOLINT
397 : base{in_place_type<typename base::value_type>, static_cast<T &&>(t)}
398 {
399 using namespace hooks;
400 hook_result_construction(this, static_cast<T &&>(t));
401 }
402 /*! AWAITING HUGO JSON CONVERSION TOOL
403 SIGNATURE NOT RECOGNISED
404 */
405 BOOST_OUTCOME_TEMPLATE(class T)
406 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>))
407 constexpr basic_result(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept(
408 std::is_nothrow_constructible<error_type, T>::value) // NOLINT
409 : base{in_place_type<typename base::error_type>, static_cast<T &&>(t)}
410 {
411 using namespace hooks;
412 hook_result_construction(this, static_cast<T &&>(t));
413 }
414 /*! AWAITING HUGO JSON CONVERSION TOOL
415 SIGNATURE NOT RECOGNISED
416 */
417 BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum)
418 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), //
419 BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
420 constexpr basic_result(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept(
421 noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT
422 : base{in_place_type<typename base::error_type>, make_error_code(t)}
423 {
424 using namespace hooks;
425 hook_result_construction(this, static_cast<ErrorCondEnum &&>(t));
426 }
427
428 /*! AWAITING HUGO JSON CONVERSION TOOL
429 SIGNATURE NOT RECOGNISED
430 */
431 BOOST_OUTCOME_TEMPLATE(class T)
432 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_result, std::decay_t<T>>::enable_result_inputs || !is_basic_result_v<T>), //
433 BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_result, std::decay_t<T>>{}(std::declval<T>())))
434 constexpr explicit basic_result(T &&o,
435 explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT
436 : basic_result{convert::value_or_error<basic_result, std::decay_t<T>>{}(static_cast<T &&>(o))}
437 {
438 }
439 /*! AWAITING HUGO JSON CONVERSION TOOL
440 SIGNATURE NOT RECOGNISED
441 */
442 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
443 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V>))
444 constexpr explicit basic_result(
445 const basic_result<T, U, V> &o,
446 explicit_compatible_copy_conversion_tag /*unused*/ =
447 explicit_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value &&std::is_nothrow_constructible<error_type, U>::value)
448 : base{typename base::compatible_conversion_tag(), o}
449 {
450 using namespace hooks;
451 hook_result_copy_construction(this, o);
452 }
453 /*! AWAITING HUGO JSON CONVERSION TOOL
454 SIGNATURE 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>))
458 constexpr explicit basic_result(
459 basic_result<T, U, V> &&o,
460 explicit_compatible_move_conversion_tag /*unused*/ =
461 explicit_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value &&std::is_nothrow_constructible<error_type, U>::value)
462 : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
463 {
464 using namespace hooks;
465 hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
466 }
467 /*! AWAITING HUGO JSON CONVERSION TOOL
468 SIGNATURE NOT RECOGNISED
469 */
470 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
471 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
472 constexpr explicit basic_result(const basic_result<T, U, V> &o,
473 explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
474 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value
475 &&noexcept(make_error_code(std::declval<U>())))
476 : base{typename base::make_error_code_compatible_conversion_tag(), o}
477 {
478 using namespace hooks;
479 hook_result_copy_construction(this, o);
480 }
481 /*! AWAITING HUGO JSON CONVERSION TOOL
482 SIGNATURE NOT RECOGNISED
483 */
484 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
485 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<T, U, V>))
486 constexpr explicit basic_result(basic_result<T, U, V> &&o,
487 explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
488 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value
489 &&noexcept(make_error_code(std::declval<U>())))
490 : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
491 {
492 using namespace hooks;
493 hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
494 }
495 /*! AWAITING HUGO JSON CONVERSION TOOL
496 SIGNATURE NOT RECOGNISED
497 */
498 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
499 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
500 constexpr explicit basic_result(const basic_result<T, U, V> &o,
501 explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ =
502 explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value
503 &&noexcept(make_exception_ptr(std::declval<U>())))
504 : base{typename base::make_exception_ptr_compatible_conversion_tag(), o}
505 {
506 using namespace hooks;
507 hook_result_copy_construction(this, o);
508 }
509 /*! AWAITING HUGO JSON CONVERSION TOOL
510 SIGNATURE NOT RECOGNISED
511 */
512 BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
513 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<T, U, V>))
514 constexpr explicit basic_result(basic_result<T, U, V> &&o,
515 explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ =
516 explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value
517 &&noexcept(make_exception_ptr(std::declval<U>())))
518 : base{typename base::make_exception_ptr_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
519 {
520 using namespace hooks;
521 hook_result_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
522 }
523
524 /*! AWAITING HUGO JSON CONVERSION TOOL
525 SIGNATURE NOT RECOGNISED
526 */
527 BOOST_OUTCOME_TEMPLATE(class... Args)
528 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
529 constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, Args &&... args) noexcept(std::is_nothrow_constructible<value_type, Args...>::value)
530 : base{_, static_cast<Args &&>(args)...}
531 {
532 using namespace hooks;
533 hook_result_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
534 }
535 /*! AWAITING HUGO JSON CONVERSION TOOL
536 SIGNATURE NOT RECOGNISED
537 */
538 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
539 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
540 constexpr explicit basic_result(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il,
541 Args &&... args) noexcept(std::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>::value)
542 : base{_, il, static_cast<Args &&>(args)...}
543 {
544 using namespace hooks;
545 hook_result_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
546 }
547 /*! AWAITING HUGO JSON CONVERSION TOOL
548 SIGNATURE NOT RECOGNISED
549 */
550 BOOST_OUTCOME_TEMPLATE(class... Args)
551 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
552 constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, Args &&... args) noexcept(std::is_nothrow_constructible<error_type, Args...>::value)
553 : base{_, static_cast<Args &&>(args)...}
554 {
555 using namespace hooks;
556 hook_result_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
557 }
558 /*! AWAITING HUGO JSON CONVERSION TOOL
559 SIGNATURE NOT RECOGNISED
560 */
561 BOOST_OUTCOME_TEMPLATE(class U, class... Args)
562 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
563 constexpr explicit basic_result(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il,
564 Args &&... args) noexcept(std::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>::value)
565 : base{_, il, static_cast<Args &&>(args)...}
566 {
567 using namespace hooks;
568 hook_result_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
569 }
570 /*! AWAITING HUGO JSON CONVERSION TOOL
571 SIGNATURE NOT RECOGNISED
572 */
573 BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args)
574 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_constructor<A1, A2, Args...>))
575 constexpr basic_result(A1 &&a1, A2 &&a2, Args &&... args) noexcept(noexcept(
576 typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(), std::declval<Args>()...)))
577 : basic_result(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1),
578 static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
579 {
580 /* I was a little surprised that the below is needed given that we forward to another constructor.
581 But it turns out that ADL only fires on the first constructor for some reason.
582 */
583 using namespace hooks;
584 // hook_result_in_place_construction(in_place_type<typename predicate::template choose_inplace_value_error_constructor<A1, A2, Args...>>, this);
585 }
586
587 /*! AWAITING HUGO JSON CONVERSION TOOL
588 SIGNATURE NOT RECOGNISED
589 */
590 constexpr basic_result(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT
591 : base{in_place_type<value_type_if_enabled>}
592 {
593 using namespace hooks;
594 hook_result_copy_construction(this, o);
595 }
596 /*! AWAITING HUGO JSON CONVERSION TOOL
597 SIGNATURE NOT RECOGNISED
598 */
599 BOOST_OUTCOME_TEMPLATE(class T)
600 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, void, void>))
601 constexpr basic_result(const success_type<T> &o) noexcept(std::is_nothrow_constructible<value_type, T>::value) // NOLINT
602 : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(o)}
603 {
604 using namespace hooks;
605 hook_result_copy_construction(this, o);
606 }
607 /*! AWAITING HUGO JSON CONVERSION TOOL
608 SIGNATURE NOT RECOGNISED
609 */
610 BOOST_OUTCOME_TEMPLATE(class T)
611 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void>))
612 constexpr basic_result(success_type<T> &&o) noexcept(std::is_nothrow_constructible<value_type, T>::value) // NOLINT
613 : base{in_place_type<value_type_if_enabled>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
614 {
615 using namespace hooks;
616 hook_result_move_construction(this, static_cast<success_type<T> &&>(o));
617 }
618 /*! AWAITING HUGO JSON CONVERSION TOOL
619 SIGNATURE NOT RECOGNISED
620 */
621 BOOST_OUTCOME_TEMPLATE(class T)
622 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
623 constexpr basic_result(const failure_type<T> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(
624 std::is_nothrow_constructible<error_type, T>::value) // NOLINT
625 : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(o)}
626 {
627 using namespace hooks;
628 hook_result_copy_construction(this, o);
629 }
630 /*! AWAITING HUGO JSON CONVERSION TOOL
631 SIGNATURE NOT RECOGNISED
632 */
633 BOOST_OUTCOME_TEMPLATE(class T)
634 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<void, T, void>))
635 constexpr basic_result(failure_type<T> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(
636 std::is_nothrow_constructible<error_type, T>::value) // NOLINT
637 : base{in_place_type<error_type_if_enabled>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
638 {
639 using namespace hooks;
640 hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
641 }
642 /*! AWAITING HUGO JSON CONVERSION TOOL
643 SIGNATURE NOT RECOGNISED
644 */
645 BOOST_OUTCOME_TEMPLATE(class T)
646 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
647 constexpr basic_result(const failure_type<T> &o,
648 explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
649 explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
650 : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
651 {
652 using namespace hooks;
653 hook_result_copy_construction(this, o);
654 }
655 /*! AWAITING HUGO JSON CONVERSION TOOL
656 SIGNATURE NOT RECOGNISED
657 */
658 BOOST_OUTCOME_TEMPLATE(class T)
659 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_error_code_compatible_conversion<void, T, void>))
660 constexpr basic_result(failure_type<T> &&o,
661 explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
662 explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
663 : base{in_place_type<error_type_if_enabled>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
664 {
665 using namespace hooks;
666 hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
667 }
668 /*! AWAITING HUGO JSON CONVERSION TOOL
669 SIGNATURE NOT RECOGNISED
670 */
671 BOOST_OUTCOME_TEMPLATE(class T)
672 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
673 constexpr basic_result(const failure_type<T> &o,
674 explicit_make_exception_ptr_compatible_copy_conversion_tag /*unused*/ =
675 explicit_make_exception_ptr_compatible_copy_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT
676 : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(o))}
677 {
678 using namespace hooks;
679 hook_result_copy_construction(this, o);
680 }
681 /*! AWAITING HUGO JSON CONVERSION TOOL
682 SIGNATURE NOT RECOGNISED
683 */
684 BOOST_OUTCOME_TEMPLATE(class T)
685 BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_make_exception_ptr_compatible_conversion<void, T, void>))
686 constexpr basic_result(failure_type<T> &&o,
687 explicit_make_exception_ptr_compatible_move_conversion_tag /*unused*/ =
688 explicit_make_exception_ptr_compatible_move_conversion_tag()) noexcept(noexcept(make_exception_ptr(std::declval<T>()))) // NOLINT
689 : base{in_place_type<error_type_if_enabled>, make_exception_ptr(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
690 {
691 using namespace hooks;
692 hook_result_move_construction(this, static_cast<failure_type<T> &&>(o));
693 }
694
695 /*! AWAITING HUGO JSON CONVERSION TOOL
696 SIGNATURE NOT RECOGNISED
697 */
698 constexpr void swap(basic_result &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) //
699 && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value))
700 {
701 constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value;
702 constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value;
703 detail::basic_result_storage_swap<value_throws, error_throws>(*this, o);
704 }
705
706 /*! AWAITING HUGO JSON CONVERSION TOOL
707 SIGNATURE NOT RECOGNISED
708 */
709 auto as_failure() const & { return failure(this->assume_error()); }
710 /*! AWAITING HUGO JSON CONVERSION TOOL
711 SIGNATURE NOT RECOGNISED
712 */
713 auto as_failure() && { return failure(static_cast<basic_result &&>(*this).assume_error()); }
714 };
715
716 /*! AWAITING HUGO JSON CONVERSION TOOL
717 SIGNATURE NOT RECOGNISED
718 */
719 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)))
720 {
721 a.swap(b);
722 }
723
724 #if !defined(NDEBUG)
725 // Check is trivial in all ways except default constructibility
726 // static_assert(std::is_trivial<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivial!");
727 // static_assert(std::is_trivially_default_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially default
728 // constructible!");
729 static_assert(std::is_trivially_copyable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copyable!");
730 static_assert(std::is_trivially_assignable<basic_result<int, long, policy::all_narrow>, basic_result<int, long, policy::all_narrow>>::value,
731 "result<int> is not trivially assignable!");
732 static_assert(std::is_trivially_destructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially destructible!");
733 static_assert(std::is_trivially_copy_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy constructible!");
734 static_assert(std::is_trivially_move_constructible<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move constructible!");
735 static_assert(std::is_trivially_copy_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially copy assignable!");
736 static_assert(std::is_trivially_move_assignable<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not trivially move assignable!");
737 // Also check is standard layout
738 static_assert(std::is_standard_layout<basic_result<int, long, policy::all_narrow>>::value, "result<int> is not a standard layout type!");
739 #endif
740
741 BOOST_OUTCOME_V2_NAMESPACE_END
742
743 #ifdef __clang__
744 #pragma clang diagnostic pop
745 #endif
746
747 #endif