[libc++] NFCI: Implement make_shared as allocate_shared with std::allocator

This simplifies the implementation, and it appears to be equivalent since
make_shared was allocating memory with std::allocator anyway.

Differential Revision: https://reviews.llvm.org/D93071
This commit is contained in:
Louis Dionne
2020-12-09 16:57:28 -05:00
parent 1deff4009e
commit ece3e5bb8b
3 changed files with 45 additions and 28 deletions

View File

@@ -4036,28 +4036,6 @@ shared_ptr<_Tp>::reset(_Yp* __p, _Dp __d, _Alloc __a)
shared_ptr(__p, __d, __a).swap(*this);
}
template<class _Tp, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
<
!is_array<_Tp>::value,
shared_ptr<_Tp>
>::type
make_shared(_Args&& ...__args)
{
static_assert(is_constructible<_Tp, _Args...>::value, "Can't construct object in make_shared");
typedef __shared_ptr_emplace<_Tp, allocator<_Tp> > _CntrlBlk;
typedef allocator<_CntrlBlk> _A2;
typedef __allocator_destructor<_A2> _D2;
_A2 __a2;
unique_ptr<_CntrlBlk, _D2> __hold2(__a2.allocate(1), _D2(__a2, 1));
::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
_Tp *__ptr = __hold2->__get_elem();
return shared_ptr<_Tp>::__create_with_control_block(__ptr, __hold2.release());
}
template<class _Tp, class _Alloc, class ..._Args>
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if
@@ -4067,7 +4045,8 @@ typename enable_if
>::type
allocate_shared(const _Alloc& __a, _Args&& ...__args)
{
static_assert( is_constructible<_Tp, _Args...>::value, "Can't construct object in allocate_shared");
static_assert(is_constructible<_Tp, _Args...>::value,
"allocate_shared/make_shared: the type is not constructible from the provided arguments");
typedef __shared_ptr_emplace<_Tp, _Alloc> _CntrlBlk;
typedef typename __allocator_traits_rebind<_Alloc, _CntrlBlk>::type _A2;
@@ -4082,6 +4061,13 @@ allocate_shared(const _Alloc& __a, _Args&& ...__args)
return shared_ptr<_Tp>::__create_with_control_block(__p, _VSTD::addressof(*__hold2.release()));
}
template<class _Tp, class ..._Args, class = _EnableIf<!is_array<_Tp>::value> >
_LIBCPP_HIDE_FROM_ABI
shared_ptr<_Tp> make_shared(_Args&& ...__args)
{
return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...);
}
template<class _Tp, class _Up>
inline _LIBCPP_INLINE_VISIBILITY
bool

View File

@@ -0,0 +1,34 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// GCC 5 does not evaluate static assertions dependent on a template parameter.
// UNSUPPORTED: gcc-5
// <memory>
// shared_ptr
// template<class T, class A, class... Args>
// shared_ptr<T> allocate_shared(const A& a, Args&&... args);
#include <memory>
#include "test_macros.h"
struct S {
protected:
S () {}; // ctor is protected
};
int main(int, char**) {
typedef std::allocator<S> A;
A a;
std::shared_ptr<S> p = std::allocate_shared<S, A>(a); // expected-error@memory:* {{static_assert failed due to requirement 'is_constructible<S>::value}}
return 0;
}

View File

@@ -16,7 +16,6 @@
// template<class T, class... Args> shared_ptr<T> make_shared(Args&&... args);
#include <memory>
#include <cassert>
#include "test_macros.h"
@@ -25,10 +24,8 @@ protected:
S () {}; // ctor is protected
};
int main(int, char**)
{
std::shared_ptr<S> p = std::make_shared<
S>(); // expected-error@memory:* {{static_assert failed due to requirement 'is_constructible<S>::value' "Can't construct object in make_shared"}}
int main(int, char**) {
std::shared_ptr<S> p = std::make_shared<S>(); // expected-error@memory:* {{static_assert failed due to requirement 'is_constructible<S>::value}}
return 0;
}