basic_outcome.hpp 59 KB

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