Skip to content

Commit 1181df7

Browse files
committed
[lazy] Add support for reference_wrapper in make_lazy
1 parent 97c64f5 commit 1181df7

File tree

3 files changed

+67
-4
lines changed

3 files changed

+67
-4
lines changed

include/boost/hana/fwd/lazy.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ namespace boost { namespace hana {
8787
//! equal to `x`, and `make<lazy_tag>(f)(x1, ..., xN)` is a lazy function
8888
//! call that is equal to `f(x1, ..., xN)` when it is `eval`uated.
8989
//!
90+
//! `make<lazy_tag>` supports reference wrappers. When a reference wrapper
91+
//! is passed to it, the resulting `hana::lazy` will hold a reference
92+
//! to the object instead of the object itself.
93+
//!
9094
//! @note
9195
//! It is interesting to note that `make<lazy_tag>(f)(x1, ..., xN)` is
9296
//! equivalent to

include/boost/hana/lazy.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
1414

1515
#include <boost/hana/basic_tuple.hpp>
1616
#include <boost/hana/core/make.hpp>
17-
#include <boost/hana/detail/decay.hpp>
17+
#include <boost/hana/detail/as_container_element.hpp>
1818
#include <boost/hana/detail/operators/adl.hpp>
1919
#include <boost/hana/detail/operators/monad.hpp>
2020
#include <boost/hana/functional/apply.hpp>
@@ -68,7 +68,7 @@ namespace boost { namespace hana {
6868
template <typename ...Args>
6969
constexpr lazy_apply_t<
7070
std::make_index_sequence<sizeof...(Args)>,
71-
X, typename detail::decay<Args>::type...
71+
X, detail::as_container_element_t<Args>...
7272
> operator()(Args&& ...args) const& {
7373
return {detail::lazy_secret{},
7474
hana::get_impl<0>(storage_), static_cast<Args&&>(args)...};
@@ -77,7 +77,7 @@ namespace boost { namespace hana {
7777
template <typename ...Args>
7878
constexpr lazy_apply_t<
7979
std::make_index_sequence<sizeof...(Args)>,
80-
X, typename detail::decay<Args>::type...
80+
X, detail::as_container_element_t<Args>...
8181
> operator()(Args&& ...args) && {
8282
return {detail::lazy_secret{},
8383
static_cast<X&&>(hana::get_impl<0>(storage_)),
@@ -92,7 +92,7 @@ namespace boost { namespace hana {
9292
template <>
9393
struct make_impl<lazy_tag> {
9494
template <typename X>
95-
static constexpr lazy_value_t<typename detail::decay<X>::type> apply(X&& x) {
95+
static constexpr lazy_value_t<detail::as_container_element_t<X>> apply(X&& x) {
9696
return {detail::lazy_secret{}, static_cast<X&&>(x)};
9797
}
9898
};

test/lazy/make.ref.cpp

+59
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)