meta: reduce cost of meta prop
This commit is contained in:
@@ -111,13 +111,19 @@ protected:
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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{};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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 */
|
||||
@@ -1422,7 +1432,7 @@ public:
|
||||
* @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{};
|
||||
}
|
||||
|
||||
@@ -1444,7 +1454,7 @@ public:
|
||||
* @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{};
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -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 {
|
||||
@@ -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 {
|
||||
@@ -162,12 +162,31 @@ 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 = deprecated_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)>::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;
|
||||
@@ -175,7 +194,7 @@ 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);
|
||||
return static_cast<typename std::remove_reference_t<decltype(node.details.get()->*Member)>::value_type *>(nullptr);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
|
||||
@@ -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>;
|
||||
@@ -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}};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user