diff --git a/include/core/any.hpp b/include/core/any.hpp index 825a764..d60c078 100644 --- a/include/core/any.hpp +++ b/include/core/any.hpp @@ -11,12 +11,14 @@ namespace core { inline namespace v1 { namespace impl { +using data_type = add_pointer_t; + template using is_small = std::integral_constant; struct any_dispatch { - using destroy_function = void (*)(void**); - using clone_function = void(*)(void* const*, void**); + using destroy_function = void (*)(data_type&); + using clone_function = void(*)(data_type const&, data_type&); using type_function = std::type_info const& (*)(); destroy_function const destroy; @@ -30,38 +32,40 @@ struct any_dispatch_select; template struct any_dispatch_select { using allocator_type = std::allocator; + using allocator_traits = std::allocator_traits; - static void clone (void* const* source, void** data) { + static void clone (data_type const& source, data_type& data) { allocator_type alloc { }; - auto const& value = *reinterpret_cast(source); - auto pointer = reinterpret_cast(data); - std::allocator_traits::construct(alloc, pointer, value); + auto const& value = reinterpret_cast(source); + auto& ref = reinterpret_cast(data); + allocator_traits::construct(alloc, std::addressof(ref), value); } - static void destroy (void** data) { + static void destroy (data_type& data) { allocator_type alloc { }; - auto pointer = reinterpret_cast(data); - std::allocator_traits::destroy(alloc, pointer); + auto& ref = reinterpret_cast(data); + allocator_traits::destroy(alloc, std::addressof(ref)); } }; template struct any_dispatch_select { using allocator_type = std::allocator; + using allocator_traits = std::allocator_traits; - static void clone (void* const* source, void** data) { + static void clone (data_type const& source, data_type& data) { allocator_type alloc { }; - auto const& value = **reinterpret_cast(source); - auto pointer = std::allocator_traits::allocate(alloc, 1); - std::allocator_traits::construct(alloc, pointer, value); - *data = pointer; + auto const& value = *static_cast(source); + auto pointer = allocator_traits::allocate(alloc, 1); + allocator_traits::construct(alloc, pointer, value); + data = pointer; } - static void destroy (void** data) { + static void destroy (data_type& data) { allocator_type alloc { }; - auto& value = *reinterpret_cast(data); - std::allocator_traits::destroy(alloc, value); - std::allocator_traits::deallocate(alloc, value, 1); + auto value = static_cast(data); + allocator_traits::destroy(alloc, value); + allocator_traits::deallocate(alloc, value, 1); } }; @@ -78,8 +82,8 @@ any_dispatch const* get_any_dispatch () { template <> inline any_dispatch const* get_any_dispatch () { static any_dispatch const instance = { - [] (void**) { }, - [] (void* const*, void**) { }, + [] (data_type&) { }, + [] (data_type const&, data_type&) { }, [] () -> std::type_info const& { return typeid(void); } }; return std::addressof(instance); @@ -100,7 +104,7 @@ class any final { template friend ValueType* any_cast (any*) noexcept; impl::any_dispatch const* table; - void* data; + impl::data_type data; template any (ValueType&& value, std::true_type&&) : @@ -143,21 +147,19 @@ class any final { template ValueType const* cast (std::false_type&&) const { - return reinterpret_cast(this->data); + return static_cast(this->data); } template ValueType* cast (std::false_type&&) { - return reinterpret_cast(this->data); + return static_cast(this->data); } public: any (any const& that) : table { that.table }, data { nullptr } - { - this->table->clone(std::addressof(that.data), std::addressof(this->data)); - } + { this->table->clone(that.data, this->data); } any (any&& that) noexcept : table { that.table }, @@ -197,7 +199,7 @@ class any final { } void clear () noexcept { - this->table->destroy(std::addressof(this->data)); + this->table->destroy(this->data); this->table = impl::get_any_dispatch(); }