basic_result.hpp 41 KB

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