Skip to content

Commit f3fa119

Browse files
committed
[lazy] Add support for reference_wrapper in make_lazy
1 parent 6a6bb3c commit f3fa119

File tree

3 files changed

+67
-4
lines changed

3 files changed

+67
-4
lines changed

include/boost/hana/fwd/lazy.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ BOOST_HANA_NAMESPACE_BEGIN
8888
//! equal to `x`, and `make<lazy_tag>(f)(x1, ..., xN)` is a lazy function
8989
//! call that is equal to `f(x1, ..., xN)` when it is `eval`uated.
9090
//!
91+
//! `make<lazy_tag>` supports reference wrappers. When a reference wrapper
92+
//! is passed to it, the resulting `hana::lazy` will hold a reference
93+
//! to the object instead of the object itself.
94+
//!
9195
//! @note
9296
//! It is interesting to note that `make<lazy_tag>(f)(x1, ..., xN)` is
9397
//! equivalent to

include/boost/hana/lazy.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
1515
#include <boost/hana/basic_tuple.hpp>
1616
#include <boost/hana/config.hpp>
1717
#include <boost/hana/core/make.hpp>
18-
#include <boost/hana/detail/decay.hpp>
18+
#include <boost/hana/detail/as_container_element.hpp>
1919
#include <boost/hana/detail/operators/adl.hpp>
2020
#include <boost/hana/detail/operators/monad.hpp>
2121
#include <boost/hana/functional/apply.hpp>
@@ -71,7 +71,7 @@ BOOST_HANA_NAMESPACE_BEGIN
7171
template <typename ...Args>
7272
constexpr lazy_apply_t<
7373
std::make_index_sequence<sizeof...(Args)>,
74-
X, typename detail::decay<Args>::type...
74+
X, detail::as_container_element_t<Args>...
7575
> operator()(Args&& ...args) const& {
7676
return {detail::lazy_secret{},
7777
hana::get_impl<0>(storage_), static_cast<Args&&>(args)...};
@@ -80,7 +80,7 @@ BOOST_HANA_NAMESPACE_BEGIN
8080
template <typename ...Args>
8181
constexpr lazy_apply_t<
8282
std::make_index_sequence<sizeof...(Args)>,
83-
X, typename detail::decay<Args>::type...
83+
X, detail::as_container_element_t<Args>...
8484
> operator()(Args&& ...args) && {
8585
return {detail::lazy_secret{},
8686
static_cast<X&&>(hana::get_impl<0>(storage_)),
@@ -95,7 +95,7 @@ BOOST_HANA_NAMESPACE_BEGIN
9595
template <>
9696
struct make_impl<lazy_tag> {
9797
template <typename X>
98-
static constexpr lazy_value_t<typename detail::decay<X>::type> apply(X&& x) {
98+
static constexpr lazy_value_t<detail::as_container_element_t<X>> apply(X&& x) {
9999
return {detail::lazy_secret{}, static_cast<X&&>(x)};
100100
}
101101
};

test/lazy/make.ref.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
@copyright Louis Dionne 2015
3+
Distributed under the Boost Software License, Version 1.0.
4+
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
5+
*/
6+
7+
#include <boost/hana/assert.hpp>
8+
#include <boost/hana/eval.hpp>
9+
#include <boost/hana/lazy.hpp>
10+
11+
#include <functional>
12+
namespace hana = boost::hana;
13+
14+
15+
// We make it non-copyable and non-movable to make sure it is taken by
16+
// reference below.
17+
template <typename Signature>
18+
struct Function;
19+
20+
template <typename Return, typename ...Args>
21+
struct Function<Return(Args...)> {
22+
std::function<Return(Args...)> f_;
23+
24+
Function(std::function<Return(Args...)> f) : f_(f) { }
25+
Function(Function const&) = delete;
26+
Function(Function &&) = delete;
27+
28+
template <typename ...T>
29+
decltype(auto) operator()(T&& ...t) const {
30+
return f_(static_cast<T&&>(t)...);
31+
}
32+
};
33+
34+
int main() {
35+
// lazy value
36+
{
37+
int i = 3;
38+
auto lazy = hana::make_lazy(std::ref(i));
39+
int& i_ref = hana::eval(lazy);
40+
BOOST_HANA_RUNTIME_CHECK(&i_ref == &i);
41+
}
42+
43+
// lazy function call
44+
{
45+
Function<void(int&, char&)> f([](int& a, char& b) -> void {
46+
a = 10;
47+
b = 'z';
48+
});
49+
int a = 3;
50+
char b = 'b';
51+
auto lazy = hana::make_lazy(std::ref(f))(std::ref(a), std::ref(b));
52+
53+
BOOST_HANA_RUNTIME_CHECK(a == 3);
54+
BOOST_HANA_RUNTIME_CHECK(b == 'b');
55+
hana::eval(lazy);
56+
BOOST_HANA_RUNTIME_CHECK(a == 10);
57+
BOOST_HANA_RUNTIME_CHECK(b == 'z');
58+
}
59+
}

0 commit comments

Comments
 (0)