meta: iterable base types as instances of meta_type
This commit is contained in:
@@ -309,11 +309,8 @@ The meta objects that compose a meta type are accessed in the following ways:
|
||||
auto base = entt::resolve<derived_type>().base("base"_hs);
|
||||
```
|
||||
|
||||
The returned type is `meta_base` and may be invalid if there is no meta base
|
||||
object associated with the given identifier.<br/>
|
||||
Meta bases aren't meant to be used directly, even though they are freely
|
||||
accessible. They expose only a few methods to use to know the meta type of the
|
||||
base class and to convert a raw pointer between types.
|
||||
The returned type is `meta_type` and may be invalid if there is no meta base
|
||||
object associated with the given identifier.
|
||||
|
||||
All the objects thus obtained as well as the meta types can be explicitly
|
||||
converted to a boolean value to check if they are valid:
|
||||
@@ -325,7 +322,7 @@ if(auto func = entt::resolve<my_type>().func("member"_hs); func) {
|
||||
```
|
||||
|
||||
Furthermore, all them are also returned by specific overloads that provide the
|
||||
caller with iterable objects. As an example:
|
||||
caller with iterable ranges of top-level elements. As an example:
|
||||
|
||||
```cpp
|
||||
for(auto data = entt::resolve<my_type>().data()) {
|
||||
@@ -345,11 +342,8 @@ member function in its API. Destructors are invoked implicitly by `meta_any`
|
||||
behind the scenes and users have not to deal with them explicitly. Furthermore,
|
||||
they have no name, cannot be searched and wouldn't have member functions to
|
||||
expose anyway.<br/>
|
||||
Similarly, conversion functions and base types aren't directly accessible. They
|
||||
are used internally by `meta_any` and the meta objects when needed.<br/>
|
||||
It wouldn't make sense to give direct access to these elements and to open the
|
||||
doors to the possibility of making mistakes. On the other side, the library
|
||||
already offers enough ways to use them correctly.
|
||||
Similarly, conversion functions aren't directly accessible. They are used
|
||||
internally by `meta_any` and the meta objects when needed.
|
||||
|
||||
Meta types and meta objects in general contain much more than what is said: a
|
||||
plethora of functions in addition to those listed whose purposes and uses go
|
||||
|
||||
@@ -1180,6 +1180,8 @@ class meta_type {
|
||||
public:
|
||||
/*! @brief Node type. */
|
||||
using node_type = internal::meta_type_node;
|
||||
/*! @brief Node type. */
|
||||
using base_node_type = internal::meta_base_node;
|
||||
/*! @brief Unsigned integer type. */
|
||||
using size_type = typename node_type::size_type;
|
||||
|
||||
@@ -1188,6 +1190,14 @@ public:
|
||||
: node{curr}
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Constructs an instance from a given base node.
|
||||
* @param curr The base node with which to construct the instance.
|
||||
*/
|
||||
meta_type(base_node_type *curr) ENTT_NOEXCEPT
|
||||
: node{curr ? curr->type() : nullptr}
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Returns the type info object of the underlying type.
|
||||
* @return The type info object of the underlying type.
|
||||
@@ -1366,6 +1376,23 @@ public:
|
||||
return node->remove_extent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a range to use to visit top-level base meta types.
|
||||
* @return An iterable range to use to visit top-level base meta types.
|
||||
*/
|
||||
[[nodiscard]] meta_range<meta_type, internal::meta_base_node> base() const ENTT_NOEXCEPT {
|
||||
return node->base;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the base meta type associated with a given identifier.
|
||||
* @param id Unique identifier.
|
||||
* @return The base meta type associated with the given identifier, if any.
|
||||
*/
|
||||
[[nodiscard]] meta_type base(const id_type id) const {
|
||||
return internal::meta_visit<&node_type::base>([id](const auto *curr) { return curr->type()->id == id; }, node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a range to use to visit top-level constructors.
|
||||
* @return An iterable range to use to visit top-level constructors.
|
||||
|
||||
@@ -11,9 +11,10 @@ namespace entt {
|
||||
|
||||
/**
|
||||
* @brief Iterable range to use to iterate all types of meta objects.
|
||||
* @tparam Type Type of meta objects iterated.
|
||||
* @tparam Type Type of meta objects returned.
|
||||
* @tparam Node Type of meta nodes iterated.
|
||||
*/
|
||||
template<typename Type>
|
||||
template<typename Type, typename Node = typename Type::node_type>
|
||||
class meta_range {
|
||||
struct range_iterator {
|
||||
using difference_type = std::ptrdiff_t;
|
||||
@@ -21,7 +22,7 @@ class meta_range {
|
||||
using pointer = void;
|
||||
using reference = value_type;
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using node_type = typename Type::node_type;
|
||||
using node_type = Node;
|
||||
|
||||
range_iterator() ENTT_NOEXCEPT = default;
|
||||
|
||||
@@ -56,7 +57,7 @@ class meta_range {
|
||||
|
||||
public:
|
||||
/*! @brief Node type. */
|
||||
using node_type = typename Type::node_type;
|
||||
using node_type = Node;
|
||||
/*! @brief Input iterator type. */
|
||||
using iterator = range_iterator;
|
||||
|
||||
|
||||
@@ -251,6 +251,22 @@ TEST_F(MetaType, RemoveExtent) {
|
||||
ASSERT_EQ(entt::resolve<derived_t>().remove_extent(), entt::resolve<derived_t>());
|
||||
}
|
||||
|
||||
TEST_F(MetaType, Base) {
|
||||
using namespace entt::literals;
|
||||
|
||||
auto type = entt::resolve<derived_t>();
|
||||
bool iterate = false;
|
||||
|
||||
for(auto curr: type.base()) {
|
||||
ASSERT_EQ(curr, entt::resolve<base_t>());
|
||||
iterate = true;
|
||||
}
|
||||
|
||||
ASSERT_TRUE(iterate);
|
||||
ASSERT_EQ(type.base("base"_hs), entt::resolve<base_t>());
|
||||
ASSERT_FALSE(type.base("esabe"_hs));
|
||||
}
|
||||
|
||||
TEST_F(MetaType, Ctor) {
|
||||
auto type = entt::resolve<clazz_t>();
|
||||
int counter{};
|
||||
|
||||
Reference in New Issue
Block a user