Commit c2a66286 authored by Dominik Charousset's avatar Dominik Charousset

Allow binary_deserializer to insert into vectors

parent dd8f1f1a
......@@ -125,6 +125,9 @@ public:
friend class abstract_actor;
friend class io::middleman;
actor_system(const actor_system&) = delete;
actor_system& operator=(const actor_system&) = delete;
/// An (optional) component of the actor system.
class module {
public:
......@@ -208,6 +211,10 @@ public:
/// @throws `std::logic_error` if the I/O module has not been loaded.
io::middleman& middleman();
/// Returns a dummy execution unit that forwards
/// everything to the scheduler.
scoped_execution_unit* dummy_execution_unit();
/// Returns a new actor ID.
actor_id next_actor_id();
......@@ -376,9 +383,8 @@ private:
: 0;
if (has_detach_flag(Os) || has_blocking_api_flag(Os))
cfg.flags |= abstract_actor::is_detached_flag;
scoped_execution_unit context{this};
if (! cfg.host)
cfg.host = &context;
cfg.host = dummy_execution_unit();
auto ptr = make_counted<C>(cfg, std::forward<Ts>(xs)...);
CAF_SET_LOGGER_SYS(this);
CAF_LOG_DEBUG("spawned actor:" << CAF_ARG(ptr->id()));
......@@ -395,6 +401,7 @@ private:
group_manager groups_;
module_array modules_;
io::middleman* middleman_;
scoped_execution_unit dummy_execution_unit_;
};
} // namespace caf
......
......@@ -31,10 +31,17 @@ namespace caf {
/// Implements the deserializer interface with a binary serialization protocol.
class binary_deserializer : public deserializer {
public:
binary_deserializer(actor_system& sys, const void* buf, size_t buf_size);
binary_deserializer(execution_unit* ctx, const void* buf, size_t buf_size);
binary_deserializer(actor_system& ctx, const void* first, const void* last);
binary_deserializer(execution_unit* ctx, const void* first, const void* last);
template <class C, class T>
binary_deserializer(C&& ctx, const T& xs)
: binary_deserializer(std::forward<C>(ctx), xs.data(), xs.size()) {
// nop
}
/// Replaces the current read buffer.
void set_rdbuf(const void* buf, size_t buf_size);
......
......@@ -23,6 +23,7 @@
#include <utility>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <functional>
#include <type_traits>
......@@ -30,7 +31,6 @@
#include "caf/serializer.hpp"
#include "caf/primitive_variant.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/type_traits.hpp"
namespace caf {
......@@ -39,9 +39,31 @@ namespace caf {
class binary_serializer : public serializer {
public:
/// Creates a binary serializer writing to given iterator position.
template <class Out>
binary_serializer(execution_unit* ctx, Out iter) : serializer(ctx) {
reset(iter);
template <class C,
class Out,
class E =
typename std::enable_if<
std::is_same<
typename std::iterator_traits<Out>::iterator_category,
std::output_iterator_tag
>::value
|| std::is_same<
typename std::iterator_traits<Out>::iterator_category,
std::random_access_iterator_tag
>::value
>::type>
binary_serializer(C&& ctx, Out it) : serializer(std::forward<C>(ctx)) {
reset_iter(it);
}
template <class C,
class T,
class E =
typename std::enable_if<
detail::has_char_insert<T>::value
>::type>
binary_serializer(C&& ctx, T& out) : serializer(std::forward<C>(ctx)) {
reset_container(out);
}
using write_fun = std::function<void(const char*, size_t)>;
......@@ -59,7 +81,7 @@ public:
void apply_builtin(builtin in_out_type, void* in_out) override;
template <class OutIter>
void reset(OutIter iter) {
void reset_iter(OutIter iter) {
struct fun {
fun(OutIter pos) : pos_(pos) {
// nop
......@@ -72,6 +94,21 @@ public:
out_ = fun{iter};
}
template <class T>
void reset_container(T& x) {
struct fun {
fun(T& container) : x_(container) {
// nop
}
void operator()(const char* first, size_t num_bytes) {
auto last = first + num_bytes;
x_.insert(x_.end(), first, last);
}
T& x_;
};
out_ = fun{x};
}
private:
write_fun out_;
};
......
......@@ -40,6 +40,8 @@ public:
using is_loading = std::true_type;
explicit deserializer(actor_system& sys);
explicit deserializer(execution_unit* ctx);
};
......
......@@ -187,6 +187,32 @@ public:
static constexpr bool value = std::is_same<bool, result_type>::value;
};
/// Checks wheter `T x` allows `x.insert(x.end(), first, last)` where
/// both `first` and `last` have type `const char*`.
template <class T>
class has_char_insert {
template <class C>
static bool sfinae_fun(C* cc,
const char* first = nullptr,
const char* last = nullptr,
decltype(cc->insert(cc->end(), first, last))* = 0) {
return true;
}
// SFNINAE default
static void sfinae_fun(const void*) {
// nop
}
using decayed = typename std::decay<T>::type;
using result_type = decltype(sfinae_fun(static_cast<decayed*>(nullptr)));
public:
static constexpr bool value = is_primitive<T>::value == false &&
std::is_same<bool, result_type>::value;
};
/// Checks wheter `T` has `begin()` and `end()` member
/// functions returning forward iterators.
template <class T>
......
......@@ -229,7 +229,7 @@ public:
>::type...>;
token tk;
check_typed_input(dest, tk);
delayed_send_impl(message_id::make(), actor_cast<abstract_channel*>(dest),
delayed_send_impl(message_id::make(), actor_cast<channel>(dest),
rtime, make_message(std::forward<Ts>(xs)...));
}
......
......@@ -39,6 +39,8 @@ public:
using is_loading = std::false_type;
explicit serializer(actor_system& sys);
explicit serializer(execution_unit* ctx);
virtual ~serializer();
......
......@@ -55,7 +55,8 @@ actor_system::actor_system(actor_system_config&& cfg)
logger_(*this),
registry_(*this),
groups_(*this),
middleman_(nullptr) {
middleman_(nullptr),
dummy_execution_unit_(this) {
CAF_SET_LOGGER_SYS(this);
for (auto& f : cfg.module_factories_) {
auto ptr = f(*this);
......@@ -174,6 +175,10 @@ io::middleman& actor_system::middleman() {
return *middleman_;
}
scoped_execution_unit* actor_system::dummy_execution_unit() {
return &dummy_execution_unit_;
}
actor_id actor_system::next_actor_id() {
return ++ids_;
}
......
......@@ -73,11 +73,22 @@ void apply_float(binary_deserializer& bd, T& x) {
} // namespace <anonmyous>
binary_deserializer::binary_deserializer(execution_unit* ctx,
binary_deserializer::binary_deserializer(actor_system& sys,
const void* buf, size_t buf_size)
: deserializer(ctx),
pos_(buf),
end_(advanced(buf, buf_size)) {
: binary_deserializer(sys, buf, advanced(buf, buf_size)) {
// nop
}
binary_deserializer::binary_deserializer(execution_unit* ctx,
const void* buf,
size_t buf_size)
: binary_deserializer(ctx, buf, advanced(buf, buf_size)) {
// nop
}
binary_deserializer::binary_deserializer(actor_system& sys,
const void* first, const void* last)
: binary_deserializer(sys.dummy_execution_unit(), first, last) {
// nop
}
......
......@@ -17,9 +17,11 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/binary_serializer.hpp"
#include <limits>
#include "caf/binary_serializer.hpp"
#include "caf/detail/ieee_754.hpp"
#include "caf/detail/network_order.hpp"
namespace caf {
......
......@@ -19,9 +19,15 @@
#include "caf/deserializer.hpp"
#include "caf/actor_system.hpp"
namespace caf {
deserializer::deserializer(execution_unit* ctx) : super(ctx) {
deserializer::deserializer(actor_system& x) : super(x.dummy_execution_unit()) {
// nop
}
deserializer::deserializer(execution_unit* x) : super(x) {
// nop
}
......
......@@ -19,8 +19,14 @@
#include "caf/serializer.hpp"
#include "caf/actor_system.hpp"
namespace caf {
serializer::serializer(actor_system& sys) : super(sys.dummy_execution_unit()) {
// nop
}
serializer::serializer(execution_unit* ctx) : super(ctx) {
// nop
}
......
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