Commit 4c8a78f6 authored by Dominik Charousset's avatar Dominik Charousset

Add typed response promises

The new typed_response_promise template allows typed actors to use promises. By
returning a typed promise, the type-checker accepts the signature of the
message handler while the actual response message will be delayed (the runtime
will not create a response message from the returned promise).
parent 1511ff95
......@@ -34,7 +34,9 @@
#include "caf/duration.hpp"
#include "caf/ref_counted.hpp"
#include "caf/skip_message.hpp"
#include "caf/response_promise.hpp"
#include "caf/timeout_definition.hpp"
#include "caf/typed_response_promise.hpp"
#include "caf/detail/int_list.hpp"
#include "caf/detail/apply_args.hpp"
......@@ -59,6 +61,15 @@ struct is_message_id_wrapper {
static constexpr bool value = sizeof(test<T>(0)) == 1;
};
template <class T>
struct is_response_promise : std::false_type { };
template <>
struct is_response_promise<response_promise> : std::true_type { };
template <class T>
struct is_response_promise<typed_response_promise<T>> : std::true_type { };
template <class T>
struct optional_message_visitor_enable_tpl {
static constexpr bool value =
......@@ -70,7 +81,8 @@ struct optional_message_visitor_enable_tpl {
optional<skip_message_t>
>::value
&& !is_message_id_wrapper<T>::value
&& !std::is_convertible<T, message>::value;
&& !std::is_convertible<T, message>::value
&& !is_response_promise<T>::value;
};
struct optional_message_visitor : static_visitor<bhvr_invoke_result> {
......@@ -92,6 +104,15 @@ struct optional_message_visitor : static_visitor<bhvr_invoke_result> {
return message{};
}
inline bhvr_invoke_result operator()(const response_promise&) const {
return message{};
}
template <class T>
inline bhvr_invoke_result operator()(const typed_response_promise<T>&) const {
return message{};
}
template <class T, class... Ts>
typename std::enable_if<
optional_message_visitor_enable_tpl<T>::value,
......
......@@ -21,6 +21,7 @@
#define CAF_DETAIL_CTM_HPP
#include "caf/replies_to.hpp"
#include "caf/typed_response_promise.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/typed_actor_util.hpp"
......@@ -42,11 +43,21 @@ struct ctm_cmp<typed_mpi<In, Out, empty_type_list>,
typed_mpi<In, type_list<typed_continue_helper<Out>>, empty_type_list>>
: std::true_type { };
template <class In, class Out>
struct ctm_cmp<typed_mpi<In, Out, empty_type_list>,
typed_mpi<In, type_list<typed_response_promise<Out>>, empty_type_list>>
: std::true_type { };
template <class In, class L, class R>
struct ctm_cmp<typed_mpi<In, L, R>,
typed_mpi<In, type_list<skip_message_t>, empty_type_list>>
: std::true_type { };
template <class In, class L, class R>
struct ctm_cmp<typed_mpi<In, L, R>,
typed_mpi<In, type_list<typed_response_promise<either_or_t<L, R>>>, empty_type_list>>
: std::true_type { };
template <class A, class B>
struct ctm : std::false_type { };
......
......@@ -27,6 +27,7 @@
#include "caf/replies_to.hpp"
#include "caf/abstract_actor.hpp"
#include "caf/typed_behavior.hpp"
#include "caf/typed_response_promise.hpp"
namespace caf {
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2014 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_TYPED_RESPONSE_PROMISE_HPP
#define CAF_TYPED_RESPONSE_PROMISE_HPP
#include "caf/either.hpp"
#include "caf/response_promise.hpp"
namespace caf {
template <class T>
class typed_response_promise {
public:
typed_response_promise(response_promise promise) : m_promise(promise) {
// nop
}
explicit operator bool() const {
// handle is valid if it has a receiver
return static_cast<bool>(m_promise);
}
void deliver(T what) const {
m_promise.deliver(make_message(std::move(what)));
}
private:
response_promise m_promise;
};
template <class L, class R>
class typed_response_promise<either_or_t<L, R>> {
public:
typed_response_promise(response_promise promise) : m_promise(promise) {
// nop
}
explicit operator bool() const {
// handle is valid if it has a receiver
return static_cast<bool>(m_promise);
}
void deliver(either_or_t<L, R> what) const {
m_promise.deliver(what.value);
}
private:
response_promise m_promise;
};
} // namespace caf
#endif // CAF_TYPED_RESPONSE_PROMISE_HPP
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