[libc++] Add test coverage for std::shared_ptr<const T>

Those tests were extracted from D120996.

Differential Revision: https://reviews.llvm.org/D121340
This commit is contained in:
Louis Dionne 2022-03-09 17:06:16 -05:00
parent 2fccde0ea7
commit 6b9e0af8db
16 changed files with 306 additions and 126 deletions

View File

@ -46,19 +46,34 @@ int A::count = 0;
int main(int, char**)
{
globalMemCounter.reset();
{
std::auto_ptr<A> ptr(new A);
A* raw_ptr = ptr.get();
std::shared_ptr<B> 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<A> ptr(new A);
A* raw_ptr = ptr.get();
std::shared_ptr<B> 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<A const> ptr(new A);
A const* raw_ptr = ptr.get();
std::shared_ptr<B const> 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<A> ptr(new A);

View File

@ -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 @@ int main(int, char**)
assert(s.use_count() == 2);
assert(s0.get() == s.get());
}
{
std::shared_ptr<A const> s0(new A);
std::weak_ptr<A const> w = s0;
auto s = std::shared_ptr(w);
ASSERT_SAME_TYPE(decltype(s), std::shared_ptr<A const>);
assert(s0.use_count() == 2);
assert(s.use_count() == 2);
assert(s0.get() == s.get());
}
{
std::unique_ptr<A> 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<A>);
assert(u == nullptr);
assert(s.get() == uPointee);
}
{
std::unique_ptr<A const> u(new A);
A const* uPointee = u.get();
std::shared_ptr s = std::move(u);
ASSERT_SAME_TYPE(decltype(s), std::shared_ptr<A const>);
assert(u == nullptr);
assert(s.get() == uPointee);
}
{
std::unique_ptr<A, D> 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<A>);
assert(u == nullptr);
assert(s.get() == uPointee);
}
{
std::unique_ptr<A const, D> u(new A, D{});
A const* uPointee = u.get();
std::shared_ptr s(std::move(u));
ASSERT_SAME_TYPE(decltype(s), std::shared_ptr<A const>);
assert(u == nullptr);
assert(s.get() == uPointee);
}
return 0;
}

View File

@ -26,8 +26,11 @@ void test() {
int main(int, char**) {
test<int>();
test<int const>();
test<A>();
test<A const>();
test<int*>();
test<int const*>();
test<int[]>();
test<int[8]>();

View File

@ -17,9 +17,17 @@
int main(int, char**)
{
{
std::shared_ptr<int> p(nullptr);
assert(p.use_count() == 0);
assert(p.get() == 0);
}
{
std::shared_ptr<int const> p(nullptr);
assert(p.use_count() == 0);
assert(p.get() == 0);
}
return 0;
}

View File

@ -31,21 +31,26 @@ int A::count = 0;
int main(int, char**)
{
{
std::shared_ptr<A> p(nullptr, test_deleter<A>(3));
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
std::shared_ptr<A> p(nullptr, test_deleter<A>(3));
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
#endif
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
return 0;
{
std::shared_ptr<A const> p(nullptr, test_deleter<A const>(3));
assert(p.get() == nullptr);
}
return 0;
}

View File

@ -32,19 +32,19 @@ int main(int, char**)
{
test_allocator_statistics alloc_stats;
{
std::shared_ptr<A> p(nullptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
std::shared_ptr<A> p(nullptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(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<A>::count == 0);
@ -52,37 +52,39 @@ int main(int, char**)
assert(alloc_stats.count == 0);
assert(alloc_stats.alloc_count == 0);
test_deleter<A>::dealloc_count = 0;
// Test an allocator with a minimal interface
{
std::shared_ptr<A> p(nullptr, test_deleter<A>(1), bare_allocator<void>());
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count ==1);
assert(test_deleter<A>::dealloc_count == 0);
std::shared_ptr<A> p(nullptr, test_deleter<A>(1), bare_allocator<void>());
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count ==1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 1);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 1);
#endif
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
test_deleter<A>::dealloc_count = 0;
#if TEST_STD_VER >= 11
// Test an allocator that returns class-type pointers
{
std::shared_ptr<A> p(nullptr, test_deleter<A>(1), min_allocator<void>());
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count ==1);
assert(test_deleter<A>::dealloc_count == 0);
std::shared_ptr<A> p(nullptr, test_deleter<A>(1), min_allocator<void>());
assert(A::count == 0);
assert(p.use_count() == 1);
assert(p.get() == 0);
assert(test_deleter<A>::count ==1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 1);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 1);
#endif
}
assert(A::count == 0);
@ -90,5 +92,11 @@ int main(int, char**)
assert(test_deleter<A>::dealloc_count == 1);
#endif
// Make sure we can use this constructor with a pointer-to-const
{
std::shared_ptr<A const> p(nullptr, test_deleter<A const>(3), test_allocator<A>(5, &alloc_stats));
(void)p;
}
return 0;
}

View File

@ -29,43 +29,53 @@ int A::count = 0;
int main(int, char**)
{
{
A* ptr = new A;
std::shared_ptr<A> 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<A> 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<void> p(ptr);
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(A::count == 0);
A const* ptr = new A;
std::shared_ptr<A const> 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<void> 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<A[8]> pA(new A[8]);
assert(pA.use_count() == 1);
assert(A::count == 8);
assert(A::count == 0);
std::shared_ptr<A[8]> pA(new A[8]);
assert(pA.use_count() == 1);
assert(A::count == 8);
}
assert(A::count == 0);
{
std::shared_ptr<A[]> pA(new A[8]);
assert(pA.use_count() == 1);
assert(A::count == 8);
assert(A::count == 0);
std::shared_ptr<A[]> pA(new A[8]);
assert(pA.use_count() == 1);
assert(A::count == 8);
}
assert(A::count == 0);
{
std::shared_ptr<const A[]> pA(new A[8]);
assert(pA.use_count() == 1);
assert(A::count == 8);
assert(A::count == 0);
std::shared_ptr<const A[]> pA(new A[8]);
assert(pA.use_count() == 1);
assert(A::count == 8);
}
assert(A::count == 0);
#endif
return 0;

View File

@ -63,23 +63,29 @@ public:
int main(int, char**)
{
{
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3));
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3));
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
#endif
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
{
A const* ptr = new A;
std::shared_ptr<A const> p(ptr, test_deleter<A const>(3));
assert(p.get() == ptr);
}
{
// Make sure we can't construct with:
// a) a deleter that doesn't have an operator ()(int*)

View File

@ -62,62 +62,92 @@ public:
int main(int, char**)
{
test_allocator_statistics alloc_stats;
{
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
test_allocator_statistics alloc_stats;
{
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3), test_allocator<A>(5, &alloc_stats));
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(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<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
assert(alloc_stats.count == 0);
assert(alloc_stats.alloc_count == 0);
test_deleter<A>::dealloc_count = 0;
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
assert(alloc_stats.count == 0);
assert(alloc_stats.alloc_count == 0);
test_deleter<A>::dealloc_count = 0;
{
test_allocator_statistics alloc_stats;
{
A const* ptr = new A;
std::shared_ptr<A const> p(ptr, test_deleter<A const>(3), test_allocator<A>(5, &alloc_stats));
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A const>::count == 1);
assert(test_deleter<A const>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A const>* d = std::get_deleter<test_deleter<A const> >(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<A const>::count == 0);
assert(test_deleter<A const>::dealloc_count == 1);
assert(alloc_stats.count == 0);
assert(alloc_stats.alloc_count == 0);
test_deleter<A const>::dealloc_count = 0;
}
// Test an allocator with a minimal interface
{
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3), bare_allocator<void>());
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3), bare_allocator<void>());
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
#endif
}
assert(A::count == 0);
assert(test_deleter<A>::count == 0);
assert(test_deleter<A>::dealloc_count == 1);
test_deleter<A>::dealloc_count = 0;
#if TEST_STD_VER >= 11
// Test an allocator that returns class-type pointers
{
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3), min_allocator<void>());
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
A* ptr = new A;
std::shared_ptr<A> p(ptr, test_deleter<A>(3), min_allocator<void>());
assert(A::count == 1);
assert(p.use_count() == 1);
assert(p.get() == ptr);
assert(test_deleter<A>::count == 1);
assert(test_deleter<A>::dealloc_count == 0);
#ifndef TEST_HAS_NO_RTTI
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
test_deleter<A>* d = std::get_deleter<test_deleter<A> >(p);
assert(d);
assert(d->state() == 3);
#endif
}
assert(A::count == 0);

View File

@ -61,5 +61,11 @@ int main(int, char**)
}
assert(A::count == 0);
{
std::shared_ptr<A const> pA(new A);
std::shared_ptr<A const> pA2(pA);
assert(pA.get() == pA2.get());
}
return 0;
}

View File

@ -152,5 +152,11 @@ int main(int, char**)
assert(A::count == 0);
#endif
{
std::shared_ptr<A const> pA(new A);
std::shared_ptr<B const> pB(pA);
assert(pB.get() == pA.get());
}
return 0;
}

View File

@ -129,5 +129,12 @@ int main(int, char**)
assert(A::count == 0);
#endif
{
std::shared_ptr<A const> pA(new A);
B const* p = pA.get();
std::shared_ptr<B const> pB(std::move(pA));
assert(pB.get() == p);
}
return 0;
}

View File

@ -61,6 +61,26 @@ int main(int, char**)
assert(A::count == 0);
assert(B::count == 0);
{
std::shared_ptr<A const> pA(new A);
assert(pA.use_count() == 1);
{
B const b;
std::shared_ptr<B const> 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<int> p1(nullptr);

View File

@ -57,6 +57,7 @@ int main(int, char**)
assert(A::count == 1);
#endif
}
assert(A::count == 0);
{
std::shared_ptr<A> pA;
@ -74,5 +75,12 @@ int main(int, char**)
}
assert(A::count == 0);
{
std::shared_ptr<A const> pA(new A);
A const* p = pA.get();
std::shared_ptr<A const> pA2(std::move(pA));
assert(pA2.get() == p);
}
return 0;
}

View File

@ -94,6 +94,18 @@ int main(int, char**)
assert(p.get() == raw_ptr);
assert(ptr.get() == 0);
}
{
std::unique_ptr<A const> ptr(new A);
A const* raw_ptr = ptr.get();
std::shared_ptr<B const> 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);
{

View File

@ -65,6 +65,15 @@ int main(int, char**)
assert(A::count == 1);
}
assert(A::count == 0);
{
std::shared_ptr<A const> sp0(new A);
std::weak_ptr<A const> wp(sp0);
std::shared_ptr<A const> 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<A> sp0(new A);