Commit 34d6c318 authored by Dominik Charousset's avatar Dominik Charousset

Merge branch 'topic/concatenated_msg' into develop

parents 943f51c8 53da8708
......@@ -36,6 +36,7 @@ set (LIBCAF_CORE_SRCS
src/binary_serializer.cpp
src/blocking_actor.cpp
src/channel.cpp
src/concatenated_tuple.cpp
src/continue_helper.cpp
src/decorated_tuple.cpp
src/default_attachable.cpp
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* 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_DETAIL_CONCATENATED_TUPLE_HPP
#define CAF_DETAIL_CONCATENATED_TUPLE_HPP
#include <vector>
#include <algorithm>
#include "caf/detail/decorated_tuple.hpp"
namespace caf {
namespace detail {
class concatenated_tuple : public message_data {
public:
concatenated_tuple& operator=(const concatenated_tuple&) = delete;
using pointer = message_data::ptr;
using vector_type = std::vector<pointer>;
static pointer make(std::initializer_list<pointer> xs);
void* mutable_at(size_t pos) override;
size_t size() const override;
concatenated_tuple* copy() const override;
const void* at(size_t pos) const override;
bool match_element(size_t pos, uint16_t typenr,
const std::type_info* rtti) const override;
uint32_t type_token() const override;
const char* uniform_name_at(size_t pos) const override;
uint16_t type_nr_at(size_t pos) const override;
concatenated_tuple() = default;
private:
concatenated_tuple(const concatenated_tuple&) = default;
std::pair<message_data*, size_t> select(size_t pos) const;
void init();
vector_type m_data;
uint32_t m_type_token;
size_t m_size;
};
} // namespace detail
} // namespace caf
#endif // CAF_DETAIL_CONCATENATED_TUPLE_HPP
......@@ -143,6 +143,10 @@ constexpr uint32_t make_type_token() {
return type_token_helper<0xFFFFFFFF, type_nr<Ts>::value...>::value;
}
constexpr uint32_t add_to_type_token(uint32_t token, uint16_t tnr) {
return (token << 6) | tnr;
}
template <class T>
struct make_type_token_from_list_helper;
......
......@@ -39,7 +39,6 @@
#include "caf/detail/implicit_conversions.hpp"
namespace caf {
class message_handler;
/**
......@@ -109,6 +108,14 @@ class message {
*/
message slice(size_t p, size_t n) const;
/**
* Concatinate messages
*/
template <class... Ts>
static message concat(const Ts&... xs) {
return concat_impl({xs.vals()...});
}
/**
* Returns a mutable pointer to the element at position `p`.
*/
......@@ -376,6 +383,8 @@ class message {
message extract_impl(size_t start, message_handler handler) const;
static message concat_impl(std::initializer_list<data_ptr> ptrs);
data_ptr m_vals;
};
......@@ -413,6 +422,13 @@ inline bool operator!=(const message& lhs, const message& rhs) {
return !(lhs == rhs);
}
/**
* @relates message
*/
inline message operator+(const message& lhs, const message& rhs) {
return message::concat(lhs, rhs);
}
/**
* Unboxes atom constants, i.e., converts `atom_constant<V>` to `V`.
* @relates message
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* 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. *
******************************************************************************/
#include "caf/message.hpp"
#include "caf/make_counted.hpp"
#include "caf/detail/concatenated_tuple.hpp"
#include <numeric>
namespace caf {
namespace detail {
auto concatenated_tuple::make(std::initializer_list<pointer> xs) -> pointer {
auto result = make_counted<concatenated_tuple>();
for (auto& x : xs) {
if (x) {
auto dptr = dynamic_cast<const concatenated_tuple*>(x.get());
if (dptr) {
auto& vec = dptr->m_data;
result->m_data.insert(result->m_data.end(), vec.begin(), vec.end());
} else {
result->m_data.push_back(std::move(x));
}
}
}
result->init();
return pointer{std::move(result)};
}
void* concatenated_tuple::mutable_at(size_t pos) {
CAF_REQUIRE(pos < size());
auto selected = select(pos);
return selected.first->mutable_at(selected.second);
}
size_t concatenated_tuple::size() const {
return m_size;
}
concatenated_tuple* concatenated_tuple::copy() const {
return new concatenated_tuple(*this);
}
const void* concatenated_tuple::at(size_t pos) const {
CAF_REQUIRE(pos < size());
auto selected = select(pos);
return selected.first->at(selected.second);
}
bool concatenated_tuple::match_element(size_t pos, uint16_t typenr,
const std::type_info* rtti) const {
auto selected = select(pos);
return selected.first->match_element(selected.second, typenr, rtti);
}
uint32_t concatenated_tuple::type_token() const {
return m_type_token;
}
const char* concatenated_tuple::uniform_name_at(size_t pos) const {
CAF_REQUIRE(pos < size());
auto selected = select(pos);
return selected.first->uniform_name_at(selected.second);
}
uint16_t concatenated_tuple::type_nr_at(size_t pos) const {
CAF_REQUIRE(pos < size());
auto selected = select(pos);
return selected.first->type_nr_at(selected.second);
}
std::pair<message_data*, size_t> concatenated_tuple::select(size_t pos) const {
auto idx = pos;
for (auto& m : m_data) {
auto s = m->size();
if (idx >= s) {
idx -= s;
} else {
return {m.get(), idx};
}
}
throw std::out_of_range("out of range: concatenated_tuple::select");
}
void concatenated_tuple::init() {
m_type_token = make_type_token();
for (auto& m : m_data) {
for (size_t i = 0; i < m->size(); ++i) {
m_type_token = add_to_type_token(m_type_token, m->type_nr_at(i));
}
}
auto acc_size = [](size_t tmp, const pointer& val) {
return tmp + val->size();
};
m_size = std::accumulate(m_data.begin(), m_data.end(), size_t{0}, acc_size);
}
} // namespace detail
} // namespace caf
......@@ -26,6 +26,7 @@
#include "caf/detail/singletons.hpp"
#include "caf/detail/decorated_tuple.hpp"
#include "caf/detail/concatenated_tuple.hpp"
namespace caf {
......@@ -294,4 +295,16 @@ message::cli_arg::cli_arg(std::string nstr, std::string tstr,
};
}
message message::concat_impl(std::initializer_list<data_ptr> xs) {
auto not_nullptr = [](const data_ptr& ptr) { return ptr.get() != nullptr; };
switch (std::count_if(xs.begin(), xs.end(), not_nullptr)) {
case 0:
return message{};
case 1:
return message{*std::find_if(xs.begin(), xs.end(), not_nullptr)};
default:
return message{detail::concatenated_tuple::make(xs)};
}
}
} // namespace caf
......@@ -105,6 +105,19 @@ void test_type_token() {
CAF_CHECK_EQUAL(m1.type_token(), detail::make_type_token<get_atom>());
}
void test_concat() {
auto m1 = make_message(get_atom::value);
auto m2 = make_message(uint32_t{1});
auto m3 = message::concat(m1, m2);
CAF_CHECK_EQUAL(to_string(m3), to_string(m1 + m2));
CAF_CHECK_EQUAL(to_string(m3), to_string(make_message(get_atom::value,
uint32_t{1})));
auto m4 = make_message(get_atom::value, uint32_t{1},
get_atom::value, uint32_t{1});
CAF_CHECK_EQUAL(to_string(message::concat(m3, message{}, m1, m2)),
to_string(m4));
}
int main() {
CAF_TEST(message);
test_drop();
......@@ -116,6 +129,7 @@ int main() {
test_extract3();
test_extract_opts();
test_type_token();
test_concat();
shutdown();
return CAF_TEST_RESULT();
}
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