Skip to content

Commit 01f0afc

Browse files
committed
[lazy] Add support for reference_wrapper in make_lazy
1 parent 8083c2c commit 01f0afc

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

include/boost/hana/lazy.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +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/as_container_element.hpp>
1718
#include <boost/hana/detail/operators/adl.hpp>
1819
#include <boost/hana/detail/operators/monad.hpp>
1920
#include <boost/hana/functional/apply.hpp>
@@ -67,7 +68,7 @@ namespace boost { namespace hana {
6768
template <typename ...Args>
6869
constexpr lazy_apply_t<
6970
std::make_index_sequence<sizeof...(Args)>,
70-
X, typename std::decay<Args>::type...
71+
X, detail::as_container_element_t<Args>...
7172
> operator()(Args&& ...args) const& {
7273
return {detail::lazy_secret{},
7374
hana::get_impl<0>(storage_), static_cast<Args&&>(args)...};
@@ -76,7 +77,7 @@ namespace boost { namespace hana {
7677
template <typename ...Args>
7778
constexpr lazy_apply_t<
7879
std::make_index_sequence<sizeof...(Args)>,
79-
X, typename std::decay<Args>::type...
80+
X, detail::as_container_element_t<Args>...
8081
> operator()(Args&& ...args) && {
8182
return {detail::lazy_secret{},
8283
static_cast<X&&>(hana::get_impl<0>(storage_)),
@@ -91,7 +92,7 @@ namespace boost { namespace hana {
9192
template <>
9293
struct make_impl<lazy_tag> {
9394
template <typename X>
94-
static constexpr lazy_value_t<typename std::decay<X>::type> apply(X&& x) {
95+
static constexpr lazy_value_t<detail::as_container_element_t<X>> apply(X&& x) {
9596
return {detail::lazy_secret{}, static_cast<X&&>(x)};
9697
}
9798
};

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)