meta: avoid a (maybe) UB in meta_any
This commit is contained in:
@@ -155,7 +155,7 @@ class meta_any {
|
||||
using vtable_type = void(const operation, const any &, void *);
|
||||
|
||||
template<typename Type>
|
||||
static void basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const any &from, [[maybe_unused]] void *to) {
|
||||
static void basic_vtable([[maybe_unused]] const operation op, [[maybe_unused]] const any &value, [[maybe_unused]] void *other) {
|
||||
static_assert(std::is_same_v<std::remove_reference_t<std::remove_const_t<Type>>, Type>, "Invalid type");
|
||||
|
||||
if constexpr(!std::is_void_v<Type>) {
|
||||
@@ -163,21 +163,21 @@ class meta_any {
|
||||
case operation::deref:
|
||||
if constexpr(is_meta_pointer_like_v<Type>) {
|
||||
if constexpr(std::is_function_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>>) {
|
||||
*static_cast<meta_any *>(to) = any_cast<Type>(from);
|
||||
*static_cast<meta_any *>(other) = any_cast<Type>(value);
|
||||
} else if constexpr(!std::is_same_v<std::remove_const_t<typename std::pointer_traits<Type>::element_type>, void>) {
|
||||
using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(from)));
|
||||
static_cast<meta_any *>(to)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(from)));
|
||||
using in_place_type = decltype(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
|
||||
static_cast<meta_any *>(other)->emplace<in_place_type>(adl_meta_pointer_like<Type>::dereference(any_cast<const Type &>(value)));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case operation::seq:
|
||||
if constexpr(is_complete_v<meta_sequence_container_traits<Type>>) {
|
||||
*static_cast<meta_sequence_container *>(to) = {std::in_place_type<Type>, std::move(const_cast<any &>(from))};
|
||||
*static_cast<meta_sequence_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
|
||||
}
|
||||
break;
|
||||
case operation::assoc:
|
||||
if constexpr(is_complete_v<meta_associative_container_traits<Type>>) {
|
||||
*static_cast<meta_associative_container *>(to) = {std::in_place_type<Type>, std::move(const_cast<any &>(from))};
|
||||
*static_cast<meta_associative_container *>(other) = {std::in_place_type<Type>, std::move(const_cast<any &>(value))};
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -509,15 +509,17 @@ public:
|
||||
* @return A sequence container proxy for the underlying object.
|
||||
*/
|
||||
[[nodiscard]] meta_sequence_container as_sequence_container() ENTT_NOEXCEPT {
|
||||
any detached = storage.as_ref();
|
||||
meta_sequence_container proxy;
|
||||
vtable(operation::seq, storage.as_ref(), &proxy);
|
||||
vtable(operation::seq, detached, &proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
/*! @copydoc as_sequence_container */
|
||||
[[nodiscard]] meta_sequence_container as_sequence_container() const ENTT_NOEXCEPT {
|
||||
any detached = storage.as_ref();
|
||||
meta_sequence_container proxy;
|
||||
vtable(operation::seq, storage.as_ref(), &proxy);
|
||||
vtable(operation::seq, detached, &proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@@ -526,15 +528,17 @@ public:
|
||||
* @return An associative container proxy for the underlying object.
|
||||
*/
|
||||
[[nodiscard]] meta_associative_container as_associative_container() ENTT_NOEXCEPT {
|
||||
any detached = storage.as_ref();
|
||||
meta_associative_container proxy;
|
||||
vtable(operation::assoc, storage.as_ref(), &proxy);
|
||||
vtable(operation::assoc, detached, &proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
/*! @copydoc as_associative_container */
|
||||
[[nodiscard]] meta_associative_container as_associative_container() const ENTT_NOEXCEPT {
|
||||
any detached = storage.as_ref();
|
||||
meta_associative_container proxy;
|
||||
vtable(operation::assoc, storage.as_ref(), &proxy);
|
||||
vtable(operation::assoc, detached, &proxy);
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@@ -1463,13 +1467,13 @@ class meta_sequence_container::meta_iterator {
|
||||
using vtable_type = void(const operation, const any &, void *);
|
||||
|
||||
template<typename It>
|
||||
static void basic_vtable(const operation op, const any &from, void *to) {
|
||||
static void basic_vtable(const operation op, const any &value, void *other) {
|
||||
switch(op) {
|
||||
case operation::incr:
|
||||
++any_cast<It &>(const_cast<any &>(from));
|
||||
++any_cast<It &>(const_cast<any &>(value));
|
||||
break;
|
||||
case operation::deref:
|
||||
static_cast<meta_any *>(to)->emplace<typename std::iterator_traits<It>::reference>(*any_cast<const It &>(from));
|
||||
static_cast<meta_any *>(other)->emplace<typename std::iterator_traits<It>::reference>(*any_cast<const It &>(value));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1663,18 +1667,18 @@ class meta_associative_container::meta_iterator {
|
||||
using vtable_type = void(const operation, const any &, void *);
|
||||
|
||||
template<bool KeyOnly, typename It>
|
||||
static void basic_vtable(const operation op, const any &from, void *to) {
|
||||
static void basic_vtable(const operation op, const any &value, void *other) {
|
||||
switch(op) {
|
||||
case operation::incr:
|
||||
++any_cast<It &>(const_cast<any &>(from));
|
||||
++any_cast<It &>(const_cast<any &>(value));
|
||||
break;
|
||||
case operation::deref:
|
||||
const auto &it = any_cast<const It &>(from);
|
||||
const auto &it = any_cast<const It &>(value);
|
||||
if constexpr(KeyOnly) {
|
||||
static_cast<std::pair<meta_any, meta_any> *>(to)->first.emplace<decltype(*it)>(*it);
|
||||
static_cast<std::pair<meta_any, meta_any> *>(other)->first.emplace<decltype(*it)>(*it);
|
||||
} else {
|
||||
static_cast<std::pair<meta_any, meta_any> *>(to)->first.emplace<decltype((it->first))>(it->first);
|
||||
static_cast<std::pair<meta_any, meta_any> *>(to)->second.emplace<decltype((it->second))>(it->second);
|
||||
static_cast<std::pair<meta_any, meta_any> *>(other)->first.emplace<decltype((it->first))>(it->first);
|
||||
static_cast<std::pair<meta_any, meta_any> *>(other)->second.emplace<decltype((it->second))>(it->second);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user