Commit 045ce1ce authored by ufownl's avatar ufownl

Make `function_view` support void result

parent 8181610d
...@@ -29,7 +29,19 @@ ...@@ -29,7 +29,19 @@
namespace caf { namespace caf {
template <class T> template <class T>
class function_view_storage; class function_view_storage {
public:
function_view_storage(T& storage) : storage_(&storage) {
// nop
}
void operator()(T& x) {
*storage_ = std::move(x);
}
private:
T* storage_;
};
template <class... Ts> template <class... Ts>
class function_view_storage<std::tuple<Ts...>> { class function_view_storage<std::tuple<Ts...>> {
...@@ -46,6 +58,18 @@ private: ...@@ -46,6 +58,18 @@ private:
std::tuple<Ts...>* storage_; std::tuple<Ts...>* storage_;
}; };
template <>
class function_view_storage<unit_t> {
public:
function_view_storage(unit_t&) {
// nop
}
void operator()() {
// nop
}
};
template <class T> template <class T>
struct function_view_flattened_result { struct function_view_flattened_result {
using type = T; using type = T;
...@@ -56,6 +80,11 @@ struct function_view_flattened_result<std::tuple<T>> { ...@@ -56,6 +80,11 @@ struct function_view_flattened_result<std::tuple<T>> {
using type = T; using type = T;
}; };
template <>
struct function_view_flattened_result<std::tuple<void>> {
using type = unit_t;
};
/// A function view for an actor hides any messaging from the caller. /// A function view for an actor hides any messaging from the caller.
/// Internally, a function view uses a `scoped_actor` and uses /// Internally, a function view uses a `scoped_actor` and uses
/// blocking send and receive operations. /// blocking send and receive operations.
...@@ -92,14 +121,16 @@ public: ...@@ -92,14 +121,16 @@ public:
/// @throws actor_exited if the requests resulted in an error /// @throws actor_exited if the requests resulted in an error
template <class... Ts, template <class... Ts,
class R = class R =
typename detail::deduce_output_type< typename function_view_flattened_result<
typename type::signatures, typename detail::deduce_output_type<
detail::type_list< typename type::signatures,
typename detail::implicit_conversions< detail::type_list<
typename std::decay<Ts>::type typename detail::implicit_conversions<
>::type...> typename std::decay<Ts>::type
>::tuple_type> >::type...>
typename function_view_flattened_result<R>::type operator()(Ts&&... xs) { >::tuple_type
>::type>
R operator()(Ts&&... xs) {
if (! impl_) if (! impl_)
throw std::bad_function_call(); throw std::bad_function_call();
R result; R result;
......
...@@ -69,6 +69,25 @@ doubler::behavior_type simple_doubler() { ...@@ -69,6 +69,25 @@ doubler::behavior_type simple_doubler() {
}; };
} }
using cell = typed_actor<reacts_to<put_atom, int>,
replies_to<get_atom>::with<int>>;
struct cell_state {
int value = 0;
};
cell::behavior_type
simple_cell(cell::stateful_pointer<cell_state> self) {
return {
[=](put_atom, int val) {
self->state.value = val;
},
[=](get_atom) {
return self->state.value;
}
};
}
struct fixture { struct fixture {
actor_system system; actor_system system;
std::vector<actor_addr> testees; std::vector<actor_addr> testees;
...@@ -133,4 +152,11 @@ CAF_TEST(tuple_res_function_view) { ...@@ -133,4 +152,11 @@ CAF_TEST(tuple_res_function_view) {
CAF_CHECK(f(10) == std::make_tuple(10, 10)); CAF_CHECK(f(10) == std::make_tuple(10, 10));
} }
CAF_TEST(cell_function_view) {
auto f = make_function_view(spawn(simple_cell));
CAF_CHECK(f(get_atom::value) == 0);
f(put_atom::value, 1024);
CAF_CHECK(f(get_atom::value) == 1024);
}
CAF_TEST_FIXTURE_SCOPE_END() CAF_TEST_FIXTURE_SCOPE_END()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment