Skip to content

Commit

Permalink
[lazy] Add support for reference_wrapper in make_lazy
Browse files Browse the repository at this point in the history
  • Loading branch information
ldionne committed Sep 13, 2015
1 parent e63d814 commit faceac0
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 3 deletions.
7 changes: 4 additions & 3 deletions include/boost/hana/lazy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.

#include <boost/hana/basic_tuple.hpp>
#include <boost/hana/core/make.hpp>
#include <boost/hana/detail/as_container_element.hpp>
#include <boost/hana/detail/operators/adl.hpp>
#include <boost/hana/detail/operators/monad.hpp>
#include <boost/hana/functional/apply.hpp>
Expand Down Expand Up @@ -67,7 +68,7 @@ namespace boost { namespace hana {
template <typename ...Args>
constexpr lazy_apply_t<
std::make_index_sequence<sizeof...(Args)>,
X, typename std::decay<Args>::type...
X, detail::as_container_element_t<Args>...
> operator()(Args&& ...args) const& {
return {detail::lazy_secret{},
hana::get_impl<0>(storage_), static_cast<Args&&>(args)...};
Expand All @@ -76,7 +77,7 @@ namespace boost { namespace hana {
template <typename ...Args>
constexpr lazy_apply_t<
std::make_index_sequence<sizeof...(Args)>,
X, typename std::decay<Args>::type...
X, detail::as_container_element_t<Args>...
> operator()(Args&& ...args) && {
return {detail::lazy_secret{},
static_cast<X&&>(hana::get_impl<0>(storage_)),
Expand All @@ -91,7 +92,7 @@ namespace boost { namespace hana {
template <>
struct make_impl<lazy_tag> {
template <typename X>
static constexpr lazy_value_t<typename std::decay<X>::type> apply(X&& x) {
static constexpr lazy_value_t<detail::as_container_element_t<X>> apply(X&& x) {
return {detail::lazy_secret{}, static_cast<X&&>(x)};
}
};
Expand Down
59 changes: 59 additions & 0 deletions test/lazy/make.ref.cpp
Original file line number Diff line number Diff line change
@@ -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 <boost/hana/assert.hpp>
#include <boost/hana/eval.hpp>
#include <boost/hana/lazy.hpp>

#include <functional>
namespace hana = boost::hana;


// We make it non-copyable and non-movable to make sure it is taken by
// reference below.
template <typename Signature>
struct Function;

template <typename Return, typename ...Args>
struct Function<Return(Args...)> {
std::function<Return(Args...)> f_;

Function(std::function<Return(Args...)> f) : f_(f) { }
Function(Function const&) = delete;
Function(Function &&) = delete;

template <typename ...T>
decltype(auto) operator()(T&& ...t) const {
return f_(static_cast<T&&>(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<void(int&, char&)> 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');
}
}

0 comments on commit faceac0

Please sign in to comment.