[libc++] NFCI: Implement make_shared as allocate_shared with std::allocator
authorLouis Dionne <ldionne.2@gmail.com>
Wed, 9 Dec 2020 21:57:28 +0000 (16:57 -0500)
committerLouis Dionne <ldionne.2@gmail.com>
Fri, 11 Dec 2020 17:01:48 +0000 (12:01 -0500)
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

libcxx/include/memory
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.protected.verify.cpp [new file with mode: 0644]
libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.verify.cpp [moved from libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/make_shared.protected.fail.cpp with 74% similarity]

index f3b890a..f8c3ace 100644 (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
diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.protected.verify.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.create/allocate_shared.protected.verify.cpp
new file mode 100644 (file)
index 0000000..fbd7bfa
--- /dev/null
@@ -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;
+}
@@ -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;
 }