More unique_ptr test cleanup. Fixes in <memory> to come later.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@245512 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier 2015-08-19 22:35:07 +00:00
parent de56f74611
commit 672575dadc
5 changed files with 118 additions and 136 deletions

View File

@ -112,7 +112,6 @@ public:
~Deleter() {assert(state_ >= 0); state_ = -1;} ~Deleter() {assert(state_ >= 0); state_ = -1;}
private:
template <class U> template <class U>
Deleter(Deleter<U> d, Deleter(Deleter<U> d,
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)

View File

@ -32,5 +32,5 @@ int main()
{ {
std::unique_ptr<A[], Deleter> s; std::unique_ptr<A[], Deleter> s;
std::unique_ptr<A, Deleter> s2; std::unique_ptr<A, Deleter> s2;
s2 = std::move(s); s2 = std::move(s); // expected-error {{no viable overloaded '='}}
} }

View File

@ -7,17 +7,21 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// libc++ cannot safely provide the auto_ptr constructor without rvalue
// references.
// XFAIL: c++98, c++03
// <memory> // <memory>
// unique_ptr // unique_ptr
// Test unique_ptr(pointer) ctor // template <class U> unique_ptr(auto_ptr<U>&&) noexcept
#include <memory> #include <memory>
#include <utility> #include <utility>
#include <cassert> #include <cassert>
// template <class U> explicit unique_ptr(auto_ptr<U>&); #include "test_macros.h"
struct A struct A
{ {
@ -65,4 +69,12 @@ int main()
} }
assert(A::count == 0); assert(A::count == 0);
assert(B::count == 0); assert(B::count == 0);
#if TEST_STD_VER >= 11
{
static_assert(std::is_nothrow_constructible<
std::unique_ptr<A>,
std::auto_ptr<B>&&
>::value, "");
}
#endif
} }

View File

@ -18,6 +18,7 @@
// XFAIL: c++98, c++03 // XFAIL: c++98, c++03
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
@ -50,126 +51,121 @@ struct B
int B::count = 0; int B::count = 0;
template <class OrigPtr, class NewPtr>
void checkDeleter(OrigPtr& O, NewPtr& N, int OrigState, int NewState) { template <class LHS, class RHS>
typedef typename NewPtr::deleter_type NewDel; void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
if (std::is_reference<NewDel>::value) { typedef typename LHS::deleter_type NewDel;
O.get_deleter().set_state(42); static_assert(std::is_reference<NewDel>::value, "");
assert(O.get_deleter().state() == 42); rhs.get_deleter().set_state(42);
assert(N.get_deleter().state() == 42); assert(rhs.get_deleter().state() == 42);
O.get_deleter().set_state(99); assert(lhs.get_deleter().state() == 42);
assert(O.get_deleter().state() == 99); lhs.get_deleter().set_state(99);
assert(N.get_deleter().state() == 99); assert(lhs.get_deleter().state() == 99);
} else { assert(rhs.get_deleter().state() == 99);
// TODO(EricWF) Enable this?
// assert(OrigState != NewState);
assert(O.get_deleter().state() == OrigState);
assert(N.get_deleter().state() == NewState);
}
} }
template <class APtr, class BPtr> template <class LHS, class RHS>
void testMoveConvertExplicit() void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) {
{ assert(lhs.get_deleter().state() == LHSVal);
{ // Test explicit constructor assert(rhs.get_deleter().state() == RHSVal);
BPtr s(new B); }
A* p = s.get();
APtr s2(std::move(s)); template <class LHS, class RHS>
assert(s2.get() == p); void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) {
assert(s.get() == 0); assert(lhs.get() == RHSVal);
assert(A::count == 1); assert(rhs.get() == nullptr);
assert(B::count == 1); assert(A::count == 1);
} assert(B::count == 1);
}
void checkNoneAlive() {
assert(A::count == 0); assert(A::count == 0);
assert(B::count == 0); assert(B::count == 0);
} }
template <class APtr, class BPtr>
void testMoveConvertImplicit() {
{ // Test implicit constructor
BPtr s(new B);
A* p = s.get();
APtr s2 = std::move(s);
assert(s2.get() == p);
assert(s.get() == 0);
assert(A::count == 1);
assert(B::count == 1);
}
assert(A::count == 0);
assert(B::count == 0);
}
template <class APtr, class BPtr, class Deleter>
#if TEST_STD_VER >= 11
void testMoveConvertExplicit(Deleter&& del) {
#else
void testMoveConvert(Deleter& del) {
#endif
int old_val = del.state();
{ // Test Explicit constructor
BPtr s(new B, std::forward<Deleter>(del));
A* p = s.get();
APtr s2(std::move(s));
assert(s2.get() == p);
assert(s.get() == 0);
checkDeleter(s, s2, del.state(), old_val);
assert(A::count == 1);
assert(B::count == 1);
}
assert(A::count == 0);
assert(B::count == 0);
}
template <class APtr, class BPtr, class Deleter>
#if TEST_STD_VER >= 11
void testMoveConvertImplicit(Deleter&& del) {
#else
void testMoveConvertImplicit(Deleter& del) {
#endif
int old_val = del.state();
{ // Test Implicit constructor
BPtr s(new B, std::forward<Deleter>(del));
A* p = s.get();
APtr s2 = std::move(s);
assert(s2.get() == p);
assert(s.get() == 0);
checkDeleter(s, s2, del.state(), old_val);
assert(A::count == 1);
assert(B::count == 1);
}
assert(A::count == 0);
assert(B::count == 0);
}
int main() int main()
{ {
{ {
typedef std::unique_ptr<A> APtr; typedef std::unique_ptr<A> APtr;
typedef std::unique_ptr<B> BPtr; typedef std::unique_ptr<B> BPtr;
testMoveConvertExplicit<APtr, BPtr>(); { // explicit
testMoveConvertImplicit<APtr, BPtr>(); BPtr b(new B);
A* p = b.get();
APtr a(std::move(b));
checkCtor(a, b, p);
}
checkNoneAlive();
{ // implicit
BPtr b(new B);
A* p = b.get();
APtr a = std::move(b);
checkCtor(a, b, p);
}
checkNoneAlive();
} }
{ { // test with moveable deleters
typedef std::unique_ptr<A, Deleter<A> > APtr; typedef std::unique_ptr<A, Deleter<A> > APtr;
typedef std::unique_ptr<B, Deleter<B> > BPtr; typedef std::unique_ptr<B, Deleter<B> > BPtr;
Deleter<B> del(5); {
testMoveConvertExplicit<APtr, BPtr>(std::move(del)); Deleter<B> del(5);
del.set_state(5); BPtr b(new B, std::move(del));
testMoveConvertImplicit<APtr, BPtr>(std::move(del)); A* p = b.get();
APtr a(std::move(b));
checkCtor(a, b, p);
checkDeleter(a, b, 5, 0);
}
checkNoneAlive();
{
Deleter<B> del(5);
BPtr b(new B, std::move(del));
A* p = b.get();
APtr a = std::move(b);
checkCtor(a, b, p);
checkDeleter(a, b, 5, 0);
}
checkNoneAlive();
} }
{ { // test with reference deleters
typedef std::unique_ptr<A, NCDeleter<A>& > APtr; typedef std::unique_ptr<A, NCDeleter<A>& > APtr;
typedef std::unique_ptr<B, NCDeleter<A>& > BPtr; typedef std::unique_ptr<B, NCDeleter<A>& > BPtr;
NCDeleter<A> del(5); NCDeleter<A> del(5);
testMoveConvertExplicit<APtr, BPtr>(del); {
testMoveConvertImplicit<APtr, BPtr>(del); BPtr b(new B, del);
A* p = b.get();
APtr a(std::move(b));
checkCtor(a, b, p);
checkReferenceDeleter(a, b);
}
checkNoneAlive();
{
BPtr b(new B, del);
A* p = b.get();
APtr a = std::move(b);
checkCtor(a, b, p);
checkReferenceDeleter(a, b);
}
checkNoneAlive();
} }
{ {
typedef std::unique_ptr<A, CDeleter<A> > APtr; typedef std::unique_ptr<A, CDeleter<A> > APtr;
typedef std::unique_ptr<B, CDeleter<B>& > BPtr; typedef std::unique_ptr<B, CDeleter<B>& > BPtr;
CDeleter<B> del(5); CDeleter<B> del(5);
testMoveConvertImplicit<APtr, BPtr>(del); {
testMoveConvertExplicit<APtr, BPtr>(del); BPtr b(new B, del);
A* p = b.get();
APtr a(std::move(b));
checkCtor(a, b, p);
checkDeleter(a, b, 5, 5);
}
checkNoneAlive();
{
BPtr b(new B, del);
A* p = b.get();
APtr a = std::move(b);
checkCtor(a, b, p);
checkDeleter(a, b, 5, 5);
}
checkNoneAlive();
} }
} }

View File

@ -7,49 +7,24 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Without rvalue references it is impossible to detect when a rvalue deleter
// is given.
// XFAIL: c++98, c++03
// <memory> // <memory>
// unique_ptr // unique_ptr
// Test unique_ptr(pointer) ctor
#include <memory>
#include <cassert>
// unique_ptr<T, const D&>(pointer, D()) should not compile // unique_ptr<T, const D&>(pointer, D()) should not compile
struct A #include <memory>
{
static int count;
A() {++count;}
A(const A&) {++count;}
~A() {--count;}
};
int A::count = 0; struct Deleter {
void operator()(int* p) const {delete p;}
class Deleter
{
int state_;
public:
Deleter() : state_(5) {}
int state() const {return state_;}
void set_state(int s) {state_ = s;}
void operator()(A* p) const {delete p;}
}; };
int main() int main()
{ {
{ // expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
A* p = new A; std::unique_ptr<int, const Deleter&> s((int*)nullptr, Deleter()); // expected-note {{requested here}}
assert(A::count == 1);
std::unique_ptr<A, const Deleter&> s(p, Deleter());
assert(s.get() == p);
assert(s.get_deleter().state() == 5);
}
assert(A::count == 0);
} }