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.

2444 lines
91 KiB

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