229[[noreturn]] TL_EXPECTED_11_CONSTEXPR
void throw_exception(E &&e)
231#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
232 throw std::forward<E>(e);
238 __builtin_unreachable();
243#ifndef TL_TRAITS_MUTEX
244#define TL_TRAITS_MUTEX
247using remove_const_t =
typename std::remove_const<T>::type;
249using remove_reference_t =
typename std::remove_reference<T>::type;
251using decay_t =
typename std::decay<T>::type;
252template <
bool E,
class T =
void>
253using enable_if_t =
typename std::enable_if<E, T>::type;
254template <
bool B,
class T,
class F>
255using conditional_t =
typename std::conditional<B, T, F>::type;
262template <
class B,
class... Bs>
263struct conjunction<B, Bs...> : std::conditional<bool(B::value), conjunction<Bs...>, B>::type {};
265#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L
266#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
272#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
274struct is_pointer_to_non_const_member_func : std::false_type {};
275template <
class T,
class Ret,
class... Args>
276struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...)> : std::true_type {};
277template <
class T,
class Ret,
class... Args>
278struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &> : std::true_type {};
279template <
class T,
class Ret,
class... Args>
280struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) &&> : std::true_type {};
281template <
class T,
class Ret,
class... Args>
282struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile> : std::true_type {};
283template <
class T,
class Ret,
class... Args>
284struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &> : std::true_type {};
285template <
class T,
class Ret,
class... Args>
286struct is_pointer_to_non_const_member_func<Ret (T::*)(Args...) volatile &&> : std::true_type {};
289struct is_const_or_const_ref : std::false_type {};
291struct is_const_or_const_ref<T const &> : std::true_type {};
293struct is_const_or_const_ref<T const> : std::true_type {};
299 typename Fn,
typename... Args,
300#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND
301 typename = enable_if_t<!(is_pointer_to_non_const_member_func<Fn>::value && is_const_or_const_ref<Args...>::value)>,
303 typename = enable_if_t<std::is_member_pointer<decay_t<Fn>>::value>,
int = 0>
304constexpr auto invoke(Fn &&f, Args &&...args)
noexcept(
noexcept(std::mem_fn(f)(std::forward<Args>(args)...)))
305 ->
decltype(std::mem_fn(f)(std::forward<Args>(args)...))
307 return std::mem_fn(f)(std::forward<Args>(args)...);
310template <
typename Fn,
typename... Args,
typename = enable_if_t<!std::is_member_pointer<decay_t<Fn>>::value>>
311constexpr auto invoke(Fn &&f, Args &&...args)
noexcept(
noexcept(std::forward<Fn>(f)(std::forward<Args>(args)...)))
312 ->
decltype(std::forward<Fn>(f)(std::forward<Args>(args)...))
314 return std::forward<Fn>(f)(std::forward<Args>(args)...);
318template <
class F,
class,
class... Us>
321template <
class F,
class... Us>
322struct invoke_result_impl<F, decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...), void()), Us...> {
323 using type =
decltype(detail::invoke(std::declval<F>(), std::declval<Us>()...));
326template <
class F,
class... Us>
329template <
class F,
class... Us>
330using invoke_result_t =
typename invoke_result<F, Us...>::type;
332#if defined(_MSC_VER) && _MSC_VER <= 1900
334template <
class T,
class U = T>
337template <
class T,
class U = T>
341namespace swap_adl_tests {
348template <
class T, std::
size_t N>
349tag swap(T (&a)[N], T (&b)[N]);
353template <
class,
class>
354std::false_type can_swap(...)
noexcept(
false);
355template <class T, class U, class = decltype(swap(std::declval<T &>(), std::declval<U &>()))>
356std::true_type can_swap(
int)
noexcept(
noexcept(swap(std::declval<T &>(), std::declval<U &>())));
358template <
class,
class>
359std::false_type uses_std(...);
360template <
class T,
class U>
361std::is_same<decltype(swap(std::declval<T &>(), std::declval<U &>())), tag> uses_std(
int);
364struct is_std_swap_noexcept : std::integral_constant<bool, std::is_nothrow_move_constructible<T>::value &&
365 std::is_nothrow_move_assignable<T>::value> {};
367template <
class T, std::
size_t N>
368struct is_std_swap_noexcept<T[N]> : is_std_swap_noexcept<T> {};
370template <
class T,
class U>
371struct is_adl_swap_noexcept : std::integral_constant<bool, noexcept(can_swap<T, U>(0))> {};
374template <
class T,
class U = T>
376 : std::integral_constant<bool, decltype(detail::swap_adl_tests::can_swap<T, U>(0))::value &&
377 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value ||
378 (std::is_move_assignable<T>::value && std::is_move_constructible<T>::value))> {
381template <
class T, std::
size_t N>
383 : std::integral_constant<bool, decltype(detail::swap_adl_tests::can_swap<T[N], T[N]>(0))::value &&
384 (!decltype(detail::swap_adl_tests::uses_std<T[N], T[N]>(0))::value ||
385 is_swappable<T, T>::value)> {};
387template <
class T,
class U = T>
389 : std::integral_constant<bool, is_swappable<T, U>::value &&
390 ((decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
391 detail::swap_adl_tests::is_std_swap_noexcept<T>::value) ||
392 (!decltype(detail::swap_adl_tests::uses_std<T, U>(0))::value &&
393 detail::swap_adl_tests::is_adl_swap_noexcept<T, U>::value))> {};
400template <
class T,
class E>
405template <
class T,
class E,
class U>
406using expected_enable_forward_value =
407 detail::enable_if_t<std::is_constructible<T, U &&>::value && !std::is_same<detail::decay_t<U>,
in_place_t>::value &&
408 !std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
409 !std::is_same<unexpected<E>, detail::decay_t<U>>::value>;
411template <
class T,
class E,
class U,
class G,
class UR,
class GR>
412using expected_enable_from_other = detail::enable_if_t<
413 std::is_constructible<T, UR>::value && std::is_constructible<E, GR>::value &&
414 !std::is_constructible<T, expected<U, G> &>::value && !std::is_constructible<T, expected<U, G> &&>::value &&
415 !std::is_constructible<T, const expected<U, G> &>::value &&
416 !std::is_constructible<T, const expected<U, G> &&>::value && !std::is_convertible<expected<U, G> &, T>::value &&
417 !std::is_convertible<expected<U, G> &&, T>::value && !std::is_convertible<const expected<U, G> &, T>::value &&
418 !std::is_convertible<const expected<U, G> &&, T>::value>;
420template <
class T,
class U>
421using is_void_or = conditional_t<std::is_void<T>::value, std::true_type, U>;
424using is_copy_constructible_or_void = is_void_or<T, std::is_copy_constructible<T>>;
427using is_move_constructible_or_void = is_void_or<T, std::is_move_constructible<T>>;
430using is_copy_assignable_or_void = is_void_or<T, std::is_copy_assignable<T>>;
433using is_move_assignable_or_void = is_void_or<T, std::is_move_assignable<T>>;
1305 static_assert(!std::is_reference<T>::value,
"T must not be a reference");
1306 static_assert(!std::is_same<T, std::remove_cv<in_place_t>::type>::value,
"T must not be in_place_t");
1307 static_assert(!std::is_same<T, std::remove_cv<unexpect_t>::type>::value,
"T must not be unexpect_t");
1308 static_assert(!std::is_same<T, typename std::remove_cv<unexpected<E>>::type>::value,
"T must not be unexpected<E>");
1309 static_assert(!std::is_reference<E>::value,
"E must not be a reference");
1313 return std::addressof(this->m_val);
1315 const T *valptr()
const
1317 return std::addressof(this->m_val);
1321 return std::addressof(this->m_unexpect);
1325 return std::addressof(this->m_unexpect);
1328 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
1329 TL_EXPECTED_11_CONSTEXPR U &val()
1335 return this->m_unexpect;
1338 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
1339 constexpr const U &val()
const
1345 return this->m_unexpect;
1352 typedef T value_type;
1353 typedef E error_type;
1356#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && !defined(TL_EXPECTED_GCC54) && \
1357 !defined(TL_EXPECTED_GCC55)
1359 TL_EXPECTED_11_CONSTEXPR
auto and_then(F &&f) &
1361 return and_then_impl(*
this, std::forward<F>(f));
1364 TL_EXPECTED_11_CONSTEXPR
auto and_then(F &&f) &&
1366 return and_then_impl(std::move(*
this), std::forward<F>(f));
1369 constexpr auto and_then(F &&f)
const &
1371 return and_then_impl(*
this, std::forward<F>(f));
1374#ifndef TL_EXPECTED_NO_CONSTRR
1376 constexpr auto and_then(F &&f)
const &&
1378 return and_then_impl(std::move(*
this), std::forward<F>(f));
1384 TL_EXPECTED_11_CONSTEXPR
auto and_then(F &&f) & ->
decltype(and_then_impl(std::declval<expected &>(),
1385 std::forward<F>(f)))
1387 return and_then_impl(*
this, std::forward<F>(f));
1390 TL_EXPECTED_11_CONSTEXPR
auto and_then(F &&f) && ->
decltype(and_then_impl(std::declval<expected &&>(),
1391 std::forward<F>(f)))
1393 return and_then_impl(std::move(*
this), std::forward<F>(f));
1396 constexpr auto and_then(F &&f)
const & ->
decltype(and_then_impl(std::declval<expected const &>(),
1397 std::forward<F>(f)))
1399 return and_then_impl(*
this, std::forward<F>(f));
1402#ifndef TL_EXPECTED_NO_CONSTRR
1404 constexpr auto and_then(F &&f)
const && ->
decltype(and_then_impl(std::declval<expected const &&>(),
1405 std::forward<F>(f)))
1407 return and_then_impl(std::move(*
this), std::forward<F>(f));
1412#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && !defined(TL_EXPECTED_GCC54) && \
1413 !defined(TL_EXPECTED_GCC55)
1415 TL_EXPECTED_11_CONSTEXPR
auto map(F &&f) &
1417 return expected_map_impl(*
this, std::forward<F>(f));
1420 TL_EXPECTED_11_CONSTEXPR
auto map(F &&f) &&
1422 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1425 constexpr auto map(F &&f)
const &
1427 return expected_map_impl(*
this, std::forward<F>(f));
1430 constexpr auto map(F &&f)
const &&
1432 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1436 TL_EXPECTED_11_CONSTEXPR
decltype(expected_map_impl(std::declval<expected &>(), std::declval<F &&>())) map(F &&f) &
1438 return expected_map_impl(*
this, std::forward<F>(f));
1441 TL_EXPECTED_11_CONSTEXPR
decltype(expected_map_impl(std::declval<expected>(), std::declval<F &&>())) map(F &&f) &&
1443 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1446 constexpr decltype(expected_map_impl(std::declval<const expected &>(), std::declval<F &&>())) map(F &&f)
const &
1448 return expected_map_impl(*
this, std::forward<F>(f));
1451#ifndef TL_EXPECTED_NO_CONSTRR
1453 constexpr decltype(expected_map_impl(std::declval<const expected &&>(), std::declval<F &&>())) map(F &&f)
const &&
1455 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1460#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && !defined(TL_EXPECTED_GCC54) && \
1461 !defined(TL_EXPECTED_GCC55)
1463 TL_EXPECTED_11_CONSTEXPR
auto transform(F &&f) &
1465 return expected_map_impl(*
this, std::forward<F>(f));
1468 TL_EXPECTED_11_CONSTEXPR
auto transform(F &&f) &&
1470 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1473 constexpr auto transform(F &&f)
const &
1475 return expected_map_impl(*
this, std::forward<F>(f));
1478 constexpr auto transform(F &&f)
const &&
1480 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1484 TL_EXPECTED_11_CONSTEXPR
decltype(expected_map_impl(std::declval<expected &>(), std::declval<F &&>())) transform(
1487 return expected_map_impl(*
this, std::forward<F>(f));
1490 TL_EXPECTED_11_CONSTEXPR
decltype(expected_map_impl(std::declval<expected>(), std::declval<F &&>())) transform(
1493 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1496 constexpr decltype(expected_map_impl(std::declval<const expected &>(), std::declval<F &&>())) transform(
1499 return expected_map_impl(*
this, std::forward<F>(f));
1502#ifndef TL_EXPECTED_NO_CONSTRR
1504 constexpr decltype(expected_map_impl(std::declval<const expected &&>(), std::declval<F &&>())) transform(
1507 return expected_map_impl(std::move(*
this), std::forward<F>(f));
1512#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && !defined(TL_EXPECTED_GCC54) && \
1513 !defined(TL_EXPECTED_GCC55)
1515 TL_EXPECTED_11_CONSTEXPR
auto map_error(F &&f) &
1517 return map_error_impl(*
this, std::forward<F>(f));
1520 TL_EXPECTED_11_CONSTEXPR
auto map_error(F &&f) &&
1522 return map_error_impl(std::move(*
this), std::forward<F>(f));
1525 constexpr auto map_error(F &&f)
const &
1527 return map_error_impl(*
this, std::forward<F>(f));
1530 constexpr auto map_error(F &&f)
const &&
1532 return map_error_impl(std::move(*
this), std::forward<F>(f));
1536 TL_EXPECTED_11_CONSTEXPR
decltype(map_error_impl(std::declval<expected &>(), std::declval<F &&>())) map_error(
1539 return map_error_impl(*
this, std::forward<F>(f));
1542 TL_EXPECTED_11_CONSTEXPR
decltype(map_error_impl(std::declval<expected &&>(), std::declval<F &&>())) map_error(
1545 return map_error_impl(std::move(*
this), std::forward<F>(f));
1548 constexpr decltype(map_error_impl(std::declval<const expected &>(), std::declval<F &&>())) map_error(F &&f)
const &
1550 return map_error_impl(*
this, std::forward<F>(f));
1553#ifndef TL_EXPECTED_NO_CONSTRR
1555 constexpr decltype(map_error_impl(std::declval<const expected &&>(), std::declval<F &&>())) map_error(
1558 return map_error_impl(std::move(*
this), std::forward<F>(f));
1562#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && !defined(TL_EXPECTED_GCC54) && \
1563 !defined(TL_EXPECTED_GCC55)
1565 TL_EXPECTED_11_CONSTEXPR
auto transform_error(F &&f) &
1567 return map_error_impl(*
this, std::forward<F>(f));
1570 TL_EXPECTED_11_CONSTEXPR
auto transform_error(F &&f) &&
1572 return map_error_impl(std::move(*
this), std::forward<F>(f));
1575 constexpr auto transform_error(F &&f)
const &
1577 return map_error_impl(*
this, std::forward<F>(f));
1580 constexpr auto transform_error(F &&f)
const &&
1582 return map_error_impl(std::move(*
this), std::forward<F>(f));
1586 TL_EXPECTED_11_CONSTEXPR
decltype(map_error_impl(std::declval<expected &>(), std::declval<F &&>())) transform_error(
1589 return map_error_impl(*
this, std::forward<F>(f));
1592 TL_EXPECTED_11_CONSTEXPR
decltype(map_error_impl(std::declval<expected &&>(), std::declval<F &&>()))
1593 transform_error(F &&f) &&
1595 return map_error_impl(std::move(*
this), std::forward<F>(f));
1598 constexpr decltype(map_error_impl(std::declval<const expected &>(), std::declval<F &&>())) transform_error(
1601 return map_error_impl(*
this, std::forward<F>(f));
1604#ifndef TL_EXPECTED_NO_CONSTRR
1606 constexpr decltype(map_error_impl(std::declval<const expected &&>(), std::declval<F &&>())) transform_error(
1609 return map_error_impl(std::move(*
this), std::forward<F>(f));
1614 expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) &
1616 return or_else_impl(*
this, std::forward<F>(f));
1620 expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) &&
1622 return or_else_impl(std::move(*
this), std::forward<F>(f));
1626 expected constexpr or_else(F &&f)
const &
1628 return or_else_impl(*
this, std::forward<F>(f));
1631#ifndef TL_EXPECTED_NO_CONSTRR
1633 expected constexpr or_else(F &&f)
const &&
1635 return or_else_impl(std::move(*
this), std::forward<F>(f));
1644 template <
class... Args, detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
nullptr>
1650 template <
class U,
class... Args,
1651 detail::enable_if_t<std::is_constructible<T, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
1657 template <class G = E, detail::enable_if_t<std::is_constructible<E, const G &>::value> * =
nullptr,
1658 detail::enable_if_t<!std::is_convertible<const G &, E>::value> * =
nullptr>
1664 template <class G = E, detail::enable_if_t<std::is_constructible<E, const G &>::value> * =
nullptr,
1665 detail::enable_if_t<std::is_convertible<const G &, E>::value> * =
nullptr>
1671 template <class G = E, detail::enable_if_t<std::is_constructible<E, G &&>::value> * =
nullptr,
1672 detail::enable_if_t<!std::is_convertible<G &&, E>::value> * =
nullptr>
1673 explicit constexpr expected(
unexpected<G> &&e)
noexcept(std::is_nothrow_constructible<E, G &&>::value)
1678 template <class G = E, detail::enable_if_t<std::is_constructible<E, G &&>::value> * =
nullptr,
1679 detail::enable_if_t<std::is_convertible<G &&, E>::value> * =
nullptr>
1685 template <
class... Args, detail::enable_if_t<std::is_constructible<E, Args &&...>::value> * =
nullptr>
1691 template <
class U,
class... Args,
1692 detail::enable_if_t<std::is_constructible<E, std::initializer_list<U> &, Args &&...>::value> * =
nullptr>
1698 template <
class U,
class G,
1699 detail::enable_if_t<!(std::is_convertible<U const &, T>::value &&
1700 std::is_convertible<G const &, E>::value)> * =
nullptr,
1701 detail::expected_enable_from_other<T, E, U, G, const U &, const G &> * =
nullptr>
1704 if (rhs.has_value()) {
1705 this->construct(*rhs);
1707 this->construct_error(rhs.error());
1711 template <
class U,
class G,
1712 detail::enable_if_t<(std::is_convertible<U const &, T>::value &&
1713 std::is_convertible<G const &, E>::value)> * =
nullptr,
1714 detail::expected_enable_from_other<T, E, U, G, const U &, const G &> * =
nullptr>
1717 if (rhs.has_value()) {
1718 this->construct(*rhs);
1720 this->construct_error(rhs.error());
1726 detail::enable_if_t<!(std::is_convertible<U &&, T>::value && std::is_convertible<G &&, E>::value)> * =
nullptr,
1727 detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * =
nullptr>
1730 if (rhs.has_value()) {
1731 this->construct(std::move(*rhs));
1733 this->construct_error(std::move(rhs.error()));
1739 detail::enable_if_t<(std::is_convertible<U &&, T>::value && std::is_convertible<G &&, E>::value)> * =
nullptr,
1740 detail::expected_enable_from_other<T, E, U, G, U &&, G &&> * =
nullptr>
1743 if (rhs.has_value()) {
1744 this->construct(std::move(*rhs));
1746 this->construct_error(std::move(rhs.error()));
1750 template <class U = T, detail::enable_if_t<!std::is_convertible<U &&, T>::value> * =
nullptr,
1751 detail::expected_enable_forward_value<T, E, U> * =
nullptr>
1752 explicit TL_EXPECTED_MSVC2015_CONSTEXPR
expected(U &&v) :
expected(in_place, std::forward<U>(v))
1756 template <class U = T, detail::enable_if_t<std::is_convertible<U &&, T>::value> * =
nullptr,
1757 detail::expected_enable_forward_value<T, E, U> * =
nullptr>
1758 TL_EXPECTED_MSVC2015_CONSTEXPR
expected(U &&v) :
expected(in_place, std::forward<U>(v))
1763 class U = T,
class G = T, detail::enable_if_t<std::is_nothrow_constructible<T, U &&>::value> * =
nullptr,
1764 detail::enable_if_t<!std::is_void<G>::value> * =
nullptr,
1765 detail::enable_if_t<(!std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
1767 std::is_constructible<T, U>::value && std::is_assignable<G &, U>::value &&
1768 std::is_nothrow_move_constructible<E>::value)> * =
nullptr>
1772 val() = std::forward<U>(v);
1774 err().~unexpected<E>();
1775 ::new (valptr()) T(std::forward<U>(v));
1776 this->m_has_val =
true;
1783 class U = T,
class G = T, detail::enable_if_t<!std::is_nothrow_constructible<T, U &&>::value> * =
nullptr,
1784 detail::enable_if_t<!std::is_void<U>::value> * =
nullptr,
1785 detail::enable_if_t<(!std::is_same<expected<T, E>, detail::decay_t<U>>::value &&
1787 std::is_constructible<T, U>::value && std::is_assignable<G &, U>::value &&
1788 std::is_nothrow_move_constructible<E>::value)> * =
nullptr>
1792 val() = std::forward<U>(v);
1794 auto tmp = std::move(err());
1795 err().~unexpected<E>();
1797#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1799 ::new (valptr()) T(std::forward<U>(v));
1800 this->m_has_val =
true;
1802 err() = std::move(tmp);
1806 ::new (valptr()) T(std::forward<U>(v));
1807 this->m_has_val =
true;
1814 template <class G = E, detail::enable_if_t<std::is_nothrow_copy_constructible<G>::value &&
1815 std::is_assignable<G &, G>::value> * =
nullptr>
1821 this->destroy_val();
1823 this->m_has_val =
false;
1829 template <class G = E, detail::enable_if_t<std::is_nothrow_move_constructible<G>::value &&
1830 std::is_move_assignable<G>::value> * =
nullptr>
1834 err() = std::move(rhs);
1836 this->destroy_val();
1838 this->m_has_val =
false;
1844 template <
class... Args, detail::enable_if_t<std::is_nothrow_constructible<T, Args &&...>::value> * =
nullptr>
1845 void emplace(Args &&...args)
1850 err().~unexpected<E>();
1851 this->m_has_val =
true;
1853 ::new (valptr()) T(std::forward<Args>(args)...);
1856 template <
class... Args, detail::enable_if_t<!std::is_nothrow_constructible<T, Args &&...>::value> * =
nullptr>
1857 void emplace(Args &&...args)
1861 ::new (valptr()) T(std::forward<Args>(args)...);
1863 auto tmp = std::move(err());
1864 err().~unexpected<E>();
1866#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1868 ::new (valptr()) T(std::forward<Args>(args)...);
1869 this->m_has_val =
true;
1871 err() = std::move(tmp);
1875 ::new (valptr()) T(std::forward<Args>(args)...);
1876 this->m_has_val =
true;
1881 template <
class U,
class... Args,
1882 detail::enable_if_t<std::is_nothrow_constructible<T, std::initializer_list<U> &, Args &&...>::value> * =
1884 void emplace(std::initializer_list<U> il, Args &&...args)
1887 T t(il, std::forward<Args>(args)...);
1888 val() = std::move(t);
1890 err().~unexpected<E>();
1891 ::new (valptr()) T(il, std::forward<Args>(args)...);
1892 this->m_has_val =
true;
1896 template <
class U,
class... Args,
1897 detail::enable_if_t<!std::is_nothrow_constructible<T, std::initializer_list<U> &, Args &&...>::value> * =
1899 void emplace(std::initializer_list<U> il, Args &&...args)
1902 T t(il, std::forward<Args>(args)...);
1903 val() = std::move(t);
1905 auto tmp = std::move(err());
1906 err().~unexpected<E>();
1908#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1910 ::new (valptr()) T(il, std::forward<Args>(args)...);
1911 this->m_has_val =
true;
1913 err() = std::move(tmp);
1917 ::new (valptr()) T(il, std::forward<Args>(args)...);
1918 this->m_has_val =
true;
1924 using t_is_void = std::true_type;
1925 using t_is_not_void = std::false_type;
1926 using t_is_nothrow_move_constructible = std::true_type;
1927 using move_constructing_t_can_throw = std::false_type;
1928 using e_is_nothrow_move_constructible = std::true_type;
1929 using move_constructing_e_can_throw = std::false_type;
1931 void swap_where_both_have_value(
expected & , t_is_void)
noexcept
1936 void swap_where_both_have_value(
expected &rhs, t_is_not_void)
1939 swap(val(), rhs.val());
1942 void swap_where_only_one_has_value(
expected &rhs, t_is_void)
noexcept(std::is_nothrow_move_constructible<E>::value)
1945 rhs.err().~unexpected_type();
1946 std::swap(this->m_has_val, rhs.m_has_val);
1949 void swap_where_only_one_has_value(
expected &rhs, t_is_not_void)
1951 swap_where_only_one_has_value_and_t_is_not_void(rhs,
typename std::is_nothrow_move_constructible<T>::type{},
1952 typename std::is_nothrow_move_constructible<E>::type{});
1955 void swap_where_only_one_has_value_and_t_is_not_void(
expected &rhs, t_is_nothrow_move_constructible,
1956 e_is_nothrow_move_constructible)
noexcept
1958 auto temp = std::move(val());
1961 rhs.err().~unexpected_type();
1962 ::new (rhs.valptr()) T(std::move(temp));
1963 std::swap(this->m_has_val, rhs.m_has_val);
1966 void swap_where_only_one_has_value_and_t_is_not_void(
expected &rhs, t_is_nothrow_move_constructible,
1967 move_constructing_e_can_throw)
1969 auto temp = std::move(val());
1971#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1974 rhs.err().~unexpected_type();
1975 ::new (rhs.valptr()) T(std::move(temp));
1976 std::swap(this->m_has_val, rhs.m_has_val);
1978 val() = std::move(temp);
1983 rhs.err().~unexpected_type();
1984 ::new (rhs.valptr()) T(std::move(temp));
1985 std::swap(this->m_has_val, rhs.m_has_val);
1989 void swap_where_only_one_has_value_and_t_is_not_void(
expected &rhs, move_constructing_t_can_throw,
1990 e_is_nothrow_move_constructible)
1992 auto temp = std::move(rhs.err());
1993 rhs.err().~unexpected_type();
1994#ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
1996 ::new (rhs.valptr()) T(std::move(val()));
1999 std::swap(this->m_has_val, rhs.m_has_val);
2001 rhs.err() = std::move(temp);
2005 ::new (rhs.valptr()) T(std::move(val()));
2008 std::swap(this->m_has_val, rhs.m_has_val);
2013 template <
class OT = T,
class OE = E>
2015 (std::is_nothrow_move_constructible<OT>::value ||
2016 std::is_nothrow_move_constructible<OE>::value)>
2017 swap(
expected &rhs)
noexcept(std::is_nothrow_move_constructible<T>::value &&
2021 if (has_value() && rhs.has_value()) {
2022 swap_where_both_have_value(rhs,
typename std::is_void<T>::type{});
2023 }
else if (!has_value() && rhs.has_value()) {
2025 }
else if (has_value()) {
2026 swap_where_only_one_has_value(rhs,
typename std::is_void<T>::type{});
2029 swap(err(), rhs.err());
2033 constexpr const T *operator->()
const
2035 TL_ASSERT(has_value());
2038 TL_EXPECTED_11_CONSTEXPR T *operator->()
2040 TL_ASSERT(has_value());
2044 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2045 constexpr const U &operator*()
const &
2047 TL_ASSERT(has_value());
2050 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2051 TL_EXPECTED_11_CONSTEXPR U &operator*() &
2053 TL_ASSERT(has_value());
2056 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2057 constexpr const U &&operator*()
const &&
2059 TL_ASSERT(has_value());
2060 return std::move(val());
2062 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2063 TL_EXPECTED_11_CONSTEXPR U &&operator*() &&
2065 TL_ASSERT(has_value());
2066 return std::move(val());
2068 constexpr bool has_value()
const noexcept
2070 return this->m_has_val;
2072 constexpr bool has_error()
const noexcept
2074 return !(this->has_value());
2076 constexpr explicit operator bool()
const noexcept
2078 return this->m_has_val;
2081 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2082 TL_EXPECTED_11_CONSTEXPR
const U &value()
const &
2087 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2088 TL_EXPECTED_11_CONSTEXPR U &value() &
2093 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2094 TL_EXPECTED_11_CONSTEXPR
const U &&value()
const &&
2097 return std::move(val());
2099 template <class U = T, detail::enable_if_t<!std::is_void<U>::value> * =
nullptr>
2100 TL_EXPECTED_11_CONSTEXPR U &&value() &&
2103 return std::move(val());
2106 constexpr const E &error()
const &
2108 TL_ASSERT(!has_value());
2109 return err().value();
2111 TL_EXPECTED_11_CONSTEXPR E &error() &
2113 TL_ASSERT(!has_value());
2114 return err().value();
2116 constexpr const E &&error()
const &&
2118 TL_ASSERT(!has_value());
2119 return std::move(err().value());
2121 TL_EXPECTED_11_CONSTEXPR E &&error() &&
2123 TL_ASSERT(!has_value());
2124 return std::move(err().value());
2128 constexpr T value_or(U &&v)
const &
2130 static_assert(std::is_copy_constructible<T>::value && std::is_convertible<U &&, T>::value,
2131 "T must be copy-constructible and convertible to from U&&");
2132 return bool(*
this) ? **this :
static_cast<T
>(std::forward<U>(v));
2135 TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) &&
2137 static_assert(std::is_move_constructible<T>::value && std::is_convertible<U &&, T>::value,
2138 "T must be move-constructible and convertible to from U&&");
2139 return bool(*
this) ? std::move(**
this) :
static_cast<T
>(std::forward<U>(v));
2143 template <
class G = E>
2144 constexpr E error_or(G &&e)
const &
2146 static_assert(std::is_copy_constructible<E>::value && std::is_convertible<G, E>::value,
2147 "E must be copy-constructible and convertible to from G&&");
2148 return has_value() ? std::forward<G>(e) : error();
2150 template <
class G = E>
2151 TL_EXPECTED_11_CONSTEXPR E error_or(G &&e) &&
2153 static_assert(std::is_move_constructible<E>::value && std::is_convertible<G, E>::value,
2154 "E must be move-constructible and convertible to from G&&");
2155 return has_value() ? std::forward<G>(e) : std::move(error());