Commit 045ce1ce authored by ufownl's avatar ufownl

Make `function_view` support void result

parent 8181610d
......@@ -29,7 +29,19 @@
namespace caf {
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>
class function_view_storage<std::tuple<Ts...>> {
......@@ -46,6 +58,18 @@ private:
std::tuple<Ts...>* storage_;
};
template <>
class function_view_storage<unit_t> {
public:
function_view_storage(unit_t&) {
// nop
}
void operator()() {
// nop
}
};
template <class T>
struct function_view_flattened_result {
using type = T;
......@@ -56,6 +80,11 @@ struct function_view_flattened_result<std::tuple<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.
/// Internally, a function view uses a `scoped_actor` and uses
/// blocking send and receive operations.
......@@ -92,14 +121,16 @@ public:
/// @throws actor_exited if the requests resulted in an error
template <class... Ts,
class R =
typename detail::deduce_output_type<
typename type::signatures,
detail::type_list<
typename detail::implicit_conversions<
typename std::decay<Ts>::type
>::type...>
>::tuple_type>
typename function_view_flattened_result<R>::type operator()(Ts&&... xs) {
typename function_view_flattened_result<
typename detail::deduce_output_type<
typename type::signatures,
detail::type_list<
typename detail::implicit_conversions<
typename std::decay<Ts>::type
>::type...>
>::tuple_type
>::type>
R operator()(Ts&&... xs) {
if (! impl_)
throw std::bad_function_call();
R result;
......
......@@ -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 {
actor_system system;
std::vector<actor_addr> testees;
......@@ -133,4 +152,11 @@ CAF_TEST(tuple_res_function_view) {
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()
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