diff --git a/include/boost/hana/fwd/lazy.hpp b/include/boost/hana/fwd/lazy.hpp index 3f310c6534..6e96d80900 100644 --- a/include/boost/hana/fwd/lazy.hpp +++ b/include/boost/hana/fwd/lazy.hpp @@ -88,6 +88,10 @@ BOOST_HANA_NAMESPACE_BEGIN //! equal to `x`, and `make(f)(x1, ..., xN)` is a lazy function //! call that is equal to `f(x1, ..., xN)` when it is `eval`uated. //! + //! `make` supports reference wrappers. When a reference wrapper + //! is passed to it, the resulting `hana::lazy` will hold a reference + //! to the object instead of the object itself. + //! //! @note //! It is interesting to note that `make(f)(x1, ..., xN)` is //! equivalent to diff --git a/include/boost/hana/lazy.hpp b/include/boost/hana/lazy.hpp index 5eccd4316f..b9678a278e 100644 --- a/include/boost/hana/lazy.hpp +++ b/include/boost/hana/lazy.hpp @@ -15,7 +15,7 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include -#include +#include #include #include #include @@ -71,7 +71,7 @@ BOOST_HANA_NAMESPACE_BEGIN template constexpr lazy_apply_t< std::make_index_sequence, - X, typename detail::decay::type... + X, detail::as_container_element_t... > operator()(Args&& ...args) const& { return {detail::lazy_secret{}, hana::get_impl<0>(storage_), static_cast(args)...}; @@ -80,7 +80,7 @@ BOOST_HANA_NAMESPACE_BEGIN template constexpr lazy_apply_t< std::make_index_sequence, - X, typename detail::decay::type... + X, detail::as_container_element_t... > operator()(Args&& ...args) && { return {detail::lazy_secret{}, static_cast(hana::get_impl<0>(storage_)), @@ -95,7 +95,7 @@ BOOST_HANA_NAMESPACE_BEGIN template <> struct make_impl { template - static constexpr lazy_value_t::type> apply(X&& x) { + static constexpr lazy_value_t> apply(X&& x) { return {detail::lazy_secret{}, static_cast(x)}; } }; diff --git a/test/lazy/make.ref.cpp b/test/lazy/make.ref.cpp new file mode 100644 index 0000000000..22ed24853d --- /dev/null +++ b/test/lazy/make.ref.cpp @@ -0,0 +1,59 @@ +/* +@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 + +#include +namespace hana = boost::hana; + + +// We make it non-copyable and non-movable to make sure it is taken by +// reference below. +template +struct Function; + +template +struct Function { + std::function f_; + + Function(std::function f) : f_(f) { } + Function(Function const&) = delete; + Function(Function &&) = delete; + + template + decltype(auto) operator()(T&& ...t) const { + return f_(static_cast(t)...); + } +}; + +int main() { + // lazy value + { + int i = 3; + auto lazy = hana::make_lazy(std::ref(i)); + int& i_ref = hana::eval(lazy); + BOOST_HANA_RUNTIME_CHECK(&i_ref == &i); + } + + // lazy function call + { + Function f([](int& a, char& b) -> void { + a = 10; + b = 'z'; + }); + int a = 3; + char b = 'b'; + auto lazy = hana::make_lazy(std::ref(f))(std::ref(a), std::ref(b)); + + BOOST_HANA_RUNTIME_CHECK(a == 3); + BOOST_HANA_RUNTIME_CHECK(b == 'b'); + hana::eval(lazy); + BOOST_HANA_RUNTIME_CHECK(a == 10); + BOOST_HANA_RUNTIME_CHECK(b == 'z'); + } +}