mirror of
https://github.com/boostorg/openmethod.git
synced 2026-01-19 04:22:12 +00:00
statically check that a class is polymorphic (where needed)
This commit is contained in:
committed by
Jean-Louis Leroy
parent
1b350beedd
commit
c610cab4a1
@@ -7,6 +7,9 @@ source:
|
||||
[source,c++]
|
||||
----
|
||||
struct std_rtti : rtti {
|
||||
template<class Class>
|
||||
static constexpr auto is_polymorphic = std::is_polymorphic_v<Class>;
|
||||
|
||||
template<typename T>
|
||||
static type_id static_type() {
|
||||
return reinterpret_cast<type_id>(&typeid(T));
|
||||
@@ -33,6 +36,9 @@ struct std_rtti : rtti {
|
||||
};
|
||||
----
|
||||
|
||||
* `is_polymorphic` is used to check if a class is polymorphic. This template is
|
||||
required.
|
||||
|
||||
* `static_type` is used by class registration, by `virtual_ptr`{empty}'s "final"
|
||||
constructs, and to format error and trace messages. `T` is not restricted to
|
||||
the classes that appear as virtual parameters. This function is required.
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
```c++
|
||||
struct minimal_rtti : rtti {
|
||||
template<class Class>
|
||||
static constexpr bool is_polymorphic = false;
|
||||
|
||||
template<typename Class>
|
||||
static auto static_type() -> type_id;
|
||||
};
|
||||
@@ -25,6 +28,15 @@ is not supported. Classes are not required to be polymorphic.
|
||||
### Members
|
||||
|
||||
|
||||
#### is_polymorphic
|
||||
|
||||
```c++
|
||||
template<class Class>
|
||||
static constexpr bool is_polymorphic = false;
|
||||
```
|
||||
|
||||
This facet does not support polymorphic classes.
|
||||
|
||||
#### static_type
|
||||
|
||||
```c++
|
||||
|
||||
@@ -21,6 +21,15 @@ an `ostream`-like object.
|
||||
|
||||
### Requirements
|
||||
|
||||
#### is_polymorphic
|
||||
|
||||
```c++
|
||||
template<class Class>
|
||||
static constexpr bool is_polymorphic;
|
||||
```
|
||||
|
||||
`true` if `Class` is polymorphic.
|
||||
|
||||
#### static_type
|
||||
|
||||
```c++
|
||||
|
||||
@@ -34,9 +34,12 @@ struct Dog : Animal {
|
||||
namespace bom = boost::openmethod;
|
||||
|
||||
struct custom_rtti : bom::policies::rtti {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() -> bom::type_id {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return T::static_type;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -45,7 +48,7 @@ struct custom_rtti : bom::policies::rtti {
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) -> bom::type_id {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return obj.type;
|
||||
} else {
|
||||
return 0;
|
||||
|
||||
@@ -739,10 +739,16 @@ class virtual_ptr : public detail::virtual_ptr_impl<Class, Policy> {
|
||||
std::is_base_of_v<element_type, other_class> ||
|
||||
std::is_base_of_v<other_class, element_type>);
|
||||
|
||||
if constexpr (Policy::template has_facet<policies::runtime_checks>) {
|
||||
if constexpr (
|
||||
Policy::template has_facet<policies::runtime_checks> &&
|
||||
Policy::template is_polymorphic<typename impl::traits::virtual_type> &&
|
||||
Policy::template is_polymorphic<other_class>) {
|
||||
// check that dynamic type == static type
|
||||
auto static_type = Policy::template static_type<other_class>();
|
||||
auto dynamic_type = Policy::dynamic_type(other_traits::peek(obj));
|
||||
|
||||
type_id dynamic_type;
|
||||
|
||||
dynamic_type = Policy::dynamic_type(other_traits::peek(obj));
|
||||
|
||||
if (dynamic_type != static_type) {
|
||||
type_mismatch_error error;
|
||||
@@ -1286,6 +1292,19 @@ method<Name(Parameters...), ReturnType, Policy>::resolve_multi_next(
|
||||
// -----------------------------------------------------------------------------
|
||||
// Error handling
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class Policy, class Class>
|
||||
auto error_type_id(const Class& obj) {
|
||||
if constexpr (Policy::template is_polymorphic<Class>) {
|
||||
return Policy::template dynamic_type<Class>(obj);
|
||||
} else {
|
||||
return Policy::template static_type<void>();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<
|
||||
typename Name, typename... Parameters, typename ReturnType, class Policy>
|
||||
BOOST_NORETURN auto
|
||||
@@ -1298,7 +1317,7 @@ method<Name(Parameters...), ReturnType, Policy>::not_implemented_handler(
|
||||
type_id types[sizeof...(args)];
|
||||
auto ti_iter = types;
|
||||
(...,
|
||||
(*ti_iter++ = Policy::dynamic_type(
|
||||
(*ti_iter++ = detail::error_type_id<Policy>(
|
||||
detail::parameter_traits<Parameters, Policy>::peek(args))));
|
||||
std::copy_n(
|
||||
types,
|
||||
|
||||
@@ -13,6 +13,9 @@ namespace openmethod {
|
||||
namespace policies {
|
||||
|
||||
struct minimal_rtti : virtual rtti {
|
||||
template<class Class>
|
||||
static constexpr bool is_polymorphic = false;
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() -> type_id {
|
||||
static char id;
|
||||
|
||||
@@ -20,6 +20,9 @@ namespace policies {
|
||||
|
||||
struct std_rtti : virtual rtti {
|
||||
#ifndef BOOST_NO_RTTI
|
||||
template<class Class>
|
||||
static constexpr bool is_polymorphic = std::is_polymorphic_v<Class>;
|
||||
|
||||
template<class Class>
|
||||
static auto static_type() -> type_id {
|
||||
auto tip = &typeid(Class);
|
||||
|
||||
@@ -39,9 +39,12 @@ struct Cat : Animal {
|
||||
};
|
||||
|
||||
struct custom_rtti : policies::rtti {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<type_id>(T::static_type);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -50,7 +53,7 @@ struct custom_rtti : policies::rtti {
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return reinterpret_cast<type_id>(obj.type);
|
||||
} else {
|
||||
return 0;
|
||||
@@ -129,9 +132,12 @@ struct Cat : Animal {
|
||||
};
|
||||
|
||||
struct custom_rtti : policies::rtti {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return T::static_type;
|
||||
} else {
|
||||
return 666;
|
||||
@@ -140,7 +146,7 @@ struct custom_rtti : policies::rtti {
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return obj.type;
|
||||
} else {
|
||||
return 666;
|
||||
@@ -277,9 +283,12 @@ struct Cat : virtual Animal {
|
||||
};
|
||||
|
||||
struct custom_rtti : policies::rtti {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return T::static_type;
|
||||
} else {
|
||||
return 666;
|
||||
@@ -288,7 +297,7 @@ struct custom_rtti : policies::rtti {
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return obj.type;
|
||||
} else {
|
||||
return 666;
|
||||
@@ -418,9 +427,12 @@ struct Cat : Animal {
|
||||
std::size_t Cat::static_type = ++Animal::last_type_id;
|
||||
|
||||
struct custom_rtti : policies::deferred_static_rtti {
|
||||
template<class T>
|
||||
static constexpr bool is_polymorphic = std::is_base_of_v<Animal, T>;
|
||||
|
||||
template<typename T>
|
||||
static auto static_type() {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return T::static_type;
|
||||
} else {
|
||||
static type_id invalid = 0;
|
||||
@@ -430,7 +442,7 @@ struct custom_rtti : policies::deferred_static_rtti {
|
||||
|
||||
template<typename T>
|
||||
static auto dynamic_type(const T& obj) {
|
||||
if constexpr (std::is_base_of_v<Animal, T>) {
|
||||
if constexpr (is_polymorphic<T>) {
|
||||
return obj.type;
|
||||
} else {
|
||||
return 666;
|
||||
|
||||
Reference in New Issue
Block a user