|
22 | 22 | #define TL_EXPECTED_HPP
|
23 | 23 |
|
24 | 24 | #define TL_EXPECTED_VERSION_MAJOR 1
|
25 |
| -#define TL_EXPECTED_VERSION_MINOR 0 |
26 |
| -#define TL_EXPECTED_VERSION_PATCH 1 |
| 25 | +#define TL_EXPECTED_VERSION_MINOR 1 |
| 26 | +#define TL_EXPECTED_VERSION_PATCH 0 |
27 | 27 |
|
28 | 28 | #include <exception>
|
29 | 29 | #include <functional>
|
|
56 | 56 | #define TL_EXPECTED_GCC55
|
57 | 57 | #endif
|
58 | 58 |
|
| 59 | +#if !defined(TL_ASSERT) |
| 60 | +// can't have assert in constexpr in C++11 and GCC 4.9 has a compiler bug |
| 61 | +#if (__cplusplus > 201103L) && !defined(TL_EXPECTED_GCC49) |
| 62 | +#include <cassert> |
| 63 | +#define TL_ASSERT(x) assert(x) |
| 64 | +#else |
| 65 | +#define TL_ASSERT(x) |
| 66 | +#endif |
| 67 | +#endif |
| 68 | + |
59 | 69 | #if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
|
60 | 70 | !defined(__clang__))
|
61 | 71 | // GCC < 5 doesn't support overloading on const&& for member functions
|
@@ -211,6 +221,7 @@ template <typename E>
|
211 | 221 | #ifdef TL_EXPECTED_EXCEPTIONS_ENABLED
|
212 | 222 | throw std::forward<E>(e);
|
213 | 223 | #else
|
| 224 | + (void)e; |
214 | 225 | #ifdef _MSC_VER
|
215 | 226 | __assume(0);
|
216 | 227 | #else
|
@@ -851,7 +862,7 @@ struct expected_operations_base : expected_storage_base<T, E> {
|
851 | 862 | geterr().~unexpected<E>();
|
852 | 863 | construct(std::move(rhs).get());
|
853 | 864 | } else {
|
854 |
| - assign_common(rhs); |
| 865 | + assign_common(std::move(rhs)); |
855 | 866 | }
|
856 | 867 | }
|
857 | 868 |
|
@@ -1214,7 +1225,7 @@ struct default_constructor_tag {
|
1214 | 1225 | };
|
1215 | 1226 |
|
1216 | 1227 | // expected_default_ctor_base will ensure that expected has a deleted default
|
1217 |
| -// constructor if T is not default constructible. |
| 1228 | +// consturctor if T is not default constructible. |
1218 | 1229 | // This specialization is for when T is default constructible
|
1219 | 1230 | template <class T, class E,
|
1220 | 1231 | bool Enable =
|
@@ -1509,6 +1520,53 @@ class expected : private detail::expected_move_assign_base<T, E>,
|
1509 | 1520 | return map_error_impl(std::move(*this), std::forward<F>(f));
|
1510 | 1521 | }
|
1511 | 1522 | #endif
|
| 1523 | +#endif |
| 1524 | +#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \ |
| 1525 | + !defined(TL_EXPECTED_GCC54) && !defined(TL_EXPECTED_GCC55) |
| 1526 | + template <class F> |
| 1527 | + TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) & { |
| 1528 | + return map_error_impl(*this, std::forward<F>(f)); |
| 1529 | + } |
| 1530 | + template <class F> |
| 1531 | + TL_EXPECTED_11_CONSTEXPR auto transform_error(F &&f) && { |
| 1532 | + return map_error_impl(std::move(*this), std::forward<F>(f)); |
| 1533 | + } |
| 1534 | + template <class F> |
| 1535 | + constexpr auto transform_error(F &&f) const & { |
| 1536 | + return map_error_impl(*this, std::forward<F>(f)); |
| 1537 | + } |
| 1538 | + template <class F> |
| 1539 | + constexpr auto transform_error(F &&f) const && { |
| 1540 | + return map_error_impl(std::move(*this), std::forward<F>(f)); |
| 1541 | + } |
| 1542 | +#else |
| 1543 | + template <class F> |
| 1544 | + TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(), |
| 1545 | + std::declval<F &&>())) |
| 1546 | + transform_error(F &&f) & { |
| 1547 | + return map_error_impl(*this, std::forward<F>(f)); |
| 1548 | + } |
| 1549 | + template <class F> |
| 1550 | + TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(), |
| 1551 | + std::declval<F &&>())) |
| 1552 | + transform_error(F &&f) && { |
| 1553 | + return map_error_impl(std::move(*this), std::forward<F>(f)); |
| 1554 | + } |
| 1555 | + template <class F> |
| 1556 | + constexpr decltype(map_error_impl(std::declval<const expected &>(), |
| 1557 | + std::declval<F &&>())) |
| 1558 | + transform_error(F &&f) const & { |
| 1559 | + return map_error_impl(*this, std::forward<F>(f)); |
| 1560 | + } |
| 1561 | + |
| 1562 | +#ifndef TL_EXPECTED_NO_CONSTRR |
| 1563 | + template <class F> |
| 1564 | + constexpr decltype(map_error_impl(std::declval<const expected &&>(), |
| 1565 | + std::declval<F &&>())) |
| 1566 | + transform_error(F &&f) const && { |
| 1567 | + return map_error_impl(std::move(*this), std::forward<F>(f)); |
| 1568 | + } |
| 1569 | +#endif |
1512 | 1570 | #endif
|
1513 | 1571 | template <class F>
|
1514 | 1572 | expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & {
|
@@ -1951,27 +2009,37 @@ class expected : private detail::expected_move_assign_base<T, E>,
|
1951 | 2009 | }
|
1952 | 2010 | }
|
1953 | 2011 |
|
1954 |
| - constexpr const T *operator->() const { return valptr(); } |
1955 |
| - TL_EXPECTED_11_CONSTEXPR T *operator->() { return valptr(); } |
| 2012 | + constexpr const T *operator->() const { |
| 2013 | + TL_ASSERT(has_value()); |
| 2014 | + return valptr(); |
| 2015 | + } |
| 2016 | + TL_EXPECTED_11_CONSTEXPR T *operator->() { |
| 2017 | + TL_ASSERT(has_value()); |
| 2018 | + return valptr(); |
| 2019 | + } |
1956 | 2020 |
|
1957 | 2021 | template <class U = T,
|
1958 | 2022 | detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
1959 | 2023 | constexpr const U &operator*() const & {
|
| 2024 | + TL_ASSERT(has_value()); |
1960 | 2025 | return val();
|
1961 | 2026 | }
|
1962 | 2027 | template <class U = T,
|
1963 | 2028 | detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
1964 | 2029 | TL_EXPECTED_11_CONSTEXPR U &operator*() & {
|
| 2030 | + TL_ASSERT(has_value()); |
1965 | 2031 | return val();
|
1966 | 2032 | }
|
1967 | 2033 | template <class U = T,
|
1968 | 2034 | detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
1969 | 2035 | constexpr const U &&operator*() const && {
|
| 2036 | + TL_ASSERT(has_value()); |
1970 | 2037 | return std::move(val());
|
1971 | 2038 | }
|
1972 | 2039 | template <class U = T,
|
1973 | 2040 | detail::enable_if_t<!std::is_void<U>::value> * = nullptr>
|
1974 | 2041 | TL_EXPECTED_11_CONSTEXPR U &&operator*() && {
|
| 2042 | + TL_ASSERT(has_value()); |
1975 | 2043 | return std::move(val());
|
1976 | 2044 | }
|
1977 | 2045 |
|
@@ -2007,10 +2075,22 @@ class expected : private detail::expected_move_assign_base<T, E>,
|
2007 | 2075 | return std::move(val());
|
2008 | 2076 | }
|
2009 | 2077 |
|
2010 |
| - constexpr const E &error() const & { return err().value(); } |
2011 |
| - TL_EXPECTED_11_CONSTEXPR E &error() & { return err().value(); } |
2012 |
| - constexpr const E &&error() const && { return std::move(err().value()); } |
2013 |
| - TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(err().value()); } |
| 2078 | + constexpr const E &error() const & { |
| 2079 | + TL_ASSERT(!has_value()); |
| 2080 | + return err().value(); |
| 2081 | + } |
| 2082 | + TL_EXPECTED_11_CONSTEXPR E &error() & { |
| 2083 | + TL_ASSERT(!has_value()); |
| 2084 | + return err().value(); |
| 2085 | + } |
| 2086 | + constexpr const E &&error() const && { |
| 2087 | + TL_ASSERT(!has_value()); |
| 2088 | + return std::move(err().value()); |
| 2089 | + } |
| 2090 | + TL_EXPECTED_11_CONSTEXPR E &&error() && { |
| 2091 | + TL_ASSERT(!has_value()); |
| 2092 | + return std::move(err().value()); |
| 2093 | + } |
2014 | 2094 |
|
2015 | 2095 | template <class U>
|
2016 | 2096 | constexpr T value_or(U &&v) const & {
|
|
0 commit comments