diff --git a/expected.hpp b/expected.hpp index a59c69c..e5f75d0 100644 --- a/expected.hpp +++ b/expected.hpp @@ -432,6 +432,7 @@ public: typedef E error_type; typedef unexpected unexpected_type; +#ifdef TL_EXPECTED_CXX14 /// \group and_then /// Carries out some operation which returns an optional on the stored object /// if there is one. \requires `std::invoke(std::forward(f), value())` @@ -486,6 +487,64 @@ public: } #endif +#else + /// \group and_then + /// Carries out some operation which returns an optional on the stored object + /// if there is one. \requires `std::invoke(std::forward(f), value())` + /// returns a `std::optional` for some `U`. \returns Let `U` be the result + /// of `std::invoke(std::forward(f), value())`. Returns a + /// `std::optional`. The return value is empty if `*this` is empty, + /// otherwise the return value of `std::invoke(std::forward(f), value())` + /// is returned. \group and_then \synopsis template \nconstexpr auto + /// and_then(F &&f) &; + template + TL_EXPECTED_11_CONSTEXPR detail::invoke_result_t and_then(F &&f) & { + using result = detail::invoke_result_t; + static_assert(detail::is_expected::value, + "F must return an expected"); + + return has_value() ? detail::invoke(std::forward(f), **this) + : result(unexpect, this->error()); + } + + /// \group and_then + /// \synopsis template \nconstexpr auto and_then(F &&f) &&; + template + TL_EXPECTED_11_CONSTEXPR detail::invoke_result_t and_then(F &&f) && { + using result = detail::invoke_result_t; + static_assert(detail::is_expected::value, + "F must return an expected"); + + return has_value() ? detail::invoke(std::forward(f), **this) + : result(unexpect, std::move(this->error())); + } + + /// \group and_then + /// \synopsis template \nconstexpr auto and_then(F &&f) const &; + template + constexpr detail::invoke_result_t and_then(F &&f) const & { + using result = detail::invoke_result_t; + static_assert(detail::is_expected::value, + "F must return an expected"); + + return has_value() ? detail::invoke(std::forward(f), **this) + : result(unexpect, this->error()); + } + +#ifndef TL_EXPECTED_NO_CONSTRR + /// \group and_then + /// \synopsis template \nconstexpr auto and_then(F &&f) const &&; + template + constexpr detail::invoke_result_t and_then(F &&f) const && { + using result = detail::invoke_result_t; + static_assert(detail::is_expected::value, + "F must return an expected"); + + return has_value() ? detail::invoke(std::forward(f), **this) + : result(unexpect, std::move(this->error())); + } +#endif + #ifdef TL_EXPECTED_CXX14 /// \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),