From 24b4725966b4c22c0144c519317ba05b8479df6c Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Tue, 19 Dec 2017 15:04:45 +0000 Subject: [PATCH 1/5] Fix #1 --- CMakeLists.txt | 1 + tests/issues.cpp | 26 ++++++++++++++++++++++++++ tl/expected.hpp | 22 +++++++++++++--------- 3 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 tests/issues.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e7bcd7..fe45fae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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/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) diff --git a/tests/issues.cpp b/tests/issues.cpp new file mode 100644 index 0000000..2dc4201 --- /dev/null +++ b/tests/issues.cpp @@ -0,0 +1,26 @@ +#include "catch.hpp" +#include "expected.hpp" + +#include + +using std::string; + +tl::expected getInt3(int val) +{ + return val; +} + +tl::expected getInt2(int val) +{ + return val; +} + +tl::expected getInt1() +{ + return getInt2(5).and_then(getInt3); +} + + +TEST_CASE("Issue 1", "[issues.1]") { + getInt1(); +} diff --git a/tl/expected.hpp b/tl/expected.hpp index 4a61b65..6515668 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -999,8 +999,9 @@ public: /// is returned. /// \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; + TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & + -> decltype(detail::invoke(std::forward(f), std::declval())) { + using result = decltype(detail::invoke(std::forward(f), **this)); static_assert(detail::is_expected::value, "F must return an expected"); @@ -1011,20 +1012,22 @@ public: /// \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; + TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) && + -> decltype(detail::invoke(std::forward(f), std::declval())) { + using result = decltype(detail::invoke(std::forward(f), std::move(**this))); static_assert(detail::is_expected::value, "F must return an expected"); - return has_value() ? detail::invoke(std::forward(f), **this) + return has_value() ? detail::invoke(std::forward(f), std::move(**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; + constexpr auto and_then(F &&f) const & + -> decltype(detail::invoke(std::forward(f), std::declval())) { + using result = decltype(detail::invoke(std::forward(f), **this)); static_assert(detail::is_expected::value, "F must return an expected"); @@ -1036,8 +1039,9 @@ public: /// \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; + constexpr auto and_then(F &&f) const && + -> decltype(detail::invoke(std::forward(f), std::declval())) { + using result = decltype(detail::invoke(std::forward(f), std::move(**this))); static_assert(detail::is_expected::value, "F must return an expected"); From d7c8a569ac572775e362ca8e6ba99586f8e16ea0 Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Tue, 19 Dec 2017 15:23:56 +0000 Subject: [PATCH 2/5] Constexpr fixes --- tl/expected.hpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tl/expected.hpp b/tl/expected.hpp index 6515668..c88f7fa 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -78,6 +78,12 @@ #define TL_EXPECTED_GCC49_CONSTEXPR constexpr #endif +#ifdef TL_EXPECTED_MSVC2015_CONSTEXPR +#define TL_EXPECTED_MSVC2015_CONSTEXPR +#else +#define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr +#endif + #if (__cplusplus == 201103L || defined(TL_EXPECTED_MSVC2015) || \ defined(TL_EXPECTED_GCC49)) && \ !defined(TL_EXPECTED_GCC54) @@ -1380,7 +1386,7 @@ public: class U = T, detail::enable_if_t::value> * = nullptr, detail::expected_enable_forward_value * = nullptr> - explicit constexpr expected(U &&v) : expected(in_place, std::forward(v)) {} + explicit TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) : expected(in_place, std::forward(v)) {} /// \exclude template < From 00dea6263b2f3228ae6a2aaaa4750d194b0e581a Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Tue, 19 Dec 2017 15:28:16 +0000 Subject: [PATCH 3/5] More constexpr fixes --- tl/expected.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tl/expected.hpp b/tl/expected.hpp index c88f7fa..5634856 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -1393,7 +1393,7 @@ public: class U = T, detail::enable_if_t::value> * = nullptr, detail::expected_enable_forward_value * = nullptr> - constexpr expected(U &&v) : expected(in_place, std::forward(v)) {} + TL_EXPECTED_MSVC2015_CONSTEXPR expected(U &&v) : expected(in_place, std::forward(v)) {} template < class U = T, From 950f0bf12f5aec3d61c3fbcaade79f94da75e1d0 Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Tue, 19 Dec 2017 17:25:59 +0000 Subject: [PATCH 4/5] More constexpr fixes --- tl/expected.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tl/expected.hpp b/tl/expected.hpp index 5634856..7af0855 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -78,7 +78,7 @@ #define TL_EXPECTED_GCC49_CONSTEXPR constexpr #endif -#ifdef TL_EXPECTED_MSVC2015_CONSTEXPR +#ifdef TL_EXPECTED_MSVC2015 #define TL_EXPECTED_MSVC2015_CONSTEXPR #else #define TL_EXPECTED_MSVC2015_CONSTEXPR constexpr From 07f7b573904c29789bfb5a0f3258cfa03edcf6e3 Mon Sep 17 00:00:00 2001 From: Simon Brand Date: Tue, 19 Dec 2017 19:03:32 +0000 Subject: [PATCH 5/5] More constexpr fixes --- tl/expected.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tl/expected.hpp b/tl/expected.hpp index 7af0855..604a869 100644 --- a/tl/expected.hpp +++ b/tl/expected.hpp @@ -368,7 +368,7 @@ template struct expected_storage_base { // T is trivial, E is not. template struct expected_storage_base { constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {} - constexpr expected_storage_base(no_init_t) : m_has_val(false) {} + TL_EXPECTED_MSVC2015_CONSTEXPR expected_storage_base(no_init_t) : m_has_val(false) {} template ::value> * =