basic_outcome.hpp 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  1. /* A less simple result type
  2. (C) 2017-2020 Niall Douglas <http://www.nedproductions.biz/> (20 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_OUTCOME_HPP
  26. #define BOOST_OUTCOME_BASIC_OUTCOME_HPP
  27. #include "config.hpp"
  28. #include "basic_result.hpp"
  29. #include "detail/basic_outcome_exception_observers.hpp"
  30. #include "detail/basic_outcome_failure_observers.hpp"
  31. #ifdef __clang__
  32. #pragma clang diagnostic push
  33. #pragma clang diagnostic ignored "-Wdocumentation" // Standardese markup confuses clang
  34. #endif
  35. BOOST_OUTCOME_V2_NAMESPACE_EXPORT_BEGIN
  36. template <class R, class S, class P, class NoValuePolicy> //
  37. class basic_outcome;
  38. namespace detail
  39. {
  40. // May be reused by basic_outcome subclasses to save load on the compiler
  41. template <class value_type, class error_type, class exception_type> struct outcome_predicates
  42. {
  43. using result = result_predicates<value_type, error_type>;
  44. // Predicate for the implicit constructors to be available
  45. static constexpr bool implicit_constructors_enabled = //
  46. result::implicit_constructors_enabled //
  47. && !detail::is_implicitly_constructible<value_type, exception_type> //
  48. && !detail::is_implicitly_constructible<error_type, exception_type> //
  49. && !detail::is_implicitly_constructible<exception_type, value_type> //
  50. && !detail::is_implicitly_constructible<exception_type, error_type>;
  51. // Predicate for the value converting constructor to be available.
  52. template <class T>
  53. static constexpr bool enable_value_converting_constructor = //
  54. implicit_constructors_enabled //
  55. &&result::template enable_value_converting_constructor<T> //
  56. && !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition
  57. // Predicate for the error converting constructor to be available.
  58. template <class T>
  59. static constexpr bool enable_error_converting_constructor = //
  60. implicit_constructors_enabled //
  61. &&result::template enable_error_converting_constructor<T> //
  62. && !detail::is_implicitly_constructible<exception_type, T>; // deliberately less tolerant of ambiguity than result's edition
  63. // Predicate for the error condition converting constructor to be available.
  64. template <class ErrorCondEnum>
  65. static constexpr bool enable_error_condition_converting_constructor = result::template enable_error_condition_converting_constructor<ErrorCondEnum> //
  66. && !detail::is_implicitly_constructible<exception_type, ErrorCondEnum>;
  67. // Predicate for the exception converting constructor to be available.
  68. template <class T>
  69. static constexpr bool enable_exception_converting_constructor = //
  70. implicit_constructors_enabled //
  71. && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
  72. && !detail::is_implicitly_constructible<value_type, T> && !detail::is_implicitly_constructible<error_type, T> &&
  73. detail::is_implicitly_constructible<exception_type, T>;
  74. // Predicate for the error + exception converting constructor to be available.
  75. template <class T, class U>
  76. static constexpr bool enable_error_exception_converting_constructor = //
  77. implicit_constructors_enabled //
  78. && !is_in_place_type_t<std::decay_t<T>>::value // not in place construction
  79. && !detail::is_implicitly_constructible<value_type, T> && detail::is_implicitly_constructible<error_type, T> //
  80. && !detail::is_implicitly_constructible<value_type, U> && detail::is_implicitly_constructible<exception_type, U>;
  81. // Predicate for the converting copy constructor from a compatible outcome to be available.
  82. template <class T, class U, class V, class W>
  83. static constexpr bool enable_compatible_conversion = //
  84. (std::is_void<T>::value ||
  85. detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // if our value types are constructible
  86. &&(std::is_void<U>::value ||
  87. detail::is_explicitly_constructible<error_type, typename basic_outcome<T, U, V, W>::error_type>) // if our error types are constructible
  88. &&(std::is_void<V>::value ||
  89. detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>) // if our exception types are constructible
  90. ;
  91. // Predicate for the converting constructor from a make_error_code() of the input to be available.
  92. template <class T, class U, class V, class W>
  93. static constexpr bool enable_make_error_code_compatible_conversion = //
  94. trait::is_error_code_available<std::decay_t<error_type>>::value // if error type has an error code
  95. && !enable_compatible_conversion<T, U, V, W> // and the normal compatible conversion is not available
  96. && (std::is_void<T>::value ||
  97. detail::is_explicitly_constructible<value_type, typename basic_outcome<T, U, V, W>::value_type>) // and if our value types are constructible
  98. &&detail::is_explicitly_constructible<error_type,
  99. typename trait::is_error_code_available<U>::type> // and our error type is constructible from a make_error_code()
  100. && (std::is_void<V>::value ||
  101. detail::is_explicitly_constructible<exception_type, typename basic_outcome<T, U, V, W>::exception_type>); // and our exception types are constructible
  102. // Predicate for the implicit converting inplace constructor from a compatible input to be available.
  103. struct disable_inplace_value_error_exception_constructor;
  104. template <class... Args>
  105. using choose_inplace_value_error_exception_constructor = std::conditional_t< //
  106. ((static_cast<int>(std::is_constructible<value_type, Args...>::value) + static_cast<int>(std::is_constructible<error_type, Args...>::value) +
  107. static_cast<int>(std::is_constructible<exception_type, Args...>::value)) > 1), //
  108. disable_inplace_value_error_exception_constructor, //
  109. std::conditional_t< //
  110. std::is_constructible<value_type, Args...>::value, //
  111. value_type, //
  112. std::conditional_t< //
  113. std::is_constructible<error_type, Args...>::value, //
  114. error_type, //
  115. std::conditional_t< //
  116. std::is_constructible<exception_type, Args...>::value, //
  117. exception_type, //
  118. disable_inplace_value_error_exception_constructor>>>>;
  119. template <class... Args>
  120. static constexpr bool enable_inplace_value_error_exception_constructor = //
  121. implicit_constructors_enabled &&
  122. !std::is_same<choose_inplace_value_error_exception_constructor<Args...>, disable_inplace_value_error_exception_constructor>::value;
  123. };
  124. // Select whether to use basic_outcome_failure_observers or not
  125. template <class Base, class R, class S, class P, class NoValuePolicy>
  126. using select_basic_outcome_failure_observers = //
  127. std::conditional_t<trait::is_error_code_available<S>::value && trait::is_exception_ptr_available<P>::value,
  128. basic_outcome_failure_observers<Base, R, S, P, NoValuePolicy>, Base>;
  129. template <class T, class U, class V> constexpr inline const V &extract_exception_from_failure(const failure_type<U, V> &v) { return v.exception(); }
  130. template <class T, class U, class V> constexpr inline V &&extract_exception_from_failure(failure_type<U, V> &&v)
  131. {
  132. return static_cast<failure_type<U, V> &&>(v).exception();
  133. }
  134. template <class T, class U> constexpr inline const U &extract_exception_from_failure(const failure_type<U, void> &v) { return v.error(); }
  135. template <class T, class U> constexpr inline U &&extract_exception_from_failure(failure_type<U, void> &&v)
  136. {
  137. return static_cast<failure_type<U, void> &&>(v).error();
  138. }
  139. template <class T> struct is_basic_outcome
  140. {
  141. static constexpr bool value = false;
  142. };
  143. template <class R, class S, class T, class N> struct is_basic_outcome<basic_outcome<R, S, T, N>>
  144. {
  145. static constexpr bool value = true;
  146. };
  147. } // namespace detail
  148. /*! AWAITING HUGO JSON CONVERSION TOOL
  149. type alias template <class T> is_basic_outcome. Potential doc page: `is_basic_outcome<T>`
  150. */
  151. template <class T> using is_basic_outcome = detail::is_basic_outcome<std::decay_t<T>>;
  152. /*! AWAITING HUGO JSON CONVERSION TOOL
  153. SIGNATURE NOT RECOGNISED
  154. */
  155. template <class T> static constexpr bool is_basic_outcome_v = detail::is_basic_outcome<std::decay_t<T>>::value;
  156. namespace hooks
  157. {
  158. /*! AWAITING HUGO JSON CONVERSION TOOL
  159. SIGNATURE NOT RECOGNISED
  160. */
  161. template <class T, class... U> constexpr inline void hook_outcome_construction(T * /*unused*/, U &&... /*unused*/) noexcept {}
  162. /*! AWAITING HUGO JSON CONVERSION TOOL
  163. SIGNATURE NOT RECOGNISED
  164. */
  165. template <class T, class U> constexpr inline void hook_outcome_copy_construction(T * /*unused*/, U && /*unused*/) noexcept {}
  166. /*! AWAITING HUGO JSON CONVERSION TOOL
  167. SIGNATURE NOT RECOGNISED
  168. */
  169. template <class T, class U> constexpr inline void hook_outcome_move_construction(T * /*unused*/, U && /*unused*/) noexcept {}
  170. /*! AWAITING HUGO JSON CONVERSION TOOL
  171. SIGNATURE NOT RECOGNISED
  172. */
  173. template <class T, class U, class... Args>
  174. constexpr inline void hook_outcome_in_place_construction(T * /*unused*/, in_place_type_t<U> /*unused*/, Args &&... /*unused*/) noexcept
  175. {
  176. }
  177. /*! AWAITING HUGO JSON CONVERSION TOOL
  178. SIGNATURE NOT RECOGNISED
  179. */
  180. template <class R, class S, class P, class NoValuePolicy, class U>
  181. constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept;
  182. } // namespace hooks
  183. /*! AWAITING HUGO JSON CONVERSION TOOL
  184. type definition template <class R, class S, class P, class NoValuePolicy> basic_outcome. Potential doc page: `basic_outcome<T, EC, EP, NoValuePolicy>`
  185. */
  186. template <class R, class S, class P, class NoValuePolicy> //
  187. class BOOST_OUTCOME_NODISCARD basic_outcome
  188. #if defined(BOOST_OUTCOME_DOXYGEN_IS_IN_THE_HOUSE) || defined(BOOST_OUTCOME_STANDARDESE_IS_IN_THE_HOUSE)
  189. : public detail::basic_outcome_failure_observers<detail::basic_result_final<R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>,
  190. public detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>,
  191. public detail::basic_result_final<R, S, NoValuePolicy>
  192. #else
  193. : public detail::select_basic_outcome_failure_observers<
  194. detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>
  195. #endif
  196. {
  197. static_assert(trait::type_can_be_used_in_basic_result<P>, "The exception_type cannot be used");
  198. static_assert(std::is_void<P>::value || std::is_default_constructible<P>::value, "exception_type must be void or default constructible");
  199. using base = detail::select_basic_outcome_failure_observers<
  200. detail::basic_outcome_exception_observers<detail::basic_result_final<R, S, NoValuePolicy>, R, S, P, NoValuePolicy>, R, S, P, NoValuePolicy>;
  201. friend struct policy::base;
  202. template <class T, class U, class V, class W> //
  203. friend class basic_outcome;
  204. template <class T, class U, class V, class W, class X>
  205. friend constexpr inline void hooks::override_outcome_exception(basic_outcome<T, U, V, W> *o, X &&v) noexcept; // NOLINT
  206. struct implicit_constructors_disabled_tag
  207. {
  208. };
  209. struct value_converting_constructor_tag
  210. {
  211. };
  212. struct error_converting_constructor_tag
  213. {
  214. };
  215. struct error_condition_converting_constructor_tag
  216. {
  217. };
  218. struct exception_converting_constructor_tag
  219. {
  220. };
  221. struct error_exception_converting_constructor_tag
  222. {
  223. };
  224. struct explicit_valueorerror_converting_constructor_tag
  225. {
  226. };
  227. struct explicit_compatible_copy_conversion_tag
  228. {
  229. };
  230. struct explicit_compatible_move_conversion_tag
  231. {
  232. };
  233. struct explicit_make_error_code_compatible_copy_conversion_tag
  234. {
  235. };
  236. struct explicit_make_error_code_compatible_move_conversion_tag
  237. {
  238. };
  239. struct error_failure_tag
  240. {
  241. };
  242. struct exception_failure_tag
  243. {
  244. };
  245. struct disable_in_place_value_type
  246. {
  247. };
  248. struct disable_in_place_error_type
  249. {
  250. };
  251. struct disable_in_place_exception_type
  252. {
  253. };
  254. public:
  255. using value_type = R;
  256. using error_type = S;
  257. using exception_type = P;
  258. template <class T, class U = S, class V = P, class W = NoValuePolicy> using rebind = basic_outcome<T, U, V, W>;
  259. protected:
  260. // Requirement predicates for outcome.
  261. struct predicate
  262. {
  263. using base = detail::outcome_predicates<value_type, error_type, exception_type>;
  264. // Predicate for any constructors to be available at all
  265. static constexpr bool constructors_enabled =
  266. (!std::is_same<std::decay_t<value_type>, std::decay_t<error_type>>::value || (std::is_void<value_type>::value && std::is_void<error_type>::value)) //
  267. && (!std::is_same<std::decay_t<value_type>, std::decay_t<exception_type>>::value ||
  268. (std::is_void<value_type>::value && std::is_void<exception_type>::value)) //
  269. && (!std::is_same<std::decay_t<error_type>, std::decay_t<exception_type>>::value ||
  270. (std::is_void<error_type>::value && std::is_void<exception_type>::value)) //
  271. ;
  272. // Predicate for implicit constructors to be available at all
  273. static constexpr bool implicit_constructors_enabled = constructors_enabled && base::implicit_constructors_enabled;
  274. // Predicate for the value converting constructor to be available.
  275. template <class T>
  276. static constexpr bool enable_value_converting_constructor = //
  277. constructors_enabled //
  278. && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
  279. && base::template enable_value_converting_constructor<T>;
  280. // Predicate for the error converting constructor to be available.
  281. template <class T>
  282. static constexpr bool enable_error_converting_constructor = //
  283. constructors_enabled //
  284. && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
  285. && base::template enable_error_converting_constructor<T>;
  286. // Predicate for the error condition converting constructor to be available.
  287. template <class ErrorCondEnum>
  288. static constexpr bool enable_error_condition_converting_constructor = //
  289. constructors_enabled //
  290. && !std::is_same<std::decay_t<ErrorCondEnum>, basic_outcome>::value // not my type
  291. && base::template enable_error_condition_converting_constructor<ErrorCondEnum>;
  292. // Predicate for the exception converting constructor to be available.
  293. template <class T>
  294. static constexpr bool enable_exception_converting_constructor = //
  295. constructors_enabled //
  296. && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
  297. && base::template enable_exception_converting_constructor<T>;
  298. // Predicate for the error + exception converting constructor to be available.
  299. template <class T, class U>
  300. static constexpr bool enable_error_exception_converting_constructor = //
  301. constructors_enabled //
  302. && !std::is_same<std::decay_t<T>, basic_outcome>::value // not my type
  303. && base::template enable_error_exception_converting_constructor<T, U>;
  304. // Predicate for the converting constructor from a compatible input to be available.
  305. template <class T, class U, class V, class W>
  306. static constexpr bool enable_compatible_conversion = //
  307. constructors_enabled //
  308. && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type
  309. && base::template enable_compatible_conversion<T, U, V, W>;
  310. // Predicate for the converting constructor from a make_error_code() of the input to be available.
  311. template <class T, class U, class V, class W>
  312. static constexpr bool enable_make_error_code_compatible_conversion = //
  313. constructors_enabled //
  314. && !std::is_same<basic_outcome<T, U, V, W>, basic_outcome>::value // not my type
  315. && base::template enable_make_error_code_compatible_conversion<T, U, V, W>;
  316. // Predicate for the inplace construction of value to be available.
  317. template <class... Args>
  318. static constexpr bool enable_inplace_value_constructor = //
  319. constructors_enabled //
  320. && (std::is_void<value_type>::value //
  321. || std::is_constructible<value_type, Args...>::value);
  322. // Predicate for the inplace construction of error to be available.
  323. template <class... Args>
  324. static constexpr bool enable_inplace_error_constructor = //
  325. constructors_enabled //
  326. && (std::is_void<error_type>::value //
  327. || std::is_constructible<error_type, Args...>::value);
  328. // Predicate for the inplace construction of exception to be available.
  329. template <class... Args>
  330. static constexpr bool enable_inplace_exception_constructor = //
  331. constructors_enabled //
  332. && (std::is_void<exception_type>::value //
  333. || std::is_constructible<exception_type, Args...>::value);
  334. // Predicate for the implicit converting inplace constructor to be available.
  335. template <class... Args>
  336. static constexpr bool enable_inplace_value_error_exception_constructor = //
  337. constructors_enabled //
  338. &&base::template enable_inplace_value_error_exception_constructor<Args...>;
  339. template <class... Args>
  340. using choose_inplace_value_error_exception_constructor = typename base::template choose_inplace_value_error_exception_constructor<Args...>;
  341. };
  342. public:
  343. using value_type_if_enabled =
  344. std::conditional_t<std::is_same<value_type, error_type>::value || std::is_same<value_type, exception_type>::value, disable_in_place_value_type, value_type>;
  345. using error_type_if_enabled =
  346. std::conditional_t<std::is_same<error_type, value_type>::value || std::is_same<error_type, exception_type>::value, disable_in_place_error_type, error_type>;
  347. using exception_type_if_enabled = std::conditional_t<std::is_same<exception_type, value_type>::value || std::is_same<exception_type, error_type>::value,
  348. disable_in_place_exception_type, exception_type>;
  349. protected:
  350. detail::devoid<exception_type> _ptr;
  351. public:
  352. /*! AWAITING HUGO JSON CONVERSION TOOL
  353. SIGNATURE NOT RECOGNISED
  354. */
  355. BOOST_OUTCOME_TEMPLATE(class Arg, class... Args)
  356. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED((!predicate::constructors_enabled && sizeof...(Args) >= 0)))
  357. basic_outcome(Arg && /*unused*/, Args &&... /*unused*/) = delete; // NOLINT basic_outcome<> with any of the same type is NOT SUPPORTED, 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::constructors_enabled && !predicate::implicit_constructors_enabled //
  363. && (detail::is_implicitly_constructible<value_type, T> || detail::is_implicitly_constructible<error_type, T> ||
  364. detail::is_implicitly_constructible<exception_type, T>) )))
  365. basic_outcome(T && /*unused*/, implicit_constructors_disabled_tag /*unused*/ = implicit_constructors_disabled_tag()) =
  366. delete; // NOLINT Implicit constructors disabled, use explicit in_place_type<T>, success() or failure(). see docs!
  367. /*! AWAITING HUGO JSON CONVERSION TOOL
  368. SIGNATURE NOT RECOGNISED
  369. */
  370. BOOST_OUTCOME_TEMPLATE(class T)
  371. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_value_converting_constructor<T>))
  372. constexpr basic_outcome(T &&t, value_converting_constructor_tag /*unused*/ = value_converting_constructor_tag()) noexcept(
  373. std::is_nothrow_constructible<value_type, T>::value) // NOLINT
  374. : base{in_place_type<typename base::_value_type>, static_cast<T &&>(t)}
  375. , _ptr()
  376. {
  377. using namespace hooks;
  378. hook_outcome_construction(this, static_cast<T &&>(t));
  379. }
  380. /*! AWAITING HUGO JSON CONVERSION TOOL
  381. SIGNATURE NOT RECOGNISED
  382. */
  383. BOOST_OUTCOME_TEMPLATE(class T)
  384. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_converting_constructor<T>))
  385. constexpr basic_outcome(T &&t, error_converting_constructor_tag /*unused*/ = error_converting_constructor_tag()) noexcept(
  386. std::is_nothrow_constructible<error_type, T>::value) // NOLINT
  387. : base{in_place_type<typename base::_error_type>, static_cast<T &&>(t)}
  388. , _ptr()
  389. {
  390. using namespace hooks;
  391. hook_outcome_construction(this, static_cast<T &&>(t));
  392. }
  393. /*! AWAITING HUGO JSON CONVERSION TOOL
  394. SIGNATURE NOT RECOGNISED
  395. */
  396. BOOST_OUTCOME_TEMPLATE(class ErrorCondEnum)
  397. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(error_type(make_error_code(ErrorCondEnum()))), //
  398. BOOST_OUTCOME_TPRED(predicate::template enable_error_condition_converting_constructor<ErrorCondEnum>))
  399. constexpr basic_outcome(ErrorCondEnum &&t, error_condition_converting_constructor_tag /*unused*/ = error_condition_converting_constructor_tag()) noexcept(
  400. noexcept(error_type(make_error_code(static_cast<ErrorCondEnum &&>(t))))) // NOLINT
  401. : base{in_place_type<typename base::_error_type>, make_error_code(t)}
  402. {
  403. using namespace hooks;
  404. hook_outcome_construction(this, static_cast<ErrorCondEnum &&>(t));
  405. }
  406. /*! AWAITING HUGO JSON CONVERSION TOOL
  407. SIGNATURE NOT RECOGNISED
  408. */
  409. BOOST_OUTCOME_TEMPLATE(class T)
  410. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_exception_converting_constructor<T>))
  411. constexpr basic_outcome(T &&t, exception_converting_constructor_tag /*unused*/ = exception_converting_constructor_tag()) noexcept(
  412. std::is_nothrow_constructible<exception_type, T>::value) // NOLINT
  413. : base()
  414. , _ptr(static_cast<T &&>(t))
  415. {
  416. using namespace hooks;
  417. this->_state._status.set_have_exception(true);
  418. hook_outcome_construction(this, static_cast<T &&>(t));
  419. }
  420. /*! AWAITING HUGO JSON CONVERSION TOOL
  421. SIGNATURE NOT RECOGNISED
  422. */
  423. BOOST_OUTCOME_TEMPLATE(class T, class U)
  424. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_error_exception_converting_constructor<T, U>))
  425. constexpr basic_outcome(T &&a, U &&b, error_exception_converting_constructor_tag /*unused*/ = error_exception_converting_constructor_tag()) noexcept(
  426. std::is_nothrow_constructible<error_type, T>::value &&std::is_nothrow_constructible<exception_type, U>::value) // NOLINT
  427. : base{in_place_type<typename base::_error_type>, static_cast<T &&>(a)}
  428. , _ptr(static_cast<U &&>(b))
  429. {
  430. using namespace hooks;
  431. this->_state._status.set_have_exception(true);
  432. hook_outcome_construction(this, static_cast<T &&>(a), static_cast<U &&>(b));
  433. }
  434. /*! AWAITING HUGO JSON CONVERSION TOOL
  435. SIGNATURE NOT RECOGNISED
  436. */
  437. BOOST_OUTCOME_TEMPLATE(class T)
  438. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_result_inputs || !is_basic_result_v<T>), //
  439. BOOST_OUTCOME_TPRED(convert::value_or_error<basic_outcome, std::decay_t<T>>::enable_outcome_inputs || !is_basic_outcome_v<T>), //
  440. BOOST_OUTCOME_TEXPR(convert::value_or_error<basic_outcome, std::decay_t<T>>{}(std::declval<T>())))
  441. constexpr explicit basic_outcome(T &&o,
  442. explicit_valueorerror_converting_constructor_tag /*unused*/ = explicit_valueorerror_converting_constructor_tag()) // NOLINT
  443. : basic_outcome{convert::value_or_error<basic_outcome, std::decay_t<T>>{}(static_cast<T &&>(o))}
  444. {
  445. }
  446. /*! AWAITING HUGO JSON CONVERSION TOOL
  447. SIGNATURE NOT RECOGNISED
  448. */
  449. BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
  450. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
  451. constexpr explicit basic_outcome(
  452. const basic_outcome<T, U, V, W> &o,
  453. explicit_compatible_copy_conversion_tag /*unused*/ =
  454. explicit_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value &&std::is_nothrow_constructible<error_type, U>::value
  455. &&std::is_nothrow_constructible<exception_type, V>::value)
  456. : base{typename base::compatible_conversion_tag(), o}
  457. , _ptr(o._ptr)
  458. {
  459. using namespace hooks;
  460. hook_outcome_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, class W)
  466. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_compatible_conversion<T, U, V, W>))
  467. constexpr explicit basic_outcome(
  468. basic_outcome<T, U, V, W> &&o,
  469. explicit_compatible_move_conversion_tag /*unused*/ =
  470. explicit_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value &&std::is_nothrow_constructible<error_type, U>::value
  471. &&std::is_nothrow_constructible<exception_type, V>::value)
  472. : base{typename base::compatible_conversion_tag(), static_cast<basic_outcome<T, U, V, W> &&>(o)}
  473. , _ptr(static_cast<typename basic_outcome<T, U, V, W>::exception_type &&>(o._ptr))
  474. {
  475. using namespace hooks;
  476. hook_outcome_move_construction(this, static_cast<basic_outcome<T, U, V, W> &&>(o));
  477. }
  478. /*! AWAITING HUGO JSON CONVERSION TOOL
  479. SIGNATURE NOT RECOGNISED
  480. */
  481. BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
  482. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
  483. constexpr explicit basic_outcome(
  484. const basic_result<T, U, V> &o,
  485. explicit_compatible_copy_conversion_tag /*unused*/ =
  486. explicit_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value &&std::is_nothrow_constructible<error_type, U>::value
  487. &&std::is_nothrow_constructible<exception_type>::value)
  488. : base{typename base::compatible_conversion_tag(), o}
  489. , _ptr()
  490. {
  491. using namespace hooks;
  492. hook_outcome_copy_construction(this, o);
  493. }
  494. /*! AWAITING HUGO JSON CONVERSION TOOL
  495. SIGNATURE NOT RECOGNISED
  496. */
  497. BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
  498. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_compatible_conversion<T, U, V>))
  499. constexpr explicit basic_outcome(
  500. basic_result<T, U, V> &&o,
  501. explicit_compatible_move_conversion_tag /*unused*/ =
  502. explicit_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value &&std::is_nothrow_constructible<error_type, U>::value
  503. &&std::is_nothrow_constructible<exception_type>::value)
  504. : base{typename base::compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
  505. , _ptr()
  506. {
  507. using namespace hooks;
  508. hook_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
  509. }
  510. /*! AWAITING HUGO JSON CONVERSION TOOL
  511. SIGNATURE NOT RECOGNISED
  512. */
  513. BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
  514. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>))
  515. constexpr explicit basic_outcome(const basic_result<T, U, V> &o,
  516. explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
  517. explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value
  518. &&noexcept(make_error_code(std::declval<U>())) &&
  519. std::is_nothrow_constructible<exception_type>::value)
  520. : base{typename base::make_error_code_compatible_conversion_tag(), o}
  521. , _ptr()
  522. {
  523. using namespace hooks;
  524. hook_outcome_copy_construction(this, o);
  525. }
  526. /*! AWAITING HUGO JSON CONVERSION TOOL
  527. SIGNATURE NOT RECOGNISED
  528. */
  529. BOOST_OUTCOME_TEMPLATE(class T, class U, class V)
  530. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(detail::result_predicates<value_type, error_type>::template enable_make_error_code_compatible_conversion<T, U, V>))
  531. constexpr explicit basic_outcome(basic_result<T, U, V> &&o,
  532. explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
  533. explicit_make_error_code_compatible_move_conversion_tag()) noexcept(std::is_nothrow_constructible<value_type, T>::value
  534. &&noexcept(make_error_code(std::declval<U>())) &&
  535. std::is_nothrow_constructible<exception_type>::value)
  536. : base{typename base::make_error_code_compatible_conversion_tag(), static_cast<basic_result<T, U, V> &&>(o)}
  537. , _ptr()
  538. {
  539. using namespace hooks;
  540. hook_outcome_move_construction(this, static_cast<basic_result<T, U, V> &&>(o));
  541. }
  542. /*! AWAITING HUGO JSON CONVERSION TOOL
  543. SIGNATURE NOT RECOGNISED
  544. */
  545. BOOST_OUTCOME_TEMPLATE(class... Args)
  546. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<Args...>))
  547. constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _,
  548. Args &&... args) noexcept(std::is_nothrow_constructible<value_type, Args...>::value)
  549. : base{_, static_cast<Args &&>(args)...}
  550. , _ptr()
  551. {
  552. using namespace hooks;
  553. hook_outcome_in_place_construction(this, in_place_type<value_type>, static_cast<Args &&>(args)...);
  554. }
  555. /*! AWAITING HUGO JSON CONVERSION TOOL
  556. SIGNATURE NOT RECOGNISED
  557. */
  558. BOOST_OUTCOME_TEMPLATE(class U, class... Args)
  559. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_constructor<std::initializer_list<U>, Args...>))
  560. constexpr explicit basic_outcome(in_place_type_t<value_type_if_enabled> _, std::initializer_list<U> il,
  561. Args &&... args) noexcept(std::is_nothrow_constructible<value_type, std::initializer_list<U>, Args...>::value)
  562. : base{_, il, static_cast<Args &&>(args)...}
  563. , _ptr()
  564. {
  565. using namespace hooks;
  566. hook_outcome_in_place_construction(this, in_place_type<value_type>, il, static_cast<Args &&>(args)...);
  567. }
  568. /*! AWAITING HUGO JSON CONVERSION TOOL
  569. SIGNATURE NOT RECOGNISED
  570. */
  571. BOOST_OUTCOME_TEMPLATE(class... Args)
  572. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<Args...>))
  573. constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _,
  574. Args &&... args) noexcept(std::is_nothrow_constructible<error_type, Args...>::value)
  575. : base{_, static_cast<Args &&>(args)...}
  576. , _ptr()
  577. {
  578. using namespace hooks;
  579. hook_outcome_in_place_construction(this, in_place_type<error_type>, static_cast<Args &&>(args)...);
  580. }
  581. /*! AWAITING HUGO JSON CONVERSION TOOL
  582. SIGNATURE NOT RECOGNISED
  583. */
  584. BOOST_OUTCOME_TEMPLATE(class U, class... Args)
  585. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_error_constructor<std::initializer_list<U>, Args...>))
  586. constexpr explicit basic_outcome(in_place_type_t<error_type_if_enabled> _, std::initializer_list<U> il,
  587. Args &&... args) noexcept(std::is_nothrow_constructible<error_type, std::initializer_list<U>, Args...>::value)
  588. : base{_, il, static_cast<Args &&>(args)...}
  589. , _ptr()
  590. {
  591. using namespace hooks;
  592. hook_outcome_in_place_construction(this, in_place_type<error_type>, il, static_cast<Args &&>(args)...);
  593. }
  594. /*! AWAITING HUGO JSON CONVERSION TOOL
  595. SIGNATURE NOT RECOGNISED
  596. */
  597. BOOST_OUTCOME_TEMPLATE(class... Args)
  598. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<Args...>))
  599. constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/,
  600. Args &&... args) noexcept(std::is_nothrow_constructible<exception_type, Args...>::value)
  601. : base()
  602. , _ptr(static_cast<Args &&>(args)...)
  603. {
  604. using namespace hooks;
  605. this->_state._status.set_have_exception(true);
  606. hook_outcome_in_place_construction(this, in_place_type<exception_type>, static_cast<Args &&>(args)...);
  607. }
  608. /*! AWAITING HUGO JSON CONVERSION TOOL
  609. SIGNATURE NOT RECOGNISED
  610. */
  611. BOOST_OUTCOME_TEMPLATE(class U, class... Args)
  612. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_exception_constructor<std::initializer_list<U>, Args...>))
  613. constexpr explicit basic_outcome(in_place_type_t<exception_type_if_enabled> /*unused*/, std::initializer_list<U> il,
  614. Args &&... args) noexcept(std::is_nothrow_constructible<exception_type, std::initializer_list<U>, Args...>::value)
  615. : base()
  616. , _ptr(il, static_cast<Args &&>(args)...)
  617. {
  618. using namespace hooks;
  619. this->_state._status.set_have_exception(true);
  620. hook_outcome_in_place_construction(this, in_place_type<exception_type>, il, static_cast<Args &&>(args)...);
  621. }
  622. /*! AWAITING HUGO JSON CONVERSION TOOL
  623. SIGNATURE NOT RECOGNISED
  624. */
  625. BOOST_OUTCOME_TEMPLATE(class A1, class A2, class... Args)
  626. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(predicate::template enable_inplace_value_error_exception_constructor<A1, A2, Args...>))
  627. constexpr basic_outcome(A1 &&a1, A2 &&a2, Args &&... args) noexcept(
  628. noexcept(typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>(std::declval<A1>(), std::declval<A2>(),
  629. std::declval<Args>()...)))
  630. : basic_outcome(in_place_type<typename predicate::template choose_inplace_value_error_exception_constructor<A1, A2, Args...>>, static_cast<A1 &&>(a1),
  631. static_cast<A2 &&>(a2), static_cast<Args &&>(args)...)
  632. {
  633. }
  634. /*! AWAITING HUGO JSON CONVERSION TOOL
  635. SIGNATURE NOT RECOGNISED
  636. */
  637. constexpr basic_outcome(const success_type<void> &o) noexcept(std::is_nothrow_default_constructible<value_type>::value) // NOLINT
  638. : base{in_place_type<typename base::_value_type>}
  639. {
  640. using namespace hooks;
  641. hook_outcome_copy_construction(this, o);
  642. }
  643. /*! AWAITING HUGO JSON CONVERSION TOOL
  644. SIGNATURE NOT RECOGNISED
  645. */
  646. BOOST_OUTCOME_TEMPLATE(class T)
  647. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
  648. constexpr basic_outcome(const success_type<T> &o) noexcept(std::is_nothrow_constructible<value_type, T>::value) // NOLINT
  649. : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(o)}
  650. {
  651. using namespace hooks;
  652. hook_outcome_copy_construction(this, o);
  653. }
  654. /*! AWAITING HUGO JSON CONVERSION TOOL
  655. SIGNATURE NOT RECOGNISED
  656. */
  657. BOOST_OUTCOME_TEMPLATE(class T)
  658. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<T, void, void, void>))
  659. constexpr basic_outcome(success_type<T> &&o) noexcept(std::is_nothrow_constructible<value_type, T>::value) // NOLINT
  660. : base{in_place_type<typename base::_value_type>, detail::extract_value_from_success<value_type>(static_cast<success_type<T> &&>(o))}
  661. {
  662. using namespace hooks;
  663. hook_outcome_move_construction(this, static_cast<success_type<T> &&>(o));
  664. }
  665. /*! AWAITING HUGO JSON CONVERSION TOOL
  666. SIGNATURE NOT RECOGNISED
  667. */
  668. BOOST_OUTCOME_TEMPLATE(class T)
  669. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
  670. constexpr basic_outcome(const failure_type<T> &o,
  671. error_failure_tag /*unused*/ = error_failure_tag()) noexcept(std::is_nothrow_constructible<error_type, T>::value) // NOLINT
  672. : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
  673. , _ptr()
  674. {
  675. using namespace hooks;
  676. hook_outcome_copy_construction(this, o);
  677. }
  678. /*! AWAITING HUGO JSON CONVERSION TOOL
  679. SIGNATURE NOT RECOGNISED
  680. */
  681. BOOST_OUTCOME_TEMPLATE(class T)
  682. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
  683. constexpr basic_outcome(const failure_type<T> &o, exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(
  684. std::is_nothrow_constructible<exception_type, T>::value) // NOLINT
  685. : base()
  686. , _ptr(detail::extract_exception_from_failure<exception_type>(o))
  687. {
  688. this->_state._status.set_have_exception(true);
  689. using namespace hooks;
  690. hook_outcome_copy_construction(this, o);
  691. }
  692. /*! AWAITING HUGO JSON CONVERSION TOOL
  693. SIGNATURE NOT RECOGNISED
  694. */
  695. BOOST_OUTCOME_TEMPLATE(class T)
  696. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>))
  697. constexpr basic_outcome(const failure_type<T> &o,
  698. explicit_make_error_code_compatible_copy_conversion_tag /*unused*/ =
  699. explicit_make_error_code_compatible_copy_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
  700. : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(o))}
  701. , _ptr()
  702. {
  703. using namespace hooks;
  704. hook_outcome_copy_construction(this, o);
  705. }
  706. /*! AWAITING HUGO JSON CONVERSION TOOL
  707. SIGNATURE NOT RECOGNISED
  708. */
  709. BOOST_OUTCOME_TEMPLATE(class T, class U)
  710. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
  711. constexpr basic_outcome(const failure_type<T, U> &o, explicit_compatible_copy_conversion_tag /*unused*/ = explicit_compatible_copy_conversion_tag()) noexcept(
  712. std::is_nothrow_constructible<error_type, T>::value &&std::is_nothrow_constructible<exception_type, U>::value) // NOLINT
  713. : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(o)}
  714. , _ptr(detail::extract_exception_from_failure<exception_type>(o))
  715. {
  716. if(!o.has_error())
  717. {
  718. this->_state._status.set_have_error(false);
  719. }
  720. if(o.has_exception())
  721. {
  722. this->_state._status.set_have_exception(true);
  723. }
  724. using namespace hooks;
  725. hook_outcome_copy_construction(this, o);
  726. }
  727. /*! AWAITING HUGO JSON CONVERSION TOOL
  728. SIGNATURE NOT RECOGNISED
  729. */
  730. BOOST_OUTCOME_TEMPLATE(class T)
  731. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, T, void, void>))
  732. constexpr basic_outcome(failure_type<T> &&o,
  733. error_failure_tag /*unused*/ = error_failure_tag()) noexcept(std::is_nothrow_constructible<error_type, T>::value) // NOLINT
  734. : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o))}
  735. , _ptr()
  736. {
  737. using namespace hooks;
  738. hook_outcome_copy_construction(this, o);
  739. }
  740. /*! AWAITING HUGO JSON CONVERSION TOOL
  741. SIGNATURE NOT RECOGNISED
  742. */
  743. BOOST_OUTCOME_TEMPLATE(class T)
  744. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_compatible_conversion<void, void, T, void>))
  745. constexpr basic_outcome(failure_type<T> &&o, exception_failure_tag /*unused*/ = exception_failure_tag()) noexcept(
  746. std::is_nothrow_constructible<exception_type, T>::value) // NOLINT
  747. : base()
  748. , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T> &&>(o)))
  749. {
  750. this->_state._status.set_have_exception(true);
  751. using namespace hooks;
  752. hook_outcome_copy_construction(this, o);
  753. }
  754. /*! AWAITING HUGO JSON CONVERSION TOOL
  755. SIGNATURE NOT RECOGNISED
  756. */
  757. BOOST_OUTCOME_TEMPLATE(class T)
  758. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<T>::value && predicate::template enable_make_error_code_compatible_conversion<void, T, void, void>))
  759. constexpr basic_outcome(failure_type<T> &&o,
  760. explicit_make_error_code_compatible_move_conversion_tag /*unused*/ =
  761. explicit_make_error_code_compatible_move_conversion_tag()) noexcept(noexcept(make_error_code(std::declval<T>()))) // NOLINT
  762. : base{in_place_type<typename base::_error_type>, make_error_code(detail::extract_error_from_failure<error_type>(static_cast<failure_type<T> &&>(o)))}
  763. , _ptr()
  764. {
  765. using namespace hooks;
  766. hook_outcome_copy_construction(this, o);
  767. }
  768. /*! AWAITING HUGO JSON CONVERSION TOOL
  769. SIGNATURE NOT RECOGNISED
  770. */
  771. BOOST_OUTCOME_TEMPLATE(class T, class U)
  772. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TPRED(!std::is_void<U>::value && predicate::template enable_compatible_conversion<void, T, U, void>))
  773. constexpr basic_outcome(failure_type<T, U> &&o, explicit_compatible_move_conversion_tag /*unused*/ = explicit_compatible_move_conversion_tag()) noexcept(
  774. std::is_nothrow_constructible<error_type, T>::value &&std::is_nothrow_constructible<exception_type, U>::value) // NOLINT
  775. : base{in_place_type<typename base::_error_type>, detail::extract_error_from_failure<error_type>(static_cast<failure_type<T, U> &&>(o))}
  776. , _ptr(detail::extract_exception_from_failure<exception_type>(static_cast<failure_type<T, U> &&>(o)))
  777. {
  778. if(!o.has_error())
  779. {
  780. this->_state._status.set_have_error(false);
  781. }
  782. if(o.has_exception())
  783. {
  784. this->_state._status.set_have_exception(true);
  785. }
  786. using namespace hooks;
  787. hook_outcome_move_construction(this, static_cast<failure_type<T, U> &&>(o));
  788. }
  789. /*! AWAITING HUGO JSON CONVERSION TOOL
  790. SIGNATURE NOT RECOGNISED
  791. */
  792. using base::operator==;
  793. using base::operator!=;
  794. /*! AWAITING HUGO JSON CONVERSION TOOL
  795. SIGNATURE NOT RECOGNISED
  796. */
  797. BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
  798. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()), //
  799. BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()), //
  800. BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
  801. constexpr bool operator==(const basic_outcome<T, U, V, W> &o) const noexcept( //
  802. noexcept(std::declval<detail::devoid<value_type>>() == std::declval<detail::devoid<T>>()) //
  803. && noexcept(std::declval<detail::devoid<error_type>>() == std::declval<detail::devoid<U>>()) //
  804. && noexcept(std::declval<detail::devoid<exception_type>>() == std::declval<detail::devoid<V>>()))
  805. {
  806. if(this->_state._status.have_value() && o._state._status.have_value())
  807. {
  808. return this->_state._value == o._state._value; // NOLINT
  809. }
  810. if(this->_state._status.have_error() && o._state._status.have_error() //
  811. && this->_state._status.have_exception() && o._state._status.have_exception())
  812. {
  813. return this->_error == o._error && this->_ptr == o._ptr;
  814. }
  815. if(this->_state._status.have_error() && o._state._status.have_error())
  816. {
  817. return this->_error == o._error;
  818. }
  819. if(this->_state._status.have_exception() && o._state._status.have_exception())
  820. {
  821. return this->_ptr == o._ptr;
  822. }
  823. return false;
  824. }
  825. /*! AWAITING HUGO JSON CONVERSION TOOL
  826. SIGNATURE NOT RECOGNISED
  827. */
  828. BOOST_OUTCOME_TEMPLATE(class T, class U)
  829. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() == std::declval<T>()), //
  830. BOOST_OUTCOME_TEXPR(std::declval<exception_type>() == std::declval<U>()))
  831. constexpr bool operator==(const failure_type<T, U> &o) const noexcept( //
  832. noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>()))
  833. {
  834. if(this->_state._status.have_error() && o._state._status.have_error() //
  835. && this->_state._status.have_exception() && o._state._status.have_exception())
  836. {
  837. return this->_error == o.error() && this->_ptr == o.exception();
  838. }
  839. if(this->_state._status.have_error() && o._state._status.have_error())
  840. {
  841. return this->_error == o.error();
  842. }
  843. if(this->_state._status.have_exception() && o._state._status.have_exception())
  844. {
  845. return this->_ptr == o.exception();
  846. }
  847. return false;
  848. }
  849. /*! AWAITING HUGO JSON CONVERSION TOOL
  850. SIGNATURE NOT RECOGNISED
  851. */
  852. BOOST_OUTCOME_TEMPLATE(class T, class U, class V, class W)
  853. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()), //
  854. BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()), //
  855. BOOST_OUTCOME_TEXPR(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
  856. constexpr bool operator!=(const basic_outcome<T, U, V, W> &o) const noexcept( //
  857. noexcept(std::declval<detail::devoid<value_type>>() != std::declval<detail::devoid<T>>()) //
  858. && noexcept(std::declval<detail::devoid<error_type>>() != std::declval<detail::devoid<U>>()) //
  859. && noexcept(std::declval<detail::devoid<exception_type>>() != std::declval<detail::devoid<V>>()))
  860. {
  861. if(this->_state._status.have_value() && o._state._status.have_value())
  862. {
  863. return this->_state._value != o._state._value; // NOLINT
  864. }
  865. if(this->_state._status.have_error() && o._state._status.have_error() //
  866. && this->_state._status.have_exception() && o._state._status.have_exception())
  867. {
  868. return this->_error != o._error || this->_ptr != o._ptr;
  869. }
  870. if(this->_state._status.have_error() && o._state._status.have_error())
  871. {
  872. return this->_error != o._error;
  873. }
  874. if(this->_state._status.have_exception() && o._state._status.have_exception())
  875. {
  876. return this->_ptr != o._ptr;
  877. }
  878. return true;
  879. }
  880. /*! AWAITING HUGO JSON CONVERSION TOOL
  881. SIGNATURE NOT RECOGNISED
  882. */
  883. BOOST_OUTCOME_TEMPLATE(class T, class U)
  884. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<error_type>() != std::declval<T>()), //
  885. BOOST_OUTCOME_TEXPR(std::declval<exception_type>() != std::declval<U>()))
  886. constexpr bool operator!=(const failure_type<T, U> &o) const noexcept( //
  887. noexcept(std::declval<error_type>() == std::declval<T>()) && noexcept(std::declval<exception_type>() == std::declval<U>()))
  888. {
  889. if(this->_state._status.have_error() && o._state._status.have_error() //
  890. && this->_state._status.have_exception() && o._state._status.have_exception())
  891. {
  892. return this->_error != o.error() || this->_ptr != o.exception();
  893. }
  894. if(this->_state._status.have_error() && o._state._status.have_error())
  895. {
  896. return this->_error != o.error();
  897. }
  898. if(this->_state._status.have_exception() && o._state._status.have_exception())
  899. {
  900. return this->_ptr != o.exception();
  901. }
  902. return true;
  903. }
  904. /*! AWAITING HUGO JSON CONVERSION TOOL
  905. SIGNATURE NOT RECOGNISED
  906. */
  907. constexpr void swap(basic_outcome &o) noexcept((std::is_void<value_type>::value || detail::is_nothrow_swappable<value_type>::value) //
  908. && (std::is_void<error_type>::value || detail::is_nothrow_swappable<error_type>::value) //
  909. && (std::is_void<exception_type>::value || detail::is_nothrow_swappable<exception_type>::value))
  910. {
  911. #ifndef BOOST_NO_EXCEPTIONS
  912. constexpr bool value_throws = !std::is_void<value_type>::value && !detail::is_nothrow_swappable<value_type>::value;
  913. constexpr bool error_throws = !std::is_void<error_type>::value && !detail::is_nothrow_swappable<error_type>::value;
  914. constexpr bool exception_throws = !std::is_void<exception_type>::value && !detail::is_nothrow_swappable<exception_type>::value;
  915. #ifdef _MSC_VER
  916. #pragma warning(push)
  917. #pragma warning(disable : 4127) // conditional expression is constant
  918. #endif
  919. if(!exception_throws && !value_throws && !error_throws)
  920. {
  921. // Simples
  922. detail::basic_result_storage_swap<value_throws, error_throws>(*this, o);
  923. using std::swap;
  924. swap(this->_ptr, o._ptr);
  925. return;
  926. }
  927. struct _
  928. {
  929. basic_outcome &a, &b;
  930. bool exceptioned{false};
  931. bool all_good{false};
  932. ~_()
  933. {
  934. if(!all_good)
  935. {
  936. // We lost one of the values
  937. a._state._status.set_have_lost_consistency(true);
  938. b._state._status.set_have_lost_consistency(true);
  939. return;
  940. }
  941. if(exceptioned)
  942. {
  943. // The value + error swap threw an exception. Try to swap back _ptr
  944. try
  945. {
  946. strong_swap(all_good, a._ptr, b._ptr);
  947. }
  948. catch(...)
  949. {
  950. // We lost one of the values
  951. a._state._status.set_have_lost_consistency(true);
  952. b._state._status.set_have_lost_consistency(true);
  953. // throw away second exception
  954. }
  955. // Prevent has_value() == has_error() or has_value() == has_exception()
  956. auto check = [](basic_outcome *t) {
  957. if(t->has_value() && (t->has_error() || t->has_exception()))
  958. {
  959. t->_state._status.set_have_error(false).set_have_exception(false);
  960. t->_state._status.set_have_lost_consistency(true);
  961. }
  962. if(!t->has_value() && !(t->has_error() || t->has_exception()))
  963. {
  964. // Choose error, for no particular reason
  965. t->_state._status.set_have_error(true).set_have_lost_consistency(true);
  966. }
  967. };
  968. check(&a);
  969. check(&b);
  970. }
  971. }
  972. } _{*this, o};
  973. strong_swap(_.all_good, this->_ptr, o._ptr);
  974. _.exceptioned = true;
  975. detail::basic_result_storage_swap<value_throws, error_throws>(*this, o);
  976. _.exceptioned = false;
  977. #ifdef _MSC_VER
  978. #pragma warning(pop)
  979. #endif
  980. #else
  981. detail::basic_result_storage_swap<false, false>(*this, o);
  982. using std::swap;
  983. swap(this->_ptr, o._ptr);
  984. #endif
  985. }
  986. /*! AWAITING HUGO JSON CONVERSION TOOL
  987. SIGNATURE NOT RECOGNISED
  988. */
  989. failure_type<error_type, exception_type> as_failure() const &
  990. {
  991. if(this->has_error() && this->has_exception())
  992. {
  993. return failure_type<error_type, exception_type>(this->assume_error(), this->assume_exception());
  994. }
  995. if(this->has_exception())
  996. {
  997. return failure_type<error_type, exception_type>(in_place_type<exception_type>, this->assume_exception());
  998. }
  999. return failure_type<error_type, exception_type>(in_place_type<error_type>, this->assume_error());
  1000. }
  1001. /*! AWAITING HUGO JSON CONVERSION TOOL
  1002. SIGNATURE NOT RECOGNISED
  1003. */
  1004. failure_type<error_type, exception_type> as_failure() &&
  1005. {
  1006. if(this->has_error() && this->has_exception())
  1007. {
  1008. return failure_type<error_type, exception_type>(static_cast<S &&>(this->assume_error()), static_cast<P &&>(this->assume_exception()));
  1009. }
  1010. if(this->has_exception())
  1011. {
  1012. return failure_type<error_type, exception_type>(in_place_type<exception_type>, static_cast<P &&>(this->assume_exception()));
  1013. }
  1014. return failure_type<error_type, exception_type>(in_place_type<error_type>, static_cast<S &&>(this->assume_error()));
  1015. }
  1016. };
  1017. /*! AWAITING HUGO JSON CONVERSION TOOL
  1018. SIGNATURE NOT RECOGNISED
  1019. */
  1020. BOOST_OUTCOME_TEMPLATE(class T, class U, class V, //
  1021. class R, class S, class P, class N)
  1022. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
  1023. constexpr inline bool operator==(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
  1024. noexcept(std::declval<basic_outcome<R, S, P, N>>() == std::declval<basic_result<T, U, V>>()))
  1025. {
  1026. return b == a;
  1027. }
  1028. /*! AWAITING HUGO JSON CONVERSION TOOL
  1029. SIGNATURE NOT RECOGNISED
  1030. */
  1031. BOOST_OUTCOME_TEMPLATE(class T, class U, class V, //
  1032. class R, class S, class P, class N)
  1033. BOOST_OUTCOME_TREQUIRES(BOOST_OUTCOME_TEXPR(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
  1034. constexpr inline bool operator!=(const basic_result<T, U, V> &a, const basic_outcome<R, S, P, N> &b) noexcept( //
  1035. noexcept(std::declval<basic_outcome<R, S, P, N>>() != std::declval<basic_result<T, U, V>>()))
  1036. {
  1037. return b != a;
  1038. }
  1039. /*! AWAITING HUGO JSON CONVERSION TOOL
  1040. SIGNATURE NOT RECOGNISED
  1041. */
  1042. template <class R, class S, class P, class N> inline void swap(basic_outcome<R, S, P, N> &a, basic_outcome<R, S, P, N> &b) noexcept(noexcept(a.swap(b)))
  1043. {
  1044. a.swap(b);
  1045. }
  1046. namespace hooks
  1047. {
  1048. /*! AWAITING HUGO JSON CONVERSION TOOL
  1049. SIGNATURE NOT RECOGNISED
  1050. */
  1051. template <class R, class S, class P, class NoValuePolicy, class U>
  1052. constexpr inline void override_outcome_exception(basic_outcome<R, S, P, NoValuePolicy> *o, U &&v) noexcept
  1053. {
  1054. o->_ptr = static_cast<U &&>(v); // NOLINT
  1055. o->_state._status.set_have_exception(true);
  1056. }
  1057. } // namespace hooks
  1058. BOOST_OUTCOME_V2_NAMESPACE_END
  1059. #ifdef __clang__
  1060. #pragma clang diagnostic pop
  1061. #endif
  1062. #include "detail/basic_outcome_exception_observers_impl.hpp"
  1063. #if !defined(NDEBUG)
  1064. BOOST_OUTCOME_V2_NAMESPACE_BEGIN
  1065. // Check is trivial in all ways except default constructibility and standard layout
  1066. // static_assert(std::is_trivial<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivial!");
  1067. // static_assert(std::is_trivially_default_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially default
  1068. // constructible!");
  1069. static_assert(std::is_trivially_copyable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copyable!");
  1070. static_assert(std::is_trivially_assignable<basic_outcome<int, long, double, policy::all_narrow>, basic_outcome<int, long, double, policy::all_narrow>>::value,
  1071. "outcome<int> is not trivially assignable!");
  1072. static_assert(std::is_trivially_destructible<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially destructible!");
  1073. static_assert(std::is_trivially_copy_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
  1074. "outcome<int> is not trivially copy constructible!");
  1075. static_assert(std::is_trivially_move_constructible<basic_outcome<int, long, double, policy::all_narrow>>::value,
  1076. "outcome<int> is not trivially move constructible!");
  1077. static_assert(std::is_trivially_copy_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially copy assignable!");
  1078. static_assert(std::is_trivially_move_assignable<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not trivially move assignable!");
  1079. // Can't be standard layout as non-static member data is defined in more than one inherited class
  1080. // static_assert(std::is_standard_layout<basic_outcome<int, long, double, policy::all_narrow>>::value, "outcome<int> is not a standard layout type!");
  1081. BOOST_OUTCOME_V2_NAMESPACE_END
  1082. #endif
  1083. #endif