Commit 3640a0d9 authored by Dominik Charousset's avatar Dominik Charousset

Integrate review feedback

parent 9a5dbc12
...@@ -57,7 +57,7 @@ struct meta_object { ...@@ -57,7 +57,7 @@ struct meta_object {
CAF_CORE_EXPORT span<const meta_object> global_meta_objects(); CAF_CORE_EXPORT span<const meta_object> global_meta_objects();
/// Returns the global meta object for given type ID. /// Returns the global meta object for given type ID.
CAF_CORE_EXPORT meta_object& global_meta_object(uint16_t id); CAF_CORE_EXPORT meta_object& global_meta_object(type_id_t id);
/// Clears the array for storing global meta objects. /// Clears the array for storing global meta objects.
/// @warning intended for unit testing only! /// @warning intended for unit testing only!
...@@ -70,12 +70,12 @@ CAF_CORE_EXPORT void clear_global_meta_objects(); ...@@ -70,12 +70,12 @@ CAF_CORE_EXPORT void clear_global_meta_objects();
/// causes undefined behavior. /// causes undefined behavior.
CAF_CORE_EXPORT span<meta_object> resize_global_meta_objects(size_t size); CAF_CORE_EXPORT span<meta_object> resize_global_meta_objects(size_t size);
/// Sets the meta objects in range `(first_id, first_id + xs.size]` to `xs`. /// Sets the meta objects in range `[first_id, first_id + xs.size)` to `xs`.
/// Resizes the global meta object if needed. Aborts the program if the range /// Resizes the global meta object if needed. Aborts the program if the range
/// already contains meta objects. /// already contains meta objects.
/// @warning calling this after constructing any ::actor_system is unsafe and /// @warning calling this after constructing any ::actor_system is unsafe and
/// causes undefined behavior. /// causes undefined behavior.
CAF_CORE_EXPORT void set_global_meta_objects(uint16_t first_id, CAF_CORE_EXPORT void set_global_meta_objects(type_id_t first_id,
span<const meta_object> xs); span<const meta_object> xs);
} // namespace caf::detail } // namespace caf::detail
...@@ -191,6 +191,7 @@ using ip_endpoint = ipv6_endpoint; ...@@ -191,6 +191,7 @@ using ip_endpoint = ipv6_endpoint;
using ip_subnet = ipv6_subnet; using ip_subnet = ipv6_subnet;
using settings = dictionary<config_value>; using settings = dictionary<config_value>;
using stream_slot = uint16_t; using stream_slot = uint16_t;
using type_id_t = uint16_t;
// -- functions ---------------------------------------------------------------- // -- functions ----------------------------------------------------------------
......
...@@ -27,47 +27,53 @@ ...@@ -27,47 +27,53 @@
namespace caf { namespace caf {
/// Maps the type `T` to a globally unique 16-bit ID. /// Internal representation of a type ID.
using type_id_t = uint16_t;
/// Maps the type `T` to a globally unique ID.
template <class T> template <class T>
struct type_id; struct type_id;
/// Convenience alias for `type_id<T>::value`. /// Convenience alias for `type_id<T>::value`.
/// @relates type_id /// @relates type_id
template <class T> template <class T>
constexpr uint16_t type_id_v = type_id<T>::value; constexpr type_id_t type_id_v = type_id<T>::value;
/// Maps the globally unique ID `V` to a type (inverse to ::type_id). /// Maps the globally unique ID `V` to a type (inverse to ::type_id).
/// @relates type_id /// @relates type_id
template <uint16_t V> template <type_id_t V>
struct type_by_id; struct type_by_id;
/// Convenience alias for `type_by_id<I>::type`. /// Convenience alias for `type_by_id<I>::type`.
/// @relates type_by_id /// @relates type_by_id
template <uint16_t I> template <type_id_t I>
using type_by_id_t = typename type_by_id<I>::type; using type_by_id_t = typename type_by_id<I>::type;
/// Maps the globally unique ID `V` to a type name. /// Maps the globally unique ID `V` to a type name.
template <uint16_t V> template <type_id_t V>
struct type_name_by_id; struct type_name_by_id;
/// Convenience alias for `type_name_by_id<I>::value`. /// Convenience alias for `type_name_by_id<I>::value`.
/// @relates type_name_by_id /// @relates type_name_by_id
template <uint16_t I> template <type_id_t I>
constexpr const char* type_name_by_id_v = type_name_by_id<I>::value; constexpr const char* type_name_by_id_v = type_name_by_id<I>::value;
/// The first type ID not reserved by CAF and its modules. /// The first type ID not reserved by CAF and its modules.
constexpr uint16_t first_custom_type_id = 200; constexpr type_id_t first_custom_type_id = 200;
} // namespace caf } // namespace caf
/// Starts a code block for registering custom types to CAF. Stores the first ID /// Starts a code block for registering custom types to CAF. Stores the first ID
/// for the project as `caf::${project_name}_first_type_id`. Unless the project /// for the project as `caf::${project_name}_first_type_id`. Usually, users
/// appends to an ID block of another project, users should use /// should use `caf::first_custom_type_id` as `first_id`. However, this
/// `caf::first_custom_type_id` as `first_id`. /// mechanism also enables modules to append IDs to a block of another module or
/// module. If two modules are developed separately to avoid dependencies, they
/// only need to define sufficiently large offsets to guarantee collision-free
/// IDs (CAF supports gaps in the ID space).
#define CAF_BEGIN_TYPE_ID_BLOCK(project_name, first_id) \ #define CAF_BEGIN_TYPE_ID_BLOCK(project_name, first_id) \
namespace caf { \ namespace caf { \
constexpr uint16_t project_name##_type_id_counter_init = __COUNTER__; \ constexpr type_id_t project_name##_type_id_counter_init = __COUNTER__; \
constexpr uint16_t project_name##_first_type_id = first_id; \ constexpr type_id_t project_name##_first_type_id = first_id; \
} }
/// Assigns the next free type ID to `fully_qualified_name`. /// Assigns the next free type ID to `fully_qualified_name`.
...@@ -75,7 +81,7 @@ constexpr uint16_t first_custom_type_id = 200; ...@@ -75,7 +81,7 @@ constexpr uint16_t first_custom_type_id = 200;
namespace caf { \ namespace caf { \
template <> \ template <> \
struct type_id<fully_qualified_name> { \ struct type_id<fully_qualified_name> { \
static constexpr uint16_t value \ static constexpr type_id_t value \
= project_name##_first_type_id \ = project_name##_first_type_id \
+ (__COUNTER__ - project_name##_type_id_counter_init - 1); \ + (__COUNTER__ - project_name##_type_id_counter_init - 1); \
}; \ }; \
...@@ -105,12 +111,12 @@ constexpr uint16_t first_custom_type_id = 200; ...@@ -105,12 +111,12 @@ constexpr uint16_t first_custom_type_id = 200;
/// type ID used by the project as `caf::${project_name}_last_type_id`. /// type ID used by the project as `caf::${project_name}_last_type_id`.
#define CAF_END_TYPE_ID_BLOCK(project_name) \ #define CAF_END_TYPE_ID_BLOCK(project_name) \
namespace caf { \ namespace caf { \
constexpr uint16_t project_name##_last_type_id \ constexpr type_id_t project_name##_last_type_id \
= project_name##_first_type_id \ = project_name##_first_type_id \
+ (__COUNTER__ - project_name##_type_id_counter_init - 2); \ + (__COUNTER__ - project_name##_type_id_counter_init - 2); \
struct project_name##_type_ids { \ struct project_name##_type_ids { \
static constexpr uint16_t first = project_name##_first_type_id; \ static constexpr type_id_t first = project_name##_first_type_id; \
static constexpr uint16_t last = project_name##_last_type_id; \ static constexpr type_id_t last = project_name##_last_type_id; \
}; \ }; \
} }
......
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
namespace caf { namespace caf {
/// A list of 16-bit type IDs, stored in a size-prefix, contiguous memory block. /// A list of type IDs, stored in a size-prefix, contiguous memory block.
class type_id_list : detail::comparable<type_id_list> { class type_id_list : detail::comparable<type_id_list> {
public: public:
using pointer = const uint16_t*; using pointer = const type_id_t*;
constexpr explicit type_id_list(pointer data) noexcept : data_(data) { constexpr explicit type_id_list(pointer data) noexcept : data_(data) {
// nop // nop
...@@ -42,7 +42,7 @@ public: ...@@ -42,7 +42,7 @@ public:
type_id_list& operator=(const type_id_list&) noexcept = default; type_id_list& operator=(const type_id_list&) noexcept = default;
/// Queries whether this type list contains data, i,e, `data() != nullptr`. /// Queries whether this type list contains data, i.e, `data() != nullptr`.
constexpr operator bool() const noexcept { constexpr operator bool() const noexcept {
return data_ != nullptr; return data_ != nullptr;
} }
...@@ -60,13 +60,13 @@ public: ...@@ -60,13 +60,13 @@ public:
/// Returns the type ID at `index`. /// Returns the type ID at `index`.
/// @pre `data() != nullptr` /// @pre `data() != nullptr`
constexpr uint16_t operator[](size_t index) const noexcept { constexpr type_id_t operator[](size_t index) const noexcept {
return data_[index + 1]; return data_[index + 1];
} }
/// Compares this list to `other`. /// Compares this list to `other`.
int compare(type_id_list other) const noexcept { int compare(type_id_list other) const noexcept {
return memcmp(data_, other.data_, size() * sizeof(uint16_t)); return memcmp(data_, other.data_, size() * sizeof(type_id_t));
} }
private: private:
...@@ -76,8 +76,8 @@ private: ...@@ -76,8 +76,8 @@ private:
/// @private /// @private
template <class... Ts> template <class... Ts>
struct make_type_id_list_helper { struct make_type_id_list_helper {
static constexpr inline uint16_t data[] static constexpr inline type_id_t data[]
= {static_cast<uint16_t>(sizeof...(Ts)), type_id_v<Ts>...}; = {static_cast<type_id_t>(sizeof...(Ts)), type_id_v<Ts>...};
}; };
/// Constructs a ::type_id_list from the template parameter pack `Ts`. /// Constructs a ::type_id_list from the template parameter pack `Ts`.
......
...@@ -55,7 +55,7 @@ span<const meta_object> global_meta_objects() { ...@@ -55,7 +55,7 @@ span<const meta_object> global_meta_objects() {
return {meta_objects, meta_objects_size}; return {meta_objects, meta_objects_size};
} }
meta_object& global_meta_object(uint16_t id) { meta_object& global_meta_object(type_id_t id) {
CAF_ASSERT(id < meta_objects_size); CAF_ASSERT(id < meta_objects_size);
return meta_objects[id]; return meta_objects[id];
} }
...@@ -80,7 +80,7 @@ span<meta_object> resize_global_meta_objects(size_t size) { ...@@ -80,7 +80,7 @@ span<meta_object> resize_global_meta_objects(size_t size) {
return {new_storage, size}; return {new_storage, size};
} }
void set_global_meta_objects(uint16_t first_id, span<const meta_object> xs) { void set_global_meta_objects(type_id_t first_id, span<const meta_object> xs) {
auto new_size = first_id + xs.size(); auto new_size = first_id + xs.size();
if (first_id < meta_objects_size) { if (first_id < meta_objects_size) {
if (new_size > meta_objects_size) if (new_size > meta_objects_size)
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
using namespace caf; using namespace caf;
CAF_TEST(lists store the size at index 0) { CAF_TEST(lists store the size at index 0) {
uint16_t data[] = {3, 1, 2, 4}; type_id_t data[] = {3, 1, 2, 4};
type_id_list xs{data}; type_id_list xs{data};
CAF_CHECK_EQUAL(xs.size(), 3u); CAF_CHECK_EQUAL(xs.size(), 3u);
CAF_CHECK_EQUAL(xs[0], 1u); CAF_CHECK_EQUAL(xs[0], 1u);
...@@ -36,9 +36,9 @@ CAF_TEST(lists store the size at index 0) { ...@@ -36,9 +36,9 @@ CAF_TEST(lists store the size at index 0) {
} }
CAF_TEST(lists are comparable) { CAF_TEST(lists are comparable) {
uint16_t data[] = {3, 1, 2, 4}; type_id_t data[] = {3, 1, 2, 4};
type_id_list xs{data}; type_id_list xs{data};
uint16_t data_copy[] = {3, 1, 2, 4}; type_id_t data_copy[] = {3, 1, 2, 4};
type_id_list ys{data_copy}; type_id_list ys{data_copy};
CAF_CHECK_EQUAL(xs, ys); CAF_CHECK_EQUAL(xs, ys);
data_copy[1] = 10; data_copy[1] = 10;
......
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