meta: exploit vtable params for meta containers
This commit is contained in:
@@ -52,44 +52,44 @@ struct basic_meta_sequence_container_traits {
|
||||
using size_type = typename meta_sequence_container::size_type;
|
||||
using iterator = typename meta_sequence_container::iterator;
|
||||
|
||||
static size_type basic_vtable(const operation op, const meta_ctx &ctx, const void *container, void *value, iterator *it) {
|
||||
switch(const Type *cont = static_cast<const Type *>(container); op) {
|
||||
static size_type basic_vtable(const operation op, const meta_ctx &ctx, const void *cvalue, void *value, iterator *it) {
|
||||
switch(op) {
|
||||
case operation::size:
|
||||
return cont->size();
|
||||
return static_cast<const Type *>(cvalue)->size();
|
||||
case operation::clear:
|
||||
if constexpr(dynamic_sequence_container<Type>::value) {
|
||||
const_cast<Type *>(cont)->clear();
|
||||
static_cast<Type *>(value)->clear();
|
||||
return true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case operation::reserve:
|
||||
if constexpr(reserve_aware_container<Type>::value) {
|
||||
const_cast<Type *>(cont)->reserve(*static_cast<size_type *>(value));
|
||||
static_cast<Type *>(value)->reserve(*static_cast<const size_type *>(cvalue));
|
||||
return true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case operation::resize:
|
||||
if constexpr(dynamic_sequence_container<Type>::value) {
|
||||
const_cast<Type *>(cont)->resize(*static_cast<size_type *>(value));
|
||||
static_cast<Type *>(value)->resize(*static_cast<const size_type *>(cvalue));
|
||||
return true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case operation::begin:
|
||||
if(value) {
|
||||
*it = iterator{ctx, const_cast<Type *>(cont)->begin()};
|
||||
*it = iterator{ctx, static_cast<Type *>(value)->begin()};
|
||||
} else {
|
||||
*it = iterator{ctx, cont->begin()};
|
||||
*it = iterator{ctx, static_cast<const Type *>(cvalue)->begin()};
|
||||
}
|
||||
|
||||
return true;
|
||||
case operation::end:
|
||||
if(value) {
|
||||
*it = iterator{ctx, const_cast<Type *>(cont)->end()};
|
||||
*it = iterator{ctx, static_cast<Type *>(value)->end()};
|
||||
} else {
|
||||
*it = iterator{ctx, cont->end()};
|
||||
*it = iterator{ctx, static_cast<const Type *>(cvalue)->end()};
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -101,13 +101,13 @@ struct basic_meta_sequence_container_traits {
|
||||
|
||||
if(op == operation::insert) {
|
||||
// this abomination is necessary because only on macos value_type and const_reference are different types for std::vector<bool>
|
||||
if(static_cast<meta_any *>(value)->allow_cast<typename Type::const_reference>() || static_cast<meta_any *>(value)->allow_cast<typename Type::value_type>()) {
|
||||
const auto *element = static_cast<meta_any *>(value)->try_cast<std::remove_reference_t<typename Type::const_reference>>();
|
||||
*it = iterator{ctx, const_cast<Type *>(cont)->insert(underlying, element ? *element : static_cast<meta_any *>(value)->cast<typename Type::value_type>())};
|
||||
if(auto &any = *static_cast<meta_any *>(const_cast<void *>(cvalue)); any.allow_cast<typename Type::const_reference>() || any.allow_cast<typename Type::value_type>()) {
|
||||
const auto *element = any.try_cast<std::remove_reference_t<typename Type::const_reference>>();
|
||||
*it = iterator{ctx, static_cast<Type *>(value)->insert(underlying, element ? *element : any.cast<typename Type::value_type>())};
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
*it = iterator{ctx, const_cast<Type *>(cont)->erase(underlying)};
|
||||
*it = iterator{ctx, static_cast<Type *>(value)->erase(underlying)};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -129,63 +129,63 @@ struct basic_meta_associative_container_traits {
|
||||
|
||||
static constexpr auto key_only = key_only_associative_container<Type>::value;
|
||||
|
||||
static size_type basic_vtable(const operation op, const meta_ctx &ctx, const void *container, meta_any *key, void *value, iterator *it) {
|
||||
switch(const Type *cont = static_cast<const Type *>(container); op) {
|
||||
static size_type basic_vtable(const operation op, const meta_ctx &ctx, const void *cvalue, void *value, meta_any *key, iterator *it) {
|
||||
switch(op) {
|
||||
case operation::size:
|
||||
return cont->size();
|
||||
return static_cast<const Type *>(cvalue)->size();
|
||||
case operation::clear:
|
||||
const_cast<Type *>(cont)->clear();
|
||||
static_cast<Type *>(value)->clear();
|
||||
return true;
|
||||
case operation::reserve:
|
||||
if constexpr(reserve_aware_container<Type>::value) {
|
||||
const_cast<Type *>(cont)->reserve(*static_cast<size_type *>(value));
|
||||
static_cast<Type *>(value)->reserve(*static_cast<const size_type *>(cvalue));
|
||||
return true;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
case operation::begin:
|
||||
if(value) {
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, const_cast<Type *>(cont)->begin()};
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<Type *>(value)->begin()};
|
||||
} else {
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, cont->begin()};
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<const Type *>(cvalue)->begin()};
|
||||
}
|
||||
|
||||
return true;
|
||||
case operation::end:
|
||||
if(value) {
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, const_cast<Type *>(cont)->end()};
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<Type *>(value)->end()};
|
||||
} else {
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, cont->end()};
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<const Type *>(cvalue)->end()};
|
||||
}
|
||||
|
||||
return true;
|
||||
case operation::insert:
|
||||
if(key->allow_cast<const typename Type::key_type &>()) {
|
||||
if constexpr(key_only) {
|
||||
return const_cast<Type *>(cont)->insert(key->cast<const typename Type::key_type &>()).second;
|
||||
return static_cast<Type *>(value)->insert(key->cast<const typename Type::key_type &>()).second;
|
||||
} else {
|
||||
meta_any *val = static_cast<meta_any *>(value);
|
||||
return val->allow_cast<const typename Type::mapped_type &>() && const_cast<Type *>(cont)->emplace(key->cast<const typename Type::key_type &>(), val->cast<const typename Type::mapped_type &>()).second;
|
||||
auto &any = *static_cast<meta_any *>(const_cast<void *>(cvalue));
|
||||
return any.allow_cast<const typename Type::mapped_type &>() && static_cast<Type *>(value)->emplace(key->cast<const typename Type::key_type &>(), any.cast<const typename Type::mapped_type &>()).second;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case operation::erase:
|
||||
if(key->allow_cast<const typename Type::key_type &>()) {
|
||||
return const_cast<Type *>(cont)->erase(key->cast<const typename Type::key_type &>());
|
||||
return static_cast<Type *>(value)->erase(key->cast<const typename Type::key_type &>());
|
||||
}
|
||||
|
||||
break;
|
||||
case operation::find:
|
||||
if(key->allow_cast<const typename Type::key_type &>()) {
|
||||
if(value) {
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, const_cast<Type *>(cont)->find(key->cast<const typename Type::key_type &>())};
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<Type *>(value)->find(key->cast<const typename Type::key_type &>())};
|
||||
} else {
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, cont->find(key->cast<const typename Type::key_type &>())};
|
||||
*it = iterator{ctx, std::bool_constant<key_only>{}, static_cast<const Type *>(cvalue)->find(key->cast<const typename Type::key_type &>())};
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ private:
|
||||
internal::meta_type_node (*key_type_node)(const internal::meta_context &){};
|
||||
internal::meta_type_node (*mapped_type_node)(const internal::meta_context &){};
|
||||
internal::meta_type_node (*value_type_node)(const internal::meta_context &){};
|
||||
size_type (*vtable)(const operation, const meta_ctx &, const void *, meta_any *, void *, iterator *){};
|
||||
size_type (*vtable)(const operation, const meta_ctx &, const void *, void *, meta_any *, iterator *){};
|
||||
any storage{};
|
||||
};
|
||||
|
||||
@@ -1875,8 +1875,7 @@ private:
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
inline bool meta_sequence_container::resize(const size_type sz) {
|
||||
auto local = sz;
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::resize, *ctx, storage.data(), &local, nullptr);
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::resize, *ctx, &sz, storage.data(), nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1884,7 +1883,7 @@ inline bool meta_sequence_container::resize(const size_type sz) {
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
inline bool meta_sequence_container::clear() {
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::clear, *ctx, storage.data(), nullptr, nullptr);
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::clear, *ctx, nullptr, storage.data(), nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1893,8 +1892,7 @@ inline bool meta_sequence_container::clear() {
|
||||
* @return True in case of success, false otherwise.
|
||||
*/
|
||||
inline bool meta_sequence_container::reserve(const size_type sz) {
|
||||
auto local = sz;
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::reserve, *ctx, storage.data(), &local, nullptr);
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::reserve, *ctx, &sz, storage.data(), nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1926,7 +1924,7 @@ inline bool meta_sequence_container::reserve(const size_type sz) {
|
||||
* @return A possibly invalid iterator to the inserted element.
|
||||
*/
|
||||
inline meta_sequence_container::iterator meta_sequence_container::insert(iterator it, meta_any value) {
|
||||
return ((storage.policy() != any_policy::cref) && vtable(operation::insert, *ctx, storage.data(), &value, &it)) ? it : iterator{};
|
||||
return ((storage.policy() != any_policy::cref) && vtable(operation::insert, *ctx, &value, storage.data(), &it)) ? it : iterator{};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1935,7 +1933,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) && vtable(operation::erase, *ctx, storage.data(), nullptr, &it)) ? it : iterator{};
|
||||
return ((storage.policy() != any_policy::cref) && vtable(operation::erase, *ctx, nullptr, storage.data(), &it)) ? it : iterator{};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1994,20 +1992,19 @@ inline meta_sequence_container::iterator meta_sequence_container::erase(iterator
|
||||
|
||||
/*! @copydoc meta_sequence_container::clear */
|
||||
inline bool meta_associative_container::clear() {
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::clear, *ctx, storage.data(), nullptr, nullptr, nullptr);
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::clear, *ctx, nullptr, storage.data(), nullptr, nullptr);
|
||||
}
|
||||
|
||||
/*! @copydoc meta_sequence_container::reserve */
|
||||
inline bool meta_associative_container::reserve(const size_type sz) {
|
||||
auto local = sz;
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::reserve, *ctx, storage.data(), nullptr, &local, nullptr);
|
||||
return (storage.policy() != any_policy::cref) && vtable(operation::reserve, *ctx, &sz, storage.data(), nullptr, nullptr);
|
||||
}
|
||||
|
||||
/*! @copydoc meta_sequence_container::begin */
|
||||
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::begin() {
|
||||
iterator it{};
|
||||
const void *data = std::as_const(storage).data();
|
||||
vtable(operation::begin, *ctx, data, nullptr, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
|
||||
vtable(operation::begin, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), nullptr, &it);
|
||||
return it;
|
||||
}
|
||||
|
||||
@@ -2015,7 +2012,7 @@ inline bool meta_associative_container::reserve(const size_type sz) {
|
||||
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::end() {
|
||||
iterator it{};
|
||||
const void *data = std::as_const(storage).data();
|
||||
vtable(operation::end, *ctx, data, nullptr, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
|
||||
vtable(operation::end, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), nullptr, &it);
|
||||
return it;
|
||||
}
|
||||
|
||||
@@ -2026,7 +2023,7 @@ inline bool meta_associative_container::reserve(const size_type sz) {
|
||||
* @return A bool denoting whether the insertion took place.
|
||||
*/
|
||||
inline bool meta_associative_container::insert(meta_any key, meta_any value = {}) {
|
||||
return ((storage.policy() != any_policy::cref) && vtable(operation::insert, *ctx, storage.data(), &key, &value, nullptr));
|
||||
return ((storage.policy() != any_policy::cref) && vtable(operation::insert, *ctx, &value, storage.data(), &key, nullptr));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2035,7 +2032,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 ((storage.policy() != any_policy::cref) && vtable(operation::erase, *ctx, storage.data(), &key, nullptr, nullptr));
|
||||
return ((storage.policy() != any_policy::cref) && vtable(operation::erase, *ctx, nullptr, storage.data(), &key, nullptr));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2046,7 +2043,7 @@ inline meta_associative_container::size_type meta_associative_container::erase(m
|
||||
[[nodiscard]] inline meta_associative_container::iterator meta_associative_container::find(meta_any key) {
|
||||
iterator it{};
|
||||
const void *data = std::as_const(storage).data();
|
||||
vtable(operation::find, *ctx, data, &key, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &it);
|
||||
vtable(operation::find, *ctx, data, storage.policy() == any_policy::cref ? nullptr : const_cast<void *>(data), &key, &it);
|
||||
return it;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user