|
|
|
|
@@ -20,10 +20,60 @@ namespace entt {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class meta_type;
|
|
|
|
|
class meta_any;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Proxy object for containers of any type. */
|
|
|
|
|
class meta_container {
|
|
|
|
|
/*! @brief A meta_any is allowed to create proxies. */
|
|
|
|
|
friend class meta_any;
|
|
|
|
|
|
|
|
|
|
struct meta_iterator;
|
|
|
|
|
|
|
|
|
|
struct meta_view {
|
|
|
|
|
[[nodiscard]] virtual std::size_t size(void *) const ENTT_NOEXCEPT = 0;
|
|
|
|
|
[[nodiscard]] virtual bool insert(void *, meta_any, meta_any) = 0;
|
|
|
|
|
[[nodiscard]] virtual bool erase(void *, meta_any) = 0;
|
|
|
|
|
[[nodiscard]] virtual meta_any begin(void *) const ENTT_NOEXCEPT = 0;
|
|
|
|
|
[[nodiscard]] virtual meta_any end(void *) const ENTT_NOEXCEPT = 0;
|
|
|
|
|
[[nodiscard]] virtual meta_any find(void *, meta_any) const ENTT_NOEXCEPT = 0;
|
|
|
|
|
[[nodiscard]] virtual meta_any value(meta_any) const ENTT_NOEXCEPT = 0;
|
|
|
|
|
virtual void incr(meta_any) const ENTT_NOEXCEPT = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
meta_container(meta_view *impl, void *container)
|
|
|
|
|
: view{impl},
|
|
|
|
|
instance{container}
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/*! @brief Unsigned integer type. */
|
|
|
|
|
using size_type = std::size_t;
|
|
|
|
|
/*! @brief Input iterator type. */
|
|
|
|
|
using iterator = meta_iterator;
|
|
|
|
|
|
|
|
|
|
/*! @brief Default constructor. */
|
|
|
|
|
meta_container()
|
|
|
|
|
: view{},
|
|
|
|
|
instance{}
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] inline size_type size() const ENTT_NOEXCEPT;
|
|
|
|
|
inline bool insert(meta_any, meta_any);
|
|
|
|
|
inline bool erase(meta_any);
|
|
|
|
|
[[nodiscard]] inline iterator begin();
|
|
|
|
|
[[nodiscard]] inline iterator end();
|
|
|
|
|
[[nodiscard]] inline iterator operator[](meta_any pos_or_key);
|
|
|
|
|
[[nodiscard]] inline explicit operator bool() const ENTT_NOEXCEPT;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
meta_view *view;
|
|
|
|
|
void *instance;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Opaque container for values of any type.
|
|
|
|
|
* @brief Opaque wrapper for values of any type.
|
|
|
|
|
*
|
|
|
|
|
* This class uses a technique called small buffer optimization (SBO) to get rid
|
|
|
|
|
* of memory allocations if possible. This should improve overall performance.
|
|
|
|
|
@@ -86,12 +136,158 @@ class meta_any {
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
meta_any(const internal::meta_type_node *curr, void *ref) ENTT_NOEXCEPT
|
|
|
|
|
: meta_any{}
|
|
|
|
|
{
|
|
|
|
|
node = curr;
|
|
|
|
|
instance = ref;
|
|
|
|
|
}
|
|
|
|
|
template<typename, typename = void>
|
|
|
|
|
struct container_view {
|
|
|
|
|
[[nodiscard]] static meta_container::meta_view * instance() {
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename Type>
|
|
|
|
|
struct container_view<Type, std::enable_if_t<is_sequence_container_v<Type>>>: meta_container::meta_view {
|
|
|
|
|
[[nodiscard]] static meta_container::meta_view * instance() {
|
|
|
|
|
static container_view common{};
|
|
|
|
|
return &common;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] std::size_t size(void *container) const ENTT_NOEXCEPT override {
|
|
|
|
|
return static_cast<Type *>(container)->size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] bool insert(void *container, meta_any it, meta_any value) override {
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if constexpr(is_dynamic_sequence_container_v<Type>) {
|
|
|
|
|
if(auto *iter = it.try_cast<typename Type::iterator>(); iter) {
|
|
|
|
|
if(const auto *curr = value.try_cast<typename Type::value_type>(); curr) {
|
|
|
|
|
*iter = static_cast<Type *>(container)->insert(*iter, *curr);
|
|
|
|
|
ret = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] bool erase(void *container, meta_any it) override {
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if constexpr(is_dynamic_sequence_container_v<Type>) {
|
|
|
|
|
if(auto *iter = it.try_cast<typename Type::iterator>(); iter) {
|
|
|
|
|
*iter = static_cast<Type *>(container)->erase(*iter);
|
|
|
|
|
ret = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any begin(void *container) const ENTT_NOEXCEPT override {
|
|
|
|
|
return static_cast<Type *>(container)->begin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any end(void *container) const ENTT_NOEXCEPT override {
|
|
|
|
|
return static_cast<Type *>(container)->end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any value(meta_any it) const ENTT_NOEXCEPT override {
|
|
|
|
|
return std::ref(*it.cast<typename Type::iterator>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any find(void *container, meta_any idx) const ENTT_NOEXCEPT override {
|
|
|
|
|
meta_any any{};
|
|
|
|
|
|
|
|
|
|
if(const auto *curr = idx.try_cast<std::size_t>(); curr) {
|
|
|
|
|
any = std::next(static_cast<Type *>(container)->begin(), *curr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return any;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void incr(meta_any it) const ENTT_NOEXCEPT override {
|
|
|
|
|
++it.cast<typename Type::iterator>();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template<typename Type>
|
|
|
|
|
struct container_view<Type, std::enable_if_t<is_associative_container_v<Type>>>: meta_container::meta_view {
|
|
|
|
|
[[nodiscard]] static meta_container::meta_view * instance() {
|
|
|
|
|
static container_view common{};
|
|
|
|
|
return &common;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] std::size_t size(void *container) const ENTT_NOEXCEPT override {
|
|
|
|
|
return static_cast<Type *>(container)->size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] bool insert(void *container, meta_any key, meta_any value) override {
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if constexpr(is_key_only_associative_container_v<Type>) {
|
|
|
|
|
if(const auto *curr = key.try_cast<typename Type::key_type>(); curr) {
|
|
|
|
|
static_cast<Type *>(container)->insert(*curr);
|
|
|
|
|
ret = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(const auto *k_curr = key.try_cast<typename Type::key_type>(); k_curr) {
|
|
|
|
|
if(const auto *v_curr = value.try_cast<typename Type::mapped_type>(); v_curr) {
|
|
|
|
|
static_cast<Type *>(container)->insert(std::make_pair(*k_curr, *v_curr));
|
|
|
|
|
ret = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] bool erase(void *container, meta_any key) override {
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if(const auto *curr = key.try_cast<typename Type::key_type>(); curr) {
|
|
|
|
|
static_cast<Type *>(container)->erase(*curr);
|
|
|
|
|
ret = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any begin(void *container) const ENTT_NOEXCEPT override {
|
|
|
|
|
return static_cast<Type *>(container)->begin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any end(void *container) const ENTT_NOEXCEPT override {
|
|
|
|
|
return static_cast<Type *>(container)->end();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any value(meta_any it) const ENTT_NOEXCEPT override {
|
|
|
|
|
if constexpr(is_key_only_associative_container_v<Type>) {
|
|
|
|
|
return *it.cast<typename Type::iterator>();
|
|
|
|
|
} else {
|
|
|
|
|
return std::ref(*it.cast<typename Type::iterator>());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[[nodiscard]] meta_any find(void *container, meta_any key) const ENTT_NOEXCEPT override {
|
|
|
|
|
meta_any any{};
|
|
|
|
|
|
|
|
|
|
if constexpr(is_key_only_associative_container_v<Type>) {
|
|
|
|
|
if(const auto *curr = key.try_cast<typename Type::key_type>(); curr) {
|
|
|
|
|
auto *cont = static_cast<Type *>(container);
|
|
|
|
|
any = std::find(cont->begin(), cont->end(), *curr);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if(const auto *curr = key.try_cast<typename Type::key_type>(); curr) {
|
|
|
|
|
any = static_cast<Type *>(container)->find(*curr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return any;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void incr(meta_any it) const ENTT_NOEXCEPT override {
|
|
|
|
|
it.cast<typename Type::iterator>().operator++();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/*! @brief Default constructor. */
|
|
|
|
|
@@ -101,12 +297,13 @@ public:
|
|
|
|
|
node{},
|
|
|
|
|
destroy_fn{},
|
|
|
|
|
copy_fn{},
|
|
|
|
|
steal_fn{}
|
|
|
|
|
steal_fn{},
|
|
|
|
|
cview{}
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Constructs a meta any by directly initializing the new object.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the container.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the wrapper.
|
|
|
|
|
* @tparam Args Types of arguments to use to construct the new instance.
|
|
|
|
|
* @param args Parameters to use to construct the instance.
|
|
|
|
|
*/
|
|
|
|
|
@@ -121,23 +318,28 @@ public:
|
|
|
|
|
destroy_fn = &type_traits<Type>::destroy;
|
|
|
|
|
copy_fn = &type_traits<Type>::copy;
|
|
|
|
|
steal_fn = &type_traits<Type>::steal;
|
|
|
|
|
cview = container_view<Type>::instance();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Constructs a meta any that holds an unmanaged object.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the container.
|
|
|
|
|
* @param value An instance of an object to use to initialize the container.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the wrapper.
|
|
|
|
|
* @param value An instance of an object to use to initialize the wrapper.
|
|
|
|
|
*/
|
|
|
|
|
template<typename Type>
|
|
|
|
|
meta_any(std::reference_wrapper<Type> value)
|
|
|
|
|
: meta_any{internal::meta_info<Type>::resolve(), &value.get()}
|
|
|
|
|
{}
|
|
|
|
|
: meta_any{}
|
|
|
|
|
{
|
|
|
|
|
node = internal::meta_info<Type>::resolve();
|
|
|
|
|
instance = &value.get();
|
|
|
|
|
cview = container_view<Type>::instance();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Constructs a meta any from a given value.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the container.
|
|
|
|
|
* @param value An instance of an object to use to initialize the container.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the wrapper.
|
|
|
|
|
* @param value An instance of an object to use to initialize the wrapper.
|
|
|
|
|
*/
|
|
|
|
|
template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_any>>>
|
|
|
|
|
meta_any(Type &&value)
|
|
|
|
|
@@ -156,6 +358,7 @@ public:
|
|
|
|
|
destroy_fn = other.destroy_fn;
|
|
|
|
|
copy_fn = other.copy_fn;
|
|
|
|
|
steal_fn = other.steal_fn;
|
|
|
|
|
cview = other.cview;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -177,8 +380,8 @@ public:
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Assignment operator.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the container.
|
|
|
|
|
* @param value An instance of an object to use to initialize the container.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the wrapper.
|
|
|
|
|
* @param value An instance of an object to use to initialize the wrapper.
|
|
|
|
|
* @return This meta any object.
|
|
|
|
|
*/
|
|
|
|
|
template<typename Type>
|
|
|
|
|
@@ -309,9 +512,8 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Replaces the contained object by initializing a new instance
|
|
|
|
|
* directly.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the container.
|
|
|
|
|
* @brief Replaces the contained object by creating a new instance directly.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the wrapper.
|
|
|
|
|
* @tparam Args Types of arguments to use to construct the new instance.
|
|
|
|
|
* @param args Parameters to use to construct the instance.
|
|
|
|
|
*/
|
|
|
|
|
@@ -325,7 +527,19 @@ public:
|
|
|
|
|
* @return A meta any that shares a reference to an unmanaged object.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] meta_any ref() const ENTT_NOEXCEPT {
|
|
|
|
|
return meta_any{node, instance};
|
|
|
|
|
meta_any alias{};
|
|
|
|
|
alias.node = node;
|
|
|
|
|
alias.instance = instance;
|
|
|
|
|
alias.cview = cview;
|
|
|
|
|
return alias;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns a container view.
|
|
|
|
|
* @return A container view for the underlying object.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] meta_container view() const ENTT_NOEXCEPT {
|
|
|
|
|
return { cview, instance };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -337,18 +551,17 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns false if a container is empty, true otherwise.
|
|
|
|
|
* @return False if the container is empty, true otherwise.
|
|
|
|
|
* @brief Returns false if a wrapper is empty, true otherwise.
|
|
|
|
|
* @return False if the wrapper is empty, true otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
|
|
|
|
|
return !(node == nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Checks if two containers differ in their content.
|
|
|
|
|
* @param other Container with which to compare.
|
|
|
|
|
* @return False if the two containers differ in their content, true
|
|
|
|
|
* otherwise.
|
|
|
|
|
* @brief Checks if two wrappers differ in their content.
|
|
|
|
|
* @param other Wrapper with which to compare.
|
|
|
|
|
* @return False if the two objects differ in their content, true otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool operator==(const meta_any &other) const {
|
|
|
|
|
return (!node && !other.node) || (node && other.node && node->type_id == other.node->type_id && node->compare(instance, other.instance));
|
|
|
|
|
@@ -377,6 +590,7 @@ public:
|
|
|
|
|
std::swap(lhs.destroy_fn, rhs.destroy_fn);
|
|
|
|
|
std::swap(lhs.copy_fn, rhs.copy_fn);
|
|
|
|
|
std::swap(lhs.steal_fn, rhs.steal_fn);
|
|
|
|
|
std::swap(lhs.cview, rhs.cview);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
@@ -386,20 +600,196 @@ private:
|
|
|
|
|
destroy_fn_type *destroy_fn;
|
|
|
|
|
copy_fn_type *copy_fn;
|
|
|
|
|
steal_fn_type *steal_fn;
|
|
|
|
|
meta_container::meta_view *cview;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Checks if two containers differ in their content.
|
|
|
|
|
* @brief Checks if two wrappers differ in their content.
|
|
|
|
|
* @param lhs A meta any object, either empty or not.
|
|
|
|
|
* @param rhs A meta any object, either empty or not.
|
|
|
|
|
* @return True if the two containers differ in their content, false otherwise.
|
|
|
|
|
* @return True if the two wrappers differ in their content, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] inline bool operator!=(const meta_any &lhs, const meta_any &rhs) ENTT_NOEXCEPT {
|
|
|
|
|
return !(lhs == rhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque iterator for meta containers. */
|
|
|
|
|
struct meta_container::meta_iterator {
|
|
|
|
|
/*! @brief Signed integer type. */
|
|
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
|
|
/*! @brief Type of elements returned by the iterator. */
|
|
|
|
|
using value_type = meta_any;
|
|
|
|
|
/*! @brief Pointer type, `void` on purpose. */
|
|
|
|
|
using pointer = void;
|
|
|
|
|
/*! @brief Reference type, it is **not** an actual reference. */
|
|
|
|
|
using reference = value_type;
|
|
|
|
|
/*! @brief Iterator category. */
|
|
|
|
|
using iterator_category = std::input_iterator_tag;
|
|
|
|
|
|
|
|
|
|
/*! @brief Default constructor. */
|
|
|
|
|
meta_iterator() ENTT_NOEXCEPT = default;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Constructs a meta iterator that wraps an actual iterator.
|
|
|
|
|
* @param ref A proxy object that _knows_ how to use the wrapped iterator.
|
|
|
|
|
* @param iter The actual iterator, properly wrapped.
|
|
|
|
|
*/
|
|
|
|
|
meta_iterator(meta_container::meta_view *ref, meta_any iter)
|
|
|
|
|
: view{ref},
|
|
|
|
|
it{std::move(iter)}
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
/*! @brief Pre-increment operator. @return This iterator. */
|
|
|
|
|
meta_iterator & operator++() ENTT_NOEXCEPT {
|
|
|
|
|
return view->incr(handle()), *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*! @brief Post-increment operator. @return This iterator. */
|
|
|
|
|
meta_iterator operator++(int) ENTT_NOEXCEPT {
|
|
|
|
|
iterator orig = *this;
|
|
|
|
|
return view->incr(handle()), orig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Checks if two meta iterators refer to the same element.
|
|
|
|
|
* @param other The meta iterator with which to compare.
|
|
|
|
|
* @return True if the two meta iterators refer to the same element, false
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool operator==(const meta_iterator &other) const ENTT_NOEXCEPT {
|
|
|
|
|
return it == other.it;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Checks if two meta iterators refer to the same element.
|
|
|
|
|
* @param other The meta iterator with which to compare.
|
|
|
|
|
* @return False if the two meta iterators refer to the same element, true
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool operator!=(const meta_iterator &other) const ENTT_NOEXCEPT {
|
|
|
|
|
return !(*this == other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indirection operator.
|
|
|
|
|
* @return The element to which the meta pointer points.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] reference operator*() const {
|
|
|
|
|
return view->value(handle());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns a handle to the underlying iterator.
|
|
|
|
|
* @return The actual iterator, properly wrapped.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] meta_any handle() const ENTT_NOEXCEPT {
|
|
|
|
|
return *it;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns false if an iterator is invalid, true otherwise.
|
|
|
|
|
* @return False if the iterator is invalid, true otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
|
|
|
|
|
return static_cast<bool>(it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
meta_container::meta_view *view;
|
|
|
|
|
entt::meta_any it;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns the number of elements.
|
|
|
|
|
* @return Number of elements.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] meta_container::size_type meta_container::size() const ENTT_NOEXCEPT {
|
|
|
|
|
return view->size(instance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Inserts an element in the container.
|
|
|
|
|
*
|
|
|
|
|
* In case of sequence containers, the first parameter must be a valid iterator
|
|
|
|
|
* handle. In case of associative containers, the type of the key must be such
|
|
|
|
|
* that a cast or conversion to the key type of the container is possible.<br/>
|
|
|
|
|
* The type of the value must be such that a cast or conversion to the value
|
|
|
|
|
* type of the container is possible.
|
|
|
|
|
*
|
|
|
|
|
* @param it_or_key A valid iterator handle in case of sequence containers, a
|
|
|
|
|
* key in case of associative containers.
|
|
|
|
|
* @param value The element to insert in the container.
|
|
|
|
|
* @return True in case of success, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
inline bool meta_container::insert(meta_any it_or_key, meta_any value = {}) {
|
|
|
|
|
return view->insert(instance, std::move(it_or_key), std::move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Erases an element from the container.
|
|
|
|
|
*
|
|
|
|
|
* In case of sequence containers, the parameter must be a valid iterator
|
|
|
|
|
* handle. In case of associative containers, the type of the key must be such
|
|
|
|
|
* that a cast or conversion to the key type of the container is possible.
|
|
|
|
|
*
|
|
|
|
|
* @param it_or_key A valid iterator handle in case of sequence containers, a
|
|
|
|
|
* key in case of associative containers.
|
|
|
|
|
* @return True in case of success, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
inline bool meta_container::erase(meta_any it_or_key) {
|
|
|
|
|
return view->erase(instance, std::move(it_or_key));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns an iterator to the first element of the container.
|
|
|
|
|
* @return An iterator to the first element of the container.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] inline meta_container::iterator meta_container::begin() {
|
|
|
|
|
return {view, view->begin(instance)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns an iterator that is past the last element of the container.
|
|
|
|
|
* @return An iterator that is past the last element of the container.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] inline meta_container::iterator meta_container::end() {
|
|
|
|
|
return {view, view->end(instance)};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns an iterator to the required element.
|
|
|
|
|
*
|
|
|
|
|
* In case of sequence containers, the parameter must be a valid position (no
|
|
|
|
|
* bounds checking is performed) and such that a cast or conversion to size_type
|
|
|
|
|
* is possible. In case of associative containers, the type of the key must be
|
|
|
|
|
* such that a cast or conversion to the key type of the container is possible.
|
|
|
|
|
*
|
|
|
|
|
* @param pos_or_key A valid position in case of sequence containers, a key in
|
|
|
|
|
* case of associative containers.
|
|
|
|
|
* @return An iterator to the required element.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] inline meta_container::iterator meta_container::operator[](meta_any pos_or_key) {
|
|
|
|
|
return {view, view->find(instance, std::move(pos_or_key))};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Returns true if a meta container is valid, false otherwise.
|
|
|
|
|
* @return True if the meta container is valid, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] meta_container::operator bool() const ENTT_NOEXCEPT {
|
|
|
|
|
return view;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Opaque pointers to instances of any type.
|
|
|
|
|
*
|
|
|
|
|
@@ -415,8 +805,8 @@ struct meta_handle {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Creates a handle that points to an unmanaged object.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the container.
|
|
|
|
|
* @param value An instance of an object to use to initialize the container.
|
|
|
|
|
* @tparam Type Type of object to use to initialize the handle.
|
|
|
|
|
* @param value An instance of an object to use to initialize the handle.
|
|
|
|
|
*/
|
|
|
|
|
template<typename Type, typename = std::enable_if_t<!std::is_same_v<std::remove_cv_t<std::remove_reference_t<Type>>, meta_handle>>>
|
|
|
|
|
meta_handle(Type &&value) ENTT_NOEXCEPT
|
|
|
|
|
@@ -440,7 +830,7 @@ private:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque container for meta properties of any type. */
|
|
|
|
|
/*! @brief Opaque wrapper for meta properties of any type. */
|
|
|
|
|
struct meta_prop {
|
|
|
|
|
/*! @brief Node type. */
|
|
|
|
|
using node_type = internal::meta_prop_node;
|
|
|
|
|
@@ -482,7 +872,7 @@ private:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque container for meta base classes. */
|
|
|
|
|
/*! @brief Opaque wrapper for meta base classes. */
|
|
|
|
|
struct meta_base {
|
|
|
|
|
/*! @brief Node type. */
|
|
|
|
|
using node_type = internal::meta_base_node;
|
|
|
|
|
@@ -523,7 +913,7 @@ private:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque container for meta conversion functions. */
|
|
|
|
|
/*! @brief Opaque wrapper for meta conversion functions. */
|
|
|
|
|
struct meta_conv {
|
|
|
|
|
/*! @brief Node type. */
|
|
|
|
|
using node_type = internal::meta_conv_node;
|
|
|
|
|
@@ -561,7 +951,7 @@ private:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque container for meta constructors. */
|
|
|
|
|
/*! @brief Opaque wrapper for meta constructors. */
|
|
|
|
|
struct meta_ctor {
|
|
|
|
|
/*! @brief Node type. */
|
|
|
|
|
using node_type = internal::meta_ctor_node;
|
|
|
|
|
@@ -596,7 +986,7 @@ struct meta_ctor {
|
|
|
|
|
*
|
|
|
|
|
* To create a valid instance, the parameters must be such that a cast or
|
|
|
|
|
* conversion to the required types is possible. Otherwise, an empty and
|
|
|
|
|
* thus invalid container is returned.
|
|
|
|
|
* thus invalid wrapper is returned.
|
|
|
|
|
*
|
|
|
|
|
* @tparam Args Types of arguments to use to construct the instance.
|
|
|
|
|
* @param args Parameters to use to construct the instance.
|
|
|
|
|
@@ -653,7 +1043,7 @@ private:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque container for meta data. */
|
|
|
|
|
/*! @brief Opaque wrapper for meta data. */
|
|
|
|
|
struct meta_data {
|
|
|
|
|
/*! @brief Node type. */
|
|
|
|
|
using node_type = internal::meta_data_node;
|
|
|
|
|
@@ -764,7 +1154,7 @@ private:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque container for meta functions. */
|
|
|
|
|
/*! @brief Opaque wrapper for meta functions. */
|
|
|
|
|
struct meta_func {
|
|
|
|
|
/*! @brief Node type. */
|
|
|
|
|
using node_type = internal::meta_func_node;
|
|
|
|
|
@@ -826,7 +1216,7 @@ struct meta_func {
|
|
|
|
|
*
|
|
|
|
|
* To invoke a meta function, the parameters must be such that a cast or
|
|
|
|
|
* conversion to the required types is possible. Otherwise, an empty and
|
|
|
|
|
* thus invalid container is returned.<br/>
|
|
|
|
|
* thus invalid wrapper is returned.<br/>
|
|
|
|
|
* It must be possible to cast the instance to the parent type of the meta
|
|
|
|
|
* function. Otherwise, invoking the underlying function results in an
|
|
|
|
|
* undefined behavior.
|
|
|
|
|
@@ -890,7 +1280,7 @@ private:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*! @brief Opaque container for meta types. */
|
|
|
|
|
/*! @brief Opaque wrapper for meta types. */
|
|
|
|
|
class meta_type {
|
|
|
|
|
template<typename... Args, std::size_t... Indexes>
|
|
|
|
|
[[nodiscard]] auto ctor(std::index_sequence<Indexes...>) const {
|
|
|
|
|
@@ -933,7 +1323,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to void or not.
|
|
|
|
|
* @brief Checks whether a type refers to void or not.
|
|
|
|
|
* @return True if the underlying type is void, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_void() const ENTT_NOEXCEPT {
|
|
|
|
|
@@ -941,7 +1331,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to an integral type or not.
|
|
|
|
|
* @brief Checks whether a type refers to an integral type or not.
|
|
|
|
|
* @return True if the underlying type is an integral type, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_integral() const ENTT_NOEXCEPT {
|
|
|
|
|
@@ -949,8 +1339,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to a floating-point type or
|
|
|
|
|
* not.
|
|
|
|
|
* @brief Checks whether a type refers to a floating-point type or not.
|
|
|
|
|
* @return True if the underlying type is a floating-point type, false
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
@@ -959,7 +1348,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to an array type or not.
|
|
|
|
|
* @brief Checks whether a type refers to an array type or not.
|
|
|
|
|
* @return True if the underlying type is an array type, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_array() const ENTT_NOEXCEPT {
|
|
|
|
|
@@ -967,7 +1356,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to an enum or not.
|
|
|
|
|
* @brief Checks whether a type refers to an enum or not.
|
|
|
|
|
* @return True if the underlying type is an enum, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_enum() const ENTT_NOEXCEPT {
|
|
|
|
|
@@ -975,7 +1364,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to an union or not.
|
|
|
|
|
* @brief Checks whether a type refers to an union or not.
|
|
|
|
|
* @return True if the underlying type is an union, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_union() const ENTT_NOEXCEPT {
|
|
|
|
|
@@ -983,7 +1372,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to a class or not.
|
|
|
|
|
* @brief Checks whether a type refers to a class or not.
|
|
|
|
|
* @return True if the underlying type is a class, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_class() const ENTT_NOEXCEPT {
|
|
|
|
|
@@ -991,7 +1380,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to a pointer or not.
|
|
|
|
|
* @brief Checks whether a type refers to a pointer or not.
|
|
|
|
|
* @return True if the underlying type is a pointer, false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_pointer() const ENTT_NOEXCEPT {
|
|
|
|
|
@@ -999,7 +1388,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to a function pointer or not.
|
|
|
|
|
* @brief Checks whether a type refers to a function pointer or not.
|
|
|
|
|
* @return True if the underlying type is a function pointer, false
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
@@ -1008,8 +1397,7 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to a pointer to data member
|
|
|
|
|
* or not.
|
|
|
|
|
* @brief Checks whether a type refers to a pointer to data member or not.
|
|
|
|
|
* @return True if the underlying type is a pointer to data member, false
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
@@ -1018,8 +1406,8 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Indicates whether a meta type refers to a pointer to member
|
|
|
|
|
* function or not.
|
|
|
|
|
* @brief Checks whether a type refers to a pointer to member function or
|
|
|
|
|
* not.
|
|
|
|
|
* @return True if the underlying type is a pointer to member function,
|
|
|
|
|
* false otherwise.
|
|
|
|
|
*/
|
|
|
|
|
@@ -1028,7 +1416,25 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief If a meta type refers to an array type, provides the number of
|
|
|
|
|
* @brief Checks whether a type refers to a sequence container or not.
|
|
|
|
|
* @return True if the underlying type is a sequence container, false
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_sequence_container() const ENTT_NOEXCEPT {
|
|
|
|
|
return node->is_sequence_container;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief Checks whether a type refers to an associative container or not.
|
|
|
|
|
* @return True if the underlying type is an associative container, false
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
[[nodiscard]] bool is_associative_container() const ENTT_NOEXCEPT {
|
|
|
|
|
return node->is_associative_container;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief If a type refers to an array type, provides the number of
|
|
|
|
|
* dimensions of the array.
|
|
|
|
|
* @return The number of dimensions of the array if the underlying type is
|
|
|
|
|
* an array type, 0 otherwise.
|
|
|
|
|
@@ -1038,8 +1444,8 @@ public:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief If a meta type refers to an array type, provides the number of
|
|
|
|
|
* elements along the given dimension of the array.
|
|
|
|
|
* @brief If a type refers to an array type, provides the number of elements
|
|
|
|
|
* along the given dimension of the array.
|
|
|
|
|
* @param dim The dimension of which to return the number of elements.
|
|
|
|
|
* @return The number of elements along the given dimension of the array if
|
|
|
|
|
* the underlying type is an array type, 0 otherwise.
|
|
|
|
|
@@ -1243,7 +1649,7 @@ public:
|
|
|
|
|
*
|
|
|
|
|
* To create a valid instance, the parameters must be such that a cast or
|
|
|
|
|
* conversion to the required types is possible. Otherwise, an empty and
|
|
|
|
|
* thus invalid container is returned.
|
|
|
|
|
* thus invalid wrapper is returned.
|
|
|
|
|
*
|
|
|
|
|
* @tparam Args Types of arguments to use to construct the instance.
|
|
|
|
|
* @param args Parameters to use to construct the instance.
|
|
|
|
|
|