Commit ba8f0cdb authored by Dominik Charousset's avatar Dominik Charousset

Support incremental build of the meta object table

parent e3e1404c
...@@ -30,7 +30,7 @@ namespace caf::detail { ...@@ -30,7 +30,7 @@ namespace caf::detail {
/// pointers. /// pointers.
struct meta_object { struct meta_object {
/// Stores a human-readable representation of the type's name. /// Stores a human-readable representation of the type's name.
const char* type_name; const char* type_name = nullptr;
/// Calls the destructor for given object. /// Calls the destructor for given object.
void (*destroy)(void*) noexcept; void (*destroy)(void*) noexcept;
...@@ -59,13 +59,23 @@ CAF_CORE_EXPORT span<const meta_object> global_meta_objects(); ...@@ -59,13 +59,23 @@ 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(uint16_t id);
/// Clears the array for storing global meta objects. Meant for unit testing /// Clears the array for storing global meta objects.
/// only! /// @warning intended for unit testing only!
CAF_CORE_EXPORT void clear_global_meta_objects(); CAF_CORE_EXPORT void clear_global_meta_objects();
/// Resizes and returns the global storage for all meta objects. Existing /// Resizes and returns the global storage for all meta objects. Existing
/// entries are copied to the new memory region. The new size *must* grow the /// entries are copied to the new memory region. The new size *must* grow the
/// array. /// array.
/// @warning calling this after constructing any ::actor_system is unsafe and
/// 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`.
/// Resizes the global meta object if needed. Aborts the program if the range
/// already contains meta objects.
/// @warning calling this after constructing any ::actor_system is unsafe and
/// causes undefined behavior.
CAF_CORE_EXPORT void set_global_meta_objects(uint16_t first_id,
span<const meta_object> xs);
} // namespace caf::detail } // namespace caf::detail
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "caf/detail/make_meta_object.hpp" #include "caf/detail/make_meta_object.hpp"
#include "caf/detail/meta_object.hpp" #include "caf/detail/meta_object.hpp"
#include "caf/span.hpp"
#include "caf/type_id.hpp" #include "caf/type_id.hpp"
namespace caf::detail { namespace caf::detail {
...@@ -54,22 +55,26 @@ using make_type_id_sequence = ...@@ -54,22 +55,26 @@ using make_type_id_sequence =
namespace caf { namespace caf {
/// @warning calling this after constructing any ::actor_system is unsafe and
/// causes undefined behavior.
template <uint16_t... Is> template <uint16_t... Is>
void init_global_meta_objects_impl(std::integer_sequence<uint16_t, Is...>, void init_global_meta_objects_impl(std::integer_sequence<uint16_t, Is...>,
size_t begin, size_t end) { uint16_t first_id) {
detail::meta_object src[] = { detail::meta_object src[] = {
detail::make_meta_object<type_by_id_t<Is>>(type_name_by_id_v<Is>)..., detail::make_meta_object<type_by_id_t<Is>>(type_name_by_id_v<Is>)...,
}; };
auto dst = detail::resize_global_meta_objects(end); detail::set_global_meta_objects(first_id, make_span(src));
std::copy(src, src + sizeof...(Is), dst.begin() + begin);
} }
/// Initializes the global meta object table with all types in `ProjectIds`.
/// @warning calling this after constructing any ::actor_system is unsafe and
/// causes undefined behavior.
template <class ProjectIds> template <class ProjectIds>
void init_global_meta_objects() { void init_global_meta_objects() {
static constexpr uint16_t begin = ProjectIds::first; static constexpr uint16_t begin = ProjectIds::first;
static constexpr uint16_t end = ProjectIds::last + 1; static constexpr uint16_t end = ProjectIds::last + 1;
init_global_meta_objects_impl(detail::make_type_id_sequence<begin, end>{}, init_global_meta_objects_impl(detail::make_type_id_sequence<begin, end>{},
begin, end); begin);
} }
} // namespace caf } // namespace caf
...@@ -96,7 +96,7 @@ constexpr uint16_t first_custom_type_id = 200; ...@@ -96,7 +96,7 @@ constexpr uint16_t first_custom_type_id = 200;
static constexpr atom_name atom_name##_v = atom_name{}; \ static constexpr atom_name atom_name##_v = atom_name{}; \
template <class Inspector> \ template <class Inspector> \
auto inspect(Inspector& f, atom_name&) { \ auto inspect(Inspector& f, atom_name&) { \
return f(caf::meta::type_name(#atom_namespace #atom_name)); \ return f(caf::meta::type_name(#atom_namespace "::" #atom_name)); \
} \ } \
} \ } \
CAF_ADD_TYPE_ID(project_name, atom_namespace##atom_name) CAF_ADD_TYPE_ID(project_name, atom_namespace##atom_name)
...@@ -114,143 +114,143 @@ constexpr uint16_t first_custom_type_id = 200; ...@@ -114,143 +114,143 @@ constexpr uint16_t first_custom_type_id = 200;
}; \ }; \
} }
CAF_BEGIN_TYPE_ID_BLOCK(caf_core, 0) CAF_BEGIN_TYPE_ID_BLOCK(builtin, 0)
// -- C types // -- C types
CAF_ADD_TYPE_ID(caf_core, bool) CAF_ADD_TYPE_ID(builtin, bool)
CAF_ADD_TYPE_ID(caf_core, double) CAF_ADD_TYPE_ID(builtin, double)
CAF_ADD_TYPE_ID(caf_core, float) CAF_ADD_TYPE_ID(builtin, float)
CAF_ADD_TYPE_ID(caf_core, int16_t) CAF_ADD_TYPE_ID(builtin, int16_t)
CAF_ADD_TYPE_ID(caf_core, int32_t) CAF_ADD_TYPE_ID(builtin, int32_t)
CAF_ADD_TYPE_ID(caf_core, int64_t) CAF_ADD_TYPE_ID(builtin, int64_t)
CAF_ADD_TYPE_ID(caf_core, int8_t) CAF_ADD_TYPE_ID(builtin, int8_t)
CAF_ADD_TYPE_ID(caf_core, long double) CAF_ADD_TYPE_ID(builtin, long double)
CAF_ADD_TYPE_ID(caf_core, uint16_t) CAF_ADD_TYPE_ID(builtin, uint16_t)
CAF_ADD_TYPE_ID(caf_core, uint32_t) CAF_ADD_TYPE_ID(builtin, uint32_t)
CAF_ADD_TYPE_ID(caf_core, uint64_t) CAF_ADD_TYPE_ID(builtin, uint64_t)
CAF_ADD_TYPE_ID(caf_core, uint8_t) CAF_ADD_TYPE_ID(builtin, uint8_t)
// -- STL types // -- STL types
CAF_ADD_TYPE_ID(caf_core, std::string) CAF_ADD_TYPE_ID(builtin, std::string)
CAF_ADD_TYPE_ID(caf_core, std::u16string) CAF_ADD_TYPE_ID(builtin, std::u16string)
CAF_ADD_TYPE_ID(caf_core, std::u32string) CAF_ADD_TYPE_ID(builtin, std::u32string)
CAF_ADD_TYPE_ID(caf_core, std::set<std::string>) CAF_ADD_TYPE_ID(builtin, std::set<std::string>)
// -- CAF types // -- CAF types
CAF_ADD_TYPE_ID(caf_core, caf::actor) CAF_ADD_TYPE_ID(builtin, caf::actor)
CAF_ADD_TYPE_ID(caf_core, caf::actor_addr) CAF_ADD_TYPE_ID(builtin, caf::actor_addr)
CAF_ADD_TYPE_ID(caf_core, caf::byte_buffer) CAF_ADD_TYPE_ID(builtin, caf::byte_buffer)
CAF_ADD_TYPE_ID(caf_core, caf::config_value) CAF_ADD_TYPE_ID(builtin, caf::config_value)
CAF_ADD_TYPE_ID(caf_core, caf::down_msg) CAF_ADD_TYPE_ID(builtin, caf::down_msg)
CAF_ADD_TYPE_ID(caf_core, caf::downstream_msg) CAF_ADD_TYPE_ID(builtin, caf::downstream_msg)
CAF_ADD_TYPE_ID(caf_core, caf::error) CAF_ADD_TYPE_ID(builtin, caf::error)
CAF_ADD_TYPE_ID(caf_core, caf::exit_msg) CAF_ADD_TYPE_ID(builtin, caf::exit_msg)
CAF_ADD_TYPE_ID(caf_core, caf::group) CAF_ADD_TYPE_ID(builtin, caf::group)
CAF_ADD_TYPE_ID(caf_core, caf::group_down_msg) CAF_ADD_TYPE_ID(builtin, caf::group_down_msg)
CAF_ADD_TYPE_ID(caf_core, caf::message) CAF_ADD_TYPE_ID(builtin, caf::message)
CAF_ADD_TYPE_ID(caf_core, caf::message_id) CAF_ADD_TYPE_ID(builtin, caf::message_id)
CAF_ADD_TYPE_ID(caf_core, caf::node_id) CAF_ADD_TYPE_ID(builtin, caf::node_id)
CAF_ADD_TYPE_ID(caf_core, caf::open_stream_msg) CAF_ADD_TYPE_ID(builtin, caf::open_stream_msg)
CAF_ADD_TYPE_ID(caf_core, caf::strong_actor_ptr) CAF_ADD_TYPE_ID(builtin, caf::strong_actor_ptr)
CAF_ADD_TYPE_ID(caf_core, caf::timeout_msg) CAF_ADD_TYPE_ID(builtin, caf::timeout_msg)
CAF_ADD_TYPE_ID(caf_core, caf::timespan) CAF_ADD_TYPE_ID(builtin, caf::timespan)
CAF_ADD_TYPE_ID(caf_core, caf::timestamp) CAF_ADD_TYPE_ID(builtin, caf::timestamp)
CAF_ADD_TYPE_ID(caf_core, caf::unit_t) CAF_ADD_TYPE_ID(builtin, caf::unit_t)
CAF_ADD_TYPE_ID(caf_core, caf::upstream_msg) CAF_ADD_TYPE_ID(builtin, caf::upstream_msg)
CAF_ADD_TYPE_ID(caf_core, caf::weak_actor_ptr) CAF_ADD_TYPE_ID(builtin, caf::weak_actor_ptr)
CAF_ADD_TYPE_ID(caf_core, std::vector<caf::actor>) CAF_ADD_TYPE_ID(builtin, std::vector<caf::actor>)
CAF_ADD_TYPE_ID(caf_core, std::vector<caf::actor_addr>) CAF_ADD_TYPE_ID(builtin, std::vector<caf::actor_addr>)
// -- predefined atoms // -- predefined atoms
CAF_ADD_TYPE_ID(caf_core, add_atom) CAF_ADD_TYPE_ID(builtin, caf::add_atom)
CAF_ADD_TYPE_ID(caf_core, close_atom) CAF_ADD_TYPE_ID(builtin, caf::close_atom)
CAF_ADD_TYPE_ID(caf_core, connect_atom) CAF_ADD_TYPE_ID(builtin, caf::connect_atom)
CAF_ADD_TYPE_ID(caf_core, contact_atom) CAF_ADD_TYPE_ID(builtin, caf::contact_atom)
CAF_ADD_TYPE_ID(caf_core, delete_atom) CAF_ADD_TYPE_ID(builtin, caf::delete_atom)
CAF_ADD_TYPE_ID(caf_core, demonitor_atom) CAF_ADD_TYPE_ID(builtin, caf::demonitor_atom)
CAF_ADD_TYPE_ID(caf_core, div_atom) CAF_ADD_TYPE_ID(builtin, caf::div_atom)
CAF_ADD_TYPE_ID(caf_core, flush_atom) CAF_ADD_TYPE_ID(builtin, caf::flush_atom)
CAF_ADD_TYPE_ID(caf_core, forward_atom) CAF_ADD_TYPE_ID(builtin, caf::forward_atom)
CAF_ADD_TYPE_ID(caf_core, get_atom) CAF_ADD_TYPE_ID(builtin, caf::get_atom)
CAF_ADD_TYPE_ID(caf_core, idle_atom) CAF_ADD_TYPE_ID(builtin, caf::idle_atom)
CAF_ADD_TYPE_ID(caf_core, join_atom) CAF_ADD_TYPE_ID(builtin, caf::join_atom)
CAF_ADD_TYPE_ID(caf_core, leave_atom) CAF_ADD_TYPE_ID(builtin, caf::leave_atom)
CAF_ADD_TYPE_ID(caf_core, link_atom) CAF_ADD_TYPE_ID(builtin, caf::link_atom)
CAF_ADD_TYPE_ID(caf_core, migrate_atom) CAF_ADD_TYPE_ID(builtin, caf::migrate_atom)
CAF_ADD_TYPE_ID(caf_core, monitor_atom) CAF_ADD_TYPE_ID(builtin, caf::monitor_atom)
CAF_ADD_TYPE_ID(caf_core, mul_atom) CAF_ADD_TYPE_ID(builtin, caf::mul_atom)
CAF_ADD_TYPE_ID(caf_core, ok_atom) CAF_ADD_TYPE_ID(builtin, caf::ok_atom)
CAF_ADD_TYPE_ID(caf_core, open_atom) CAF_ADD_TYPE_ID(builtin, caf::open_atom)
CAF_ADD_TYPE_ID(caf_core, pending_atom) CAF_ADD_TYPE_ID(builtin, caf::pending_atom)
CAF_ADD_TYPE_ID(caf_core, ping_atom) CAF_ADD_TYPE_ID(builtin, caf::ping_atom)
CAF_ADD_TYPE_ID(caf_core, pong_atom) CAF_ADD_TYPE_ID(builtin, caf::pong_atom)
CAF_ADD_TYPE_ID(caf_core, publish_atom) CAF_ADD_TYPE_ID(builtin, caf::publish_atom)
CAF_ADD_TYPE_ID(caf_core, publish_udp_atom) CAF_ADD_TYPE_ID(builtin, caf::publish_udp_atom)
CAF_ADD_TYPE_ID(caf_core, put_atom) CAF_ADD_TYPE_ID(builtin, caf::put_atom)
CAF_ADD_TYPE_ID(caf_core, receive_atom) CAF_ADD_TYPE_ID(builtin, caf::receive_atom)
CAF_ADD_TYPE_ID(caf_core, redirect_atom) CAF_ADD_TYPE_ID(builtin, caf::redirect_atom)
CAF_ADD_TYPE_ID(caf_core, reset_atom) CAF_ADD_TYPE_ID(builtin, caf::reset_atom)
CAF_ADD_TYPE_ID(caf_core, resolve_atom) CAF_ADD_TYPE_ID(builtin, caf::resolve_atom)
CAF_ADD_TYPE_ID(caf_core, spawn_atom) CAF_ADD_TYPE_ID(builtin, caf::spawn_atom)
CAF_ADD_TYPE_ID(caf_core, stream_atom) CAF_ADD_TYPE_ID(builtin, caf::stream_atom)
CAF_ADD_TYPE_ID(caf_core, sub_atom) CAF_ADD_TYPE_ID(builtin, caf::sub_atom)
CAF_ADD_TYPE_ID(caf_core, subscribe_atom) CAF_ADD_TYPE_ID(builtin, caf::subscribe_atom)
CAF_ADD_TYPE_ID(caf_core, sys_atom) CAF_ADD_TYPE_ID(builtin, caf::sys_atom)
CAF_ADD_TYPE_ID(caf_core, tick_atom) CAF_ADD_TYPE_ID(builtin, caf::tick_atom)
CAF_ADD_TYPE_ID(caf_core, timeout_atom) CAF_ADD_TYPE_ID(builtin, caf::timeout_atom)
CAF_ADD_TYPE_ID(caf_core, unlink_atom) CAF_ADD_TYPE_ID(builtin, caf::unlink_atom)
CAF_ADD_TYPE_ID(caf_core, unpublish_atom) CAF_ADD_TYPE_ID(builtin, caf::unpublish_atom)
CAF_ADD_TYPE_ID(caf_core, unpublish_udp_atom) CAF_ADD_TYPE_ID(builtin, caf::unpublish_udp_atom)
CAF_ADD_TYPE_ID(caf_core, unsubscribe_atom) CAF_ADD_TYPE_ID(builtin, caf::unsubscribe_atom)
CAF_ADD_TYPE_ID(caf_core, update_atom) CAF_ADD_TYPE_ID(builtin, caf::update_atom)
CAF_ADD_TYPE_ID(caf_core, wait_for_atom) CAF_ADD_TYPE_ID(builtin, caf::wait_for_atom)
// TODO: remove atoms from type_nr.hpp and uncomment this block // TODO: remove atoms from type_nr.hpp and uncomment this block
// CAF_ADD_ATOM(caf_core, caf, add_atom) // CAF_ADD_ATOM(builtin, caf, add_atom)
// CAF_ADD_ATOM(caf_core, caf, close_atom) // CAF_ADD_ATOM(builtin, caf, close_atom)
// CAF_ADD_ATOM(caf_core, caf, connect_atom) // CAF_ADD_ATOM(builtin, caf, connect_atom)
// CAF_ADD_ATOM(caf_core, caf, contact_atom) // CAF_ADD_ATOM(builtin, caf, contact_atom)
// CAF_ADD_ATOM(caf_core, caf, delete_atom) // CAF_ADD_ATOM(builtin, caf, delete_atom)
// CAF_ADD_ATOM(caf_core, caf, demonitor_atom) // CAF_ADD_ATOM(builtin, caf, demonitor_atom)
// CAF_ADD_ATOM(caf_core, caf, div_atom) // CAF_ADD_ATOM(builtin, caf, div_atom)
// CAF_ADD_ATOM(caf_core, caf, flush_atom) // CAF_ADD_ATOM(builtin, caf, flush_atom)
// CAF_ADD_ATOM(caf_core, caf, forward_atom) // CAF_ADD_ATOM(builtin, caf, forward_atom)
// CAF_ADD_ATOM(caf_core, caf, get_atom) // CAF_ADD_ATOM(builtin, caf, get_atom)
// CAF_ADD_ATOM(caf_core, caf, idle_atom) // CAF_ADD_ATOM(builtin, caf, idle_atom)
// CAF_ADD_ATOM(caf_core, caf, join_atom) // CAF_ADD_ATOM(builtin, caf, join_atom)
// CAF_ADD_ATOM(caf_core, caf, leave_atom) // CAF_ADD_ATOM(builtin, caf, leave_atom)
// CAF_ADD_ATOM(caf_core, caf, link_atom) // CAF_ADD_ATOM(builtin, caf, link_atom)
// CAF_ADD_ATOM(caf_core, caf, migrate_atom) // CAF_ADD_ATOM(builtin, caf, migrate_atom)
// CAF_ADD_ATOM(caf_core, caf, monitor_atom) // CAF_ADD_ATOM(builtin, caf, monitor_atom)
// CAF_ADD_ATOM(caf_core, caf, mul_atom) // CAF_ADD_ATOM(builtin, caf, mul_atom)
// CAF_ADD_ATOM(caf_core, caf, ok_atom) // CAF_ADD_ATOM(builtin, caf, ok_atom)
// CAF_ADD_ATOM(caf_core, caf, open_atom) // CAF_ADD_ATOM(builtin, caf, open_atom)
// CAF_ADD_ATOM(caf_core, caf, pending_atom) // CAF_ADD_ATOM(builtin, caf, pending_atom)
// CAF_ADD_ATOM(caf_core, caf, ping_atom) // CAF_ADD_ATOM(builtin, caf, ping_atom)
// CAF_ADD_ATOM(caf_core, caf, pong_atom) // CAF_ADD_ATOM(builtin, caf, pong_atom)
// CAF_ADD_ATOM(caf_core, caf, publish_atom) // CAF_ADD_ATOM(builtin, caf, publish_atom)
// CAF_ADD_ATOM(caf_core, caf, publish_udp_atom) // CAF_ADD_ATOM(builtin, caf, publish_udp_atom)
// CAF_ADD_ATOM(caf_core, caf, put_atom) // CAF_ADD_ATOM(builtin, caf, put_atom)
// CAF_ADD_ATOM(caf_core, caf, receive_atom) // CAF_ADD_ATOM(builtin, caf, receive_atom)
// CAF_ADD_ATOM(caf_core, caf, redirect_atom) // CAF_ADD_ATOM(builtin, caf, redirect_atom)
// CAF_ADD_ATOM(caf_core, caf, reset_atom) // CAF_ADD_ATOM(builtin, caf, reset_atom)
// CAF_ADD_ATOM(caf_core, caf, resolve_atom) // CAF_ADD_ATOM(builtin, caf, resolve_atom)
// CAF_ADD_ATOM(caf_core, caf, spawn_atom) // CAF_ADD_ATOM(builtin, caf, spawn_atom)
// CAF_ADD_ATOM(caf_core, caf, stream_atom) // CAF_ADD_ATOM(builtin, caf, stream_atom)
// CAF_ADD_ATOM(caf_core, caf, sub_atom) // CAF_ADD_ATOM(builtin, caf, sub_atom)
// CAF_ADD_ATOM(caf_core, caf, subscribe_atom) // CAF_ADD_ATOM(builtin, caf, subscribe_atom)
// CAF_ADD_ATOM(caf_core, caf, sys_atom) // CAF_ADD_ATOM(builtin, caf, sys_atom)
// CAF_ADD_ATOM(caf_core, caf, tick_atom) // CAF_ADD_ATOM(builtin, caf, tick_atom)
// CAF_ADD_ATOM(caf_core, caf, timeout_atom) // CAF_ADD_ATOM(builtin, caf, timeout_atom)
// CAF_ADD_ATOM(caf_core, caf, unlink_atom) // CAF_ADD_ATOM(builtin, caf, unlink_atom)
// CAF_ADD_ATOM(caf_core, caf, unpublish_atom) // CAF_ADD_ATOM(builtin, caf, unpublish_atom)
// CAF_ADD_ATOM(caf_core, caf, unpublish_udp_atom) // CAF_ADD_ATOM(builtin, caf, unpublish_udp_atom)
// CAF_ADD_ATOM(caf_core, caf, unsubscribe_atom) // CAF_ADD_ATOM(builtin, caf, unsubscribe_atom)
// CAF_ADD_ATOM(caf_core, caf, update_atom) // CAF_ADD_ATOM(builtin, caf, update_atom)
// CAF_ADD_ATOM(caf_core, caf, wait_for_atom) // CAF_ADD_ATOM(builtin, caf, wait_for_atom)
CAF_END_TYPE_ID_BLOCK(caf_core) CAF_END_TYPE_ID_BLOCK(builtin)
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
namespace caf::detail { namespace caf::detail {
#define fatal(str) \
do { \
fprintf(stderr, "FATAL: " str "\n"); \
abort(); \
} while (false)
namespace { namespace {
// Stores global type information. // Stores global type information.
...@@ -62,11 +68,9 @@ void clear_global_meta_objects() { ...@@ -62,11 +68,9 @@ void clear_global_meta_objects() {
} }
span<meta_object> resize_global_meta_objects(size_t size) { span<meta_object> resize_global_meta_objects(size_t size) {
if (size <= meta_objects_size) { if (size <= meta_objects_size)
fprintf(stderr, "resize_global_meta_objects called with a new size that " fatal("resize_global_meta_objects called with a new size that does not "
"does not grow the array\n"); "grow the array");
abort();
}
auto new_storage = new meta_object[size]; auto new_storage = new meta_object[size];
std::copy(meta_objects, meta_objects + meta_objects_size, new_storage); std::copy(meta_objects, meta_objects + meta_objects_size, new_storage);
delete[] meta_objects; delete[] meta_objects;
...@@ -75,4 +79,35 @@ span<meta_object> resize_global_meta_objects(size_t size) { ...@@ -75,4 +79,35 @@ 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) {
auto new_size = first_id + xs.size();
if (first_id < meta_objects_size) {
if (new_size > meta_objects_size)
fatal("set_global_meta_objects called with "
"'first_id < meta_objects_size' and "
"'new_size > meta_objects_size'");
auto out = meta_objects + first_id;
for (const auto& x : xs) {
if (out->type_name == nullptr) {
// We support calling set_global_meta_objects for building the global
// table chunk-by-chunk.
*out = x;
} else if (strcmp(out->type_name, x.type_name) == 0) {
// nop: set_global_meta_objects implements idempotency.
} else {
fprintf(stderr,
"FATAL: type ID %d already assigned to %s (tried to override "
"with %s)\n",
static_cast<int>(std::distance(meta_objects, out)),
out->type_name, x.type_name);
abort();
}
++out;
}
return;
}
auto dst = resize_global_meta_objects(first_id + xs.size());
std::copy(xs.begin(), xs.end(), dst.begin() + first_id);
}
} // namespace caf::detail } // namespace caf::detail
...@@ -172,6 +172,19 @@ CAF_TEST(init_global_meta_objects takes care of creating a meta object table) { ...@@ -172,6 +172,19 @@ CAF_TEST(init_global_meta_objects takes care of creating a meta object table) {
CAF_CHECK_EQUAL(type_name_by_id_v<type_id_v<i64_wrapper>>, "i64_wrapper"s); CAF_CHECK_EQUAL(type_name_by_id_v<type_id_v<i64_wrapper>>, "i64_wrapper"s);
CAF_CHECK_EQUAL(xs[type_id_v<i32_wrapper>].type_name, "i32_wrapper"s); CAF_CHECK_EQUAL(xs[type_id_v<i32_wrapper>].type_name, "i32_wrapper"s);
CAF_CHECK_EQUAL(xs[type_id_v<i64_wrapper>].type_name, "i64_wrapper"s); CAF_CHECK_EQUAL(xs[type_id_v<i64_wrapper>].type_name, "i64_wrapper"s);
CAF_MESSAGE("calling init_global_meta_objects again is a no-op");
init_global_meta_objects<meta_object_suite_type_ids>();
auto ys = global_meta_objects();
auto same = [](const auto& x, const auto& y) {
return x.type_name == y.type_name;
};
CAF_CHECK(std::equal(xs.begin(), xs.end(), ys.begin(), ys.end(), same));
CAF_MESSAGE("init_global_meta_objects can initialize allocated chunks");
CAF_CHECK_EQUAL(global_meta_object(type_id_v<float>).type_name, nullptr);
init_global_meta_objects<builtin_type_ids>();
CAF_MESSAGE("again, calling init_global_meta_objects again is a no-op");
init_global_meta_objects<builtin_type_ids>();
CAF_CHECK_EQUAL(global_meta_object(type_id_v<float>).type_name, "float"s);
} }
CAF_TEST_FIXTURE_SCOPE_END() CAF_TEST_FIXTURE_SCOPE_END()
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