This commit is contained in:
Simon Brand
2017-12-19 15:04:45 +00:00
parent dee71e8bcd
commit 24b4725966
3 changed files with 40 additions and 9 deletions

View File

@@ -12,6 +12,7 @@ set(TEST_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/extensions.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/extensions.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/emplace.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/bases.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/observers.cpp ${CMAKE_CURRENT_SOURCE_DIR}/tests/observers.cpp
${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp) ${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp)

26
tests/issues.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include "catch.hpp"
#include "expected.hpp"
#include <string>
using std::string;
tl::expected<int, string> getInt3(int val)
{
return val;
}
tl::expected<int, string> getInt2(int val)
{
return val;
}
tl::expected<int, string> getInt1()
{
return getInt2(5).and_then(getInt3);
}
TEST_CASE("Issue 1", "[issues.1]") {
getInt1();
}

View File

@@ -999,8 +999,9 @@ public:
/// is returned. /// is returned.
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &; /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
template <class F> template <class F>
TL_EXPECTED_11_CONSTEXPR detail::invoke_result_t<F, T &> and_then(F &&f) & { TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) &
using result = detail::invoke_result_t<F, T &>; -> decltype(detail::invoke(std::forward<F>(f), std::declval<T&>())) {
using result = decltype(detail::invoke(std::forward<F>(f), **this));
static_assert(detail::is_expected<result>::value, static_assert(detail::is_expected<result>::value,
"F must return an expected"); "F must return an expected");
@@ -1011,20 +1012,22 @@ public:
/// \group and_then /// \group and_then
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&; /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &&;
template <class F> template <class F>
TL_EXPECTED_11_CONSTEXPR detail::invoke_result_t<F, T &&> and_then(F &&f) && { TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) &&
using result = detail::invoke_result_t<F, T &&>; -> decltype(detail::invoke(std::forward<F>(f), std::declval<T&&>())) {
using result = decltype(detail::invoke(std::forward<F>(f), std::move(**this)));
static_assert(detail::is_expected<result>::value, static_assert(detail::is_expected<result>::value,
"F must return an expected"); "F must return an expected");
return has_value() ? detail::invoke(std::forward<F>(f), **this) return has_value() ? detail::invoke(std::forward<F>(f), std::move(**this))
: result(unexpect, std::move(this->error())); : result(unexpect, std::move(this->error()));
} }
/// \group and_then /// \group and_then
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &; /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &;
template <class F> template <class F>
constexpr detail::invoke_result_t<F, const T &> and_then(F &&f) const & { constexpr auto and_then(F &&f) const &
using result = detail::invoke_result_t<F, const T &>; -> decltype(detail::invoke(std::forward<F>(f), std::declval<const T&>())) {
using result = decltype(detail::invoke(std::forward<F>(f), **this));
static_assert(detail::is_expected<result>::value, static_assert(detail::is_expected<result>::value,
"F must return an expected"); "F must return an expected");
@@ -1036,8 +1039,9 @@ public:
/// \group and_then /// \group and_then
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&; /// \synopsis template <class F>\nconstexpr auto and_then(F &&f) const &&;
template <class F> template <class F>
constexpr detail::invoke_result_t<F, const T &&> and_then(F &&f) const && { constexpr auto and_then(F &&f) const &&
using result = detail::invoke_result_t<F, const T &&>; -> decltype(detail::invoke(std::forward<F>(f), std::declval<const T&&>())) {
using result = decltype(detail::invoke(std::forward<F>(f), std::move(**this)));
static_assert(detail::is_expected<result>::value, static_assert(detail::is_expected<result>::value,
"F must return an expected"); "F must return an expected");