You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

expected.hpp 87KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326
  1. ///
  2. // expected - An implementation of std::expected with extensions
  3. // Written in 2017 by Simon Brand (simonrbrand@gmail.com, @TartanLlama)
  4. //
  5. // Documentation available at http://tl.tartanllama.xyz/
  6. //
  7. // To the extent possible under law, the author(s) have dedicated all
  8. // copyright and related and neighboring rights to this software to the
  9. // public domain worldwide. This software is distributed without any warranty.
  10. //
  11. // You should have received a copy of the CC0 Public Domain Dedication
  12. // along with this software. If not, see
  13. // <http://creativecommons.org/publicdomain/zero/1.0/>.
  14. ///
  15. #ifndef TL_EXPECTED_HPP
  16. #define TL_EXPECTED_HPP
  17. #define TL_EXPECTED_VERSION_MAJOR 1
  18. #define TL_EXPECTED_VERSION_MINOR 0
  19. #define TL_EXPECTED_VERSION_PATCH 1
  20. #include <exception>
  21. #include <functional>
  22. #include <type_traits>
  23. #include <utility>
  24. #if defined(__EXCEPTIONS) || defined(_CPPUNWIND)
  25. #define TL_EXPECTED_EXCEPTIONS_ENABLED
  26. #endif
  27. #if (defined(_MSC_VER) && _MSC_VER == 1900)
  28. #define TL_EXPECTED_MSVC2015
  29. #define TL_EXPECTED_MSVC2015_CONSTEXPR
  30. #else
  31. #define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr
  32. #endif
  33. #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
  34. !defined(__clang__))
  35. #define TL_EXPECTED_GCC49
  36. #endif
  37. #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \
  38. !defined(__clang__))
  39. #define TL_EXPECTED_GCC54
  40. #endif
  41. #if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \
  42. !defined(__clang__))
  43. #define TL_EXPECTED_GCC55
  44. #endif
  45. #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
  46. !defined(__clang__))
  47. // GCC < 5 doesn't support overloading on const&& for member functions
  48. #define TL_EXPECTED_NO_CONSTRR
  49. // GCC < 5 doesn't support some standard C++11 type traits
  50. #define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
  51. std::has_trivial_copy_constructor<T>
  52. #define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
  53. std::has_trivial_copy_assign<T>
  54. // This one will be different for GCC 5.7 if it's ever supported
  55. #define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
  56. std::is_trivially_destructible<T>
  57. // GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks std::vector
  58. // for non-copyable types
  59. #elif (defined(__GNUC__) && __GNUC__ < 8 && \
  60. !defined(__clang__))
  61. #ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
  62. #define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX
  63. namespace tl {
  64. namespace detail {
  65. template<class T>
  66. struct is_trivially_copy_constructible : std::is_trivially_copy_constructible<T>{};
  67. #ifdef _GLIBCXX_VECTOR
  68. template<class T, class A>
  69. struct is_trivially_copy_constructible<std::vector<T,A>>
  70. : std::false_type{};
  71. #endif
  72. }
  73. }
  74. #endif
  75. #define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
  76. tl::detail::is_trivially_copy_constructible<T>
  77. #define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
  78. std::is_trivially_copy_assignable<T>
  79. #define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>
  80. #else
  81. #define TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
  82. std::is_trivially_copy_constructible<T>
  83. #define TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
  84. std::is_trivially_copy_assignable<T>
  85. #define TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T) \
  86. std::is_trivially_destructible<T>
  87. #endif
  88. #if __cplusplus > 201103L
  89. #define TL_EXPECTED_CXX14
  90. #endif
  91. #ifdef TL_EXPECTED_GCC49
  92. #define TL_EXPECTED_GCC49_CONSTEXPR
  93. #else
  94. #define TL_EXPECTED_GCC49_CONSTEXPR constexpr
  95. #endif
  96. #if (__cplusplus == 201103L || defined(TL_EXPECTED_MSVC2015) || \
  97. defined(TL_EXPECTED_GCC49))
  98. #define TL_EXPECTED_11_CONSTEXPR
  99. #else
  100. #define TL_EXPECTED_11_CONSTEXPR constexpr
  101. #endif
  102. namespace tl {
  103. template <class T, class E> class expected;
  104. #ifndef TL_MONOSTATE_INPLACE_MUTEX
  105. #define TL_MONOSTATE_INPLACE_MUTEX
  106. class monostate {};
  107. struct in_place_t {
  108. explicit in_place_t() = default;
  109. };
  110. static constexpr in_place_t in_place{};
  111. #endif
  112. template <class E> class unexpected {
  113. public:
  114. static_assert(!std::is_same<E, void>::value, "E must not be void");
  115. unexpected() = delete;
  116. constexpr explicit unexpected(const E &e) : m_val(e) {}
  117. constexpr explicit unexpected(E &&e) : m_val(std::move(e)) {}
  118. constexpr const E &value() const & { return m_val; }
  119. TL_EXPECTED_11_CONSTEXPR E &value() & { return m_val; }
  120. TL_EXPECTED_11_CONSTEXPR E &&value() && { return std::move(m_val); }
  121. constexpr const E &&value() const && { return std::move(m_val); }
  122. private:
  123. E m_val;
  124. };
  125. template <class E>
  126. constexpr bool operator==(const unexpected<E> &lhs, const unexpected<E> &rhs) {
  127. return lhs.value() == rhs.value();
  128. }
  129. template <class E>
  130. constexpr bool operator!=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
  131. return lhs.value() != rhs.value();
  132. }
  133. template <class E>
  134. constexpr bool operator<(const unexpected<E> &lhs, const unexpected<E> &rhs) {
  135. return lhs.value() < rhs.value();
  136. }
  137. template <class E>
  138. constexpr bool operator<=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
  139. return lhs.value() <= rhs.value();
  140. }
  141. template <class E>
  142. constexpr bool operator>(const unexpected<E> &lhs, const unexpected<E> &rhs) {
  143. return lhs.value() > rhs.value();
  144. }
  145. template <class E>
  146. constexpr bool operator>=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
  147. return lhs.value() >= rhs.value();
  148. }
  149. template <class E>
  150. unexpected<typename std::decay<E>::type> make_unexpected(E &&e) {
  151. return unexpected<typename std::decay<E>::type>(std::forward<E>(e));
  152. }
  153. struct unexpect_t {
  154. unexpect_t() = default;
  155. };
  156. static constexpr unexpect_t unexpect{};
  157. namespace detail {
  158. template<typename E>
  159. [[noreturn]] TL_EXPECTED_11_CONSTEXPR void throw_exception(E &&e) {
  160. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  161. throw std::forward<E>(e);
  162. #else
  163. #ifdef _MSC_VER
  164. __assume(0);
  165. #else
  166. __builtin_unreachable();
  167. #endif
  168. #endif
  169. }
  170. #ifndef TL_TRAITS_MUTEX
  171. #define TL_TRAITS_MUTEX
  172. // C++14-style aliases for brevity
  173. template <class T> using remove_const_t = typename std::remove_const<T>::type;
  174. template <class T>
  175. using remove_reference_t = typename std::remove_reference<T>::type;
  176. template <class T> using decay_t = typename std::decay<T>::type;
  177. template <bool E, class T = void>
  178. using enable_if_t = typename std::enable_if<E, T>::type;
  179. template <bool B, class T, class F>
  180. using conditional_t = typename std::conditional<B, T, F>::type;
  181. // std::conjunction from C++17
  182. template <class...> struct conjunction : std::true_type {};
  183. template <class B> struct conjunction<B> : B {};
  184. template <class B, class... Bs>
  185. struct conjunction<B, Bs...>
  186. : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
  187. #if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
  188. #define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
  189. #endif
  190. // In C++11 mode, there's an issue in libc++'s std::mem_fn
  191. // which results in a hard-error when using it in a noexcept expression
  192. // in some cases. This is a check to workaround the common failing case.
  193. #ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
  194. template <class T> struct is_pointer_to_non_const_member_func : std::false_type {};
  195. template <class T, class Ret, class... Args>
  196. struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...)> : std::true_type {};
  197. template <class T, class Ret, class... Args>
  198. struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...)&> : std::true_type {};
  199. template <class T, class Ret, class... Args>
  200. struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) &&> : std::true_type {};
  201. template <class T, class Ret, class... Args>
  202. struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile> : std::true_type {};
  203. template <class T, class Ret, class... Args>
  204. struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile &> : std::true_type {};
  205. template <class T, class Ret, class... Args>
  206. struct is_pointer_to_non_const_member_func<Ret(T::*) (Args...) volatile &&> : std::true_type {};
  207. template <class T> struct is_const_or_const_ref : std::false_type {};
  208. template <class T> struct is_const_or_const_ref<T const&> : std::true_type {};
  209. template <class T> struct is_const_or_const_ref<T const> : std::true_type {};
  210. #endif
  211. // std::invoke from C++17
  212. // https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround
  213. template <typename Fn, typename... Args,
  214. #ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
  215. typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value
  216. && is_const_or_const_ref<Args...>::value)>,
  217. #endif
  218. typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
  219. int = 0>
  220. constexpr auto invoke(Fn && f, Args && ... args) noexcept(
  221. noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
  222. -> decltype(std::mem_fn(f)(std::forward<Args>(args)...)) {
  223. return std::mem_fn(f)(std::forward<Args>(args)...);
  224. }
  225. template <typename Fn, typename... Args,
  226. typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
  227. constexpr auto invoke(Fn && f, Args && ... args) noexcept(
  228. noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
  229. -> decltype(std::forward<Fn>(f)(std::forward<Args>(args)...)) {
  230. return std::forward<Fn>(f)(std::forward<Args>(args)...);
  231. }
  232. // std::invoke_result from C++17
  233. template <class F, class, class... Us> struct invoke_result_impl;
  234. template <class F, class... Us>
  235. struct invoke_result_impl<
  236. F, decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()),
  237. Us...> {
  238. using type = decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
  239. };
  240. template <class F, class... Us>
  241. using invoke_result = invoke_result_impl<F, void, Us...>;
  242. template <class F, class... Us>
  243. using invoke_result_t = typename invoke_result<F, Us...>::type;
  244. #if defined(_MSC_VER) && _MSC_VER <= 1900
  245. // TODO make a version which works with MSVC 2015
  246. template <class T, class U = T> struct is_swappable : std::true_type {};
  247. template <class T, class U = T> struct is_nothrow_swappable : std::true_type {};
  248. #else
  249. // https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept
  250. namespace swap_adl_tests {
  251. // if swap ADL finds this then it would call std::swap otherwise (same
  252. // signature)
  253. struct tag {};
  254. template <class T> tag swap(T&, T&);
  255. template <class T, std::size_t N> tag swap(T(&a)[N], T(&b)[N]);
  256. // helper functions to test if an unqualified swap is possible, and if it
  257. // becomes std::swap
  258. template <class, class> std::false_type can_swap(...) noexcept(false);
  259. template <class T, class U,
  260. class = decltype(swap(std::declval<T&>(), std::declval<U&>()))>
  261. std::true_type can_swap(int) noexcept(noexcept(swap(std::declval<T&>(),
  262. std::declval<U&>())));
  263. template <class, class> std::false_type uses_std(...);
  264. template <class T, class U>
  265. std::is_same<decltype(swap(std::declval<T&>(), std::declval<U&>())), tag>
  266. uses_std(int);
  267. template <class T>
  268. struct is_std_swap_noexcept
  269. : std::integral_constant<bool,
  270. std::is_nothrow_move_constructible<T>::value&&
  271. std::is_nothrow_move_assignable<T>::value> {};
  272. template <class T, std::size_t N>
  273. struct is_std_swap_noexcept<T[N]> : is_std_swap_noexcept<T> {};
  274. template <class T, class U>
  275. struct is_adl_swap_noexcept
  276. : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
  277. } // namespace swap_adl_tests
  278. template <class T, class U = T>
  279. struct is_swappable
  280. : std::integral_constant<
  281. bool,
  282. decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
  283. (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
  284. (std::is_move_assignable<T>::value &&
  285. std::is_move_constructible<T>::value))> {};
  286. template <class T, std::size_t N>
  287. struct is_swappable<T[N], T[N]>
  288. : std::integral_constant<
  289. bool,
  290. decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
  291. (!decltype(
  292. detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value ||
  293. is_swappable<T, T>::value)> {};
  294. template <class T, class U = T>
  295. struct is_nothrow_swappable
  296. : std::integral_constant<
  297. bool,
  298. is_swappable<T, U>::value &&
  299. ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value
  300. && detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
  301. (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
  302. detail::swap_adl_tests::is_adl_swap_noexcept<T,
  303. U>::value))> {
  304. };
  305. #endif
  306. #endif
  307. // Trait for checking if a type is a tl::expected
  308. template <class T> struct is_expected_impl : std::false_type {};
  309. template <class T, class E>
  310. struct is_expected_impl<expected<T, E>> : std::true_type {};
  311. template <class T> using is_expected = is_expected_impl<decay_t<T>>;
  312. template <class T, class E, class U>
  313. using expected_enable_forward_value = detail::enable_if_t<
  314. std::is_constructible<T, U &&>::value &&
  315. !std::is_same<detail::decay_t<U>, in_place_t>::value &&
  316. !std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
  317. !std::is_same<unexpected<E>, detail::decay_t<U>>::value>;
  318. template <class T, class E, class U, class G, class UR, class GR>
  319. using expected_enable_from_other = detail::enable_if_t<
  320. std::is_constructible<T, UR>::value &&
  321. std::is_constructible<E, GR>::value &&
  322. !std::is_constructible<T, expected<U, G> &>::value &&
  323. !std::is_constructible<T, expected<U, G> &&>::value &&
  324. !std::is_constructible<T, const expected<U, G> &>::value &&
  325. !std::is_constructible<T, const expected<U, G> &&>::value &&
  326. !std::is_convertible<expected<U, G> &, T>::value &&
  327. !std::is_convertible<expected<U, G> &&, T>::value &&
  328. !std::is_convertible<const expected<U, G> &, T>::value &&
  329. !std::is_convertible<const expected<U, G> &&, T>::value>;
  330. template <class T, class U>
  331. using is_void_or = conditional_t<std::is_void<T>::value, std::true_type, U>;
  332. template <class T>
  333. using is_copy_constructible_or_void =
  334. is_void_or<T, std::is_copy_constructible<T>>;
  335. template <class T>
  336. using is_move_constructible_or_void =
  337. is_void_or<T, std::is_move_constructible<T>>;
  338. template <class T>
  339. using is_copy_assignable_or_void =
  340. is_void_or<T, std::is_copy_assignable<T>>;
  341. template <class T>
  342. using is_move_assignable_or_void =
  343. is_void_or<T, std::is_move_assignable<T>>;
  344. } // namespace detail
  345. namespace detail {
  346. struct no_init_t {};
  347. static constexpr no_init_t no_init{};
  348. // Implements the storage of the values, and ensures that the destructor is
  349. // trivial if it can be.
  350. //
  351. // This specialization is for where neither `T` or `E` is trivially
  352. // destructible, so the destructors must be called on destruction of the
  353. // `expected`
  354. template <class T, class E, bool = std::is_trivially_destructible<T>::value,
  355. bool = std::is_trivially_destructible<E>::value>
  356. struct expected_storage_base {
  357. constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
  358. constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
  359. template <class... Args,
  360. detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
  361. nullptr>
  362. constexpr expected_storage_base(in_place_t, Args &&... args)
  363. : m_val(std::forward<Args>(args)...), m_has_val(true) {}
  364. template <class U, class... Args,
  365. detail::enable_if_t<std::is_constructible<
  366. T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  367. constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
  368. Args &&... args)
  369. : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
  370. template <class... Args,
  371. detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
  372. nullptr>
  373. constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
  374. : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
  375. template <class U, class... Args,
  376. detail::enable_if_t<std::is_constructible<
  377. E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  378. constexpr explicit expected_storage_base(unexpect_t,
  379. std::initializer_list<U> il,
  380. Args &&... args)
  381. : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
  382. ~expected_storage_base() {
  383. if (m_has_val) {
  384. m_val.~T();
  385. } else {
  386. m_unexpect.~unexpected<E>();
  387. }
  388. }
  389. union {
  390. T m_val;
  391. unexpected<E> m_unexpect;
  392. char m_no_init;
  393. };
  394. bool m_has_val;
  395. };
  396. // This specialization is for when both `T` and `E` are trivially-destructible,
  397. // so the destructor of the `expected` can be trivial.
  398. template <class T, class E> struct expected_storage_base<T, E, true, true> {
  399. constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
  400. constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
  401. template <class... Args,
  402. detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
  403. nullptr>
  404. constexpr expected_storage_base(in_place_t, Args &&... args)
  405. : m_val(std::forward<Args>(args)...), m_has_val(true) {}
  406. template <class U, class... Args,
  407. detail::enable_if_t<std::is_constructible<
  408. T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  409. constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
  410. Args &&... args)
  411. : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
  412. template <class... Args,
  413. detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
  414. nullptr>
  415. constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
  416. : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
  417. template <class U, class... Args,
  418. detail::enable_if_t<std::is_constructible<
  419. E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  420. constexpr explicit expected_storage_base(unexpect_t,
  421. std::initializer_list<U> il,
  422. Args &&... args)
  423. : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
  424. ~expected_storage_base() = default;
  425. union {
  426. T m_val;
  427. unexpected<E> m_unexpect;
  428. char m_no_init;
  429. };
  430. bool m_has_val;
  431. };
  432. // T is trivial, E is not.
  433. template <class T, class E> struct expected_storage_base<T, E, true, false> {
  434. constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
  435. TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t)
  436. : m_no_init(), m_has_val(false) {}
  437. template <class... Args,
  438. detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
  439. nullptr>
  440. constexpr expected_storage_base(in_place_t, Args &&... args)
  441. : m_val(std::forward<Args>(args)...), m_has_val(true) {}
  442. template <class U, class... Args,
  443. detail::enable_if_t<std::is_constructible<
  444. T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  445. constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
  446. Args &&... args)
  447. : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
  448. template <class... Args,
  449. detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
  450. nullptr>
  451. constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
  452. : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
  453. template <class U, class... Args,
  454. detail::enable_if_t<std::is_constructible<
  455. E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  456. constexpr explicit expected_storage_base(unexpect_t,
  457. std::initializer_list<U> il,
  458. Args &&... args)
  459. : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
  460. ~expected_storage_base() {
  461. if (!m_has_val) {
  462. m_unexpect.~unexpected<E>();
  463. }
  464. }
  465. union {
  466. T m_val;
  467. unexpected<E> m_unexpect;
  468. char m_no_init;
  469. };
  470. bool m_has_val;
  471. };
  472. // E is trivial, T is not.
  473. template <class T, class E> struct expected_storage_base<T, E, false, true> {
  474. constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
  475. constexpr expected_storage_base(no_init_t) : m_no_init(), m_has_val(false) {}
  476. template <class... Args,
  477. detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
  478. nullptr>
  479. constexpr expected_storage_base(in_place_t, Args &&... args)
  480. : m_val(std::forward<Args>(args)...), m_has_val(true) {}
  481. template <class U, class... Args,
  482. detail::enable_if_t<std::is_constructible<
  483. T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  484. constexpr expected_storage_base(in_place_t, std::initializer_list<U> il,
  485. Args &&... args)
  486. : m_val(il, std::forward<Args>(args)...), m_has_val(true) {}
  487. template <class... Args,
  488. detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
  489. nullptr>
  490. constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
  491. : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
  492. template <class U, class... Args,
  493. detail::enable_if_t<std::is_constructible<
  494. E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  495. constexpr explicit expected_storage_base(unexpect_t,
  496. std::initializer_list<U> il,
  497. Args &&... args)
  498. : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
  499. ~expected_storage_base() {
  500. if (m_has_val) {
  501. m_val.~T();
  502. }
  503. }
  504. union {
  505. T m_val;
  506. unexpected<E> m_unexpect;
  507. char m_no_init;
  508. };
  509. bool m_has_val;
  510. };
  511. // `T` is `void`, `E` is trivially-destructible
  512. template <class E> struct expected_storage_base<void, E, false, true> {
  513. TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base() : m_has_val(true) {}
  514. constexpr expected_storage_base(no_init_t) : m_val(), m_has_val(false) {}
  515. constexpr expected_storage_base(in_place_t) : m_has_val(true) {}
  516. template <class... Args,
  517. detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
  518. nullptr>
  519. constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
  520. : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
  521. template <class U, class... Args,
  522. detail::enable_if_t<std::is_constructible<
  523. E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  524. constexpr explicit expected_storage_base(unexpect_t,
  525. std::initializer_list<U> il,
  526. Args &&... args)
  527. : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
  528. ~expected_storage_base() = default;
  529. struct dummy {};
  530. union {
  531. unexpected<E> m_unexpect;
  532. dummy m_val;
  533. };
  534. bool m_has_val;
  535. };
  536. // `T` is `void`, `E` is not trivially-destructible
  537. template <class E> struct expected_storage_base<void, E, false, false> {
  538. constexpr expected_storage_base() : m_dummy(), m_has_val(true) {}
  539. constexpr expected_storage_base(no_init_t) : m_dummy(), m_has_val(false) {}
  540. constexpr expected_storage_base(in_place_t) : m_dummy(), m_has_val(true) {}
  541. template <class... Args,
  542. detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
  543. nullptr>
  544. constexpr explicit expected_storage_base(unexpect_t, Args &&... args)
  545. : m_unexpect(std::forward<Args>(args)...), m_has_val(false) {}
  546. template <class U, class... Args,
  547. detail::enable_if_t<std::is_constructible<
  548. E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  549. constexpr explicit expected_storage_base(unexpect_t,
  550. std::initializer_list<U> il,
  551. Args &&... args)
  552. : m_unexpect(il, std::forward<Args>(args)...), m_has_val(false) {}
  553. ~expected_storage_base() {
  554. if (!m_has_val) {
  555. m_unexpect.~unexpected<E>();
  556. }
  557. }
  558. union {
  559. unexpected<E> m_unexpect;
  560. char m_dummy;
  561. };
  562. bool m_has_val;
  563. };
  564. // This base class provides some handy member functions which can be used in
  565. // further derived classes
  566. template <class T, class E>
  567. struct expected_operations_base : expected_storage_base<T, E> {
  568. using expected_storage_base<T, E>::expected_storage_base;
  569. template <class... Args> void construct(Args &&... args) noexcept {
  570. new (std::addressof(this->m_val)) T(std::forward<Args>(args)...);
  571. this->m_has_val = true;
  572. }
  573. template <class Rhs> void construct_with(Rhs &&rhs) noexcept {
  574. new (std::addressof(this->m_val)) T(std::forward<Rhs>(rhs).get());
  575. this->m_has_val = true;
  576. }
  577. template <class... Args> void construct_error(Args &&... args) noexcept {
  578. new (std::addressof(this->m_unexpect))
  579. unexpected<E>(std::forward<Args>(args)...);
  580. this->m_has_val = false;
  581. }
  582. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  583. // These assign overloads ensure that the most efficient assignment
  584. // implementation is used while maintaining the strong exception guarantee.
  585. // The problematic case is where rhs has a value, but *this does not.
  586. //
  587. // This overload handles the case where we can just copy-construct `T`
  588. // directly into place without throwing.
  589. template <class U = T,
  590. detail::enable_if_t<std::is_nothrow_copy_constructible<U>::value>
  591. * = nullptr>
  592. void assign(const expected_operations_base &rhs) noexcept {
  593. if (!this->m_has_val && rhs.m_has_val) {
  594. geterr().~unexpected<E>();
  595. construct(rhs.get());
  596. } else {
  597. assign_common(rhs);
  598. }
  599. }
  600. // This overload handles the case where we can attempt to create a copy of
  601. // `T`, then no-throw move it into place if the copy was successful.
  602. template <class U = T,
  603. detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
  604. std::is_nothrow_move_constructible<U>::value>
  605. * = nullptr>
  606. void assign(const expected_operations_base &rhs) noexcept {
  607. if (!this->m_has_val && rhs.m_has_val) {
  608. T tmp = rhs.get();
  609. geterr().~unexpected<E>();
  610. construct(std::move(tmp));
  611. } else {
  612. assign_common(rhs);
  613. }
  614. }
  615. // This overload is the worst-case, where we have to move-construct the
  616. // unexpected value into temporary storage, then try to copy the T into place.
  617. // If the construction succeeds, then everything is fine, but if it throws,
  618. // then we move the old unexpected value back into place before rethrowing the
  619. // exception.
  620. template <class U = T,
  621. detail::enable_if_t<!std::is_nothrow_copy_constructible<U>::value &&
  622. !std::is_nothrow_move_constructible<U>::value>
  623. * = nullptr>
  624. void assign(const expected_operations_base &rhs) {
  625. if (!this->m_has_val && rhs.m_has_val) {
  626. auto tmp = std::move(geterr());
  627. geterr().~unexpected<E>();
  628. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  629. try {
  630. construct(rhs.get());
  631. } catch (...) {
  632. geterr() = std::move(tmp);
  633. throw;
  634. }
  635. #else
  636. construct(rhs.get());
  637. #endif
  638. } else {
  639. assign_common(rhs);
  640. }
  641. }
  642. // These overloads do the same as above, but for rvalues
  643. template <class U = T,
  644. detail::enable_if_t<std::is_nothrow_move_constructible<U>::value>
  645. * = nullptr>
  646. void assign(expected_operations_base &&rhs) noexcept {
  647. if (!this->m_has_val && rhs.m_has_val) {
  648. geterr().~unexpected<E>();
  649. construct(std::move(rhs).get());
  650. } else {
  651. assign_common(std::move(rhs));
  652. }
  653. }
  654. template <class U = T,
  655. detail::enable_if_t<!std::is_nothrow_move_constructible<U>::value>
  656. * = nullptr>
  657. void assign(expected_operations_base &&rhs) {
  658. if (!this->m_has_val && rhs.m_has_val) {
  659. auto tmp = std::move(geterr());
  660. geterr().~unexpected<E>();
  661. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  662. try {
  663. construct(std::move(rhs).get());
  664. } catch (...) {
  665. geterr() = std::move(tmp);
  666. throw;
  667. }
  668. #else
  669. construct(std::move(rhs).get());
  670. #endif
  671. } else {
  672. assign_common(std::move(rhs));
  673. }
  674. }
  675. #else
  676. // If exceptions are disabled then we can just copy-construct
  677. void assign(const expected_operations_base &rhs) noexcept {
  678. if (!this->m_has_val && rhs.m_has_val) {
  679. geterr().~unexpected<E>();
  680. construct(rhs.get());
  681. } else {
  682. assign_common(rhs);
  683. }
  684. }
  685. void assign(expected_operations_base &&rhs) noexcept {
  686. if (!this->m_has_val && rhs.m_has_val) {
  687. geterr().~unexpected<E>();
  688. construct(std::move(rhs).get());
  689. } else {
  690. assign_common(rhs);
  691. }
  692. }
  693. #endif
  694. // The common part of move/copy assigning
  695. template <class Rhs> void assign_common(Rhs &&rhs) {
  696. if (this->m_has_val) {
  697. if (rhs.m_has_val) {
  698. get() = std::forward<Rhs>(rhs).get();
  699. } else {
  700. destroy_val();
  701. construct_error(std::forward<Rhs>(rhs).geterr());
  702. }
  703. } else {
  704. if (!rhs.m_has_val) {
  705. geterr() = std::forward<Rhs>(rhs).geterr();
  706. }
  707. }
  708. }
  709. bool has_value() const { return this->m_has_val; }
  710. TL_EXPECTED_11_CONSTEXPR T &get() & { return this->m_val; }
  711. constexpr const T &get() const & { return this->m_val; }
  712. TL_EXPECTED_11_CONSTEXPR T &&get() && { return std::move(this->m_val); }
  713. #ifndef TL_EXPECTED_NO_CONSTRR
  714. constexpr const T &&get() const && { return std::move(this->m_val); }
  715. #endif
  716. TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & {
  717. return this->m_unexpect;
  718. }
  719. constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; }
  720. TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && {
  721. return std::move(this->m_unexpect);
  722. }
  723. #ifndef TL_EXPECTED_NO_CONSTRR
  724. constexpr const unexpected<E> &&geterr() const && {
  725. return std::move(this->m_unexpect);
  726. }
  727. #endif
  728. TL_EXPECTED_11_CONSTEXPR void destroy_val() {
  729. get().~T();
  730. }
  731. };
  732. // This base class provides some handy member functions which can be used in
  733. // further derived classes
  734. template <class E>
  735. struct expected_operations_base<void, E> : expected_storage_base<void, E> {
  736. using expected_storage_base<void, E>::expected_storage_base;
  737. template <class... Args> void construct() noexcept { this->m_has_val = true; }
  738. // This function doesn't use its argument, but needs it so that code in
  739. // levels above this can work independently of whether T is void
  740. template <class Rhs> void construct_with(Rhs &&) noexcept {
  741. this->m_has_val = true;
  742. }
  743. template <class... Args> void construct_error(Args &&... args) noexcept {
  744. new (std::addressof(this->m_unexpect))
  745. unexpected<E>(std::forward<Args>(args)...);
  746. this->m_has_val = false;
  747. }
  748. template <class Rhs> void assign(Rhs &&rhs) noexcept {
  749. if (!this->m_has_val) {
  750. if (rhs.m_has_val) {
  751. geterr().~unexpected<E>();
  752. construct();
  753. } else {
  754. geterr() = std::forward<Rhs>(rhs).geterr();
  755. }
  756. } else {
  757. if (!rhs.m_has_val) {
  758. construct_error(std::forward<Rhs>(rhs).geterr());
  759. }
  760. }
  761. }
  762. bool has_value() const { return this->m_has_val; }
  763. TL_EXPECTED_11_CONSTEXPR unexpected<E> &geterr() & {
  764. return this->m_unexpect;
  765. }
  766. constexpr const unexpected<E> &geterr() const & { return this->m_unexpect; }
  767. TL_EXPECTED_11_CONSTEXPR unexpected<E> &&geterr() && {
  768. return std::move(this->m_unexpect);
  769. }
  770. #ifndef TL_EXPECTED_NO_CONSTRR
  771. constexpr const unexpected<E> &&geterr() const && {
  772. return std::move(this->m_unexpect);
  773. }
  774. #endif
  775. TL_EXPECTED_11_CONSTEXPR void destroy_val() {
  776. //no-op
  777. }
  778. };
  779. // This class manages conditionally having a trivial copy constructor
  780. // This specialization is for when T and E are trivially copy constructible
  781. template <class T, class E,
  782. bool = is_void_or<T, TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T)>::
  783. value &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value>
  784. struct expected_copy_base : expected_operations_base<T, E> {
  785. using expected_operations_base<T, E>::expected_operations_base;
  786. };
  787. // This specialization is for when T or E are not trivially copy constructible
  788. template <class T, class E>
  789. struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
  790. using expected_operations_base<T, E>::expected_operations_base;
  791. expected_copy_base() = default;
  792. expected_copy_base(const expected_copy_base &rhs)
  793. : expected_operations_base<T, E>(no_init) {
  794. if (rhs.has_value()) {
  795. this->construct_with(rhs);
  796. } else {
  797. this->construct_error(rhs.geterr());
  798. }
  799. }
  800. expected_copy_base(expected_copy_base &&rhs) = default;
  801. expected_copy_base &operator=(const expected_copy_base &rhs) = default;
  802. expected_copy_base &operator=(expected_copy_base &&rhs) = default;
  803. };
  804. // This class manages conditionally having a trivial move constructor
  805. // Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
  806. // doesn't implement an analogue to std::is_trivially_move_constructible. We
  807. // have to make do with a non-trivial move constructor even if T is trivially
  808. // move constructible
  809. #ifndef TL_EXPECTED_GCC49
  810. template <class T, class E,
  811. bool = is_void_or<T, std::is_trivially_move_constructible<T>>::value
  812. &&std::is_trivially_move_constructible<E>::value>
  813. struct expected_move_base : expected_copy_base<T, E> {
  814. using expected_copy_base<T, E>::expected_copy_base;
  815. };
  816. #else
  817. template <class T, class E, bool = false> struct expected_move_base;
  818. #endif
  819. template <class T, class E>
  820. struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
  821. using expected_copy_base<T, E>::expected_copy_base;
  822. expected_move_base() = default;
  823. expected_move_base(const expected_move_base &rhs) = default;
  824. expected_move_base(expected_move_base &&rhs) noexcept(
  825. std::is_nothrow_move_constructible<T>::value)
  826. : expected_copy_base<T, E>(no_init) {
  827. if (rhs.has_value()) {
  828. this->construct_with(std::move(rhs));
  829. } else {
  830. this->construct_error(std::move(rhs.geterr()));
  831. }
  832. }
  833. expected_move_base &operator=(const expected_move_base &rhs) = default;
  834. expected_move_base &operator=(expected_move_base &&rhs) = default;
  835. };
  836. // This class manages conditionally having a trivial copy assignment operator
  837. template <class T, class E,
  838. bool = is_void_or<
  839. T, conjunction<TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(T),
  840. TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T),
  841. TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(T)>>::value
  842. &&TL_EXPECTED_IS_TRIVIALLY_COPY_ASSIGNABLE(E)::value
  843. &&TL_EXPECTED_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E)::value
  844. &&TL_EXPECTED_IS_TRIVIALLY_DESTRUCTIBLE(E)::value>
  845. struct expected_copy_assign_base : expected_move_base<T, E> {
  846. using expected_move_base<T, E>::expected_move_base;
  847. };
  848. template <class T, class E>
  849. struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
  850. using expected_move_base<T, E>::expected_move_base;
  851. expected_copy_assign_base() = default;
  852. expected_copy_assign_base(const expected_copy_assign_base &rhs) = default;
  853. expected_copy_assign_base(expected_copy_assign_base &&rhs) = default;
  854. expected_copy_assign_base &operator=(const expected_copy_assign_base &rhs) {
  855. this->assign(rhs);
  856. return *this;
  857. }
  858. expected_copy_assign_base &
  859. operator=(expected_copy_assign_base &&rhs) = default;
  860. };
  861. // This class manages conditionally having a trivial move assignment operator
  862. // Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it
  863. // doesn't implement an analogue to std::is_trivially_move_assignable. We have
  864. // to make do with a non-trivial move assignment operator even if T is trivially
  865. // move assignable
  866. #ifndef TL_EXPECTED_GCC49
  867. template <class T, class E,
  868. bool =
  869. is_void_or<T, conjunction<std::is_trivially_destructible<T>,
  870. std::is_trivially_move_constructible<T>,
  871. std::is_trivially_move_assignable<T>>>::
  872. value &&std::is_trivially_destructible<E>::value
  873. &&std::is_trivially_move_constructible<E>::value
  874. &&std::is_trivially_move_assignable<E>::value>
  875. struct expected_move_assign_base : expected_copy_assign_base<T, E> {
  876. using expected_copy_assign_base<T, E>::expected_copy_assign_base;
  877. };
  878. #else
  879. template <class T, class E, bool = false> struct expected_move_assign_base;
  880. #endif
  881. template <class T, class E>
  882. struct expected_move_assign_base<T, E, false>
  883. : expected_copy_assign_base<T, E> {
  884. using expected_copy_assign_base<T, E>::expected_copy_assign_base;
  885. expected_move_assign_base() = default;
  886. expected_move_assign_base(const expected_move_assign_base &rhs) = default;
  887. expected_move_assign_base(expected_move_assign_base &&rhs) = default;
  888. expected_move_assign_base &
  889. operator=(const expected_move_assign_base &rhs) = default;
  890. expected_move_assign_base &
  891. operator=(expected_move_assign_base &&rhs) noexcept(
  892. std::is_nothrow_move_constructible<T>::value
  893. &&std::is_nothrow_move_assignable<T>::value) {
  894. this->assign(std::move(rhs));
  895. return *this;
  896. }
  897. };
  898. // expected_delete_ctor_base will conditionally delete copy and move
  899. // constructors depending on whether T is copy/move constructible
  900. template <class T, class E,
  901. bool EnableCopy = (is_copy_constructible_or_void<T>::value &&
  902. std::is_copy_constructible<E>::value),
  903. bool EnableMove = (is_move_constructible_or_void<T>::value &&
  904. std::is_move_constructible<E>::value)>
  905. struct expected_delete_ctor_base {
  906. expected_delete_ctor_base() = default;
  907. expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
  908. expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
  909. expected_delete_ctor_base &
  910. operator=(const expected_delete_ctor_base &) = default;
  911. expected_delete_ctor_base &
  912. operator=(expected_delete_ctor_base &&) noexcept = default;
  913. };
  914. template <class T, class E>
  915. struct expected_delete_ctor_base<T, E, true, false> {
  916. expected_delete_ctor_base() = default;
  917. expected_delete_ctor_base(const expected_delete_ctor_base &) = default;
  918. expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
  919. expected_delete_ctor_base &
  920. operator=(const expected_delete_ctor_base &) = default;
  921. expected_delete_ctor_base &
  922. operator=(expected_delete_ctor_base &&) noexcept = default;
  923. };
  924. template <class T, class E>
  925. struct expected_delete_ctor_base<T, E, false, true> {
  926. expected_delete_ctor_base() = default;
  927. expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
  928. expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = default;
  929. expected_delete_ctor_base &
  930. operator=(const expected_delete_ctor_base &) = default;
  931. expected_delete_ctor_base &
  932. operator=(expected_delete_ctor_base &&) noexcept = default;
  933. };
  934. template <class T, class E>
  935. struct expected_delete_ctor_base<T, E, false, false> {
  936. expected_delete_ctor_base() = default;
  937. expected_delete_ctor_base(const expected_delete_ctor_base &) = delete;
  938. expected_delete_ctor_base(expected_delete_ctor_base &&) noexcept = delete;
  939. expected_delete_ctor_base &
  940. operator=(const expected_delete_ctor_base &) = default;
  941. expected_delete_ctor_base &
  942. operator=(expected_delete_ctor_base &&) noexcept = default;
  943. };
  944. // expected_delete_assign_base will conditionally delete copy and move
  945. // constructors depending on whether T and E are copy/move constructible +
  946. // assignable
  947. template <class T, class E,
  948. bool EnableCopy = (is_copy_constructible_or_void<T>::value &&
  949. std::is_copy_constructible<E>::value &&
  950. is_copy_assignable_or_void<T>::value &&
  951. std::is_copy_assignable<E>::value),
  952. bool EnableMove = (is_move_constructible_or_void<T>::value &&
  953. std::is_move_constructible<E>::value &&
  954. is_move_assignable_or_void<T>::value &&
  955. std::is_move_assignable<E>::value)>
  956. struct expected_delete_assign_base {
  957. expected_delete_assign_base() = default;
  958. expected_delete_assign_base(const expected_delete_assign_base &) = default;
  959. expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
  960. default;
  961. expected_delete_assign_base &
  962. operator=(const expected_delete_assign_base &) = default;
  963. expected_delete_assign_base &
  964. operator=(expected_delete_assign_base &&) noexcept = default;
  965. };
  966. template <class T, class E>
  967. struct expected_delete_assign_base<T, E, true, false> {
  968. expected_delete_assign_base() = default;
  969. expected_delete_assign_base(const expected_delete_assign_base &) = default;
  970. expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
  971. default;
  972. expected_delete_assign_base &
  973. operator=(const expected_delete_assign_base &) = default;
  974. expected_delete_assign_base &
  975. operator=(expected_delete_assign_base &&) noexcept = delete;
  976. };
  977. template <class T, class E>
  978. struct expected_delete_assign_base<T, E, false, true> {
  979. expected_delete_assign_base() = default;
  980. expected_delete_assign_base(const expected_delete_assign_base &) = default;
  981. expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
  982. default;
  983. expected_delete_assign_base &
  984. operator=(const expected_delete_assign_base &) = delete;
  985. expected_delete_assign_base &
  986. operator=(expected_delete_assign_base &&) noexcept = default;
  987. };
  988. template <class T, class E>
  989. struct expected_delete_assign_base<T, E, false, false> {
  990. expected_delete_assign_base() = default;
  991. expected_delete_assign_base(const expected_delete_assign_base &) = default;
  992. expected_delete_assign_base(expected_delete_assign_base &&) noexcept =
  993. default;
  994. expected_delete_assign_base &
  995. operator=(const expected_delete_assign_base &) = delete;
  996. expected_delete_assign_base &
  997. operator=(expected_delete_assign_base &&) noexcept = delete;
  998. };
  999. // This is needed to be able to construct the expected_default_ctor_base which
  1000. // follows, while still conditionally deleting the default constructor.
  1001. struct default_constructor_tag {
  1002. explicit constexpr default_constructor_tag() = default;
  1003. };
  1004. // expected_default_ctor_base will ensure that expected has a deleted default
  1005. // consturctor if T is not default constructible.
  1006. // This specialization is for when T is default constructible
  1007. template <class T, class E,
  1008. bool Enable =
  1009. std::is_default_constructible<T>::value || std::is_void<T>::value>
  1010. struct expected_default_ctor_base {
  1011. constexpr expected_default_ctor_base() noexcept = default;
  1012. constexpr expected_default_ctor_base(
  1013. expected_default_ctor_base const &) noexcept = default;
  1014. constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
  1015. default;
  1016. expected_default_ctor_base &
  1017. operator=(expected_default_ctor_base const &) noexcept = default;
  1018. expected_default_ctor_base &
  1019. operator=(expected_default_ctor_base &&) noexcept = default;
  1020. constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
  1021. };
  1022. // This specialization is for when T is not default constructible
  1023. template <class T, class E> struct expected_default_ctor_base<T, E, false> {
  1024. constexpr expected_default_ctor_base() noexcept = delete;
  1025. constexpr expected_default_ctor_base(
  1026. expected_default_ctor_base const &) noexcept = default;
  1027. constexpr expected_default_ctor_base(expected_default_ctor_base &&) noexcept =
  1028. default;
  1029. expected_default_ctor_base &
  1030. operator=(expected_default_ctor_base const &) noexcept = default;
  1031. expected_default_ctor_base &
  1032. operator=(expected_default_ctor_base &&) noexcept = default;
  1033. constexpr explicit expected_default_ctor_base(default_constructor_tag) {}
  1034. };
  1035. } // namespace detail
  1036. template <class E> class bad_expected_access : public std::exception {
  1037. public:
  1038. explicit bad_expected_access(E e) : m_val(std::move(e)) {}
  1039. virtual const char *what() const noexcept override {
  1040. return "Bad expected access";
  1041. }
  1042. const E &error() const & { return m_val; }
  1043. E &error() & { return m_val; }
  1044. const E &&error() const && { return std::move(m_val); }
  1045. E &&error() && { return std::move(m_val); }
  1046. private:
  1047. E m_val;
  1048. };
  1049. /// An `expected<T, E>` object is an object that contains the storage for
  1050. /// another object and manages the lifetime of this contained object `T`.
  1051. /// Alternatively it could contain the storage for another unexpected object
  1052. /// `E`. The contained object may not be initialized after the expected object
  1053. /// has been initialized, and may not be destroyed before the expected object
  1054. /// has been destroyed. The initialization state of the contained object is
  1055. /// tracked by the expected object.
  1056. template <class T, class E>
  1057. class expected : private detail::expected_move_assign_base<T, E>,
  1058. private detail::expected_delete_ctor_base<T, E>,
  1059. private detail::expected_delete_assign_base<T, E>,
  1060. private detail::expected_default_ctor_base<T, E> {
  1061. static_assert(!std::is_reference<T>::value, "T must not be a reference");
  1062. static_assert(!std::is_same<T, std::remove_cv<in_place_t>>::value,
  1063. "T must not be in_place_t");
  1064. static_assert(!std::is_same<T, std::remove_cv<unexpect_t>>::value,
  1065. "T must not be unexpect_t");
  1066. static_assert(!std::is_same<T, std::remove_cv<unexpected<E>>>::value,
  1067. "T must not be unexpected<E>");
  1068. static_assert(!std::is_reference<E>::value, "E must not be a reference");
  1069. T *valptr() { return std::addressof(this->m_val); }
  1070. const T *valptr() const { return std::addressof(this->m_val); }
  1071. unexpected<E> *errptr() { return std::addressof(this->m_unexpect); }
  1072. const unexpected<E> *errptr() const { return std::addressof(this->m_unexpect); }
  1073. template <class U = T,
  1074. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1075. TL_EXPECTED_11_CONSTEXPR U &val() {
  1076. return this->m_val;
  1077. }
  1078. TL_EXPECTED_11_CONSTEXPR unexpected<E> &err() { return this->m_unexpect; }
  1079. template <class U = T,
  1080. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1081. constexpr const U &val() const {
  1082. return this->m_val;
  1083. }
  1084. constexpr const unexpected<E> &err() const { return this->m_unexpect; }
  1085. using impl_base = detail::expected_move_assign_base<T, E>;
  1086. using ctor_base = detail::expected_default_ctor_base<T, E>;
  1087. public:
  1088. typedef T value_type;
  1089. typedef E error_type;
  1090. typedef unexpected<E> unexpected_type;
  1091. #if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
  1092. !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
  1093. template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & {
  1094. return and_then_impl(*this, std::forward<F>(f));
  1095. }
  1096. template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && {
  1097. return and_then_impl(std::move(*this), std::forward<F>(f));
  1098. }
  1099. template <class F> constexpr auto and_then(F &&f) const & {
  1100. return and_then_impl(*this, std::forward<F>(f));
  1101. }
  1102. #ifndef TL_EXPECTED_NO_CONSTRR
  1103. template <class F> constexpr auto and_then(F &&f) const && {
  1104. return and_then_impl(std::move(*this), std::forward<F>(f));
  1105. }
  1106. #endif
  1107. #else
  1108. template <class F>
  1109. TL_EXPECTED_11_CONSTEXPR auto
  1110. and_then(F &&f) & -> decltype(and_then_impl(std::declval<expected&>(), std::forward<F>(f))) {
  1111. return and_then_impl(*this, std::forward<F>(f));
  1112. }
  1113. template <class F>
  1114. TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && -> decltype(
  1115. and_then_impl(std::declval<expected&&>(), std::forward<F>(f))) {
  1116. return and_then_impl(std::move(*this), std::forward<F>(f));
  1117. }
  1118. template <class F>
  1119. constexpr auto and_then(F &&f) const & -> decltype(
  1120. and_then_impl(std::declval<expected const&>(), std::forward<F>(f))) {
  1121. return and_then_impl(*this, std::forward<F>(f));
  1122. }
  1123. #ifndef TL_EXPECTED_NO_CONSTRR
  1124. template <class F>
  1125. constexpr auto and_then(F &&f) const && -> decltype(
  1126. and_then_impl(std::declval<expected const&&>(), std::forward<F>(f))) {
  1127. return and_then_impl(std::move(*this), std::forward<F>(f));
  1128. }
  1129. #endif
  1130. #endif
  1131. #if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
  1132. !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
  1133. template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & {
  1134. return expected_map_impl(*this, std::forward<F>(f));
  1135. }
  1136. template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && {
  1137. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1138. }
  1139. template <class F> constexpr auto map(F &&f) const & {
  1140. return expected_map_impl(*this, std::forward<F>(f));
  1141. }
  1142. template <class F> constexpr auto map(F &&f) const && {
  1143. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1144. }
  1145. #else
  1146. template <class F>
  1147. TL_EXPECTED_11_CONSTEXPR decltype(
  1148. expected_map_impl(std::declval<expected &>(), std::declval<F &&>()))
  1149. map(F &&f) & {
  1150. return expected_map_impl(*this, std::forward<F>(f));
  1151. }
  1152. template <class F>
  1153. TL_EXPECTED_11_CONSTEXPR decltype(
  1154. expected_map_impl(std::declval<expected>(), std::declval<F &&>()))
  1155. map(F &&f) && {
  1156. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1157. }
  1158. template <class F>
  1159. constexpr decltype(expected_map_impl(std::declval<const expected &>(),
  1160. std::declval<F &&>()))
  1161. map(F &&f) const & {
  1162. return expected_map_impl(*this, std::forward<F>(f));
  1163. }
  1164. #ifndef TL_EXPECTED_NO_CONSTRR
  1165. template <class F>
  1166. constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
  1167. std::declval<F &&>()))
  1168. map(F &&f) const && {
  1169. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1170. }
  1171. #endif
  1172. #endif
  1173. #if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
  1174. !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
  1175. template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) & {
  1176. return expected_map_impl(*this, std::forward<F>(f));
  1177. }
  1178. template <class F> TL_EXPECTED_11_CONSTEXPR auto transform(F &&f) && {
  1179. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1180. }
  1181. template <class F> constexpr auto transform(F &&f) const & {
  1182. return expected_map_impl(*this, std::forward<F>(f));
  1183. }
  1184. template <class F> constexpr auto transform(F &&f) const && {
  1185. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1186. }
  1187. #else
  1188. template <class F>
  1189. TL_EXPECTED_11_CONSTEXPR decltype(
  1190. expected_map_impl(std::declval<expected &>(), std::declval<F &&>()))
  1191. transform(F &&f) & {
  1192. return expected_map_impl(*this, std::forward<F>(f));
  1193. }
  1194. template <class F>
  1195. TL_EXPECTED_11_CONSTEXPR decltype(
  1196. expected_map_impl(std::declval<expected>(), std::declval<F &&>()))
  1197. transform(F &&f) && {
  1198. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1199. }
  1200. template <class F>
  1201. constexpr decltype(expected_map_impl(std::declval<const expected &>(),
  1202. std::declval<F &&>()))
  1203. transform(F &&f) const & {
  1204. return expected_map_impl(*this, std::forward<F>(f));
  1205. }
  1206. #ifndef TL_EXPECTED_NO_CONSTRR
  1207. template <class F>
  1208. constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
  1209. std::declval<F &&>()))
  1210. transform(F &&f) const && {
  1211. return expected_map_impl(std::move(*this), std::forward<F>(f));
  1212. }
  1213. #endif
  1214. #endif
  1215. #if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
  1216. !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
  1217. template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & {
  1218. return map_error_impl(*this, std::forward<F>(f));
  1219. }
  1220. template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && {
  1221. return map_error_impl(std::move(*this), std::forward<F>(f));
  1222. }
  1223. template <class F> constexpr auto map_error(F &&f) const & {
  1224. return map_error_impl(*this, std::forward<F>(f));
  1225. }
  1226. template <class F> constexpr auto map_error(F &&f) const && {
  1227. return map_error_impl(std::move(*this), std::forward<F>(f));
  1228. }
  1229. #else
  1230. template <class F>
  1231. TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(),
  1232. std::declval<F &&>()))
  1233. map_error(F &&f) & {
  1234. return map_error_impl(*this, std::forward<F>(f));
  1235. }
  1236. template <class F>
  1237. TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(),
  1238. std::declval<F &&>()))
  1239. map_error(F &&f) && {
  1240. return map_error_impl(std::move(*this), std::forward<F>(f));
  1241. }
  1242. template <class F>
  1243. constexpr decltype(map_error_impl(std::declval<const expected &>(),
  1244. std::declval<F &&>()))
  1245. map_error(F &&f) const & {
  1246. return map_error_impl(*this, std::forward<F>(f));
  1247. }
  1248. #ifndef TL_EXPECTED_NO_CONSTRR
  1249. template <class F>
  1250. constexpr decltype(map_error_impl(std::declval<const expected &&>(),
  1251. std::declval<F &&>()))
  1252. map_error(F &&f) const && {
  1253. return map_error_impl(std::move(*this), std::forward<F>(f));
  1254. }
  1255. #endif
  1256. #endif
  1257. template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & {
  1258. return or_else_impl(*this, std::forward<F>(f));
  1259. }
  1260. template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && {
  1261. return or_else_impl(std::move(*this), std::forward<F>(f));
  1262. }
  1263. template <class F> expected constexpr or_else(F &&f) const & {
  1264. return or_else_impl(*this, std::forward<F>(f));
  1265. }
  1266. #ifndef TL_EXPECTED_NO_CONSTRR
  1267. template <class F> expected constexpr or_else(F &&f) const && {
  1268. return or_else_impl(std::move(*this), std::forward<F>(f));
  1269. }
  1270. #endif
  1271. constexpr expected() = default;
  1272. constexpr expected(const expected &rhs) = default;
  1273. constexpr expected(expected &&rhs) = default;
  1274. expected &operator=(const expected &rhs) = default;
  1275. expected &operator=(expected &&rhs) = default;
  1276. template <class... Args,
  1277. detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
  1278. nullptr>
  1279. constexpr expected(in_place_t, Args &&... args)
  1280. : impl_base(in_place, std::forward<Args>(args)...),
  1281. ctor_base(detail::default_constructor_tag{}) {}
  1282. template <class U, class... Args,
  1283. detail::enable_if_t<std::is_constructible<
  1284. T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  1285. constexpr expected(in_place_t, std::initializer_list<U> il, Args &&... args)
  1286. : impl_base(in_place, il, std::forward<Args>(args)...),
  1287. ctor_base(detail::default_constructor_tag{}) {}
  1288. template <class G = E,
  1289. detail::enable_if_t<std::is_constructible<E, const G &>::value> * =
  1290. nullptr,
  1291. detail::enable_if_t<!std::is_convertible<const G &, E>::value> * =
  1292. nullptr>
  1293. explicit constexpr expected(const unexpected<G> &e)
  1294. : impl_base(unexpect, e.value()),
  1295. ctor_base(detail::default_constructor_tag{}) {}
  1296. template <
  1297. class G = E,
  1298. detail::enable_if_t<std::is_constructible<E, const G &>::value> * =
  1299. nullptr,
  1300. detail::enable_if_t<std::is_convertible<const G &, E>::value> * = nullptr>
  1301. constexpr expected(unexpected<G> const &e)
  1302. : impl_base(unexpect, e.value()),
  1303. ctor_base(detail::default_constructor_tag{}) {}
  1304. template <
  1305. class G = E,
  1306. detail::enable_if_t<std::is_constructible<E, G &&>::value> * = nullptr,
  1307. detail::enable_if_t<!std::is_convertible<G &&, E>::value> * = nullptr>
  1308. explicit constexpr expected(unexpected<G> &&e) noexcept(
  1309. std::is_nothrow_constructible<E, G &&>::value)
  1310. : impl_base(unexpect, std::move(e.value())),
  1311. ctor_base(detail::default_constructor_tag{}) {}
  1312. template <
  1313. class G = E,
  1314. detail::enable_if_t<std::is_constructible<E, G &&>::value> * = nullptr,
  1315. detail::enable_if_t<std::is_convertible<G &&, E>::value> * = nullptr>
  1316. constexpr expected(unexpected<G> &&e) noexcept(
  1317. std::is_nothrow_constructible<E, G &&>::value)
  1318. : impl_base(unexpect, std::move(e.value())),
  1319. ctor_base(detail::default_constructor_tag{}) {}
  1320. template <class... Args,
  1321. detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
  1322. nullptr>
  1323. constexpr explicit expected(unexpect_t, Args &&... args)
  1324. : impl_base(unexpect, std::forward<Args>(args)...),
  1325. ctor_base(detail::default_constructor_tag{}) {}
  1326. template <class U, class... Args,
  1327. detail::enable_if_t<std::is_constructible<
  1328. E, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  1329. constexpr explicit expected(unexpect_t, std::initializer_list<U> il,
  1330. Args &&... args)
  1331. : impl_base(unexpect, il, std::forward<Args>(args)...),
  1332. ctor_base(detail::default_constructor_tag{}) {}
  1333. template <class U, class G,
  1334. detail::enable_if_t<!(std::is_convertible<U const &, T>::value &&
  1335. std::is_convertible<G const &, E>::value)> * =
  1336. nullptr,
  1337. detail::expected_enable_from_other<T, E, U, G, const U &, const G &>
  1338. * = nullptr>
  1339. explicit TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs)
  1340. : ctor_base(detail::default_constructor_tag{}) {
  1341. if (rhs.has_value()) {
  1342. this->construct(*rhs);
  1343. } else {
  1344. this->construct_error(rhs.error());
  1345. }
  1346. }
  1347. template <class U, class G,
  1348. detail::enable_if_t<(std::is_convertible<U const &, T>::value &&
  1349. std::is_convertible<G const &, E>::value)> * =
  1350. nullptr,
  1351. detail::expected_enable_from_other<T, E, U, G, const U &, const G &>
  1352. * = nullptr>
  1353. TL_EXPECTED_11_CONSTEXPR expected(const expected<U, G> &rhs)
  1354. : ctor_base(detail::default_constructor_tag{}) {
  1355. if (rhs.has_value()) {
  1356. this->construct(*rhs);
  1357. } else {
  1358. this->construct_error(rhs.error());
  1359. }
  1360. }
  1361. template <
  1362. class U, class G,
  1363. detail::enable_if_t<!(std::is_convertible<U &&, T>::value &&
  1364. std::is_convertible<G &&, E>::value)> * = nullptr,
  1365. detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr>
  1366. explicit TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs)
  1367. : ctor_base(detail::default_constructor_tag{}) {
  1368. if (rhs.has_value()) {
  1369. this->construct(std::move(*rhs));
  1370. } else {
  1371. this->construct_error(std::move(rhs.error()));
  1372. }
  1373. }
  1374. template <
  1375. class U, class G,
  1376. detail::enable_if_t<(std::is_convertible<U &&, T>::value &&
  1377. std::is_convertible<G &&, E>::value)> * = nullptr,
  1378. detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * = nullptr>
  1379. TL_EXPECTED_11_CONSTEXPR expected(expected<U, G> &&rhs)
  1380. : ctor_base(detail::default_constructor_tag{}) {
  1381. if (rhs.has_value()) {
  1382. this->construct(std::move(*rhs));
  1383. } else {
  1384. this->construct_error(std::move(rhs.error()));
  1385. }
  1386. }
  1387. template <
  1388. class U = T,
  1389. detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr,
  1390. detail::expected_enable_forward_value<T, E, U> * = nullptr>
  1391. explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v)
  1392. : expected(in_place, std::forward<U>(v)) {}
  1393. template <
  1394. class U = T,
  1395. detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr,
  1396. detail::expected_enable_forward_value<T, E, U> * = nullptr>
  1397. TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v)
  1398. : expected(in_place, std::forward<U>(v)) {}
  1399. template <
  1400. class U = T, class G = T,
  1401. detail::enable_if_t<std::is_nothrow_constructible<T, U &&>::value> * =
  1402. nullptr,
  1403. detail::enable_if_t<!std::is_void<G>::value> * = nullptr,
  1404. detail::enable_if_t<
  1405. (!std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
  1406. !detail::conjunction<std::is_scalar<T>,
  1407. std::is_same<T, detail::decay_t<U>>>::value &&
  1408. std::is_constructible<T, U>::value &&
  1409. std::is_assignable<G &, U>::value &&
  1410. std::is_nothrow_move_constructible<E>::value)> * = nullptr>
  1411. expected &operator=(U &&v) {
  1412. if (has_value()) {
  1413. val() = std::forward<U>(v);
  1414. } else {
  1415. err().~unexpected<E>();
  1416. ::new (valptr()) T(std::forward<U>(v));
  1417. this->m_has_val = true;
  1418. }
  1419. return *this;
  1420. }
  1421. template <
  1422. class U = T, class G = T,
  1423. detail::enable_if_t<!std::is_nothrow_constructible<T, U &&>::value> * =
  1424. nullptr,
  1425. detail::enable_if_t<!std::is_void<U>::value> * = nullptr,
  1426. detail::enable_if_t<
  1427. (!std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
  1428. !detail::conjunction<std::is_scalar<T>,
  1429. std::is_same<T, detail::decay_t<U>>>::value &&
  1430. std::is_constructible<T, U>::value &&
  1431. std::is_assignable<G &, U>::value &&
  1432. std::is_nothrow_move_constructible<E>::value)> * = nullptr>
  1433. expected &operator=(U &&v) {
  1434. if (has_value()) {
  1435. val() = std::forward<U>(v);
  1436. } else {
  1437. auto tmp = std::move(err());
  1438. err().~unexpected<E>();
  1439. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  1440. try {
  1441. ::new (valptr()) T(std::forward<U>(v));
  1442. this->m_has_val = true;
  1443. } catch (...) {
  1444. err() = std::move(tmp);
  1445. throw;
  1446. }
  1447. #else
  1448. ::new (valptr()) T(std::forward<U>(v));
  1449. this->m_has_val = true;
  1450. #endif
  1451. }
  1452. return *this;
  1453. }
  1454. template <class G = E,
  1455. detail::enable_if_t<std::is_nothrow_copy_constructible<G>::value &&
  1456. std::is_assignable<G &, G>::value> * = nullptr>
  1457. expected &operator=(const unexpected<G> &rhs) {
  1458. if (!has_value()) {
  1459. err() = rhs;
  1460. } else {
  1461. this->destroy_val();
  1462. ::new (errptr()) unexpected<E>(rhs);
  1463. this->m_has_val = false;
  1464. }
  1465. return *this;
  1466. }
  1467. template <class G = E,
  1468. detail::enable_if_t<std::is_nothrow_move_constructible<G>::value &&
  1469. std::is_move_assignable<G>::value> * = nullptr>
  1470. expected &operator=(unexpected<G> &&rhs) noexcept {
  1471. if (!has_value()) {
  1472. err() = std::move(rhs);
  1473. } else {
  1474. this->destroy_val();
  1475. ::new (errptr()) unexpected<E>(std::move(rhs));
  1476. this->m_has_val = false;
  1477. }
  1478. return *this;
  1479. }
  1480. template <class... Args, detail::enable_if_t<std::is_nothrow_constructible<
  1481. T, Args &&...>::value> * = nullptr>
  1482. void emplace(Args &&... args) {
  1483. if (has_value()) {
  1484. val() = T(std::forward<Args>(args)...);
  1485. } else {
  1486. err().~unexpected<E>();
  1487. ::new (valptr()) T(std::forward<Args>(args)...);
  1488. this->m_has_val = true;
  1489. }
  1490. }
  1491. template <class... Args, detail::enable_if_t<!std::is_nothrow_constructible<
  1492. T, Args &&...>::value> * = nullptr>
  1493. void emplace(Args &&... args) {
  1494. if (has_value()) {
  1495. val() = T(std::forward<Args>(args)...);
  1496. } else {
  1497. auto tmp = std::move(err());
  1498. err().~unexpected<E>();
  1499. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  1500. try {
  1501. ::new (valptr()) T(std::forward<Args>(args)...);
  1502. this->m_has_val = true;
  1503. } catch (...) {
  1504. err() = std::move(tmp);
  1505. throw;
  1506. }
  1507. #else
  1508. ::new (valptr()) T(std::forward<Args>(args)...);
  1509. this->m_has_val = true;
  1510. #endif
  1511. }
  1512. }
  1513. template <class U, class... Args,
  1514. detail::enable_if_t<std::is_nothrow_constructible<
  1515. T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  1516. void emplace(std::initializer_list<U> il, Args &&... args) {
  1517. if (has_value()) {
  1518. T t(il, std::forward<Args>(args)...);
  1519. val() = std::move(t);
  1520. } else {
  1521. err().~unexpected<E>();
  1522. ::new (valptr()) T(il, std::forward<Args>(args)...);
  1523. this->m_has_val = true;
  1524. }
  1525. }
  1526. template <class U, class... Args,
  1527. detail::enable_if_t<!std::is_nothrow_constructible<
  1528. T, std::initializer_list<U> &, Args &&...>::value> * = nullptr>
  1529. void emplace(std::initializer_list<U> il, Args &&... args) {
  1530. if (has_value()) {
  1531. T t(il, std::forward<Args>(args)...);
  1532. val() = std::move(t);
  1533. } else {
  1534. auto tmp = std::move(err());
  1535. err().~unexpected<E>();
  1536. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  1537. try {
  1538. ::new (valptr()) T(il, std::forward<Args>(args)...);
  1539. this->m_has_val = true;
  1540. } catch (...) {
  1541. err() = std::move(tmp);
  1542. throw;
  1543. }
  1544. #else
  1545. ::new (valptr()) T(il, std::forward<Args>(args)...);
  1546. this->m_has_val = true;
  1547. #endif
  1548. }
  1549. }
  1550. private:
  1551. using t_is_void = std::true_type;
  1552. using t_is_not_void = std::false_type;
  1553. using t_is_nothrow_move_constructible = std::true_type;
  1554. using move_constructing_t_can_throw = std::false_type;
  1555. using e_is_nothrow_move_constructible = std::true_type;
  1556. using move_constructing_e_can_throw = std::false_type;
  1557. void swap_where_both_have_value(expected &/*rhs*/ , t_is_void) noexcept {
  1558. // swapping void is a no-op
  1559. }
  1560. void swap_where_both_have_value(expected &rhs, t_is_not_void) {
  1561. using std::swap;
  1562. swap(val(), rhs.val());
  1563. }
  1564. void swap_where_only_one_has_value(expected &rhs, t_is_void) noexcept(
  1565. std::is_nothrow_move_constructible<E>::value) {
  1566. ::new (errptr()) unexpected_type(std::move(rhs.err()));
  1567. rhs.err().~unexpected_type();
  1568. std::swap(this->m_has_val, rhs.m_has_val);
  1569. }
  1570. void swap_where_only_one_has_value(expected &rhs, t_is_not_void) {
  1571. swap_where_only_one_has_value_and_t_is_not_void(
  1572. rhs, typename std::is_nothrow_move_constructible<T>::type{},
  1573. typename std::is_nothrow_move_constructible<E>::type{});
  1574. }
  1575. void swap_where_only_one_has_value_and_t_is_not_void(
  1576. expected &rhs, t_is_nothrow_move_constructible,
  1577. e_is_nothrow_move_constructible) noexcept {
  1578. auto temp = std::move(val());
  1579. val().~T();
  1580. ::new (errptr()) unexpected_type(std::move(rhs.err()));
  1581. rhs.err().~unexpected_type();
  1582. ::new (rhs.valptr()) T(std::move(temp));
  1583. std::swap(this->m_has_val, rhs.m_has_val);
  1584. }
  1585. void swap_where_only_one_has_value_and_t_is_not_void(
  1586. expected &rhs, t_is_nothrow_move_constructible,
  1587. move_constructing_e_can_throw) {
  1588. auto temp = std::move(val());
  1589. val().~T();
  1590. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  1591. try {
  1592. ::new (errptr()) unexpected_type(std::move(rhs.err()));
  1593. rhs.err().~unexpected_type();
  1594. ::new (rhs.valptr()) T(std::move(temp));
  1595. std::swap(this->m_has_val, rhs.m_has_val);
  1596. } catch (...) {
  1597. val() = std::move(temp);
  1598. throw;
  1599. }
  1600. #else
  1601. ::new (errptr()) unexpected_type(std::move(rhs.err()));
  1602. rhs.err().~unexpected_type();
  1603. ::new (rhs.valptr()) T(std::move(temp));
  1604. std::swap(this->m_has_val, rhs.m_has_val);
  1605. #endif
  1606. }
  1607. void swap_where_only_one_has_value_and_t_is_not_void(
  1608. expected &rhs, move_constructing_t_can_throw,
  1609. t_is_nothrow_move_constructible) {
  1610. auto temp = std::move(rhs.err());
  1611. rhs.err().~unexpected_type();
  1612. #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
  1613. try {
  1614. ::new (rhs.valptr()) T(val());
  1615. val().~T();
  1616. ::new (errptr()) unexpected_type(std::move(temp));
  1617. std::swap(this->m_has_val, rhs.m_has_val);
  1618. } catch (...) {
  1619. rhs.err() = std::move(temp);
  1620. throw;
  1621. }
  1622. #else
  1623. ::new (rhs.valptr()) T(val());
  1624. val().~T();
  1625. ::new (errptr()) unexpected_type(std::move(temp));
  1626. std::swap(this->m_has_val, rhs.m_has_val);
  1627. #endif
  1628. }
  1629. public:
  1630. template <class OT = T, class OE = E>
  1631. detail::enable_if_t<detail::is_swappable<OT>::value &&
  1632. detail::is_swappable<OE>::value &&
  1633. (std::is_nothrow_move_constructible<OT>::value ||
  1634. std::is_nothrow_move_constructible<OE>::value)>
  1635. swap(expected &rhs) noexcept(
  1636. std::is_nothrow_move_constructible<T>::value
  1637. &&detail::is_nothrow_swappable<T>::value
  1638. &&std::is_nothrow_move_constructible<E>::value
  1639. &&detail::is_nothrow_swappable<E>::value) {
  1640. if (has_value() && rhs.has_value()) {
  1641. swap_where_both_have_value(rhs, typename std::is_void<T>::type{});
  1642. } else if (!has_value() && rhs.has_value()) {
  1643. rhs.swap(*this);
  1644. } else if (has_value()) {
  1645. swap_where_only_one_has_value(rhs, typename std::is_void<T>::type{});
  1646. } else {
  1647. using std::swap;
  1648. swap(err(), rhs.err());
  1649. }
  1650. }
  1651. constexpr const T *operator->() const { return valptr(); }
  1652. TL_EXPECTED_11_CONSTEXPR T *operator->() { return valptr(); }
  1653. template <class U = T,
  1654. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1655. constexpr const U &operator*() const & {
  1656. return val();
  1657. }
  1658. template <class U = T,
  1659. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1660. TL_EXPECTED_11_CONSTEXPR U &operator*() & {
  1661. return val();
  1662. }
  1663. template <class U = T,
  1664. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1665. constexpr const U &&operator*() const && {
  1666. return std::move(val());
  1667. }
  1668. template <class U = T,
  1669. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1670. TL_EXPECTED_11_CONSTEXPR U &&operator*() && {
  1671. return std::move(val());
  1672. }
  1673. constexpr bool has_value() const noexcept { return this->m_has_val; }
  1674. constexpr explicit operator bool() const noexcept { return this->m_has_val; }
  1675. template <class U = T,
  1676. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1677. TL_EXPECTED_11_CONSTEXPR const U &value() const & {
  1678. if (!has_value())
  1679. detail::throw_exception(bad_expected_access<E>(err().value()));
  1680. return val();
  1681. }
  1682. template <class U = T,
  1683. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1684. TL_EXPECTED_11_CONSTEXPR U &value() & {
  1685. if (!has_value())
  1686. detail::throw_exception(bad_expected_access<E>(err().value()));
  1687. return val();
  1688. }
  1689. template <class U = T,
  1690. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1691. TL_EXPECTED_11_CONSTEXPR const U &&value() const && {
  1692. if (!has_value())
  1693. detail::throw_exception(bad_expected_access<E>(std::move(err()).value()));
  1694. return std::move(val());
  1695. }
  1696. template <class U = T,
  1697. detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
  1698. TL_EXPECTED_11_CONSTEXPR U &&value() && {
  1699. if (!has_value())
  1700. detail::throw_exception(bad_expected_access<E>(std::move(err()).value()));
  1701. return std::move(val());
  1702. }
  1703. constexpr const E &error() const & { return err().value(); }
  1704. TL_EXPECTED_11_CONSTEXPR E &error() & { return err().value(); }
  1705. constexpr const E &&error() const && { return std::move(err().value()); }
  1706. TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(err().value()); }
  1707. template <class U> constexpr T value_or(U &&v) const & {
  1708. static_assert(std::is_copy_constructible<T>::value &&
  1709. std::is_convertible<U &&, T>::value,
  1710. "T must be copy-constructible and convertible to from U&&");
  1711. return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
  1712. }
  1713. template <class U> TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && {
  1714. static_assert(std::is_move_constructible<T>::value &&
  1715. std::is_convertible<U &&, T>::value,
  1716. "T must be move-constructible and convertible to from U&&");
  1717. return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v));
  1718. }
  1719. };
  1720. namespace detail {
  1721. template <class Exp> using exp_t = typename detail::decay_t<Exp>::value_type;
  1722. template <class Exp> using err_t = typename detail::decay_t<Exp>::error_type;
  1723. template <class Exp, class Ret> using ret_t = expected<Ret, err_t<Exp>>;
  1724. #ifdef TL_EXPECTED_CXX14
  1725. template <class Exp, class F,
  1726. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1727. class Ret = decltype(detail::invoke(std::declval<F>(),
  1728. *std::declval<Exp>()))>
  1729. constexpr auto and_then_impl(Exp &&exp, F &&f) {
  1730. static_assert(detail::is_expected<Ret>::value, "F must return an expected");
  1731. return exp.has_value()
  1732. ? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
  1733. : Ret(unexpect, std::forward<Exp>(exp).error());
  1734. }
  1735. template <class Exp, class F,
  1736. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1737. class Ret = decltype(detail::invoke(std::declval<F>()))>
  1738. constexpr auto and_then_impl(Exp &&exp, F &&f) {
  1739. static_assert(detail::is_expected<Ret>::value, "F must return an expected");
  1740. return exp.has_value() ? detail::invoke(std::forward<F>(f))
  1741. : Ret(unexpect, std::forward<Exp>(exp).error());
  1742. }
  1743. #else
  1744. template <class> struct TC;
  1745. template <class Exp, class F,
  1746. class Ret = decltype(detail::invoke(std::declval<F>(),
  1747. *std::declval<Exp>())),
  1748. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr>
  1749. auto and_then_impl(Exp &&exp, F &&f) -> Ret {
  1750. static_assert(detail::is_expected<Ret>::value, "F must return an expected");
  1751. return exp.has_value()
  1752. ? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
  1753. : Ret(unexpect, std::forward<Exp>(exp).error());
  1754. }
  1755. template <class Exp, class F,
  1756. class Ret = decltype(detail::invoke(std::declval<F>())),
  1757. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr>
  1758. constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret {
  1759. static_assert(detail::is_expected<Ret>::value, "F must return an expected");
  1760. return exp.has_value() ? detail::invoke(std::forward<F>(f))
  1761. : Ret(unexpect, std::forward<Exp>(exp).error());
  1762. }
  1763. #endif
  1764. #ifdef TL_EXPECTED_CXX14
  1765. template <class Exp, class F,
  1766. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1767. class Ret = decltype(detail::invoke(std::declval<F>(),
  1768. *std::declval<Exp>())),
  1769. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1770. constexpr auto expected_map_impl(Exp &&exp, F &&f) {
  1771. using result = ret_t<Exp, detail::decay_t<Ret>>;
  1772. return exp.has_value() ? result(detail::invoke(std::forward<F>(f),
  1773. *std::forward<Exp>(exp)))
  1774. : result(unexpect, std::forward<Exp>(exp).error());
  1775. }
  1776. template <class Exp, class F,
  1777. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1778. class Ret = decltype(detail::invoke(std::declval<F>(),
  1779. *std::declval<Exp>())),
  1780. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1781. auto expected_map_impl(Exp &&exp, F &&f) {
  1782. using result = expected<void, err_t<Exp>>;
  1783. if (exp.has_value()) {
  1784. detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
  1785. return result();
  1786. }
  1787. return result(unexpect, std::forward<Exp>(exp).error());
  1788. }
  1789. template <class Exp, class F,
  1790. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1791. class Ret = decltype(detail::invoke(std::declval<F>())),
  1792. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1793. constexpr auto expected_map_impl(Exp &&exp, F &&f) {
  1794. using result = ret_t<Exp, detail::decay_t<Ret>>;
  1795. return exp.has_value() ? result(detail::invoke(std::forward<F>(f)))
  1796. : result(unexpect, std::forward<Exp>(exp).error());
  1797. }
  1798. template <class Exp, class F,
  1799. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1800. class Ret = decltype(detail::invoke(std::declval<F>())),
  1801. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1802. auto expected_map_impl(Exp &&exp, F &&f) {
  1803. using result = expected<void, err_t<Exp>>;
  1804. if (exp.has_value()) {
  1805. detail::invoke(std::forward<F>(f));
  1806. return result();
  1807. }
  1808. return result(unexpect, std::forward<Exp>(exp).error());
  1809. }
  1810. #else
  1811. template <class Exp, class F,
  1812. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1813. class Ret = decltype(detail::invoke(std::declval<F>(),
  1814. *std::declval<Exp>())),
  1815. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1816. constexpr auto expected_map_impl(Exp &&exp, F &&f)
  1817. -> ret_t<Exp, detail::decay_t<Ret>> {
  1818. using result = ret_t<Exp, detail::decay_t<Ret>>;
  1819. return exp.has_value() ? result(detail::invoke(std::forward<F>(f),
  1820. *std::forward<Exp>(exp)))
  1821. : result(unexpect, std::forward<Exp>(exp).error());
  1822. }
  1823. template <class Exp, class F,
  1824. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1825. class Ret = decltype(detail::invoke(std::declval<F>(),
  1826. *std::declval<Exp>())),
  1827. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1828. auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
  1829. if (exp.has_value()) {
  1830. detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
  1831. return {};
  1832. }
  1833. return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
  1834. }
  1835. template <class Exp, class F,
  1836. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1837. class Ret = decltype(detail::invoke(std::declval<F>())),
  1838. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1839. constexpr auto expected_map_impl(Exp &&exp, F &&f)
  1840. -> ret_t<Exp, detail::decay_t<Ret>> {
  1841. using result = ret_t<Exp, detail::decay_t<Ret>>;
  1842. return exp.has_value() ? result(detail::invoke(std::forward<F>(f)))
  1843. : result(unexpect, std::forward<Exp>(exp).error());
  1844. }
  1845. template <class Exp, class F,
  1846. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1847. class Ret = decltype(detail::invoke(std::declval<F>())),
  1848. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1849. auto expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
  1850. if (exp.has_value()) {
  1851. detail::invoke(std::forward<F>(f));
  1852. return {};
  1853. }
  1854. return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
  1855. }
  1856. #endif
  1857. #if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
  1858. !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55)
  1859. template <class Exp, class F,
  1860. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1861. class Ret = decltype(detail::invoke(std::declval<F>(),
  1862. std::declval<Exp>().error())),
  1863. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1864. constexpr auto map_error_impl(Exp &&exp, F &&f) {
  1865. using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
  1866. return exp.has_value()
  1867. ? result(*std::forward<Exp>(exp))
  1868. : result(unexpect, detail::invoke(std::forward<F>(f),
  1869. std::forward<Exp>(exp).error()));
  1870. }
  1871. template <class Exp, class F,
  1872. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1873. class Ret = decltype(detail::invoke(std::declval<F>(),
  1874. std::declval<Exp>().error())),
  1875. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1876. auto map_error_impl(Exp &&exp, F &&f) {
  1877. using result = expected<exp_t<Exp>, monostate>;
  1878. if (exp.has_value()) {
  1879. return result(*std::forward<Exp>(exp));
  1880. }
  1881. detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
  1882. return result(unexpect, monostate{});
  1883. }
  1884. template <class Exp, class F,
  1885. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1886. class Ret = decltype(detail::invoke(std::declval<F>(),
  1887. std::declval<Exp>().error())),
  1888. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1889. constexpr auto map_error_impl(Exp &&exp, F &&f) {
  1890. using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
  1891. return exp.has_value()
  1892. ? result()
  1893. : result(unexpect, detail::invoke(std::forward<F>(f),
  1894. std::forward<Exp>(exp).error()));
  1895. }
  1896. template <class Exp, class F,
  1897. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1898. class Ret = decltype(detail::invoke(std::declval<F>(),
  1899. std::declval<Exp>().error())),
  1900. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1901. auto map_error_impl(Exp &&exp, F &&f) {
  1902. using result = expected<exp_t<Exp>, monostate>;
  1903. if (exp.has_value()) {
  1904. return result();
  1905. }
  1906. detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
  1907. return result(unexpect, monostate{});
  1908. }
  1909. #else
  1910. template <class Exp, class F,
  1911. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1912. class Ret = decltype(detail::invoke(std::declval<F>(),
  1913. std::declval<Exp>().error())),
  1914. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1915. constexpr auto map_error_impl(Exp &&exp, F &&f)
  1916. -> expected<exp_t<Exp>, detail::decay_t<Ret>> {
  1917. using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
  1918. return exp.has_value()
  1919. ? result(*std::forward<Exp>(exp))
  1920. : result(unexpect, detail::invoke(std::forward<F>(f),
  1921. std::forward<Exp>(exp).error()));
  1922. }
  1923. template <class Exp, class F,
  1924. detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr,
  1925. class Ret = decltype(detail::invoke(std::declval<F>(),
  1926. std::declval<Exp>().error())),
  1927. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1928. auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
  1929. using result = expected<exp_t<Exp>, monostate>;
  1930. if (exp.has_value()) {
  1931. return result(*std::forward<Exp>(exp));
  1932. }
  1933. detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
  1934. return result(unexpect, monostate{});
  1935. }
  1936. template <class Exp, class F,
  1937. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1938. class Ret = decltype(detail::invoke(std::declval<F>(),
  1939. std::declval<Exp>().error())),
  1940. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1941. constexpr auto map_error_impl(Exp &&exp, F &&f)
  1942. -> expected<exp_t<Exp>, detail::decay_t<Ret>> {
  1943. using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
  1944. return exp.has_value()
  1945. ? result()
  1946. : result(unexpect, detail::invoke(std::forward<F>(f),
  1947. std::forward<Exp>(exp).error()));
  1948. }
  1949. template <class Exp, class F,
  1950. detail::enable_if_t<std::is_void<exp_t<Exp>>::value> * = nullptr,
  1951. class Ret = decltype(detail::invoke(std::declval<F>(),
  1952. std::declval<Exp>().error())),
  1953. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1954. auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
  1955. using result = expected<exp_t<Exp>, monostate>;
  1956. if (exp.has_value()) {
  1957. return result();
  1958. }
  1959. detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
  1960. return result(unexpect, monostate{});
  1961. }
  1962. #endif
  1963. #ifdef TL_EXPECTED_CXX14
  1964. template <class Exp, class F,
  1965. class Ret = decltype(detail::invoke(std::declval<F>(),
  1966. std::declval<Exp>().error())),
  1967. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1968. constexpr auto or_else_impl(Exp &&exp, F &&f) {
  1969. static_assert(detail::is_expected<Ret>::value, "F must return an expected");
  1970. return exp.has_value()
  1971. ? std::forward<Exp>(exp)
  1972. : detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
  1973. }
  1974. template <class Exp, class F,
  1975. class Ret = decltype(detail::invoke(std::declval<F>(),
  1976. std::declval<Exp>().error())),
  1977. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1978. detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
  1979. return exp.has_value()
  1980. ? std::forward<Exp>(exp)
  1981. : (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
  1982. std::forward<Exp>(exp));
  1983. }
  1984. #else
  1985. template <class Exp, class F,
  1986. class Ret = decltype(detail::invoke(std::declval<F>(),
  1987. std::declval<Exp>().error())),
  1988. detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
  1989. auto or_else_impl(Exp &&exp, F &&f) -> Ret {
  1990. static_assert(detail::is_expected<Ret>::value, "F must return an expected");
  1991. return exp.has_value()
  1992. ? std::forward<Exp>(exp)
  1993. : detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error());
  1994. }
  1995. template <class Exp, class F,
  1996. class Ret = decltype(detail::invoke(std::declval<F>(),
  1997. std::declval<Exp>().error())),
  1998. detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
  1999. detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
  2000. return exp.has_value()
  2001. ? std::forward<Exp>(exp)
  2002. : (detail::invoke(std::forward<F>(f), std::forward<Exp>(exp).error()),
  2003. std::forward<Exp>(exp));
  2004. }
  2005. #endif
  2006. } // namespace detail
  2007. template <class T, class E, class U, class F>
  2008. constexpr bool operator==(const expected<T, E> &lhs,
  2009. const expected<U, F> &rhs) {
  2010. return (lhs.has_value() != rhs.has_value())
  2011. ? false
  2012. : (!lhs.has_value() ? lhs.error() == rhs.error() : *lhs == *rhs);
  2013. }
  2014. template <class T, class E, class U, class F>
  2015. constexpr bool operator!=(const expected<T, E> &lhs,
  2016. const expected<U, F> &rhs) {
  2017. return (lhs.has_value() != rhs.has_value())
  2018. ? true
  2019. : (!lhs.has_value() ? lhs.error() != rhs.error() : *lhs != *rhs);
  2020. }
  2021. template <class T, class E, class U>
  2022. constexpr bool operator==(const expected<T, E> &x, const U &v) {
  2023. return x.has_value() ? *x == v : false;
  2024. }
  2025. template <class T, class E, class U>
  2026. constexpr bool operator==(const U &v, const expected<T, E> &x) {
  2027. return x.has_value() ? *x == v : false;
  2028. }
  2029. template <class T, class E, class U>
  2030. constexpr bool operator!=(const expected<T, E> &x, const U &v) {
  2031. return x.has_value() ? *x != v : true;
  2032. }
  2033. template <class T, class E, class U>
  2034. constexpr bool operator!=(const U &v, const expected<T, E> &x) {
  2035. return x.has_value() ? *x != v : true;
  2036. }
  2037. template <class T, class E>
  2038. constexpr bool operator==(const expected<T, E> &x, const unexpected<E> &e) {
  2039. return x.has_value() ? false : x.error() == e.value();
  2040. }
  2041. template <class T, class E>
  2042. constexpr bool operator==(const unexpected<E> &e, const expected<T, E> &x) {
  2043. return x.has_value() ? false : x.error() == e.value();
  2044. }
  2045. template <class T, class E>
  2046. constexpr bool operator!=(const expected<T, E> &x, const unexpected<E> &e) {
  2047. return x.has_value() ? true : x.error() != e.value();
  2048. }
  2049. template <class T, class E>
  2050. constexpr bool operator!=(const unexpected<E> &e, const expected<T, E> &x) {
  2051. return x.has_value() ? true : x.error() != e.value();
  2052. }
  2053. template <class T, class E,
  2054. detail::enable_if_t<(std::is_void<T>::value ||
  2055. std::is_move_constructible<T>::value) &&
  2056. detail::is_swappable<T>::value &&
  2057. std::is_move_constructible<E>::value &&
  2058. detail::is_swappable<E>::value> * = nullptr>
  2059. void swap(expected<T, E> &lhs,
  2060. expected<T, E> &rhs) noexcept(noexcept(lhs.swap(rhs))) {
  2061. lhs.swap(rhs);
  2062. }
  2063. } // namespace tl
  2064. #endif