[libcxx-commits] [PATCH] D81133: Use allocator_traits to consistently allocate/deallocate/construct/destroy objects in std::any
Marshall Clow via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Jun 3 23:57:36 PDT 2020
mclow.lists created this revision.
mclow.lists added a reviewer: libc++.
mclow.lists added a project: libc++.
mclow.lists edited the summary of this revision.
mclow.lists added a reviewer: tkoeppe.
PR45099 <https://llvm.org/PR40599> notes (correctly) that we're inconsistent in memory allocation in `std::any`. We allocate memory with `std::allocator<T>::allocate`, construct with placement new, destroy by calling the destructor directly, and deallocate by calling `delete`. Most of those are customizable by the user - but in different ways.
The standard is silent on how these things are to be accomplished.
This patch makes it so we use `allocator_traits<allocator<T>>` for all of these operations (allocate, construct, destruct, deallocate). This is, at least, consistent.
https://reviews.llvm.org/D81133
Files:
libcxx/include/any
Index: libcxx/include/any
===================================================================
--- libcxx/include/any
+++ libcxx/include/any
@@ -82,7 +82,6 @@
#include <experimental/__config>
#include <memory>
-#include <new>
#include <typeinfo>
#include <type_traits>
#include <cstdlib>
@@ -368,7 +367,11 @@
template <class ..._Args>
_LIBCPP_INLINE_VISIBILITY
static _Tp& __create(any & __dest, _Args&&... __args) {
- _Tp* __ret = ::new (static_cast<void*>(&__dest.__s.__buf)) _Tp(_VSTD::forward<_Args>(__args)...);
+ typedef allocator<_Tp> _Alloc;
+ typedef allocator_traits<_Alloc> _ATraits;
+ _Alloc __a;
+ _Tp * __ret = static_cast<_Tp*>(static_cast<void*>(&__dest.__s.__buf));
+ _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
__dest.__h = &_SmallHandler::__handle;
return *__ret;
}
@@ -376,8 +379,11 @@
private:
_LIBCPP_INLINE_VISIBILITY
static void __destroy(any & __this) {
- _Tp & __value = *static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
- __value.~_Tp();
+ typedef allocator<_Tp> _Alloc;
+ typedef allocator_traits<_Alloc> _ATraits;
+ _Alloc __a;
+ _Tp * __p = static_cast<_Tp *>(static_cast<void*>(&__this.__s.__buf));
+ _ATraits::destroy(__a, __p);
__this.__h = nullptr;
}
@@ -445,10 +451,12 @@
_LIBCPP_INLINE_VISIBILITY
static _Tp& __create(any & __dest, _Args&&... __args) {
typedef allocator<_Tp> _Alloc;
+ typedef allocator_traits<_Alloc> _ATraits;
typedef __allocator_destructor<_Alloc> _Dp;
_Alloc __a;
- unique_ptr<_Tp, _Dp> __hold(__a.allocate(1), _Dp(__a, 1));
- _Tp* __ret = ::new ((void*)__hold.get()) _Tp(_VSTD::forward<_Args>(__args)...);
+ unique_ptr<_Tp, _Dp> __hold(_ATraits::allocate(__a, 1), _Dp(__a, 1));
+ _Tp * __ret = __hold.get();
+ _ATraits::construct(__a, __ret, _VSTD::forward<_Args>(__args)...);
__dest.__s.__ptr = __hold.release();
__dest.__h = &_LargeHandler::__handle;
return *__ret;
@@ -458,7 +466,12 @@
_LIBCPP_INLINE_VISIBILITY
static void __destroy(any & __this){
- delete static_cast<_Tp*>(__this.__s.__ptr);
+ typedef allocator<_Tp> _Alloc;
+ typedef allocator_traits<_Alloc> _ATraits;
+ _Alloc __a;
+ _Tp * __p = static_cast<_Tp *>(__this.__s.__ptr);
+ _ATraits::destroy(__a, __p);
+ _ATraits::deallocate(__a, __p, 1);
__this.__h = nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D81133.268368.patch
Type: text/x-patch
Size: 2572 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20200604/30d871c2/attachment.bin>
More information about the libcxx-commits
mailing list