forked from TartanLlama/optional
Fix #14
This commit is contained in:
@ -27,6 +27,7 @@ if(OPTIONAL_ENABLE_TESTS)
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/constexpr.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/constexpr.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/constructors.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/assignment.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/nullopt.cpp)
|
${CMAKE_CURRENT_SOURCE_DIR}/tests/nullopt.cpp)
|
||||||
|
|
||||||
|
19
tests/issues.cpp
Normal file
19
tests/issues.cpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
#include "optional.hpp"
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
struct foo{
|
||||||
|
int& v() { return i; }
|
||||||
|
int i = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
int& x(int& i) { i = 42; return i;}
|
||||||
|
|
||||||
|
TEST_CASE("issue 14") {
|
||||||
|
tl::optional<foo> f = foo{};
|
||||||
|
auto v = f.map(&foo::v).map(x);
|
||||||
|
static_assert(std::is_same<decltype(v), tl::optional<int&>>::value, "Must return a reference");
|
||||||
|
REQUIRE(f->i == 42);
|
||||||
|
REQUIRE(*v == 42);
|
||||||
|
REQUIRE((&f->i) == (&*v));
|
||||||
|
}
|
@ -1639,7 +1639,7 @@ template <class Opt, class F,
|
|||||||
constexpr auto optional_map_impl(Opt &&opt, F &&f) {
|
constexpr auto optional_map_impl(Opt &&opt, F &&f) {
|
||||||
return opt.has_value()
|
return opt.has_value()
|
||||||
? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
|
? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
|
||||||
: optional<detail::decay_t<Ret>>(nullopt);
|
: optional<Ret>(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Opt, class F,
|
template <class Opt, class F,
|
||||||
@ -1660,10 +1660,10 @@ template <class Opt, class F,
|
|||||||
*std::declval<Opt>())),
|
*std::declval<Opt>())),
|
||||||
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
detail::enable_if_t<!std::is_void<Ret>::value> * = nullptr>
|
||||||
|
|
||||||
constexpr auto optional_map_impl(Opt &&opt, F &&f) -> optional<detail::decay_t<Ret>> {
|
constexpr auto optional_map_impl(Opt &&opt, F &&f) -> optional<Ret> {
|
||||||
return opt.has_value()
|
return opt.has_value()
|
||||||
? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
|
? detail::invoke(std::forward<F>(f), *std::forward<Opt>(opt))
|
||||||
: optional<detail::decay_t<Ret>>(nullopt);
|
: optional<Ret>(nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Opt, class F,
|
template <class Opt, class F,
|
||||||
|
Reference in New Issue
Block a user