Merge branch 'master' into trivial_copy_fix
This commit is contained in:
4 files changed
+139
-29
No files matched your search
+73
-28
@@ -158,8 +158,8 @@ constexpr bool operator>=(const unexpected<E> &lhs, const unexpected<E> &rhs) {
|
||||
/// *Example:*
|
||||
/// auto e1 = tl::make_unexpected(42);
|
||||
/// unexpected<int> e2 (42); //same semantics
|
||||
template <class E> unexpected<E> make_unexpected(E &&e) {
|
||||
return unexpected<E>(std::forward<E>(e));
|
||||
template <class E> unexpected<typename std::decay<E>::type> make_unexpected(E &&e) {
|
||||
return unexpected<typename std::decay<E>::type>(std::forward<E>(e));
|
||||
}
|
||||
|
||||
/// \brief A tag type to tell expected to construct the unexpected value
|
||||
@@ -631,7 +631,8 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
|
||||
// move constructible
|
||||
#ifndef TL_EXPECTED_GCC49
|
||||
template <class T, class E,
|
||||
bool = std::is_trivially_move_constructible<T>::value>
|
||||
bool = std::is_trivially_move_constructible<T>::value
|
||||
&& std::is_trivially_move_constructible<E>::value>
|
||||
struct expected_move_base : expected_copy_base<T, E> {
|
||||
using expected_copy_base<T, E>::expected_copy_base;
|
||||
};
|
||||
@@ -662,7 +663,10 @@ struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
|
||||
template <class T, class E,
|
||||
bool = IS_TRIVIALLY_COPY_ASSIGNABLE(T) &&
|
||||
IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) &&
|
||||
IS_TRIVIALLY_DESTRUCTIBLE(T)>
|
||||
IS_TRIVIALLY_DESTRUCTIBLE(T) &&
|
||||
IS_TRIVIALLY_COPY_ASSIGNABLE(E) &&
|
||||
IS_TRIVIALLY_COPY_CONSTRUCTIBLE(E) &&
|
||||
IS_TRIVIALLY_DESTRUCTIBLE(E)>
|
||||
struct expected_copy_assign_base : expected_move_base<T, E> {
|
||||
using expected_move_base<T, E>::expected_move_base;
|
||||
};
|
||||
@@ -691,8 +695,11 @@ struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> {
|
||||
#ifndef TL_EXPECTED_GCC49
|
||||
template <class T, class E,
|
||||
bool = std::is_trivially_destructible<T>::value
|
||||
&&std::is_trivially_move_constructible<T>::value
|
||||
&&std::is_trivially_move_assignable<T>::value>
|
||||
&&std::is_trivially_move_constructible<T>::value
|
||||
&&std::is_trivially_move_assignable<T>::value
|
||||
&&std::is_trivially_destructible<E>::value
|
||||
&&std::is_trivially_move_constructible<E>::value
|
||||
&&std::is_trivially_move_assignable<E>::value>
|
||||
struct expected_move_assign_base : expected_copy_assign_base<T, E> {
|
||||
using expected_copy_assign_base<T, E>::expected_copy_assign_base;
|
||||
};
|
||||
@@ -709,14 +716,17 @@ struct expected_move_assign_base<T, E, false>
|
||||
expected_move_assign_base(const expected_move_assign_base &rhs) = default;
|
||||
|
||||
expected_move_assign_base(expected_move_assign_base &&rhs) = default;
|
||||
|
||||
expected_move_assign_base &
|
||||
operator=(const expected_move_assign_base &rhs) = default;
|
||||
|
||||
expected_move_assign_base &
|
||||
|
||||
operator=(expected_move_assign_base &&rhs) noexcept(
|
||||
std::is_nothrow_move_constructible<T>::value
|
||||
&&std::is_nothrow_move_assignable<T>::value) {
|
||||
this->assign(std::move(rhs));
|
||||
return *this;
|
||||
std::is_nothrow_move_constructible<T>::value
|
||||
&&std::is_nothrow_move_assignable<T>::value) {
|
||||
this->assign(std::move(rhs));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -929,9 +939,9 @@ public:
|
||||
/// \group and_then
|
||||
/// Carries out some operation which returns an expected on the stored object
|
||||
/// if there is one. \requires `std::invoke(std::forward<F>(f), value())`
|
||||
/// returns a `std::expected<U>` for some `U`. \returns Let `U` be the result
|
||||
/// of `std::invoke(std::forward<F>(f), value())`. Returns a
|
||||
/// `std::expected<U>`. The return value is empty if `*this` is empty,
|
||||
/// returns an `expected<U>` for some `U`. \returns Let `U` be the result
|
||||
/// of `std::invoke(std::forward<F>(f), value())`. Returns an
|
||||
/// `expected<U>`. The return value is empty if `*this` is empty,
|
||||
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
||||
/// is returned.
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
|
||||
@@ -983,9 +993,9 @@ public:
|
||||
/// \group and_then
|
||||
/// Carries out some operation which returns an expected on the stored object
|
||||
/// if there is one. \requires `std::invoke(std::forward<F>(f), value())`
|
||||
/// returns a `std::expected<U>` for some `U`. \returns Let `U` be the result
|
||||
/// of `std::invoke(std::forward<F>(f), value())`. Returns a
|
||||
/// `std::expected<U>`. The return value is empty if `*this` is empty,
|
||||
/// returns an `expected<U>` for some `U`. \returns Let `U` be the result
|
||||
/// of `std::invoke(std::forward<F>(f), value())`. Returns an
|
||||
/// `expected<U>`. The return value is empty if `*this` is empty,
|
||||
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
||||
/// is returned.
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
|
||||
@@ -1042,7 +1052,8 @@ public:
|
||||
!defined(TL_EXPECTED_GCC54)
|
||||
/// \brief Carries out some operation on the stored object if there is one.
|
||||
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
||||
/// value())`. Returns a `std::expected<U,E>`. If `*this` is unexpected, the
|
||||
/// value())`. If `U` is `void`, returns an `expected<monostate,E>, otherwise
|
||||
// returns an `expected<U,E>`. If `*this` is unexpected, the
|
||||
/// result is `*this`, otherwise an `expected<U,E>` is constructed from the
|
||||
/// return value of `std::invoke(std::forward<F>(f), value())` and is
|
||||
/// returned.
|
||||
@@ -1073,7 +1084,8 @@ public:
|
||||
#else
|
||||
/// \brief Carries out some operation on the stored object if there is one.
|
||||
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
||||
/// value())`. Returns a `std::expected<U,E>`. If `*this` is unexpected, the
|
||||
/// value())`. If `U` is `void`, returns an `expected<monostate,E>, otherwise
|
||||
// returns an `expected<U,E>`. If `*this` is unexpected, the
|
||||
/// result is `*this`, otherwise an `expected<U,E>` is constructed from the
|
||||
/// return value of `std::invoke(std::forward<F>(f), value())` and is
|
||||
/// returned.
|
||||
@@ -1122,7 +1134,8 @@ public:
|
||||
/// \brief Carries out some operation on the stored unexpected object if there
|
||||
/// is one.
|
||||
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
||||
/// value())`. Returns a `std::expected<T,U>`. If `*this` has an expected
|
||||
/// value())`. If `U` is `void`, returns an `expected<T,monostate>`, otherwise
|
||||
/// returns an `expected<T,U>`. If `*this` has an expected
|
||||
/// value, the result is `*this`, otherwise an `expected<T,U>` is constructed
|
||||
/// from `make_unexpected(std::invoke(std::forward<F>(f), value()))` and is
|
||||
/// returned.
|
||||
@@ -1154,7 +1167,7 @@ public:
|
||||
/// \brief Carries out some operation on the stored unexpected object if there
|
||||
/// is one.
|
||||
/// \returns Let `U` be the result of `std::invoke(std::forward<F>(f),
|
||||
/// value())`. Returns a `std::expected<T,U>`. If `*this` has an expected
|
||||
/// value())`. Returns an `expected<T,U>`. If `*this` has an expected
|
||||
/// value, the result is `*this`, otherwise an `expected<T,U>` is constructed
|
||||
/// from `make_unexpected(std::invoke(std::forward<F>(f), value()))` and is
|
||||
/// returned.
|
||||
@@ -1630,6 +1643,7 @@ public:
|
||||
|
||||
/// \exclude
|
||||
namespace detail {
|
||||
template <class Exp> using exp_t = typename detail::decay_t<Exp>::error_type;
|
||||
template <class Exp> using err_t = typename detail::decay_t<Exp>::error_type;
|
||||
template <class Exp, class Ret> using ret_t = expected<Ret, err_t<Exp>>;
|
||||
|
||||
@@ -1639,7 +1653,7 @@ template <class Exp, class F,
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||
constexpr auto map_impl(Exp &&exp, F &&f) {
|
||||
using result = ret_t<Exp, Ret>;
|
||||
using result = ret_t<Exp, detail::decay_t<Ret>>;
|
||||
return exp.has_value() ? result(detail::invoke(std::forward<F>(f),
|
||||
*std::forward<Exp>(exp)))
|
||||
: result(unexpect, std::forward<Exp>(exp).error());
|
||||
@@ -1664,8 +1678,8 @@ template <class Exp, class F,
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||
|
||||
constexpr auto map_impl(Exp &&exp, F &&f) -> ret_t<Exp, Ret> {
|
||||
using result = ret_t<Exp, Ret>;
|
||||
constexpr auto map_impl(Exp &&exp, F &&f) -> ret_t<Exp, detail::decay_t<Ret>> {
|
||||
using result = ret_t<Exp, detail::decay_t<Ret>>;
|
||||
|
||||
return exp.has_value() ? result(detail::invoke(std::forward<F>(f),
|
||||
*std::forward<Exp>(exp)))
|
||||
@@ -1691,26 +1705,57 @@ auto map_impl(Exp &&exp, F &&f) -> expected<monostate, err_t<Exp>> {
|
||||
!defined(TL_EXPECTED_GCC54)
|
||||
template <class Exp, class F,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
*std::declval<Exp>()))>
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||
constexpr auto map_error_impl(Exp &&exp, F &&f) {
|
||||
using result = ret_t<Exp, Ret>;
|
||||
using result = expected<exp_t<Exp>, detail::decay_t<Ret>>;
|
||||
return exp.has_value()
|
||||
? result(*std::forward<Exp>(exp))
|
||||
: result(unexpect, detail::invoke(std::forward<F>(f),
|
||||
std::forward<Exp>(exp).error()));
|
||||
}
|
||||
template <class Exp, class F,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
|
||||
auto map_error_impl(Exp &&exp, F &&f) {
|
||||
using result = expected<exp_t<Exp>, monostate>;
|
||||
if (exp.has_value()) {
|
||||
return result(*std::forward<Exp>(exp));
|
||||
}
|
||||
|
||||
detail::invoke(std::forward<F>(f),
|
||||
std::forward<Exp>(exp).error());
|
||||
return result(unexpect, monostate{});
|
||||
}
|
||||
#else
|
||||
template <class Exp, class F,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
*std::declval<Exp>()))>
|
||||
constexpr auto map_error_impl(Exp &&exp, F &&f) -> ret_t<Exp, Ret> {
|
||||
using result = ret_t<Exp, Ret>;
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||
constexpr auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, detail::decay_t<Ret>> {
|
||||
using result = ret_t<Exp, detail::decay_t<Ret>>;
|
||||
|
||||
return exp.has_value()
|
||||
? result(*std::forward<Exp>(exp))
|
||||
: result(unexpect, detail::invoke(std::forward<F>(f),
|
||||
std::forward<Exp>(exp).error()));
|
||||
}
|
||||
|
||||
template <class Exp, class F,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<std::is_void<Ret>::value> * = nullptr>
|
||||
auto map_error_impl(Exp &&exp, F &&f) -> expected<exp_t<Exp>, monostate> {
|
||||
using result = expected<exp_t<Exp>, monostate>;
|
||||
if (exp.has_value()) {
|
||||
return result(*std::forward<Exp>(exp));
|
||||
}
|
||||
|
||||
detail::invoke(std::forward<F>(f),
|
||||
std::forward<Exp>(exp).error());
|
||||
return result(unexpect, monostate{});
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class Exp, class F,
|
||||
|
||||
Reference in new issue
Block a user