Commit 5b4652e2 authored by Dominik Charousset's avatar Dominik Charousset

Move type_nr to namespace caf

parent 1e828b18
// showcases how to add custom POD message types to CAF
// Showcases how to add custom POD message types.
// This file is referenced in the manual, do not modify without updating refs!
// ConfiguringActorApplications: 23-26, 29-33, 87-90, 93-96
#include <tuple>
#include <string>
......@@ -16,17 +19,17 @@ using std::vector;
using namespace caf;
// POD struct
// POD struct foo
struct foo {
std::vector<int> a;
int b;
};
// foo needs to be serializable
template <class T>
void serialize(T& in_or_out, foo& x, const unsigned int) {
in_or_out & x.a;
in_or_out & x.b;
template <class Processor>
void serialize(Processor& proc, foo& x, const unsigned int) {
proc & x.a;
proc & x.b;
}
// also, CAF gives us `deep_to_string` for implementing `to_string` easily
......@@ -48,10 +51,10 @@ struct foo2 {
};
// foo2 also needs to be serializable
template <class T>
void serialize(T& in_or_out, foo2& x, const unsigned int) {
in_or_out & x.a;
in_or_out & x.b; // traversed automatically and recursively
template <class Processor>
void serialize(Processor& proc, foo2& x, const unsigned int) {
proc & x.a;
proc & x.b; // traversed automatically and recursively
}
// `deep_to_string` also traverses nested containers
......
// showcases how to add custom message types to CAF
// if no friend access for serialization is possible
// Showcases how to add custom message types to CAF
// if no friend access for serialization is possible.
// This file is referenced in the manual, do not modify without updating refs!
// ConfiguringActorApplications: 57-59, 64-66
#include <utility>
#include <iostream>
......
......@@ -58,7 +58,7 @@ using rtti_pair_vec_triple = std::tuple<rtti_pair_vec,
template <class T>
struct mpi_field_access {
std::string operator()(const uniform_type_info_map& types) {
auto nr = detail::type_nr<T>::value;
auto nr = type_nr<T>::value;
if (nr != 0)
return *types.portable_name(nr, nullptr);
auto ptr = types.portable_name(0, &typeid(T));
......
......@@ -17,6 +17,9 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
// This file is referenced in the manual, do not modify without updating refs!
// ConfiguringActorApplications: 36-40
#ifndef CAF_ALLOWED_UNSAFE_MESSAGE_TYPE_HPP
#define CAF_ALLOWED_UNSAFE_MESSAGE_TYPE_HPP
......
......@@ -27,7 +27,7 @@
#include "caf/atom.hpp"
#include "caf/message.hpp"
#include "caf/detail/type_nr.hpp"
#include "caf/type_nr.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/pseudo_tuple.hpp"
......@@ -47,7 +47,7 @@ bool match_element(const meta_element&, const type_erased_tuple*,
bool match_atom_constant(const meta_element&, const type_erased_tuple*,
size_t, void**);
template <class T, uint16_t TN = detail::type_nr<T>::value>
template <class T, uint16_t TN = type_nr<T>::value>
struct meta_element_factory {
static meta_element create() {
return {static_cast<atom_value>(0), TN, nullptr, match_element};
......@@ -64,7 +64,7 @@ struct meta_element_factory<T, 0> {
template <atom_value V>
struct meta_element_factory<atom_constant<V>, type_nr<atom_value>::value> {
static meta_element create() {
return {V, detail::type_nr<atom_value>::value,
return {V, type_nr<atom_value>::value,
nullptr, match_atom_constant};
}
};
......
......@@ -27,7 +27,7 @@
#include "caf/deserializer.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/detail/type_nr.hpp"
#include "caf/type_nr.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/detail/message_data.hpp"
......@@ -115,7 +115,7 @@ struct tup_ptr_access<Pos, Max, false> {
}
};
template <class T, uint16_t N = detail::type_nr<T>::value>
template <class T, uint16_t N = type_nr<T>::value>
struct tuple_vals_type_helper {
static typename message_data::rtti_pair get() {
return {N, nullptr};
......
......@@ -33,7 +33,7 @@
#include "caf/abstract_actor.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/detail/type_nr.hpp"
#include "caf/type_nr.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/shared_spinlock.hpp"
#include "caf/detail/single_reader_queue.hpp"
......
......@@ -179,7 +179,7 @@ public:
trivial_match_case& operator=(const trivial_match_case&) = default;
trivial_match_case(F f)
: match_case(detail::make_type_token_from_list<pattern>()),
: match_case(make_type_token_from_list<pattern>()),
fun_(std::move(f)) {
// nop
}
......
......@@ -107,14 +107,14 @@ public:
/// Returns the value at position `p` as const reference of type `T`.
template <class T>
const T& get_as(size_t p) const {
CAF_ASSERT(match_element(p, detail::type_nr<T>::value, &typeid(T)));
CAF_ASSERT(match_element(p, type_nr<T>::value, &typeid(T)));
return *reinterpret_cast<const T*>(at(p));
}
/// Returns the value at position `p` as mutable reference of type `T`.
template <class T>
T& get_as_mutable(size_t p) {
CAF_ASSERT(match_element(p, detail::type_nr<T>::value, &typeid(T)));
CAF_ASSERT(match_element(p, type_nr<T>::value, &typeid(T)));
return *reinterpret_cast<T*>(get_mutable(p));
}
......@@ -197,7 +197,7 @@ public:
/// storing its matched argument in `dest`.
template <class T>
cli_arg(typename std::enable_if<
detail::type_nr<T>::value != 0,
type_nr<T>::value != 0,
std::string
>::type name,
std::string text, T& dest);
......@@ -258,10 +258,10 @@ public:
template <class T>
bool match_element(size_t p) const {
const std::type_info* rtti = nullptr;
if (detail::type_nr<T>::value == 0) {
if (type_nr<T>::value == 0) {
rtti = &typeid(T);
}
return match_element(p, detail::type_nr<T>::value, rtti);
return match_element(p, type_nr<T>::value, rtti);
}
/// Queries whether the types of this message are `Ts...`.
......@@ -444,7 +444,7 @@ inline message make_message() {
template <class T>
message::cli_arg::cli_arg(typename std::enable_if<
detail::type_nr<T>::value != 0,
type_nr<T>::value != 0,
std::string
>::type
nstr, std::string tstr, T& arg)
......
......@@ -26,10 +26,9 @@
#include <typeinfo>
#include "caf/fwd.hpp"
#include "caf/type_nr.hpp"
#include "caf/type_erased_value.hpp"
#include "caf/detail/type_nr.hpp"
namespace caf {
/// Represents a tuple of type-erased values.
......@@ -85,6 +84,8 @@ public:
// -- observers --------------------------------------------------------------
bool empty() const;
/// Returns a string representation of the tuple.
std::string stringify() const;
......@@ -165,7 +166,7 @@ public:
}
uint32_t type_token() const override {
return detail::make_type_token<Ts...>();
return make_type_token<Ts...>();
}
rtti_pair type(size_t pos) const override {
......
......@@ -25,9 +25,9 @@
#include <functional>
#include "caf/fwd.hpp"
#include "caf/type_nr.hpp"
#include "caf/deep_to_string.hpp"
#include "caf/detail/type_nr.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/detail/try_serialize.hpp"
......@@ -154,7 +154,7 @@ public:
// -- overridden observers ---------------------------------------------------
rtti_pair type() const override {
auto nr = detail::type_nr<T>::value;
auto nr = caf::type_nr<T>::value;
return {nr, &typeid(T)};
}
......
......@@ -17,8 +17,8 @@
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_DETAIL_TYPE_NR_HPP
#define CAF_DETAIL_TYPE_NR_HPP
#ifndef CAF_TYPE_NR_HPP
#define CAF_TYPE_NR_HPP
#include <map>
#include <set>
......@@ -32,89 +32,89 @@
#include "caf/detail/type_list.hpp"
namespace caf {
namespace detail {
using strmap = std::map<std::string, std::string>;
// WARNING: types are sorted by uniform name
/// Compile-time list of all built-in types.
/// @warning Types are sorted by uniform name.
using sorted_builtin_types =
type_list<
actor, // @actor
std::vector<actor>, // @actorvec
actor_addr, // @addr
std::vector<actor_addr>, // @addrvec
atom_value, // @atom
std::vector<char>, // @charbuf
down_msg, // @down
duration, // @duration
error, // @error
exit_msg, // @exit
group, // @group
group_down_msg, // @group_down
int16_t, // @i16
int32_t, // @i32
int64_t, // @i64
int8_t, // @i8
long double, // @ldouble
message, // @message
message_id, // @message_id
node_id, // @node
std::string, // @str
strmap, // @strmap
strong_actor_ptr, // @strong_actor_ptr
std::set<std::string>, // @strset
std::vector<std::string>, // @strvec
sync_timeout_msg, // @sync_timeout_msg
timeout_msg, // @timeout
uint16_t, // @u16
std::u16string, // @u16_str
uint32_t, // @u32
std::u32string, // @u32_str
uint64_t, // @u64
uint8_t, // @u8
unit_t, // @unit
weak_actor_ptr, // @weak_actor_ptr
bool, // bool
double, // double
float // float
detail::type_list<
actor, // @actor
std::vector<actor>, // @actorvec
actor_addr, // @addr
std::vector<actor_addr>, // @addrvec
atom_value, // @atom
std::vector<char>, // @charbuf
down_msg, // @down
duration, // @duration
error, // @error
exit_msg, // @exit
group, // @group
group_down_msg, // @group_down
int16_t, // @i16
int32_t, // @i32
int64_t, // @i64
int8_t, // @i8
long double, // @ldouble
message, // @message
message_id, // @message_id
node_id, // @node
std::string, // @str
std::map<std::string, std::string>, // @strmap
strong_actor_ptr, // @strong_actor_ptr
std::set<std::string>, // @strset
std::vector<std::string>, // @strvec
sync_timeout_msg, // @sync_timeout_msg
timeout_msg, // @timeout
uint16_t, // @u16
std::u16string, // @u16_str
uint32_t, // @u32
std::u32string, // @u32_str
uint64_t, // @u64
uint8_t, // @u8
unit_t, // @unit
weak_actor_ptr, // @weak_actor_ptr
bool, // bool
double, // double
float // float
>;
/// Compile-time list of integer types types.
using int_types_by_size =
type_list< // bytes
void, // 0
type_pair<int8_t, uint8_t>, // 1
type_pair<int16_t, uint16_t>, // 2
void, // 3
type_pair<int32_t, uint32_t>, // 4
void, // 5
void, // 6
void, // 7
type_pair<int64_t, uint64_t> // 8
detail::type_list< // bytes
void, // 0
detail::type_pair<int8_t, uint8_t>, // 1
detail::type_pair<int16_t, uint16_t>, // 2
void, // 3
detail::type_pair<int32_t, uint32_t>, // 4
void, // 5
void, // 6
void, // 7
detail::type_pair<int64_t, uint64_t> // 8
>;
/// Computes the type number for `T`.
template <class T, bool IsIntegral = std::is_integral<T>::value>
struct type_nr {
static constexpr uint16_t value =
static_cast<uint16_t>(tl_index_of<sorted_builtin_types, T>::value + 1);
static constexpr uint16_t value = static_cast<uint16_t>(
detail::tl_index_of<sorted_builtin_types, T>::value + 1);
};
template <class T>
struct type_nr<T, true> {
using tpair = typename tl_at<int_types_by_size, sizeof(T)>::type;
using tpair = typename detail::tl_at<int_types_by_size, sizeof(T)>::type;
using type =
typename std::conditional<
std::is_signed<T>::value,
typename tpair::first,
typename tpair::second
>::type;
static constexpr uint16_t value =
static_cast<uint16_t>(tl_index_of<sorted_builtin_types, type>::value + 1);
static constexpr uint16_t value = static_cast<uint16_t>(
detail::tl_index_of<sorted_builtin_types, type>::value + 1);
};
template <>
struct type_nr<bool, true> {
static constexpr uint16_t value =
static_cast<uint16_t>(tl_index_of<sorted_builtin_types, bool>::value + 1);
static constexpr uint16_t value = static_cast<uint16_t>(
detail::tl_index_of<sorted_builtin_types, bool>::value + 1);
};
template <atom_value V>
......@@ -122,8 +122,11 @@ struct type_nr<atom_constant<V>, false> {
static constexpr uint16_t value = type_nr<atom_value>::value;
};
static constexpr size_t type_nrs = tl_size<sorted_builtin_types>::value + 1;
/// The number of built-in types.
static constexpr size_t type_nrs = detail::tl_size<sorted_builtin_types>::value
+ 1;
/// List of all type names, indexed via `type_nr`.
extern const char* numbered_type_names[];
template <uint32_t R, uint16_t... Is>
......@@ -152,7 +155,7 @@ template <class T>
struct make_type_token_from_list_helper;
template <class... Ts>
struct make_type_token_from_list_helper<type_list<Ts...>>
struct make_type_token_from_list_helper<detail::type_list<Ts...>>
: type_token_helper<0xFFFFFFFF, type_nr<Ts>::value...> {
// nop
};
......@@ -162,7 +165,6 @@ constexpr uint32_t make_type_token_from_list() {
return make_type_token_from_list_helper<T>::value;
}
} // namespace detail
} // namespace caf
#endif // CAF_DETAIL_TYPE_NR_HPP
#endif // CAF_TYPE_NR_HPP
......@@ -39,7 +39,7 @@
#include "caf/system_messages.hpp"
#include "caf/type_erased_value.hpp"
#include "caf/detail/type_nr.hpp"
#include "caf/type_nr.hpp"
#include "caf/detail/type_list.hpp"
#include "caf/detail/shared_spinlock.hpp"
......@@ -103,14 +103,14 @@ private:
actor_system& system_;
// message types
std::array<value_factory_kvp, detail::type_nrs - 1> builtin_;
std::array<value_factory_kvp, type_nrs - 1> builtin_;
value_factories_by_name custom_by_name_;
value_factories_by_rtti custom_by_rtti_;
value_factories_by_name ad_hoc_;
mutable detail::shared_spinlock ad_hoc_mtx_;
// message type names
std::array<std::string, detail::type_nrs - 1> builtin_names_;
std::array<std::string, type_nrs - 1> builtin_names_;
portable_names custom_names_;
// actor types
......
......@@ -308,7 +308,7 @@ local_actor::msg_type local_actor::filter_msg(mailbox_element& node) {
if (mid.is_response())
return msg_type::response;
switch (msg.type_token()) {
case detail::make_type_token<atom_value, atom_value, std::string>():
case make_type_token<atom_value, atom_value, std::string>():
if (msg.get_as<atom_value>(0) == sys_atom::value
&& msg.get_as<atom_value>(1) == get_atom::value) {
auto& what = msg.get_as<std::string>(2);
......@@ -328,14 +328,14 @@ local_actor::msg_type local_actor::filter_msg(mailbox_element& node) {
return msg_type::sys_message;
}
return msg_type::ordinary;
case detail::make_type_token<timeout_msg>(): {
case make_type_token<timeout_msg>(): {
auto& tm = msg.get_as<timeout_msg>(0);
auto tid = tm.timeout_id;
CAF_ASSERT(! mid.valid());
return is_active_timeout(tid) ? msg_type::timeout
: msg_type::expired_timeout;
}
case detail::make_type_token<exit_msg>(): {
case make_type_token<exit_msg>(): {
auto& em = msg.get_as_mutable<exit_msg>(0);
// make sure to get rid of attachables if they're no longer needed
unlink_from(em.source);
......@@ -346,12 +346,12 @@ local_actor::msg_type local_actor::filter_msg(mailbox_element& node) {
exit_handler_(this, em);
return msg_type::sys_message;
}
case detail::make_type_token<down_msg>(): {
case make_type_token<down_msg>(): {
auto& dm = msg.get_as_mutable<down_msg>(0);
down_handler_(this, dm);
return msg_type::sys_message;
}
case detail::make_type_token<error>(): {
case make_type_token<error>(): {
auto& err = msg.get_as_mutable<error>(0);
error_handler_(this, err);
return msg_type::sys_message;
......@@ -447,13 +447,13 @@ void local_actor::handle_response(mailbox_element_ptr& ptr,
error_handler_(this, err);
}
};
if (msg.type_token() == detail::make_type_token<sync_timeout_msg>()) {
if (msg.type_token() == make_type_token<sync_timeout_msg>()) {
// TODO: check if condition can ever be true
if (ref_fun.timeout().valid())
ref_fun.handle_timeout();
invoke_error(sec::request_timeout);
} else if (ref_fun(visitor, msg) == match_case::no_match) {
if (msg.type_token() == detail::make_type_token<error>()) {
if (msg.type_token() == make_type_token<error>()) {
error_handler_(this, msg.get_as_mutable<error>(0));
} else {
// wrap unhandled message into an error object and try invoke again
......
......@@ -35,8 +35,8 @@ bool match_element(const meta_element& me, const type_erased_tuple* xs,
bool match_atom_constant(const meta_element& me, const type_erased_tuple* xs,
size_t pos, void** storage) {
CAF_ASSERT(me.typenr == detail::type_nr<atom_value>::value);
if (! xs->matches(pos, detail::type_nr<atom_value>::value, nullptr))
CAF_ASSERT(me.typenr == type_nr<atom_value>::value);
if (! xs->matches(pos, type_nr<atom_value>::value, nullptr))
return false;
auto ptr = xs->get(pos);
if (me.v != *reinterpret_cast<const atom_value*>(ptr))
......
......@@ -34,6 +34,10 @@ void type_erased_tuple::load(deserializer& source) {
load(i, source);
}
bool type_erased_tuple::empty() const {
return size() == 0;
}
std::string type_erased_tuple::stringify() const {
if (size() == 0)
return "()";
......
......@@ -43,15 +43,13 @@
#include "caf/proxy_registry.hpp"
#include "caf/message_builder.hpp"
#include "caf/detail/type_nr.hpp"
#include "caf/type_nr.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/detail/scope_guard.hpp"
#include "caf/detail/shared_spinlock.hpp"
namespace caf {
namespace detail {
const char* numbered_type_names[] = {
"@actor",
"@actorvec",
......@@ -93,12 +91,10 @@ const char* numbered_type_names[] = {
"float"
};
} // namespace detail
namespace {
using builtins = std::array<uniform_type_info_map::value_factory_kvp,
detail::type_nrs - 1>;
type_nrs - 1>;
void fill_builtins(builtins&, detail::type_list<>, size_t) {
// end of recursion
......@@ -108,7 +104,7 @@ template <class List>
void fill_builtins(builtins& arr, List, size_t pos) {
using type = typename detail::tl_head<List>::type;
typename detail::tl_tail<List>::type next;
arr[pos].first = detail::numbered_type_names[pos];
arr[pos].first = numbered_type_names[pos];
arr[pos].second = &make_type_erased_value<type>;
fill_builtins(arr, next, pos + 1);
}
......@@ -175,10 +171,10 @@ actor_factory_result uniform_type_info_map::make_actor(const std::string& name,
}
uniform_type_info_map::uniform_type_info_map(actor_system& sys) : system_(sys) {
detail::sorted_builtin_types list;
sorted_builtin_types list;
fill_builtins(builtin_, list, 0);
for (size_t i = 0; i < builtin_names_.size(); ++i)
builtin_names_[i] = detail::numbered_type_names[i];
builtin_names_[i] = numbered_type_names[i];
}
} // namespace caf
......@@ -150,7 +150,7 @@ CAF_TEST(extract_opts) {
CAF_TEST(type_token) {
auto m1 = make_message(get_atom::value);
CAF_CHECK_EQUAL(m1.type_token(), detail::make_type_token<get_atom>());
CAF_CHECK_EQUAL(m1.type_token(), make_type_token<get_atom>());
}
CAF_TEST(concat) {
......
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