Skip to content

Commit

Permalink
meta: internal changes to make things easier to maintain and evolve
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed Nov 21, 2023
1 parent 8ce8014 commit 24c95e4
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 87 deletions.
87 changes: 38 additions & 49 deletions src/entt/meta/container.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <vector>
#include "../container/dense_map.hpp"
#include "../container/dense_set.hpp"
#include "context.hpp"
#include "meta.hpp"
#include "type_traits.hpp"

Expand Down Expand Up @@ -130,70 +131,64 @@ struct basic_meta_sequence_container_traits {

/**
* @brief Returns a possibly const iterator to the beginning.
* @param area The context to pass to the newly created iterator.
* @param container Opaque pointer to a container of the given type.
* @param as_const True for const-only containers, false otherwise.
* @param it The meta iterator to rebind the underlying iterator to.
* @return An iterator to the first element of the container.
*/
static void begin(const void *container, const bool as_const, iterator &it) {
if(as_const) {
it.rebind(static_cast<const Type *>(container)->begin());
} else {
it.rebind(static_cast<Type *>(const_cast<void *>(container))->begin());
}
static iterator begin(const meta_ctx &area, const void *container, const bool as_const) {
return as_const ? iterator{area, static_cast<const Type *>(container)->begin()}
: iterator{area, static_cast<Type *>(const_cast<void *>(container))->begin()};
}

/**
* @brief Returns a possibly const iterator to the end.
* @param area The context to pass to the newly created iterator.
* @param container Opaque pointer to a container of the given type.
* @param as_const True for const-only containers, false otherwise.
* @param it The meta iterator to rebind the underlying iterator to.
* @return An iterator that is past the last element of the container.
*/
static void end(const void *container, const bool as_const, iterator &it) {
if(as_const) {
it.rebind(static_cast<const Type *>(container)->end());
} else {
it.rebind(static_cast<Type *>(const_cast<void *>(container))->end());
}
static iterator end(const meta_ctx &area, const void *container, const bool as_const) {
return as_const ? iterator{area, static_cast<const Type *>(container)->end()}
: iterator{area, static_cast<Type *>(const_cast<void *>(container))->end()};
}

/**
* @brief Assigns one element to a container and constructs its object from
* a given opaque instance.
* @param area The context to pass to the newly created iterator.
* @param container Opaque pointer to a container of the given type.
* @param value Optional opaque instance of the object to construct (as
* value type).
* @param cref Optional opaque instance of the object to construct (as
* decayed const reference type).
* @param it Iterator before which the element will be inserted.
* @return True in case of success, false otherwise.
* @return A possibly invalid iterator to the inserted element.
*/
[[nodiscard]] static bool insert([[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] iterator &it) {
[[nodiscard]] static iterator insert([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const void *value, [[maybe_unused]] const void *cref, [[maybe_unused]] const iterator &it) {
if constexpr(fixed_size) {
return false;
return iterator{area};
} else {
auto *const non_const = any_cast<typename Type::iterator>(&it.base());

it.rebind(static_cast<Type *>(container)->insert(
non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
value ? *static_cast<const typename Type::value_type *>(value) : *static_cast<const std::remove_reference_t<typename Type::const_reference> *>(cref)));

return true;
return {area, static_cast<Type *>(container)->insert(
non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()),
value ? *static_cast<const typename Type::value_type *>(value) : *static_cast<const std::remove_reference_t<typename Type::const_reference> *>(cref))};
}
}

/**
* @brief Erases an element from a container.
* @param area The context to pass to the newly created iterator.
* @param container Opaque pointer to a container of the given type.
* @param it An opaque iterator to the element to erase.
* @return True in case of success, false otherwise.
* @return A possibly invalid iterator following the last removed element.
*/
[[nodiscard]] static bool erase([[maybe_unused]] void *container, [[maybe_unused]] iterator &it) {
[[nodiscard]] static iterator erase([[maybe_unused]] const meta_ctx &area, [[maybe_unused]] void *container, [[maybe_unused]] const iterator &it) {
if constexpr(fixed_size) {
return false;
return iterator{area};
} else {
auto *const non_const = any_cast<typename Type::iterator>(&it.base());
it.rebind(static_cast<Type *>(container)->erase(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base())));
return true;
return {area, static_cast<Type *>(container)->erase(non_const ? *non_const : any_cast<const typename Type::const_iterator &>(it.base()))};
}
}
};
Expand Down Expand Up @@ -250,30 +245,26 @@ struct basic_meta_associative_container_traits {

/**
* @brief Returns a possibly const iterator to the beginning.
* @param area The context to pass to the newly created iterator.
* @param container Opaque pointer to a container of the given type.
* @param as_const True for const-only containers, false otherwise.
* @param it The meta iterator to rebind the underlying iterator to.
* @return An iterator to the first element of the container.
*/
static void begin(const void *container, const bool as_const, iterator &it) {
if(as_const) {
it.rebind<key_only>(static_cast<const Type *>(container)->begin());
} else {
it.rebind<key_only>(static_cast<Type *>(const_cast<void *>(container))->begin());
}
static iterator begin(const meta_ctx &area, const void *container, const bool as_const) {
return as_const ? iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(container)->begin()}
: iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(const_cast<void *>(container))->begin()};
}

/**
* @brief Returns a possibly const iterator to the end.
* @param area The context to pass to the newly created iterator.
* @param container Opaque pointer to a container of the given type.
* @param as_const True for const-only containers, false otherwise.
* @param it The meta iterator to rebind the underlying iterator to.
* @return An iterator that is past the last element of the container.
*/
static void end(const void *container, const bool as_const, iterator &it) {
if(as_const) {
it.rebind<key_only>(static_cast<const Type *>(container)->end());
} else {
it.rebind<key_only>(static_cast<Type *>(const_cast<void *>(container))->end());
}
static iterator end(const meta_ctx &area, const void *container, const bool as_const) {
return as_const ? iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(container)->end()}
: iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(const_cast<void *>(container))->end()};
}

/**
Expand Down Expand Up @@ -303,17 +294,15 @@ struct basic_meta_associative_container_traits {

/**
* @brief Finds an element with a given key.
* @param area The context to pass to the newly created iterator.
* @param container Opaque pointer to a container of the given type.
* @param as_const True for const-only containers, false otherwise.
* @param key Opaque key value of an element to search for.
* @param it The meta iterator to rebind the underlying iterator to.
* @return An iterator to the element with the given key, if any.
*/
static void find(const void *container, const bool as_const, const void *key, iterator &it) {
if(const auto &elem = *static_cast<const typename Type::key_type *>(key); as_const) {
it.rebind<key_only>(static_cast<const Type *>(container)->find(elem));
} else {
it.rebind<key_only>(static_cast<Type *>(const_cast<void *>(container))->find(elem));
}
static iterator find(const meta_ctx &area, const void *container, const bool as_const, const void *key) {
return as_const ? iterator{area, std::bool_constant<key_only>{}, static_cast<const Type *>(container)->find(*static_cast<const typename Type::key_type *>(key))}
: iterator{area, std::bool_constant<key_only>{}, static_cast<Type *>(const_cast<void *>(container))->find(*static_cast<const typename Type::key_type *>(key))};
}
};

Expand Down
63 changes: 25 additions & 38 deletions src/entt/meta/meta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ class meta_sequence_container {
bool (*clear_fn)(void *){};
bool (*reserve_fn)(void *, const size_type){};
bool (*resize_fn)(void *, const size_type){};
void (*begin_fn)(const void *, const bool, iterator &){};
void (*end_fn)(const void *, const bool, iterator &){};
bool (*insert_fn)(void *, const void *, const void *, iterator &){};
bool (*erase_fn)(void *, iterator &){};
iterator (*begin_fn)(const meta_ctx &, const void *, const bool){};
iterator (*end_fn)(const meta_ctx &, const void *, const bool){};
iterator (*insert_fn)(const meta_ctx &, void *, const void *, const void *, const iterator &){};
iterator (*erase_fn)(const meta_ctx &, void *, const iterator &){};
any storage{};
};

Expand Down Expand Up @@ -162,11 +162,11 @@ class meta_associative_container {
size_type (*size_fn)(const void *){};
bool (*clear_fn)(void *){};
bool (*reserve_fn)(void *, const size_type){};
void (*begin_fn)(const void *, const bool, iterator &){};
void (*end_fn)(const void *, const bool, iterator &){};
iterator (*begin_fn)(const meta_ctx &, const void *, const bool){};
iterator (*end_fn)(const meta_ctx &, const void *, const bool){};
bool (*insert_fn)(void *, const void *, const void *){};
size_type (*erase_fn)(void *, const void *){};
void (*find_fn)(const void *, const bool, const void *, iterator &){};
iterator (*find_fn)(const meta_ctx &, const void *, const bool, const void *){};
any storage{};
};

Expand Down Expand Up @@ -1650,10 +1650,10 @@ class meta_sequence_container::meta_iterator final {
: ctx{&area} {}

template<typename It>
void rebind(It iter) noexcept {
vtable = &basic_vtable<It>;
handle = iter;
}
meta_iterator(const meta_ctx &area, It iter) noexcept
: ctx{&area},
vtable{&basic_vtable<It>},
handle{iter} {}

meta_iterator &operator++() noexcept {
vtable(handle.data(), 1, nullptr);
Expand Down Expand Up @@ -1740,10 +1740,10 @@ class meta_associative_container::meta_iterator final {
: ctx{&area} {}

template<bool KeyOnly, typename It>
void rebind(It iter) noexcept {
vtable = &basic_vtable<KeyOnly, It>;
handle = iter;
}
meta_iterator(const meta_ctx &area, std::bool_constant<KeyOnly>, It iter) noexcept
: ctx{&area},
vtable{&basic_vtable<KeyOnly, It>},
handle{iter} {}

meta_iterator &operator++() noexcept {
vtable(handle.data(), nullptr);
Expand Down Expand Up @@ -1836,19 +1836,15 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
* @return An iterator to the first element of the container.
*/
[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::begin() {
iterator it{*ctx};
begin_fn(std::as_const(storage).data(), storage.policy() == any_policy::cref, it);
return it;
return begin_fn(*ctx, std::as_const(storage).data(), storage.policy() == any_policy::cref);
}

/**
* @brief Returns an iterator that is past the last element of a container.
* @return An iterator that is past the last element of the container.
*/
[[nodiscard]] inline meta_sequence_container::iterator meta_sequence_container::end() {
iterator it{*ctx};
end_fn(std::as_const(storage).data(), storage.policy() == any_policy::cref, it);
return it;
return end_fn(*ctx, std::as_const(storage).data(), storage.policy() == any_policy::cref);
}

/**
Expand All @@ -1860,9 +1856,8 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
// this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
if(const auto vtype = value_type_node(internal::meta_context::from(*ctx)); (storage.policy() != any_policy::cref) && (value.allow_cast({*ctx, vtype}) || value.allow_cast({*ctx, const_reference_node(internal::meta_context::from(*ctx))}))) {
if(const bool is_value_type = (value.type().info() == *vtype.info); insert_fn(storage.data(), is_value_type ? std::as_const(value).data() : nullptr, is_value_type ? nullptr : std::as_const(value).data(), it)) {
return it;
}
const bool is_value_type = (value.type().info() == *vtype.info);
return insert_fn(*ctx, storage.data(), is_value_type ? std::as_const(value).data() : nullptr, is_value_type ? nullptr : std::as_const(value).data(), it);
}

return iterator{*ctx};
Expand All @@ -1874,7 +1869,7 @@ inline meta_sequence_container::iterator meta_sequence_container::insert(iterato
* @return A possibly invalid iterator following the last removed element.
*/
inline meta_sequence_container::iterator meta_sequence_container::erase(iterator it) {
return ((storage.policy() != any_policy::cref) && erase_fn(storage.data(), it)) ? it : iterator{*ctx};
return (storage.policy() != any_policy::cref) ? erase_fn(*ctx, storage.data(), it) : iterator{*ctx};
}

/**
Expand Down Expand Up @@ -1943,16 +1938,12 @@ inline bool meta_associative_container::reserve(const size_type sz) {

/*! @copydoc meta_sequence_container::begin */
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
iterator it{*ctx};
begin_fn(std::as_const(storage).data(), storage.policy() == any_policy::cref, it);
return it;
return begin_fn(*ctx, std::as_const(storage).data(), storage.policy() == any_policy::cref);
}

/*! @copydoc meta_sequence_container::end */
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
iterator it{*ctx};
end_fn(std::as_const(storage).data(), storage.policy() == any_policy::cref, it);
return it;
return end_fn(*ctx, std::as_const(storage).data(), storage.policy() == any_policy::cref);
}

/**
Expand Down Expand Up @@ -1982,13 +1973,9 @@ inline meta_associative_container::size_type meta_associative_container::erase(m
* @return An iterator to the element with the given key, if any.
*/
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
iterator it{*ctx};

if(key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})) {
find_fn(std::as_const(storage).data(), storage.policy() == any_policy::cref, std::as_const(key).data(), it);
}

return it;
return key.allow_cast(meta_type{*ctx, key_type_node(internal::meta_context::from(*ctx))})
? find_fn(*ctx, std::as_const(storage).data(), storage.policy() == any_policy::cref, std::as_const(key).data())
: iterator{*ctx};
}

/**
Expand Down

0 comments on commit 24c95e4

Please sign in to comment.