|
|
@@ -23,7 +23,7 @@ namespace entt {
|
|
|
*/
|
|
|
template<std::size_t Len, std::size_t Align>
|
|
|
class basic_any {
|
|
|
- enum class operation: std::uint8_t { COPY, MOVE, DTOR, COMP, ADDR, CADDR, TYPE };
|
|
|
+ enum class operation: std::uint8_t { COPY, MOVE, DTOR, COMP, ADDR, TYPE };
|
|
|
enum class policy: std::uint8_t { OWNER, REF, CREF };
|
|
|
|
|
|
using storage_type = std::aligned_storage_t<Len + !Len, Align>;
|
|
|
@@ -78,24 +78,17 @@ class basic_any {
|
|
|
|
|
|
return (static_cast<basic_any *>(to)->instance = std::exchange(const_cast<basic_any &>(from).instance, nullptr));
|
|
|
case operation::DTOR:
|
|
|
- if(from.mode == policy::OWNER) {
|
|
|
- if constexpr(in_situ<Type>) {
|
|
|
- instance->~Type();
|
|
|
- } else if constexpr(std::is_array_v<Type>) {
|
|
|
- delete[] instance;
|
|
|
- } else {
|
|
|
- delete instance;
|
|
|
- }
|
|
|
+ if constexpr(in_situ<Type>) {
|
|
|
+ instance->~Type();
|
|
|
+ } else if constexpr(std::is_array_v<Type>) {
|
|
|
+ delete[] instance;
|
|
|
+ } else {
|
|
|
+ delete instance;
|
|
|
}
|
|
|
break;
|
|
|
case operation::COMP:
|
|
|
return compare<Type>(instance, (*static_cast<const basic_any **>(to))->data()) ? to : nullptr;
|
|
|
case operation::ADDR:
|
|
|
- if(from.mode == policy::CREF) {
|
|
|
- return nullptr;
|
|
|
- }
|
|
|
- [[fallthrough]];
|
|
|
- case operation::CADDR:
|
|
|
return instance;
|
|
|
case operation::TYPE:
|
|
|
*static_cast<type_info *>(to) = type_id<Type>();
|
|
|
@@ -106,6 +99,12 @@ class basic_any {
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
+ void destroy_if_owner() {
|
|
|
+ if(mode == policy::OWNER) {
|
|
|
+ vtable(operation::DTOR, *this, nullptr);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
template<typename Type, typename... Args>
|
|
|
void initialize([[maybe_unused]] Args &&... args) {
|
|
|
if constexpr(!std::is_void_v<Type>) {
|
|
|
@@ -202,7 +201,7 @@ public:
|
|
|
|
|
|
/*! @brief Frees the internal storage, whatever it means. */
|
|
|
~basic_any() {
|
|
|
- vtable(operation::DTOR, *this, nullptr);
|
|
|
+ destroy_if_owner();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -222,8 +221,9 @@ public:
|
|
|
* @return This any object.
|
|
|
*/
|
|
|
basic_any & operator=(basic_any &&other) ENTT_NOEXCEPT {
|
|
|
- std::exchange(vtable, other.vtable)(operation::DTOR, *this, nullptr);
|
|
|
+ destroy_if_owner();
|
|
|
other.vtable(operation::MOVE, other, this);
|
|
|
+ vtable = other.vtable;
|
|
|
mode = other.mode;
|
|
|
return *this;
|
|
|
}
|
|
|
@@ -256,12 +256,12 @@ public:
|
|
|
* @return An opaque pointer the contained instance, if any.
|
|
|
*/
|
|
|
[[nodiscard]] const void * data() const ENTT_NOEXCEPT {
|
|
|
- return vtable(operation::CADDR, *this, nullptr);
|
|
|
+ return vtable(operation::ADDR, *this, nullptr);
|
|
|
}
|
|
|
|
|
|
/*! @copydoc data */
|
|
|
[[nodiscard]] void * data() ENTT_NOEXCEPT {
|
|
|
- return const_cast<void *>(vtable(operation::ADDR, *this, nullptr));
|
|
|
+ return mode == policy::CREF ? nullptr : const_cast<void *>(vtable(operation::ADDR, *this, nullptr));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -272,14 +272,16 @@ public:
|
|
|
*/
|
|
|
template<typename Type, typename... Args>
|
|
|
void emplace(Args &&... args) {
|
|
|
- std::exchange(vtable, &basic_vtable<std::remove_const_t<std::remove_reference_t<Type>>>)(operation::DTOR, *this, nullptr);
|
|
|
- mode = type_to_policy<Type>();
|
|
|
+ destroy_if_owner();
|
|
|
initialize<Type>(std::forward<Args>(args)...);
|
|
|
+ vtable = &basic_vtable<std::remove_const_t<std::remove_reference_t<Type>>>;
|
|
|
+ mode = type_to_policy<Type>();
|
|
|
}
|
|
|
|
|
|
/*! @brief Destroys contained object */
|
|
|
void reset() {
|
|
|
- std::exchange(vtable, &basic_vtable<void>)(operation::DTOR, *this, nullptr);
|
|
|
+ destroy_if_owner();
|
|
|
+ vtable = &basic_vtable<void>;
|
|
|
mode = policy::OWNER;
|
|
|
}
|
|
|
|
|
|
@@ -288,7 +290,7 @@ public:
|
|
|
* @return False if the wrapper is empty, true otherwise.
|
|
|
*/
|
|
|
[[nodiscard]] explicit operator bool() const ENTT_NOEXCEPT {
|
|
|
- return !(vtable(operation::CADDR, *this, nullptr) == nullptr);
|
|
|
+ return !(vtable(operation::ADDR, *this, nullptr) == nullptr);
|
|
|
}
|
|
|
|
|
|
/**
|