forked from TartanLlama/expected
Remove extensions
This commit is contained in:
@ -9,10 +9,8 @@ target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
|
||||
|
||||
# Make test executable
|
||||
set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/extensions.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/emplace.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/issues.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/bases.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/observers.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp)
|
||||
|
458
tl/expected.hpp
458
tl/expected.hpp
@ -1080,271 +1080,6 @@ public:
|
||||
typedef E error_type;
|
||||
typedef unexpected<E> unexpected_type;
|
||||
|
||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||
!defined(TL_EXPECTED_GCC54)
|
||||
/// \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 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) &;
|
||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & {
|
||||
return and_then_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group and_then
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
|
||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && {
|
||||
return and_then_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group and_then
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
|
||||
template <class F> constexpr auto and_then(F &&f) const & {
|
||||
return and_then_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||
/// \group and_then
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
|
||||
template <class F> constexpr auto and_then(F &&f) const && {
|
||||
return and_then_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
/// \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 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) &;
|
||||
template <class F>
|
||||
TL_EXPECTED_11_CONSTEXPR auto
|
||||
and_then(F &&f) & -> decltype(and_then_impl(*this, std::forward<F>(f))) {
|
||||
return and_then_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group and_then
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
|
||||
template <class F>
|
||||
TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && -> decltype(
|
||||
and_then_impl(std::move(*this), std::forward<F>(f))) {
|
||||
return and_then_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group and_then
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
|
||||
template <class F>
|
||||
constexpr auto and_then(F &&f) const & -> decltype(
|
||||
and_then_impl(*this, std::forward<F>(f))) {
|
||||
return and_then_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||
/// \group and_then
|
||||
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
|
||||
template <class F>
|
||||
constexpr auto and_then(F &&f) const && -> decltype(
|
||||
and_then_impl(std::move(*this), std::forward<F>(f))) {
|
||||
return and_then_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||
!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())`. 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.
|
||||
///
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) &;
|
||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) & {
|
||||
return expected_map_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) &&;
|
||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map(F &&f) && {
|
||||
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) const &;
|
||||
template <class F> constexpr auto map(F &&f) const & {
|
||||
return expected_map_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) const &&;
|
||||
template <class F> constexpr auto map(F &&f) const && {
|
||||
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
#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())`. 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.
|
||||
///
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) &;
|
||||
template <class F>
|
||||
TL_EXPECTED_11_CONSTEXPR decltype(
|
||||
expected_map_impl(std::declval<expected &>(), std::declval<F &&>()))
|
||||
map(F &&f) & {
|
||||
return expected_map_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) &&;
|
||||
template <class F>
|
||||
TL_EXPECTED_11_CONSTEXPR decltype(
|
||||
expected_map_impl(std::declval<expected &>(), std::declval<F &&>()))
|
||||
map(F &&f) && {
|
||||
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) const &;
|
||||
template <class F>
|
||||
constexpr decltype(expected_map_impl(std::declval<const expected &>(),
|
||||
std::declval<F &&>()))
|
||||
map(F &&f) const & {
|
||||
return expected_map_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||
/// \group map
|
||||
/// \synopsis template <class F> constexpr auto map(F &&f) const &&;
|
||||
template <class F>
|
||||
constexpr decltype(expected_map_impl(std::declval<const expected &&>(),
|
||||
std::declval<F &&>()))
|
||||
map(F &&f) const && {
|
||||
return expected_map_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||
!defined(TL_EXPECTED_GCC54)
|
||||
/// \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())`. 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.
|
||||
///
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) &;
|
||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) & {
|
||||
return map_error_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) &&;
|
||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto map_error(F &&f) && {
|
||||
return map_error_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &;
|
||||
template <class F> constexpr auto map_error(F &&f) const & {
|
||||
return map_error_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &&;
|
||||
template <class F> constexpr auto map_error(F &&f) const && {
|
||||
return map_error_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
#else
|
||||
/// \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 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.
|
||||
///
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) &;
|
||||
template <class F>
|
||||
TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &>(),
|
||||
std::declval<F &&>()))
|
||||
map_error(F &&f) & {
|
||||
return map_error_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) &&;
|
||||
template <class F>
|
||||
TL_EXPECTED_11_CONSTEXPR decltype(map_error_impl(std::declval<expected &&>(),
|
||||
std::declval<F &&>()))
|
||||
map_error(F &&f) && {
|
||||
return map_error_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &;
|
||||
template <class F>
|
||||
constexpr decltype(map_error_impl(std::declval<const expected &>(),
|
||||
std::declval<F &&>()))
|
||||
map_error(F &&f) const & {
|
||||
return map_error_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||
/// \group map_error
|
||||
/// \synopsis template <class F> constexpr auto map_error(F &&f) const &&;
|
||||
template <class F>
|
||||
constexpr decltype(map_error_impl(std::declval<const expected &&>(),
|
||||
std::declval<F &&>()))
|
||||
map_error(F &&f) const && {
|
||||
return map_error_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// \brief Calls `f` if the expectd is in the unexpected state
|
||||
/// \requires `std::invoke_result_t<F>` must be void or convertible to
|
||||
/// `expcted<T,E>`.
|
||||
/// \effects If `*this` has a value, returns `*this`.
|
||||
/// Otherwise, if `f` returns `void`, calls `std::forward<F>(f)` and returns
|
||||
/// `std::nullopt`. Otherwise, returns `std::forward<F>(f)()`.
|
||||
///
|
||||
/// \group or_else
|
||||
template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) & {
|
||||
return or_else_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <class F> expected TL_EXPECTED_11_CONSTEXPR or_else(F &&f) && {
|
||||
return or_else_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <class F> expected constexpr or_else(F &&f) const & {
|
||||
return or_else_impl(*this, std::forward<F>(f));
|
||||
}
|
||||
|
||||
template <class F> expected constexpr or_else(F &&f) const && {
|
||||
return or_else_impl(std::move(*this), std::forward<F>(f));
|
||||
}
|
||||
|
||||
constexpr expected() = default;
|
||||
constexpr expected(const expected &rhs) = default;
|
||||
constexpr expected(expected &&rhs) = default;
|
||||
@ -1780,199 +1515,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/// \exclude
|
||||
namespace detail {
|
||||
template <class Exp> using exp_t = typename detail::decay_t<Exp>::value_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>>;
|
||||
|
||||
#ifdef TL_EXPECTED_CXX14
|
||||
template <class Exp, class F,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr>
|
||||
constexpr auto and_then_impl(Exp &&exp, F &&f) {
|
||||
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
|
||||
|
||||
return exp.has_value()
|
||||
? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
|
||||
: Ret(unexpect, 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<exp_t<Exp>>::value> * = nullptr>
|
||||
constexpr auto and_then_impl(Exp &&exp, F &&f) {
|
||||
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
|
||||
|
||||
return exp.has_value() ? detail::invoke(std::forward<F>(f))
|
||||
: Ret(unexpect, exp.error());
|
||||
}
|
||||
#else
|
||||
template <class> struct TC;
|
||||
template <class Exp, class F,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<!std::is_void<exp_t<Exp>>::value> * = nullptr>
|
||||
auto and_then_impl(Exp &&exp, F &&f) -> Ret {
|
||||
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
|
||||
|
||||
return exp.has_value()
|
||||
? detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp))
|
||||
: Ret(unexpect, 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<exp_t<Exp>>::value> * = nullptr>
|
||||
constexpr auto and_then_impl(Exp &&exp, F &&f) -> Ret {
|
||||
static_assert(detail::is_expected<Ret>::value, "F must return an expected");
|
||||
|
||||
return exp.has_value() ? detail::invoke(std::forward<F>(f))
|
||||
: Ret(unexpect, exp.error());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TL_EXPECTED_CXX14
|
||||
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>
|
||||
constexpr auto expected_map_impl(Exp &&exp, F &&f) {
|
||||
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());
|
||||
}
|
||||
|
||||
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 expected_map_impl(Exp &&exp, F &&f) {
|
||||
using result = expected<void, err_t<Exp>>;
|
||||
if (exp.has_value()) {
|
||||
detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
|
||||
return result();
|
||||
}
|
||||
|
||||
return result(unexpect, std::forward<Exp>(exp).error());
|
||||
}
|
||||
#else
|
||||
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>
|
||||
|
||||
constexpr auto expected_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)))
|
||||
: result(unexpect, 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 expected_map_impl(Exp &&exp, F &&f) -> expected<void, err_t<Exp>> {
|
||||
if (exp.has_value()) {
|
||||
detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
|
||||
return {};
|
||||
}
|
||||
|
||||
return unexpected<err_t<Exp>>(std::forward<Exp>(exp).error());
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TL_EXPECTED_CXX14) && !defined(TL_EXPECTED_GCC49) && \
|
||||
!defined(TL_EXPECTED_GCC54)
|
||||
template <class Exp, class F,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
std::declval<Exp>().error())),
|
||||
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||
constexpr auto map_error_impl(Exp &&exp, F &&f) {
|
||||
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>().error())),
|
||||
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>().error())),
|
||||
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>().error())),
|
||||
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,
|
||||
class Ret = decltype(detail::invoke(std::declval<F>(),
|
||||
*std::declval<Exp>())),
|
||||
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||
constexpr detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
|
||||
if (exp.has_value()) {
|
||||
return std::forward<Exp>(exp);
|
||||
}
|
||||
|
||||
return detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
|
||||
}
|
||||
|
||||
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>
|
||||
detail::decay_t<Exp> or_else_impl(Exp &&exp, F &&f) {
|
||||
if (exp.has_value()) {
|
||||
return std::forward<Exp>(exp);
|
||||
}
|
||||
|
||||
detail::invoke(std::forward<F>(f), *std::forward<Exp>(exp));
|
||||
return std::forward<Exp>(exp);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <class T, class E, class U, class F>
|
||||
constexpr bool operator==(const expected<T, E> &lhs,
|
||||
const expected<U, F> &rhs) {
|
||||
|
Reference in New Issue
Block a user