diff --git a/libcxx/docs/ReleaseNotes.rst b/libcxx/docs/ReleaseNotes.rst --- a/libcxx/docs/ReleaseNotes.rst +++ b/libcxx/docs/ReleaseNotes.rst @@ -74,6 +74,11 @@ - The C++14 function ``std::quoted(const char*)`` is no longer supported in C++03 or C++11 modes. +- libc++ no longer supports containers of ``const``-qualified element type, + such as ``vector`` and ``list``. This used to be supported + as an extension. Likewise, ``std::allocator`` is no longer supported. + If you were using ``vector``, replace it with ``vector`` instead. + ABI Changes ----------- diff --git a/libcxx/include/__memory/allocator.h b/libcxx/include/__memory/allocator.h --- a/libcxx/include/__memory/allocator.h +++ b/libcxx/include/__memory/allocator.h @@ -37,17 +37,6 @@ template struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;}; }; - -template <> -class _LIBCPP_TEMPLATE_VIS allocator -{ -public: - _LIBCPP_DEPRECATED_IN_CXX17 typedef const void* pointer; - _LIBCPP_DEPRECATED_IN_CXX17 typedef const void* const_pointer; - _LIBCPP_DEPRECATED_IN_CXX17 typedef const void value_type; - - template struct _LIBCPP_DEPRECATED_IN_CXX17 rebind {typedef allocator<_Up> other;}; -}; #endif // This class provides a non-trivial default constructor to the class that derives from it @@ -80,6 +69,7 @@ class _LIBCPP_TEMPLATE_VIS allocator : private __non_trivial_if::value, allocator<_Tp> > { + static_assert(!is_const<_Tp>::value, "std::allocator does not support const types"); static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types"); public: typedef size_t size_type; @@ -158,84 +148,6 @@ #endif }; -template -class _LIBCPP_TEMPLATE_VIS allocator - : private __non_trivial_if::value, allocator > -{ - static_assert(!is_volatile<_Tp>::value, "std::allocator does not support volatile types"); -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef const _Tp value_type; - typedef true_type propagate_on_container_move_assignment; - typedef true_type is_always_equal; - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - allocator() _NOEXCEPT = default; - - template - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - allocator(const allocator<_Up>&) _NOEXCEPT { } - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - const _Tp* allocate(size_t __n) { - if (__n > allocator_traits::max_size(*this)) - __throw_bad_array_new_length(); - if (__libcpp_is_constant_evaluated()) { - return static_cast(::operator new(__n * sizeof(_Tp))); - } else { - return static_cast(_VSTD::__libcpp_allocate(__n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp))); - } - } - - _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 - void deallocate(const _Tp* __p, size_t __n) { - if (__libcpp_is_constant_evaluated()) { - ::operator delete(const_cast<_Tp*>(__p)); - } else { - _VSTD::__libcpp_deallocate((void*) const_cast<_Tp *>(__p), __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp)); - } - } - - // C++20 Removed members -#if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_ALLOCATOR_MEMBERS) - _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* pointer; - _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp* const_pointer; - _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& reference; - _LIBCPP_DEPRECATED_IN_CXX17 typedef const _Tp& const_reference; - - template - struct _LIBCPP_DEPRECATED_IN_CXX17 rebind { - typedef allocator<_Up> other; - }; - - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY - const_pointer address(const_reference __x) const _NOEXCEPT { - return _VSTD::addressof(__x); - } - - _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY _LIBCPP_DEPRECATED_IN_CXX17 - const _Tp* allocate(size_t __n, const void*) { - return allocate(__n); - } - - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT { - return size_type(~0) / sizeof(_Tp); - } - - template - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY - void construct(_Up* __p, _Args&&... __args) { - ::new ((void*)__p) _Up(_VSTD::forward<_Args>(__args)...); - } - - _LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY - void destroy(pointer __p) { - __p->~_Tp(); - } -#endif -}; - template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 bool operator==(const allocator<_Tp>&, const allocator<_Up>&) _NOEXCEPT {return true;} diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -282,13 +282,15 @@ struct __shared_ptr_emplace : __shared_weak_count { + using _TpAlloc = typename __allocator_traits_rebind<_Alloc, typename remove_cv<_Tp>::type>::type; + using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type; + template _LIBCPP_HIDE_FROM_ABI explicit __shared_ptr_emplace(_Alloc __a, _Args&& ...__args) : __storage_(_VSTD::move(__a)) { #if _LIBCPP_STD_VER > 17 - using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; _TpAlloc __tmp(*__get_alloc()); allocator_traits<_TpAlloc>::construct(__tmp, __get_elem(), _VSTD::forward<_Args>(__args)...); #else @@ -305,7 +307,6 @@ private: virtual void __on_zero_shared() _NOEXCEPT { #if _LIBCPP_STD_VER > 17 - using _TpAlloc = typename __allocator_traits_rebind<_Alloc, _Tp>::type; _TpAlloc __tmp(*__get_alloc()); allocator_traits<_TpAlloc>::destroy(__tmp, __get_elem()); #else @@ -314,7 +315,6 @@ } virtual void __on_zero_shared_weak() _NOEXCEPT { - using _ControlBlockAlloc = typename __allocator_traits_rebind<_Alloc, __shared_ptr_emplace>::type; using _ControlBlockPointer = typename allocator_traits<_ControlBlockAlloc>::pointer; _ControlBlockAlloc __tmp(*__get_alloc()); __storage_.~_Storage(); @@ -643,8 +643,9 @@ shared_ptr(auto_ptr<_Yp>&& __r) : __ptr_(__r.get()) { - typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, allocator<_Yp> > _CntrlBlk; - __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), allocator<_Yp>()); + typedef allocator::type> _YpAlloc; + typedef __shared_ptr_pointer<_Yp*, default_delete<_Yp>, _YpAlloc> _CntrlBlk; + __cntrl_ = new _CntrlBlk(__r.get(), default_delete<_Yp>(), _YpAlloc()); __enable_weak_this(__r.get(), __r.get()); __r.release(); } @@ -890,7 +891,7 @@ template ::value> struct __shared_ptr_default_allocator { - typedef allocator<_Yp> type; + typedef allocator::type> type; }; template @@ -960,7 +961,7 @@ _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp> make_shared(_Args&& ...__args) { - return _VSTD::allocate_shared<_Tp>(allocator<_Tp>(), _VSTD::forward<_Args>(__args)...); + return _VSTD::allocate_shared<_Tp>(allocator::type>(), _VSTD::forward<_Args>(__args)...); } template diff --git a/libcxx/include/memory b/libcxx/include/memory --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -895,19 +895,17 @@ } template ::type, - class _RawDest = typename remove_const<_Dest>::type, class = typename enable_if< is_trivially_copy_constructible<_Dest>::value && - is_same<_RawSource, _RawDest>::value && + is_same::type, _Dest>::value && (__is_default_allocator<_Alloc>::value || !__has_construct<_Alloc, _Dest*, _Source&>::value) >::type> _LIBCPP_INLINE_VISIBILITY void __construct_range_forward(_Alloc&, _Source* __begin1, _Source* __end1, _Dest*& __begin2) { ptrdiff_t _Np = __end1 - __begin1; if (_Np > 0) { - _VSTD::memcpy(const_cast<_RawDest*>(__begin2), __begin1, _Np * sizeof(_Dest)); + _VSTD::memcpy(__begin2, __begin1, _Np * sizeof(_Dest)); __begin2 += _Np; } } diff --git a/libcxx/test/libcxx/containers/sequences/vector/const_value_type.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/const_value_type.pass.cpp deleted file mode 100644 --- a/libcxx/test/libcxx/containers/sequences/vector/const_value_type.pass.cpp +++ /dev/null @@ -1,25 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++03 - -// - -// vector v; // an extension - -#include -#include - -#include "test_macros.h" - -int main(int, char**) -{ - std::vector v = {1, 2, 3}; - - return 0; -} diff --git a/libcxx/test/libcxx/memory/allocator_volatile.verify.cpp b/libcxx/test/libcxx/memory/allocator.cv.verify.cpp rename from libcxx/test/libcxx/memory/allocator_volatile.verify.cpp rename to libcxx/test/libcxx/memory/allocator.cv.verify.cpp --- a/libcxx/test/libcxx/memory/allocator_volatile.verify.cpp +++ b/libcxx/test/libcxx/memory/allocator.cv.verify.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -// http://wg21.link/LWG2447 gives implementors freedom to reject volatile types in `std::allocator`. +// http://wg21.link/LWG2447 gives implementors freedom to reject const or volatile types in `std::allocator`. #include std::allocator A1; // expected-error@*:* {{std::allocator does not support volatile types}} -std::allocator A2; // expected-error@*:* {{std::allocator does not support volatile types}} +std::allocator A2; // expected-error@*:* {{std::allocator does not support const types}} diff --git a/libcxx/test/libcxx/memory/allocator_void.trivial.compile.pass.cpp b/libcxx/test/libcxx/memory/allocator_void.trivial.compile.pass.cpp --- a/libcxx/test/libcxx/memory/allocator_void.trivial.compile.pass.cpp +++ b/libcxx/test/libcxx/memory/allocator_void.trivial.compile.pass.cpp @@ -17,18 +17,10 @@ #include typedef std::allocator A1; -typedef std::allocator A2; -struct A3 : std::allocator { }; -struct A4 : std::allocator { }; +struct A2 : std::allocator { }; static_assert(std::is_trivially_default_constructible::value, ""); static_assert(std::is_trivial::value, ""); static_assert(std::is_trivially_default_constructible::value, ""); static_assert(std::is_trivial::value, ""); - -static_assert(std::is_trivially_default_constructible::value, ""); -static_assert(std::is_trivial::value, ""); - -static_assert(std::is_trivially_default_constructible::value, ""); -static_assert(std::is_trivial::value, ""); diff --git a/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp --- a/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp +++ b/libcxx/test/std/concepts/concepts.lang/concept.default.init/default_initializable.compile.pass.cpp @@ -202,9 +202,6 @@ test_not_const>(); test_false >(); test_true >(); -#ifdef _LIBCPP_VERSION - test_true >(); -#endif // _LIBCPP_VERSION test_true >(); test_true >(); test_true >(); @@ -223,9 +220,6 @@ // Container adaptors test_true >(); -#ifdef _LIBCPP_VERSION - test_true >(); -#endif // _LIBCPP_VERSION test_true >(); test_true >(); diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.ctor.pass.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.ctor.pass.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator.ctor.pass.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.ctor.pass.cpp @@ -37,12 +37,12 @@ int main(int, char**) { test(); - test(); + test(); test(); #if TEST_STD_VER > 17 static_assert(test()); - static_assert(test()); + static_assert(test()); static_assert(test()); #endif return 0; diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.dtor.pass.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.dtor.pass.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator.dtor.pass.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.dtor.pass.cpp @@ -26,15 +26,9 @@ { test(); test(); -#ifdef _LIBCPP_VERSION // extension - test(); -#endif // _LIBCPP_VERSION static_assert(test()); static_assert(test()); -#ifdef _LIBCPP_VERSION // extension - static_assert(test()); -#endif // _LIBCPP_VERSION return 0; } diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.constexpr.size.verify.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.constexpr.size.verify.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.constexpr.size.verify.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.constexpr.size.verify.cpp @@ -35,6 +35,5 @@ int main(int, char**) { static_assert(test()); // expected-error {{static_assert expression is not an integral constant expression}} - LIBCPP_STATIC_ASSERT(test()); // expected-error {{static_assert expression is not an integral constant expression}} return 0; } diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator.members/allocate.size.pass.cpp @@ -44,7 +44,6 @@ int main(int, char**) { test(); - LIBCPP_ONLY(test()); return 0; } diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator_types.deprecated_in_cxx17.verify.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator_types.deprecated_in_cxx17.verify.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator_types.deprecated_in_cxx17.verify.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator_types.deprecated_in_cxx17.verify.cpp @@ -35,13 +35,6 @@ typedef std::allocator::const_reference ConstReference; // expected-warning {{'const_reference' is deprecated}} typedef std::allocator::rebind::other Rebind; // expected-warning {{'rebind' is deprecated}} } - { - typedef std::allocator::pointer Pointer; // expected-warning {{'pointer' is deprecated}} - typedef std::allocator::const_pointer ConstPointer; // expected-warning {{'const_pointer' is deprecated}} - typedef std::allocator::reference Reference; // expected-warning {{'reference' is deprecated}} - typedef std::allocator::const_reference ConstReference; // expected-warning {{'const_reference' is deprecated}} - typedef std::allocator::rebind::other Rebind; // expected-warning {{'rebind' is deprecated}} - } { typedef std::allocator::pointer Pointer; // expected-warning {{'pointer' is deprecated}} typedef std::allocator::const_pointer ConstPointer; // expected-warning {{'const_pointer' is deprecated}} diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator_types.pass.cpp @@ -59,8 +59,5 @@ int main(int, char**) { test(); -#ifdef _LIBCPP_VERSION - test(); // extension -#endif return 0; } diff --git a/libcxx/test/std/utilities/memory/default.allocator/allocator_types.removed_in_cxx20.verify.cpp b/libcxx/test/std/utilities/memory/default.allocator/allocator_types.removed_in_cxx20.verify.cpp --- a/libcxx/test/std/utilities/memory/default.allocator/allocator_types.removed_in_cxx20.verify.cpp +++ b/libcxx/test/std/utilities/memory/default.allocator/allocator_types.removed_in_cxx20.verify.cpp @@ -31,17 +31,16 @@ template void check() { - typedef typename std::allocator::pointer AP; // expected-error 3 {{no type named 'pointer'}} - typedef typename std::allocator::const_pointer ACP; // expected-error 3 {{no type named 'const_pointer'}} - typedef typename std::allocator::reference AR; // expected-error 3 {{no type named 'reference'}} - typedef typename std::allocator::const_reference ACR; // expected-error 3 {{no type named 'const_reference'}} - typedef typename std::allocator::template rebind::other ARO; // expected-error 3 {{no member named 'rebind'}} + typedef typename std::allocator::pointer AP; // expected-error 2 {{no type named 'pointer'}} + typedef typename std::allocator::const_pointer ACP; // expected-error 2 {{no type named 'const_pointer'}} + typedef typename std::allocator::reference AR; // expected-error 2 {{no type named 'reference'}} + typedef typename std::allocator::const_reference ACR; // expected-error 2 {{no type named 'const_reference'}} + typedef typename std::allocator::template rebind::other ARO; // expected-error 2 {{no member named 'rebind'}} } int main(int, char**) { check(); - check(); check(); return 0; } diff --git a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp --- a/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp +++ b/libcxx/test/std/utilities/memory/specialized.algorithms/specialized.construct/construct_at.pass.cpp @@ -82,7 +82,7 @@ } { - std::allocator a; + std::allocator a; Counted const* p = a.allocate(2); int count = 0; std::construct_at(p, count); @@ -93,7 +93,7 @@ assert(count == 1); p->~Counted(); assert(count == 0); - a.deallocate(p, 2); + a.deallocate(const_cast(p), 2); } return true; diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/auto_ptr.pass.cpp @@ -46,19 +46,34 @@ int main(int, char**) { - globalMemCounter.reset(); - { - std::auto_ptr ptr(new A); - A* raw_ptr = ptr.get(); - std::shared_ptr p(std::move(ptr)); - assert(A::count == 1); - assert(B::count == 1); - assert(p.use_count() == 1); - assert(p.get() == raw_ptr); - assert(ptr.get() == 0); - } + globalMemCounter.reset(); + { + std::auto_ptr ptr(new A); + A* raw_ptr = ptr.get(); + std::shared_ptr p(std::move(ptr)); + assert(A::count == 1); + assert(B::count == 1); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + assert(A::count == 0); + assert(globalMemCounter.checkOutstandingNewEq(0)); + + globalMemCounter.reset(); + { + std::auto_ptr ptr(new A); + A const* raw_ptr = ptr.get(); + std::shared_ptr p(std::move(ptr)); + assert(A::count == 1); + assert(B::count == 1); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } assert(A::count == 0); assert(globalMemCounter.checkOutstandingNewEq(0)); + #if !defined(TEST_HAS_NO_EXCEPTIONS) && !defined(DISABLE_NEW_COUNT) { std::auto_ptr ptr(new A); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/deduction.pass.cpp @@ -22,7 +22,7 @@ struct A {}; struct D { - void operator()(A* ptr) const + void operator()(A const* ptr) const { delete ptr; } @@ -39,22 +39,49 @@ assert(s.use_count() == 2); assert(s0.get() == s.get()); } + { + std::shared_ptr s0(new A); + std::weak_ptr w = s0; + auto s = std::shared_ptr(w); + ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); + assert(s0.use_count() == 2); + assert(s.use_count() == 2); + assert(s0.get() == s.get()); + } + { std::unique_ptr u(new A); - A* const uPointee = u.get(); + A* uPointee = u.get(); std::shared_ptr s = std::move(u); ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); assert(u == nullptr); assert(s.get() == uPointee); } + { + std::unique_ptr u(new A); + A const* uPointee = u.get(); + std::shared_ptr s = std::move(u); + ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); + assert(u == nullptr); + assert(s.get() == uPointee); + } + { std::unique_ptr u(new A, D{}); - A* const uPointee = u.get(); + A* uPointee = u.get(); std::shared_ptr s(std::move(u)); ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); assert(u == nullptr); assert(s.get() == uPointee); } + { + std::unique_ptr u(new A, D{}); + A const* uPointee = u.get(); + std::shared_ptr s(std::move(u)); + ASSERT_SAME_TYPE(decltype(s), std::shared_ptr); + assert(u == nullptr); + assert(s.get() == uPointee); + } return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/default.pass.cpp @@ -26,8 +26,11 @@ int main(int, char**) { test(); + test(); test(); + test(); test(); + test(); test(); test(); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t.pass.cpp @@ -17,9 +17,17 @@ int main(int, char**) { + { std::shared_ptr p(nullptr); assert(p.use_count() == 0); assert(p.get() == 0); + } + + { + std::shared_ptr p(nullptr); + assert(p.use_count() == 0); + assert(p.get() == 0); + } return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter.pass.cpp @@ -31,21 +31,26 @@ int main(int, char**) { { - std::shared_ptr p(nullptr, test_deleter(3)); - assert(A::count == 0); - assert(p.use_count() == 1); - assert(p.get() == 0); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); + std::shared_ptr p(nullptr, test_deleter(3)); + assert(A::count == 0); + assert(p.use_count() == 1); + assert(p.get() == 0); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 3); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 3); #endif } assert(A::count == 0); assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); - return 0; + { + std::shared_ptr p(nullptr, test_deleter(3)); + assert(p.get() == nullptr); + } + + return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/nullptr_t_deleter_allocator.pass.cpp @@ -32,19 +32,19 @@ { test_allocator_statistics alloc_stats; { - std::shared_ptr p(nullptr, test_deleter(3), test_allocator(5, &alloc_stats)); - assert(A::count == 0); - assert(p.use_count() == 1); - assert(p.get() == 0); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); + std::shared_ptr p(nullptr, test_deleter(3), test_allocator(5, &alloc_stats)); + assert(A::count == 0); + assert(p.use_count() == 1); + assert(p.get() == 0); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 3); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 3); #endif - assert(alloc_stats.count == 1); - assert(alloc_stats.alloc_count == 1); + assert(alloc_stats.count == 1); + assert(alloc_stats.alloc_count == 1); } assert(A::count == 0); assert(test_deleter::count == 0); @@ -52,37 +52,39 @@ assert(alloc_stats.count == 0); assert(alloc_stats.alloc_count == 0); test_deleter::dealloc_count = 0; + // Test an allocator with a minimal interface { - std::shared_ptr p(nullptr, test_deleter(1), bare_allocator()); - assert(A::count == 0); - assert(p.use_count() == 1); - assert(p.get() == 0); - assert(test_deleter::count ==1); - assert(test_deleter::dealloc_count == 0); + std::shared_ptr p(nullptr, test_deleter(1), bare_allocator()); + assert(A::count == 0); + assert(p.use_count() == 1); + assert(p.get() == 0); + assert(test_deleter::count ==1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 1); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 1); #endif } assert(A::count == 0); assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); test_deleter::dealloc_count = 0; + #if TEST_STD_VER >= 11 // Test an allocator that returns class-type pointers { - std::shared_ptr p(nullptr, test_deleter(1), min_allocator()); - assert(A::count == 0); - assert(p.use_count() == 1); - assert(p.get() == 0); - assert(test_deleter::count ==1); - assert(test_deleter::dealloc_count == 0); + std::shared_ptr p(nullptr, test_deleter(1), min_allocator()); + assert(A::count == 0); + assert(p.use_count() == 1); + assert(p.get() == 0); + assert(test_deleter::count ==1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 1); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 1); #endif } assert(A::count == 0); @@ -90,5 +92,11 @@ assert(test_deleter::dealloc_count == 1); #endif + // Make sure we can use this constructor with a pointer-to-const + { + std::shared_ptr p(nullptr, test_deleter(3), test_allocator(5, &alloc_stats)); + (void)p; + } + return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer.pass.cpp @@ -29,43 +29,53 @@ int main(int, char**) { { - A* ptr = new A; - std::shared_ptr p(ptr); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); + assert(A::count == 0); + A* ptr = new A; + std::shared_ptr p(ptr); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); } - assert(A::count == 0); + + { + assert(A::count == 0); + A const* ptr = new A; + std::shared_ptr p(ptr); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + } + { - A* ptr = new A; - std::shared_ptr p(ptr); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); + assert(A::count == 0); + A* ptr = new A; + std::shared_ptr p(ptr); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); } - assert(A::count == 0); #if TEST_STD_VER > 14 { - std::shared_ptr pA(new A[8]); - assert(pA.use_count() == 1); - assert(A::count == 8); + assert(A::count == 0); + std::shared_ptr pA(new A[8]); + assert(pA.use_count() == 1); + assert(A::count == 8); } - assert(A::count == 0); { - std::shared_ptr pA(new A[8]); - assert(pA.use_count() == 1); - assert(A::count == 8); + assert(A::count == 0); + std::shared_ptr pA(new A[8]); + assert(pA.use_count() == 1); + assert(A::count == 8); } - assert(A::count == 0); { - std::shared_ptr pA(new A[8]); - assert(pA.use_count() == 1); - assert(A::count == 8); + assert(A::count == 0); + std::shared_ptr pA(new A[8]); + assert(pA.use_count() == 1); + assert(A::count == 8); } - assert(A::count == 0); #endif return 0; diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter.pass.cpp @@ -63,23 +63,29 @@ int main(int, char**) { { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3)); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3)); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 3); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 3); #endif } assert(A::count == 0); assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); + { + A const* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3)); + assert(p.get() == ptr); + } + { // Make sure we can't construct with: // a) a deleter that doesn't have an operator ()(int*) diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/pointer_deleter_allocator.pass.cpp @@ -62,62 +62,92 @@ int main(int, char**) { - test_allocator_statistics alloc_stats; { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3), test_allocator(5, &alloc_stats)); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); + test_allocator_statistics alloc_stats; + { + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3), test_allocator(5, &alloc_stats)); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 3); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 3); #endif - assert(alloc_stats.count == 1); - assert(alloc_stats.alloc_count == 1); + assert(alloc_stats.count == 1); + assert(alloc_stats.alloc_count == 1); + } + assert(A::count == 0); + assert(test_deleter::count == 0); + assert(test_deleter::dealloc_count == 1); + assert(alloc_stats.count == 0); + assert(alloc_stats.alloc_count == 0); + test_deleter::dealloc_count = 0; } - assert(A::count == 0); - assert(test_deleter::count == 0); - assert(test_deleter::dealloc_count == 1); - assert(alloc_stats.count == 0); - assert(alloc_stats.alloc_count == 0); - test_deleter::dealloc_count = 0; + + { + test_allocator_statistics alloc_stats; + { + A const* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3), test_allocator(5, &alloc_stats)); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); +#ifndef TEST_HAS_NO_RTTI + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 3); +#endif + assert(alloc_stats.count == 1); + assert(alloc_stats.alloc_count == 1); + } + assert(A::count == 0); + assert(test_deleter::count == 0); + assert(test_deleter::dealloc_count == 1); + assert(alloc_stats.count == 0); + assert(alloc_stats.alloc_count == 0); + test_deleter::dealloc_count = 0; + } + // Test an allocator with a minimal interface { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3), bare_allocator()); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3), bare_allocator()); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 3); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 3); #endif } assert(A::count == 0); assert(test_deleter::count == 0); assert(test_deleter::dealloc_count == 1); test_deleter::dealloc_count = 0; + #if TEST_STD_VER >= 11 // Test an allocator that returns class-type pointers { - A* ptr = new A; - std::shared_ptr p(ptr, test_deleter(3), min_allocator()); - assert(A::count == 1); - assert(p.use_count() == 1); - assert(p.get() == ptr); - assert(test_deleter::count == 1); - assert(test_deleter::dealloc_count == 0); + A* ptr = new A; + std::shared_ptr p(ptr, test_deleter(3), min_allocator()); + assert(A::count == 1); + assert(p.use_count() == 1); + assert(p.get() == ptr); + assert(test_deleter::count == 1); + assert(test_deleter::dealloc_count == 0); #ifndef TEST_HAS_NO_RTTI - test_deleter* d = std::get_deleter >(p); - assert(d); - assert(d->state() == 3); + test_deleter* d = std::get_deleter >(p); + assert(d); + assert(d->state() == 3); #endif } assert(A::count == 0); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr.pass.cpp @@ -61,5 +61,11 @@ } assert(A::count == 0); + { + std::shared_ptr pA(new A); + std::shared_ptr pA2(pA); + assert(pA.get() == pA2.get()); + } + return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y.pass.cpp @@ -152,5 +152,11 @@ assert(A::count == 0); #endif + { + std::shared_ptr pA(new A); + std::shared_ptr pB(pA); + assert(pB.get() == pA.get()); + } + return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_Y_rv.pass.cpp @@ -129,5 +129,12 @@ assert(A::count == 0); #endif + { + std::shared_ptr pA(new A); + B const* p = pA.get(); + std::shared_ptr pB(std::move(pA)); + assert(pB.get() == p); + } + return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_pointer.pass.cpp @@ -61,6 +61,26 @@ assert(A::count == 0); assert(B::count == 0); + { + std::shared_ptr pA(new A); + assert(pA.use_count() == 1); + + { + B const b; + std::shared_ptr pB(pA, &b); + assert(A::count == 1); + assert(B::count == 1); + assert(pA.use_count() == 2); + assert(pB.use_count() == 2); + assert(pB.get() == &b); + } + assert(pA.use_count() == 1); + assert(A::count == 1); + assert(B::count == 0); + } + assert(A::count == 0); + assert(B::count == 0); + int *pi = new int; { std::shared_ptr p1(nullptr); diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/shared_ptr_rv.pass.cpp @@ -57,6 +57,7 @@ assert(A::count == 1); #endif } + assert(A::count == 0); { std::shared_ptr pA; @@ -74,5 +75,12 @@ } assert(A::count == 0); + { + std::shared_ptr pA(new A); + A const* p = pA.get(); + std::shared_ptr pA2(std::move(pA)); + assert(pA2.get() == p); + } + return 0; } diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/unique_ptr.pass.cpp @@ -94,6 +94,18 @@ assert(p.get() == raw_ptr); assert(ptr.get() == 0); } + + { + std::unique_ptr ptr(new A); + A const* raw_ptr = ptr.get(); + std::shared_ptr p(std::move(ptr)); + assert(A::count == 1); + assert(B::count == 1); + assert(p.use_count() == 1); + assert(p.get() == raw_ptr); + assert(ptr.get() == 0); + } + #ifndef TEST_HAS_NO_EXCEPTIONS assert(A::count == 0); { diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.const/weak_ptr.pass.cpp @@ -65,6 +65,15 @@ assert(A::count == 1); } assert(A::count == 0); + { + std::shared_ptr sp0(new A); + std::weak_ptr wp(sp0); + std::shared_ptr sp(wp); + assert(sp.use_count() == 2); + assert(sp.get() == sp0.get()); + assert(A::count == 1); + } + assert(A::count == 0); #ifndef TEST_HAS_NO_EXCEPTIONS { std::shared_ptr sp0(new A);