diff --git a/include/boost/hana/fwd/optional.hpp b/include/boost/hana/fwd/optional.hpp index 0c7da4bd91..d7aad34957 100644 --- a/include/boost/hana/fwd/optional.hpp +++ b/include/boost/hana/fwd/optional.hpp @@ -250,6 +250,11 @@ namespace boost { namespace hana { //! `make(x)` is equivalent to `just(x)`. This is provided //! for consistency with the other `make<...>` functions. //! + //! @note + //! `make` supports reference wrappers. When a reference + //! wrapper is passed to it, the resulting `hana::optional` will hold a + //! reference to the object instead of the object itself. + //! //! //! Example //! ------- diff --git a/include/boost/hana/optional.hpp b/include/boost/hana/optional.hpp index c9e73bc452..4e80e69747 100644 --- a/include/boost/hana/optional.hpp +++ b/include/boost/hana/optional.hpp @@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include +#include #include #include #include @@ -58,6 +59,9 @@ namespace boost { namespace hana { constexpr optional(optional const&) = default; constexpr optional(optional&&) = default; + template ::value + >::type> constexpr optional(T const& t) : value_(t) { } @@ -71,8 +75,15 @@ namespace boost { namespace hana { constexpr optional& operator=(optional&&) = default; // 5.3.5, Observers - constexpr T const* operator->() const { return &value_; } - constexpr T* operator->() { return &value_; } + template ::value + >::type> + constexpr U const* operator->() const { return &value_; } + + template ::value + >::type> + constexpr U* operator->() { return &value_; } constexpr T& value() & { return value_; } constexpr T const& value() const& { return value_; } @@ -114,7 +125,7 @@ namespace boost { namespace hana { template constexpr auto make_just_t::operator()(T&& t) const { - return optional::type>( + return optional>( static_cast(t) ); } diff --git a/test/optional/make.ref.cpp b/test/optional/make.ref.cpp new file mode 100644 index 0000000000..099f256605 --- /dev/null +++ b/test/optional/make.ref.cpp @@ -0,0 +1,43 @@ +/* +@copyright Louis Dionne 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#include +#include + +#include +namespace hana = boost::hana; + + +int main() { + { + int i = 0; + auto ref = hana::just(std::ref(i)); + + int& i_ref = *ref; + BOOST_HANA_RUNTIME_CHECK(&i_ref == &i); + + i_ref = 3; + BOOST_HANA_RUNTIME_CHECK(i == 3); + } + + { + int const i = 4; + auto ref = hana::just(std::cref(i)); + + int const& i_ref = *ref; + BOOST_HANA_RUNTIME_CHECK(&i_ref == &i); + BOOST_HANA_RUNTIME_CHECK(i == 4); + } + + // Instantiate .value_or to make sure it works with references. + { + int i = 0; + auto ref = hana::just(std::ref(i)); + BOOST_HANA_RUNTIME_CHECK(ref.value_or(999) == i); + BOOST_HANA_RUNTIME_CHECK(static_cast(ref).value_or(999) == i); + BOOST_HANA_RUNTIME_CHECK(hana::just(std::ref(i)).value_or(999) == i); + } +}