Skip to content

Commit

Permalink
meta: reduce cost of meta prop
Browse files Browse the repository at this point in the history
  • Loading branch information
skypjack committed Aug 27, 2024
1 parent 9c6780c commit da615cc
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 15 deletions.
12 changes: 9 additions & 3 deletions src/entt/meta/factory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,19 @@ class basic_meta_factory {
}

void prop(meta_prop_node node) {
std::vector<meta_prop_node> *container = nullptr;

if(bucket == parent) {
details->prop[node.id] = std::move(node);
container = &details->prop;
} else if(invoke == nullptr) {
find_member(details->data)->prop[node.id] = std::move(node);
container = &find_member(details->data)->prop;
} else {
find_overload()->prop[node.id] = std::move(node);
container = &find_overload()->prop;
}

std::size_t pos{};
for(const std::size_t last = container->size(); (pos != last) && ((*container)[pos].id != node.id); ++pos) {}
(pos == container->size()) ? container->emplace_back(std::move(node)) : ((*container)[pos] = std::move(node));
}

void traits(const meta_traits value) {
Expand Down
22 changes: 16 additions & 6 deletions src/entt/meta/meta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,8 +948,13 @@ struct meta_data {
* @return The registered meta property for the given key, if any.
*/
[[nodiscard]] meta_prop prop(const id_type key) const {
const auto it = node->prop.find(key);
return it != node->prop.cend() ? meta_prop{*ctx, it->second} : meta_prop{};
for(auto &&elem: node->prop) {
if(elem.id == key) {
return meta_prop{*ctx, elem};
}
}

return meta_prop{};
}

/**
Expand Down Expand Up @@ -1088,8 +1093,13 @@ struct meta_func {
* @return The registered meta property for the given key, if any.
*/
[[nodiscard]] meta_prop prop(const id_type key) const {
const auto it = node->prop.find(key);
return it != node->prop.cend() ? meta_prop{*ctx, it->second} : meta_prop{};
for(auto &&elem: node->prop) {
if(elem.id == key) {
return meta_prop{*ctx, elem};
}
}

return meta_prop{};
}

/*! @copydoc meta_data::traits */
Expand Down Expand Up @@ -1422,7 +1432,7 @@ class meta_type {
* @return The registered meta data for the given identifier, if any.
*/
[[nodiscard]] meta_data data(const id_type id) const {
const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), node, id);
const auto *elem = internal::deprecated_look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), node, id);
return elem ? meta_data{*ctx, *elem} : meta_data{};
}

Expand All @@ -1444,7 +1454,7 @@ class meta_type {
* @return The registered meta function for the given identifier, if any.
*/
[[nodiscard]] meta_func func(const id_type id) const {
const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), node, id);
const auto *elem = internal::deprecated_look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), node, id);
return elem ? meta_func{*ctx, *elem} : meta_func{};
}

Expand Down
29 changes: 24 additions & 5 deletions src/entt/meta/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ struct meta_data_node {
bool (*set)(meta_handle, meta_any){};
meta_any (*get)(const meta_ctx &, meta_handle){};
meta_custom_node custom{};
dense_map<id_type, meta_prop_node, identity> prop{};
std::vector<meta_prop_node> prop{};
};

struct meta_func_node {
Expand All @@ -123,7 +123,7 @@ struct meta_func_node {
meta_any (*invoke)(const meta_ctx &, meta_handle, meta_any *const){};
std::shared_ptr<meta_func_node> next{};
meta_custom_node custom{};
dense_map<id_type, meta_prop_node, identity> prop{};
std::vector<meta_prop_node> prop{};
};

struct meta_template_node {
Expand All @@ -140,7 +140,7 @@ struct meta_type_descriptor {
std::vector<meta_conv_node> conv{};
dense_map<id_type, meta_data_node, identity> data{};
dense_map<id_type, meta_func_node, identity> func{};
dense_map<id_type, meta_prop_node, identity> prop{};
std::vector<meta_prop_node> prop{};
};

struct meta_type_node {
Expand All @@ -162,14 +162,14 @@ struct meta_type_node {
};

template<auto Member>
auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id) {
auto *deprecated_look_for(const meta_context &context, const meta_type_node &node, const id_type id) {
if(node.details) {
if(const auto it = (node.details.get()->*Member).find(id); it != (node.details.get()->*Member).cend()) {
return &it->second;
}

for(auto &&curr: node.details->base) {
if(auto *elem = look_for<Member>(context, curr.second.type(context), id); elem) {
if(auto *elem = deprecated_look_for<Member>(context, curr.second.type(context), id); elem) {
return elem;
}
}
Expand All @@ -178,6 +178,25 @@ auto *look_for(const meta_context &context, const meta_type_node &node, const id
return static_cast<typename std::remove_reference_t<decltype(node.details.get()->*Member)>::mapped_type *>(nullptr);
}

template<auto Member>
auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id) {
if(node.details) {
for(auto &&elem: (node.details.get()->*Member)) {
if(elem.id == id) {
return &elem;
}
}

for(auto &&curr: node.details->base) {
if(auto *elem = look_for<Member>(context, curr.second.type(context), id); elem) {
return elem;
}
}
}

return static_cast<typename std::remove_reference_t<decltype(node.details.get()->*Member)>::value_type *>(nullptr);
}

template<typename Type>
meta_type_node resolve(const meta_context &) noexcept;

Expand Down
83 changes: 82 additions & 1 deletion src/entt/meta/range.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace entt {
/*! @cond TURN_OFF_DOXYGEN */
namespace internal {

template<typename Type, typename It>
template<typename Type, typename It, typename = void>
struct meta_range_iterator final {
using value_type = std::pair<id_type, Type>;
using pointer = input_iterator_pointer<value_type>;
Expand Down Expand Up @@ -66,6 +66,87 @@ struct meta_range_iterator final {
return (*this + -value);
}

[[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
return {it[value].id, Type{*ctx, it[value]}};
}

[[nodiscard]] constexpr pointer operator->() const noexcept {
return operator*();
}

[[nodiscard]] constexpr reference operator*() const noexcept {
return operator[](0);
}

template<typename... Args>
friend constexpr std::ptrdiff_t operator-(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;

template<typename... Args>
friend constexpr bool operator==(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;

template<typename... Args>
friend constexpr bool operator<(const meta_range_iterator<Args...> &, const meta_range_iterator<Args...> &) noexcept;

private:
It it;
const meta_ctx *ctx;
};

template<typename Type, typename It>
struct meta_range_iterator<Type, It, std::void_t<typename std::iterator_traits<It>::value_type::second_type>> final {
// deprecated work-in-progress specialization

using value_type = std::pair<id_type, Type>;
using pointer = input_iterator_pointer<value_type>;
using reference = value_type;
using difference_type = std::ptrdiff_t;
using iterator_category = std::input_iterator_tag;
using iterator_concept = std::random_access_iterator_tag;

constexpr meta_range_iterator() noexcept
: it{},
ctx{} {}

constexpr meta_range_iterator(const meta_ctx &area, const It iter) noexcept
: it{iter},
ctx{&area} {}

constexpr meta_range_iterator &operator++() noexcept {
return ++it, *this;
}

constexpr meta_range_iterator operator++(int) noexcept {
meta_range_iterator orig = *this;
return ++(*this), orig;
}

constexpr meta_range_iterator &operator--() noexcept {
return --it, *this;
}

constexpr meta_range_iterator operator--(int) noexcept {
meta_range_iterator orig = *this;
return operator--(), orig;
}

constexpr meta_range_iterator &operator+=(const difference_type value) noexcept {
it += value;
return *this;
}

constexpr meta_range_iterator operator+(const difference_type value) const noexcept {
meta_range_iterator copy = *this;
return (copy += value);
}

constexpr meta_range_iterator &operator-=(const difference_type value) noexcept {
return (*this += -value);
}

constexpr meta_range_iterator operator-(const difference_type value) const noexcept {
return (*this + -value);
}

[[nodiscard]] constexpr reference operator[](const difference_type value) const noexcept {
return {it[value].first, Type{*ctx, it[value].second}};
}
Expand Down

0 comments on commit da615cc

Please sign in to comment.