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

llvm-svn: 245512
This commit is contained in:
Eric Fiselier 2015-08-19 22:35:07 +00:00
parent 1b7bf7a2a7
commit 2228a8a3f2
5 changed files with 118 additions and 136 deletions

View File

@ -112,7 +112,6 @@ public:
~Deleter() {assert(state_ >= 0); state_ = -1;}
private:
template <class U>
Deleter(Deleter<U> d,
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> 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>
// unique_ptr
// Test unique_ptr(pointer) ctor
// template <class U> unique_ptr(auto_ptr<U>&&) noexcept
#include <memory>
#include <utility>
#include <cassert>
// template <class U> explicit unique_ptr(auto_ptr<U>&);
#include "test_macros.h"
struct A
{
@ -65,4 +69,12 @@ int main()
}
assert(A::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
#include <memory>
#include <type_traits>
#include <utility>
@ -50,126 +51,121 @@ struct B
int B::count = 0;
template <class OrigPtr, class NewPtr>
void checkDeleter(OrigPtr& O, NewPtr& N, int OrigState, int NewState) {
typedef typename NewPtr::deleter_type NewDel;
if (std::is_reference<NewDel>::value) {
O.get_deleter().set_state(42);
assert(O.get_deleter().state() == 42);
assert(N.get_deleter().state() == 42);
O.get_deleter().set_state(99);
assert(O.get_deleter().state() == 99);
assert(N.get_deleter().state() == 99);
} else {
// TODO(EricWF) Enable this?
// assert(OrigState != NewState);
assert(O.get_deleter().state() == OrigState);
assert(N.get_deleter().state() == NewState);
}
template <class LHS, class RHS>
void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
typedef typename LHS::deleter_type NewDel;
static_assert(std::is_reference<NewDel>::value, "");
rhs.get_deleter().set_state(42);
assert(rhs.get_deleter().state() == 42);
assert(lhs.get_deleter().state() == 42);
lhs.get_deleter().set_state(99);
assert(lhs.get_deleter().state() == 99);
assert(rhs.get_deleter().state() == 99);
}
template <class APtr, class BPtr>
void testMoveConvertExplicit()
{
{ // Test explicit 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);
}
template <class LHS, class RHS>
void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) {
assert(lhs.get_deleter().state() == LHSVal);
assert(rhs.get_deleter().state() == RHSVal);
}
template <class LHS, class RHS>
void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) {
assert(lhs.get() == RHSVal);
assert(rhs.get() == nullptr);
assert(A::count == 1);
assert(B::count == 1);
}
void checkNoneAlive() {
assert(A::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()
{
{
typedef std::unique_ptr<A> APtr;
typedef std::unique_ptr<B> BPtr;
testMoveConvertExplicit<APtr, BPtr>();
testMoveConvertImplicit<APtr, BPtr>();
{ // explicit
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<B, Deleter<B> > BPtr;
Deleter<B> del(5);
testMoveConvertExplicit<APtr, BPtr>(std::move(del));
del.set_state(5);
testMoveConvertImplicit<APtr, BPtr>(std::move(del));
{
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();
{
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<B, NCDeleter<A>& > BPtr;
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<B, CDeleter<B>& > BPtr;
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>
// unique_ptr
// Test unique_ptr(pointer) ctor
#include <memory>
#include <cassert>
// unique_ptr<T, const D&>(pointer, D()) should not compile
struct A
{
static int count;
A() {++count;}
A(const A&) {++count;}
~A() {--count;}
};
#include <memory>
int A::count = 0;
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;}
struct Deleter {
void operator()(int* p) const {delete p;}
};
int main()
{
{
A* p = new A;
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);
// expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
std::unique_ptr<int, const Deleter&> s((int*)nullptr, Deleter()); // expected-note {{requested here}}
}