basic_result.hpp 42 KB

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