Unverified Commit b08139c6 authored by Noir's avatar Noir Committed by GitHub

Merge pull request #1199

Avoid collisions with user types in CAF_ADD_ATOM
parents c089c764 1de110dd
...@@ -88,6 +88,8 @@ is based on [Keep a Changelog](https://keepachangelog.com). ...@@ -88,6 +88,8 @@ is based on [Keep a Changelog](https://keepachangelog.com).
- Fix undefined behavior in the experimental datagram brokers (#1174). - Fix undefined behavior in the experimental datagram brokers (#1174).
- Response promises no longer send empty messages in response to asynchronous - Response promises no longer send empty messages in response to asynchronous
messages. messages.
- `CAF_ADD_TYPE_ID` now works with types that live in namespaces that also exist
as nested namespace in CAF such as `detail` or `io` (#1195).
## [0.18.0-rc.1] - 2020-09-09 ## [0.18.0-rc.1] - 2020-09-09
......
...@@ -131,7 +131,7 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name); ...@@ -131,7 +131,7 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name);
#ifdef CAF_MSVC #ifdef CAF_MSVC
# define CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \ # define CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \
template <> \ template <> \
struct type_id<CAF_PP_EXPAND fully_qualified_name> { \ struct type_id<::CAF_PP_EXPAND fully_qualified_name> { \
static constexpr type_id_t value \ static constexpr type_id_t value \
= id_block::project_name##_first_type_id \ = id_block::project_name##_first_type_id \
+ (CAF_PP_CAT(CAF_PP_COUNTER, ()) \ + (CAF_PP_CAT(CAF_PP_COUNTER, ()) \
...@@ -140,7 +140,7 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name); ...@@ -140,7 +140,7 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name);
#else #else
# define CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \ # define CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \
template <> \ template <> \
struct type_id<CAF_PP_EXPAND fully_qualified_name> { \ struct type_id<::CAF_PP_EXPAND fully_qualified_name> { \
static constexpr type_id_t value \ static constexpr type_id_t value \
= id_block::project_name##_first_type_id \ = id_block::project_name##_first_type_id \
+ (__COUNTER__ - id_block::project_name##_type_id_counter_init - 1); \ + (__COUNTER__ - id_block::project_name##_type_id_counter_init - 1); \
...@@ -151,33 +151,33 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name); ...@@ -151,33 +151,33 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name);
namespace caf { \ namespace caf { \
CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \ CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \
template <> \ template <> \
struct type_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> { \ struct type_by_id<type_id<::CAF_PP_EXPAND fully_qualified_name>::value> { \
using type = CAF_PP_EXPAND fully_qualified_name; \ using type = ::CAF_PP_EXPAND fully_qualified_name; \
}; \ }; \
template <> \ template <> \
struct type_name<CAF_PP_EXPAND fully_qualified_name> { \ struct type_name<::CAF_PP_EXPAND fully_qualified_name> { \
static constexpr string_view value \ static constexpr string_view value \
= CAF_PP_STR(CAF_PP_EXPAND fully_qualified_name); \ = CAF_PP_STR(CAF_PP_EXPAND fully_qualified_name); \
}; \ }; \
template <> \ template <> \
struct type_name_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> \ struct type_name_by_id<type_id<::CAF_PP_EXPAND fully_qualified_name>::value> \
: type_name<CAF_PP_EXPAND fully_qualified_name> {}; \ : type_name<::CAF_PP_EXPAND fully_qualified_name> {}; \
} }
#define CAF_ADD_TYPE_ID_3(project_name, fully_qualified_name, user_type_name) \ #define CAF_ADD_TYPE_ID_3(project_name, fully_qualified_name, user_type_name) \
namespace caf { \ namespace caf { \
CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \ CAF_DETAIL_NEXT_TYPE_ID(project_name, fully_qualified_name) \
template <> \ template <> \
struct type_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> { \ struct type_by_id<type_id<::CAF_PP_EXPAND fully_qualified_name>::value> { \
using type = CAF_PP_EXPAND fully_qualified_name; \ using type = ::CAF_PP_EXPAND fully_qualified_name; \
}; \ }; \
template <> \ template <> \
struct type_name<CAF_PP_EXPAND fully_qualified_name> { \ struct type_name<::CAF_PP_EXPAND fully_qualified_name> { \
static constexpr string_view value = user_type_name; \ static constexpr string_view value = user_type_name; \
}; \ }; \
template <> \ template <> \
struct type_name_by_id<type_id<CAF_PP_EXPAND fully_qualified_name>::value> \ struct type_name_by_id<type_id<::CAF_PP_EXPAND fully_qualified_name>::value> \
: type_name<CAF_PP_EXPAND fully_qualified_name> {}; \ : type_name<::CAF_PP_EXPAND fully_qualified_name> {}; \
} }
/// @def CAF_ADD_TYPE_ID(project_name, fully_qualified_name, user_type_name) /// @def CAF_ADD_TYPE_ID(project_name, fully_qualified_name, user_type_name)
...@@ -276,22 +276,32 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name); ...@@ -276,22 +276,32 @@ CAF_CORE_EXPORT type_id_t query_type_id(string_view name);
}; \ }; \
} }
namespace caf::detail {
// We can't pass a builtin type such as `bool` to CAF_ADD_TYPE_ID because it
// expands to `::bool`, which for some reason is invalid in C++. This alias only
// exists to work around this limitation.
template <class T>
using id_t = T;
} // namespace caf::detail
CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0) CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
// -- C types // -- C types
CAF_ADD_TYPE_ID(core_module, (bool) ) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<bool>), "bool")
CAF_ADD_TYPE_ID(core_module, (double) ) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<double>), "double")
CAF_ADD_TYPE_ID(core_module, (float) ) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<float>), "float")
CAF_ADD_TYPE_ID(core_module, (int16_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<int16_t>), "int16_t")
CAF_ADD_TYPE_ID(core_module, (int32_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<int32_t>), "int32_t")
CAF_ADD_TYPE_ID(core_module, (int64_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<int64_t>), "int64_t")
CAF_ADD_TYPE_ID(core_module, (int8_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<int8_t>), "int8_t")
CAF_ADD_TYPE_ID(core_module, (long double), "ldouble") CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<long double>), "ldouble")
CAF_ADD_TYPE_ID(core_module, (uint16_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<uint16_t>), "uint16_t")
CAF_ADD_TYPE_ID(core_module, (uint32_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<uint32_t>), "uint32_t")
CAF_ADD_TYPE_ID(core_module, (uint64_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<uint64_t>), "uint64_t")
CAF_ADD_TYPE_ID(core_module, (uint8_t)) CAF_ADD_TYPE_ID(core_module, (caf::detail::id_t<uint8_t>), "uint8_t")
// -- STL types // -- STL types
......
...@@ -8,6 +8,44 @@ ...@@ -8,6 +8,44 @@
#include "core-test.hpp" #include "core-test.hpp"
namespace detail {
struct my_secret {
int value;
};
template <class Inspector>
bool inspect(Inspector& f, my_secret& x) {
return f.object(x).fields(f.field("value", x.value));
}
} // namespace detail
namespace io {
struct protocol {
std::string name;
};
template <class Inspector>
bool inspect(Inspector& f, protocol& x) {
return f.object(x).fields(f.field("name", x.name));
}
} // namespace io
// A type ID block with types that live in namespaces that also exist as nested
// CAF namespaces. This is a regression test for
// https://github.com/actor-framework/actor-framework/issues/1195. We don't need
// to actually use these types, only check whether the code compiles.
CAF_BEGIN_TYPE_ID_BLOCK(type_id_test, caf::id_block::core_test::end)
CAF_ADD_TYPE_ID(type_id_test, (detail::my_secret))
CAF_ADD_TYPE_ID(type_id_test, (io::protocol))
CAF_END_TYPE_ID_BLOCK(type_id_test)
using namespace caf; using namespace caf;
CAF_TEST(lists store the size at index 0) { CAF_TEST(lists store the size at index 0) {
......
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