meta: reduce a little the number and size of vtables/fake functions

This commit is contained in:
Michele Caini
2022-07-04 08:26:53 +02:00
parent 437f1fea54
commit 3318ac2699
2 changed files with 31 additions and 42 deletions
+22 -29
View File
@@ -63,13 +63,18 @@ struct basic_meta_sequence_container_traits {
return iterator{as_const, static_cast<typename iterator::difference_type>(as_end * as_const.size())};
}
[[nodiscard]] static iterator insert([[maybe_unused]] any &container, [[maybe_unused]] const std::ptrdiff_t offset, [[maybe_unused]] meta_any &value) {
[[nodiscard]] static iterator insert_or_erase([[maybe_unused]] any &container, [[maybe_unused]] const std::ptrdiff_t offset, [[maybe_unused]] meta_any &value) {
if constexpr(is_dynamic_sequence_container<Type>::value) {
if(auto *const cont = any_cast<Type>(&container); cont) {
// this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
if(value.allow_cast<typename Type::const_reference>() || value.allow_cast<typename Type::value_type>()) {
const auto *element = value.try_cast<std::remove_reference_t<typename Type::const_reference>>();
const auto curr = cont->insert(cont->begin() + offset, element ? *element : value.cast<typename Type::value_type>());
if(value) {
// this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
if(value.allow_cast<typename Type::const_reference>() || value.allow_cast<typename Type::value_type>()) {
const auto *element = value.try_cast<std::remove_reference_t<typename Type::const_reference>>();
const auto curr = cont->insert(cont->begin() + offset, element ? *element : value.cast<typename Type::value_type>());
return iterator{*cont, curr - cont->begin()};
}
} else {
const auto curr = cont->erase(cont->begin() + offset);
return iterator{*cont, curr - cont->begin()};
}
}
@@ -77,17 +82,6 @@ struct basic_meta_sequence_container_traits {
return {};
}
[[nodiscard]] static iterator erase([[maybe_unused]] any &container, [[maybe_unused]] const std::ptrdiff_t offset) {
if constexpr(is_dynamic_sequence_container<Type>::value) {
if(auto *const cont = any_cast<Type>(&container); cont) {
const auto curr = cont->erase(cont->begin() + offset);
return iterator{*cont, curr - cont->begin()};
}
}
return {};
}
};
template<typename Type>
@@ -119,21 +113,20 @@ struct basic_meta_associative_container_traits {
return iterator{std::integral_constant<bool, key_only>{}, as_end ? as_const.end() : as_const.begin()};
}
[[nodiscard]] static bool insert(any &container, meta_any &key, [[maybe_unused]] meta_any &value) {
auto *const cont = any_cast<Type>(&container);
if constexpr(is_key_only_meta_associative_container<Type>::value) {
return cont && key.allow_cast<const typename Type::key_type &>()
&& cont->insert(key.cast<const typename Type::key_type &>()).second;
} else {
return cont && key.allow_cast<const typename Type::key_type &>() && value.allow_cast<const typename Type::mapped_type &>()
&& cont->emplace(key.cast<const typename Type::key_type &>(), value.cast<const typename Type::mapped_type &>()).second;
[[nodiscard]] static size_type insert_or_erase(any &container, meta_any &key, meta_any &value) {
if(auto *const cont = any_cast<Type>(&container); cont && key.allow_cast<const typename Type::key_type &>()) {
if(value) {
if constexpr(is_key_only_meta_associative_container<Type>::value) {
return cont->insert(key.cast<const typename Type::key_type &>()).second;
} else {
return value.allow_cast<const typename Type::mapped_type &>() && cont->emplace(key.cast<const typename Type::key_type &>(), value.cast<const typename Type::mapped_type &>()).second;
}
} else {
return cont->erase(key.cast<const typename Type::key_type &>());
}
}
}
[[nodiscard]] static size_type erase(any &container, meta_any &key) {
auto *const cont = any_cast<Type>(&container);
return cont && key.allow_cast<const typename Type::key_type &>() ? cont->erase(key.cast<const typename Type::key_type &>()) : size_type{};
return 0u;
}
[[nodiscard]] static iterator find(any &container, meta_any &key) {
+9 -13
View File
@@ -49,8 +49,7 @@ public:
size_fn{&meta_sequence_container_traits<Type>::size},
resize_fn{&meta_sequence_container_traits<Type>::resize},
iter_fn{&meta_sequence_container_traits<Type>::iter},
insert_fn{&meta_sequence_container_traits<Type>::insert},
erase_fn{&meta_sequence_container_traits<Type>::erase},
insert_or_erase_fn{&meta_sequence_container_traits<Type>::insert_or_erase},
storage{std::move(instance)} {}
[[nodiscard]] inline meta_type value_type() const noexcept;
@@ -69,8 +68,7 @@ private:
size_type (*size_fn)(const any &) noexcept = nullptr;
bool (*resize_fn)(any &, size_type) = nullptr;
iterator (*iter_fn)(any &, const bool) = nullptr;
iterator (*insert_fn)(any &, const std::ptrdiff_t, meta_any &) = nullptr;
iterator (*erase_fn)(any &, const std::ptrdiff_t) = nullptr;
iterator (*insert_or_erase_fn)(any &, const std::ptrdiff_t, meta_any &) = nullptr;
any storage{};
};
@@ -101,8 +99,7 @@ public:
size_fn{&meta_associative_container_traits<Type>::size},
clear_fn{&meta_associative_container_traits<Type>::clear},
iter_fn{&meta_associative_container_traits<Type>::iter},
insert_fn{&meta_associative_container_traits<Type>::insert},
erase_fn{&meta_associative_container_traits<Type>::erase},
insert_or_erase_fn{&meta_associative_container_traits<Type>::insert_or_erase},
find_fn{&meta_associative_container_traits<Type>::find},
storage{std::move(instance)} {
if constexpr(!meta_associative_container_traits<Type>::key_only) {
@@ -131,8 +128,7 @@ private:
size_type (*size_fn)(const any &) noexcept = nullptr;
bool (*clear_fn)(any &) = nullptr;
iterator (*iter_fn)(any &, const bool) = nullptr;
bool (*insert_fn)(any &, meta_any &, meta_any &) = nullptr;
size_type (*erase_fn)(any &, meta_any &) = nullptr;
size_type (*insert_or_erase_fn)(any &, meta_any &, meta_any &) = nullptr;
iterator (*find_fn)(any &, meta_any &) = nullptr;
any storage{};
};
@@ -1668,7 +1664,7 @@ inline bool meta_sequence_container::clear() {
* @return A possibly invalid iterator to the inserted element.
*/
inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
return insert_fn(storage, it.offset, value);
return insert_or_erase_fn(storage, it.offset, value);
}
/**
@@ -1677,7 +1673,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 erase_fn(storage, it.offset);
return insert(std::move(it), {});
}
/**
@@ -1755,8 +1751,8 @@ inline bool meta_associative_container::clear() {
* @param value The value of the element to insert.
* @return A bool denoting whether the insertion took place.
*/
inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
return insert_fn(storage, key, value);
inline bool meta_associative_container::insert(meta_any key, meta_any value = std::in_place_type<void>) {
return (insert_or_erase_fn(storage, key, value) != 0u);
}
/**
@@ -1765,7 +1761,7 @@ inline bool meta_associative_container::insert(meta_any key, meta_any value = {}
* @return A bool denoting whether the removal took place.
*/
inline meta_associative_container::size_type meta_associative_container::erase(meta_any key) {
return erase_fn(storage, key);
return insert(std::move(key), {});
}
/**