blob: 7ddd1626510788291cd7f264caab924c84ff8220 [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// <memory>
// unique_ptr
//=============================================================================
// TESTING unique_ptr(pointer, deleter)
//
// Concerns:
// 1 unique_ptr(pointer, deleter&&) only requires a MoveConstructible deleter.
// 2 unique_ptr(pointer, deleter&) requires a CopyConstructible deleter.
// 3 unique_ptr<T, D&>(pointer, deleter) does not require a CopyConstructible deleter.
// 4 unique_ptr<T, D const&>(pointer, deleter) does not require a CopyConstructible deleter.
// 5 unique_ptr(pointer, deleter) should work for derived pointers.
// 6 unique_ptr(pointer, deleter) should work with function pointers.
// 7 unique_ptr<void> should work.
#include <memory>
#include <cassert>
#include "../../deleter.h"
struct A
{
static int count;
A() {++count;}
A(const A&) {++count;}
virtual ~A() {--count;}
};
int A::count = 0;
struct B
: public A
{
static int count;
B() {++count;}
B(const B&) {++count;}
virtual ~B() {--count;}
};
int B::count = 0;
bool my_free_called = false;
void my_free(void*) {
my_free_called = true;
}
int main()
{
{ // MoveConstructible deleter (C-1)
A* p = new A;
assert(A::count == 1);
std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>(5));
assert(s.get() == p);
assert(s.get_deleter().state() == 5);
}
assert(A::count == 0);
{ // CopyConstructible deleter (C-2)
A* p = new A;
assert(A::count == 1);
CopyDeleter<A> d(5);
std::unique_ptr<A, CopyDeleter<A> > s(p, d);
assert(s.get() == p);
assert(s.get_deleter().state() == 5);
d.set_state(6);
assert(s.get_deleter().state() == 5);
}
assert(A::count == 0);
{ // Reference deleter (C-3)
A* p = new A;
assert(A::count == 1);
NCDeleter<A> d(5);
std::unique_ptr<A, NCDeleter<A>&> s(p, d);
assert(s.get() == p);
assert(&s.get_deleter() == &d);
assert(s.get_deleter().state() == 5);
d.set_state(6);
assert(s.get_deleter().state() == 6);
}
assert(A::count == 0);
{ // Const Reference deleter (C-4)
A* p = new A;
assert(A::count == 1);
NCConstDeleter<A> d(5);
std::unique_ptr<A, NCConstDeleter<A> const&> s(p, d);
assert(s.get() == p);
assert(s.get_deleter().state() == 5);
assert(&s.get_deleter() == &d);
}
assert(A::count == 0);
{ // Derived pointers (C-5)
B* p = new B;
assert(A::count == 1);
assert(B::count == 1);
std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>(5));
assert(s.get() == p);
assert(s.get_deleter().state() == 5);
}
assert(A::count == 0);
assert(B::count == 0);
{ // Void and function pointers (C-6,7)
{
int i = 0;
std::unique_ptr<void, void(*)(void*)> s(&i, my_free);
assert(s.get() == &i);
assert(s.get_deleter() == my_free);
assert(!my_free_called);
}
assert(my_free_called);
}
}