Start cleanup of unique_ptr tests.
One of the last sections of tests that still fail in C++03 are the unique_ptr tests. This patch begins cleaning up the tests and fixing C++03 failures. The main changes of this patch: - The "Deleter" type in "deleter.h" tried to be "move-only" in C++03. However the move simulation no longer works (see "__rv"). "Deleter" is now copy constructible in C++03. However copying "Deleter" will "move" the test value instead of copying it. - Reduce the unique.ptr.single.ctor tests files from ~25 to 4. There is no reason the tests were split through so many files. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@243730 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
65a1d45c0a
commit
76581dc450
@ -20,21 +20,19 @@
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
#if TEST_STD_VER >= 11
|
||||
|
||||
template <class T>
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(const Deleter&);
|
||||
Deleter& operator=(const Deleter&);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
public:
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
||||
Deleter& operator=(Deleter&& r)
|
||||
{
|
||||
@ -42,22 +40,12 @@ public:
|
||||
r.state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
|
||||
Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
|
||||
Deleter& operator=(std::__rv<Deleter> r)
|
||||
{
|
||||
state_ = r->state_;
|
||||
r->state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
|
||||
Deleter() : state_(0) {}
|
||||
explicit Deleter(int s) : state_(s) {}
|
||||
~Deleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U>&& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
@ -67,12 +55,6 @@ private:
|
||||
template <class U>
|
||||
Deleter(const Deleter<U>& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U> d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
: state_(d.state()) {}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
public:
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
@ -85,16 +67,11 @@ class Deleter<T[]>
|
||||
{
|
||||
int state_;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(const Deleter&);
|
||||
Deleter& operator=(const Deleter&);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
public:
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
||||
Deleter& operator=(Deleter&& r)
|
||||
{
|
||||
@ -102,16 +79,6 @@ public:
|
||||
r.state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
|
||||
Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
|
||||
Deleter& operator=(std::__rv<Deleter> r)
|
||||
{
|
||||
state_ = r->state_;
|
||||
r->state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
Deleter() : state_(0) {}
|
||||
explicit Deleter(int s) : state_(s) {}
|
||||
@ -123,6 +90,69 @@ public:
|
||||
void operator()(T* p) {delete [] p;}
|
||||
};
|
||||
|
||||
#else // TEST_STD_VER < 11
|
||||
|
||||
template <class T>
|
||||
class Deleter
|
||||
{
|
||||
mutable int state_;
|
||||
|
||||
public:
|
||||
Deleter() : state_(0) {}
|
||||
explicit Deleter(int s) : state_(s) {}
|
||||
|
||||
Deleter(Deleter const & other) : state_(other.state_) {
|
||||
other.state_ = 0;
|
||||
}
|
||||
Deleter& operator=(Deleter const& other) {
|
||||
state_ = other.state_;
|
||||
other.state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~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)
|
||||
: state_(d.state()) {}
|
||||
|
||||
public:
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class Deleter<T[]>
|
||||
{
|
||||
mutable int state_;
|
||||
|
||||
public:
|
||||
|
||||
Deleter(Deleter const& other) : state_(other.state_) {
|
||||
other.state_ = 0;
|
||||
}
|
||||
Deleter& operator=(Deleter const& other) {
|
||||
state_ = other.state_;
|
||||
other.state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Deleter() : state_(0) {}
|
||||
explicit Deleter(int s) : state_(s) {}
|
||||
~Deleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete [] p;}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
void
|
||||
swap(Deleter<T>& x, Deleter<T>& y)
|
||||
@ -132,6 +162,7 @@ swap(Deleter<T>& x, Deleter<T>& y)
|
||||
y = std::move(t);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
class CDeleter
|
||||
{
|
||||
@ -179,4 +210,130 @@ swap(CDeleter<T>& x, CDeleter<T>& y)
|
||||
y = std::move(t);
|
||||
}
|
||||
|
||||
// Non-copyable deleter
|
||||
template <class T>
|
||||
class NCDeleter
|
||||
{
|
||||
int state_;
|
||||
NCDeleter(NCDeleter const&);
|
||||
NCDeleter& operator=(NCDeleter const&);
|
||||
public:
|
||||
|
||||
NCDeleter() : state_(0) {}
|
||||
explicit NCDeleter(int s) : state_(s) {}
|
||||
~NCDeleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class NCDeleter<T[]>
|
||||
{
|
||||
int state_;
|
||||
NCDeleter(NCDeleter const&);
|
||||
NCDeleter& operator=(NCDeleter const&);
|
||||
public:
|
||||
|
||||
NCDeleter() : state_(0) {}
|
||||
explicit NCDeleter(int s) : state_(s) {}
|
||||
~NCDeleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete [] p;}
|
||||
};
|
||||
|
||||
|
||||
// Non-copyable deleter
|
||||
template <class T>
|
||||
class NCConstDeleter
|
||||
{
|
||||
int state_;
|
||||
NCConstDeleter(NCConstDeleter const&);
|
||||
NCConstDeleter& operator=(NCConstDeleter const&);
|
||||
public:
|
||||
|
||||
NCConstDeleter() : state_(0) {}
|
||||
explicit NCConstDeleter(int s) : state_(s) {}
|
||||
~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) const {delete p;}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class NCConstDeleter<T[]>
|
||||
{
|
||||
int state_;
|
||||
NCConstDeleter(NCConstDeleter const&);
|
||||
NCConstDeleter& operator=(NCConstDeleter const&);
|
||||
public:
|
||||
|
||||
NCConstDeleter() : state_(0) {}
|
||||
explicit NCConstDeleter(int s) : state_(s) {}
|
||||
~NCConstDeleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) const {delete [] p;}
|
||||
};
|
||||
|
||||
|
||||
// Non-copyable deleter
|
||||
template <class T>
|
||||
class CopyDeleter
|
||||
{
|
||||
int state_;
|
||||
public:
|
||||
|
||||
CopyDeleter() : state_(0) {}
|
||||
explicit CopyDeleter(int s) : state_(s) {}
|
||||
~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
|
||||
CopyDeleter& operator=(CopyDeleter const& other) {
|
||||
state_ = other.state_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class CopyDeleter<T[]>
|
||||
{
|
||||
int state_;
|
||||
|
||||
public:
|
||||
|
||||
CopyDeleter() : state_(0) {}
|
||||
explicit CopyDeleter(int s) : state_(s) {}
|
||||
~CopyDeleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
CopyDeleter(CopyDeleter const& other) : state_(other.state_) {}
|
||||
CopyDeleter& operator=(CopyDeleter const& other) {
|
||||
state_ = other.state_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete [] p;}
|
||||
};
|
||||
|
||||
|
||||
#endif // DELETER_H
|
||||
|
@ -14,26 +14,15 @@
|
||||
// Test unique_ptr move assignment
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// Can't copy from lvalue
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
#include "test_macros.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<A> s(new A);
|
||||
std::unique_ptr<A> s2;
|
||||
s2 = s;
|
||||
}
|
||||
std::unique_ptr<int> s, s2;
|
||||
#if TEST_STD_VER >= 11
|
||||
s2 = s; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
|
||||
#else
|
||||
s2 = s; // expected-error {{'operator=' is a private member of 'std::__1::unique_ptr}}
|
||||
#endif
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// XFAIL: c++98, c++03
|
||||
|
||||
// <memory>
|
||||
|
||||
// unique_ptr
|
||||
@ -16,40 +18,16 @@
|
||||
// unique_ptr<T, const D&>(pointer, D()) should not compile
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
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;}
|
||||
Deleter() {}
|
||||
void operator()(int* p) const {delete [] p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
A* p = new A[3];
|
||||
assert(A::count == 3);
|
||||
std::unique_ptr<A[], const Deleter&> s(p, Deleter());
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
int* p = nullptr;
|
||||
std::unique_ptr<int[], const Deleter&> s(p, Deleter()); // expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 std::unique_ptr::unique_ptr()
|
||||
//
|
||||
// Concerns:
|
||||
// 1 The default constructor works for any default constructible deleter types.
|
||||
// 2 The stored type 'T' is allowed to be incomplete.
|
||||
//
|
||||
// Plan
|
||||
// 1 Default construct unique_ptr's with various deleter types (C-1)
|
||||
// 2 Default construct a unique_ptr with a incomplete element_type and
|
||||
// various deleter types (C-1,2)
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../deleter.h"
|
||||
|
||||
struct IncompleteT;
|
||||
|
||||
void checkNumIncompleteTypeAlive(int i);
|
||||
|
||||
template <class Del = std::default_delete<IncompleteT> >
|
||||
struct StoresIncomplete {
|
||||
std::unique_ptr<IncompleteT, Del> m_ptr;
|
||||
StoresIncomplete() {}
|
||||
~StoresIncomplete();
|
||||
|
||||
IncompleteT* get() const { return m_ptr.get(); }
|
||||
Del& get_deleter() { return m_ptr.get_deleter(); }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<int> p;
|
||||
assert(p.get() == 0);
|
||||
}
|
||||
{
|
||||
std::unique_ptr<int, NCDeleter<int> > p;
|
||||
assert(p.get() == 0);
|
||||
assert(p.get_deleter().state() == 0);
|
||||
p.get_deleter().set_state(5);
|
||||
assert(p.get_deleter().state() == 5);
|
||||
}
|
||||
{
|
||||
StoresIncomplete<> s;
|
||||
assert(s.get() == 0);
|
||||
checkNumIncompleteTypeAlive(0);
|
||||
}
|
||||
checkNumIncompleteTypeAlive(0);
|
||||
{
|
||||
StoresIncomplete< Deleter<IncompleteT> > s;
|
||||
assert(s.get() == 0);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
checkNumIncompleteTypeAlive(0);
|
||||
}
|
||||
checkNumIncompleteTypeAlive(0);
|
||||
}
|
||||
|
||||
struct IncompleteT {
|
||||
static int count;
|
||||
IncompleteT() { ++count; }
|
||||
~IncompleteT() {--count; }
|
||||
};
|
||||
|
||||
int IncompleteT::count = 0;
|
||||
|
||||
void checkNumIncompleteTypeAlive(int i) {
|
||||
assert(IncompleteT::count == i);
|
||||
}
|
||||
|
||||
template <class Del>
|
||||
StoresIncomplete<Del>::~StoresIncomplete() { }
|
@ -1,46 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr default ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// default unique_ptr ctor should only require default Deleter ctor
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
|
||||
public:
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
|
||||
void operator()(void*) {}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<int> p;
|
||||
assert(p.get() == 0);
|
||||
}
|
||||
{
|
||||
std::unique_ptr<int, Deleter> p;
|
||||
assert(p.get() == 0);
|
||||
assert(p.get_deleter().state() == 5);
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test default unique_ptr ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// default unique_ptr ctor shouldn't require complete type
|
||||
|
||||
struct A;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
|
||||
public:
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
|
||||
void operator()(A* p);
|
||||
};
|
||||
|
||||
void check(int i);
|
||||
|
||||
template <class D = std::default_delete<A> >
|
||||
struct B
|
||||
{
|
||||
std::unique_ptr<A, D> a_;
|
||||
B() {}
|
||||
~B();
|
||||
|
||||
A* get() const {return a_.get();}
|
||||
D& get_deleter() {return a_.get_deleter();}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
B<> s;
|
||||
assert(s.get() == 0);
|
||||
}
|
||||
check(0);
|
||||
{
|
||||
B<Deleter> s;
|
||||
assert(s.get() == 0);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
check(0);
|
||||
}
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
void Deleter::operator()(A* p) {delete p;}
|
||||
|
||||
void check(int i)
|
||||
{
|
||||
assert(A::count == i);
|
||||
}
|
||||
|
||||
template <class D>
|
||||
B<D>::~B() {}
|
@ -0,0 +1,140 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../deleter.h"
|
||||
|
||||
//=============================================================================
|
||||
// TESTING unique_ptr(unique_ptr&&)
|
||||
//
|
||||
// Concerns
|
||||
// 1 The moved from pointer is empty and the new pointer stores the old value.
|
||||
// 2 The only requirement on the deleter is that it is MoveConstructible
|
||||
// or a reference.
|
||||
// 3 The constructor works for explicitly moved values (ie std::move(x))
|
||||
// 4 The constructor works for true temporaries (ie a return value)
|
||||
//
|
||||
// Plan
|
||||
// 1 Explicitly construct unique_ptr<T, D> for various deleter types 'D'.
|
||||
// check that the value and deleter have been properly moved. (C-1,2,3)
|
||||
//
|
||||
// 2 Use the expression 'sink(source())' to move construct a unique_ptr<T, D>
|
||||
// from a temporary. 'source' should return the unique_ptr by value and
|
||||
// 'sink' should accept the unique_ptr by value. (C-1,2,4)
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
virtual ~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
template <class Expect>
|
||||
void sinkFunction(Expect)
|
||||
{
|
||||
}
|
||||
|
||||
typedef std::unique_ptr<A> APtrSource1;
|
||||
typedef std::unique_ptr<A, Deleter<A> > APtrSource2;
|
||||
typedef std::unique_ptr<A, NCDeleter<A>& > APtrSource3;
|
||||
|
||||
APtrSource1 source1() {
|
||||
return APtrSource1 (new A);
|
||||
}
|
||||
|
||||
void sink1(APtrSource1 p) {
|
||||
assert(p.get() != nullptr);
|
||||
}
|
||||
|
||||
APtrSource2 source2() {
|
||||
return APtrSource2(new A, Deleter<A>(5));
|
||||
}
|
||||
|
||||
void sink2(APtrSource2 p) {
|
||||
assert(p.get() != nullptr);
|
||||
assert(p.get_deleter().state() == 5);
|
||||
}
|
||||
|
||||
APtrSource3 source3() {
|
||||
static NCDeleter<A> d(5);
|
||||
return APtrSource3(new A, d);
|
||||
}
|
||||
|
||||
void sink3(APtrSource3 p) {
|
||||
assert(p.get() != nullptr);
|
||||
assert(p.get_deleter().state() == 5);
|
||||
assert(&p.get_deleter() == &source3().get_deleter());
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef std::unique_ptr<A> APtr;
|
||||
APtr s(new A);
|
||||
A* p = s.get();
|
||||
APtr s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
typedef Deleter<A> MoveDel;
|
||||
typedef std::unique_ptr<A, MoveDel> APtr;
|
||||
MoveDel d(5);
|
||||
APtr s(new A, std::move(d));
|
||||
assert(d.state() == 0);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
A* p = s.get();
|
||||
APtr s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(s2.get_deleter().state() == 5);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
typedef NCDeleter<A> NonCopyDel;
|
||||
typedef std::unique_ptr<A, NonCopyDel&> APtr;
|
||||
|
||||
NonCopyDel d;
|
||||
APtr s(new A, d);
|
||||
A* p = s.get();
|
||||
APtr s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
d.set_state(6);
|
||||
assert(s2.get_deleter().state() == d.state());
|
||||
assert(s.get_deleter().state() == d.state());
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
sink1(source1());
|
||||
assert(A::count == 0);
|
||||
sink2(source2());
|
||||
assert(A::count == 0);
|
||||
sink3(source3());
|
||||
assert(A::count == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// test move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
template <class T>
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(const Deleter&);
|
||||
Deleter& operator=(const Deleter&);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
public:
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
||||
Deleter& operator=(Deleter&& r)
|
||||
{
|
||||
state_ = r.state_;
|
||||
r.state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
|
||||
Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
|
||||
Deleter& operator=(std::__rv<Deleter> r)
|
||||
{
|
||||
state_ = r->state_;
|
||||
r->state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U>&& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
: state_(d.state()) {d.set_state(0);}
|
||||
|
||||
private:
|
||||
template <class U>
|
||||
Deleter(const Deleter<U>& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U> d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
: state_(d.state()) {}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
public:
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
class CDeleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
CDeleter(CDeleter&);
|
||||
CDeleter& operator=(CDeleter&);
|
||||
public:
|
||||
|
||||
CDeleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int s) {state_ = s;}
|
||||
|
||||
void operator()(A* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<A> s(new A);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A> s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
std::unique_ptr<A, Deleter<A> > s(new A);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A, Deleter<A> > s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(s2.get_deleter().state() == 5);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
CDeleter d;
|
||||
std::unique_ptr<A, CDeleter&> s(new A, d);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A, CDeleter&> s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
d.set_state(6);
|
||||
assert(s2.get_deleter().state() == d.state());
|
||||
assert(s.get_deleter().state() == d.state());
|
||||
}
|
||||
assert(A::count == 0);
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// test move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
template <class T>
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(const Deleter&);
|
||||
Deleter& operator=(const Deleter&);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
public:
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
||||
Deleter& operator=(Deleter&& r)
|
||||
{
|
||||
state_ = r.state_;
|
||||
r.state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
|
||||
Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
|
||||
Deleter& operator=(std::__rv<Deleter> r)
|
||||
{
|
||||
state_ = r->state_;
|
||||
r->state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U>&& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
: state_(d.state()) {d.set_state(0);}
|
||||
|
||||
private:
|
||||
template <class U>
|
||||
Deleter(const Deleter<U>& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U> d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
: state_(d.state()) {}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
public:
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
class CDeleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
CDeleter(CDeleter&);
|
||||
CDeleter& operator=(CDeleter&);
|
||||
public:
|
||||
|
||||
CDeleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int s) {state_ = s;}
|
||||
|
||||
void operator()(A* p) {delete p;}
|
||||
};
|
||||
|
||||
std::unique_ptr<A>
|
||||
source1()
|
||||
{
|
||||
return std::unique_ptr<A>(new A);
|
||||
}
|
||||
|
||||
void sink1(std::unique_ptr<A> p)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<A, Deleter<A> >
|
||||
source2()
|
||||
{
|
||||
return std::unique_ptr<A, Deleter<A> >(new A);
|
||||
}
|
||||
|
||||
void sink2(std::unique_ptr<A, Deleter<A> > p)
|
||||
{
|
||||
}
|
||||
|
||||
std::unique_ptr<A, CDeleter&>
|
||||
source3()
|
||||
{
|
||||
static CDeleter d;
|
||||
return std::unique_ptr<A, CDeleter&>(new A, d);
|
||||
}
|
||||
|
||||
void sink3(std::unique_ptr<A, CDeleter&> p)
|
||||
{
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
sink1(source1());
|
||||
sink2(source2());
|
||||
sink3(source3());
|
||||
assert(A::count == 0);
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
// NOTE: unique_ptr does not provide converting constructors in c++03
|
||||
// XFAIL: c++98, c++03
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../deleter.h"
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// Explicit version
|
||||
|
||||
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;
|
||||
|
||||
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 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);
|
||||
}
|
||||
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>();
|
||||
}
|
||||
{
|
||||
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));
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// Explicit version
|
||||
|
||||
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;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<B> s(new B);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A> 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);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../deleter.h"
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// Explicit version
|
||||
|
||||
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;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<B, Deleter<B> > s(new B, Deleter<B>(5));
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A, Deleter<A> > s2(std::move(s));
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
assert(s2.get_deleter().state() == 5);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// Explicit version
|
||||
|
||||
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;
|
||||
|
||||
template <class T>
|
||||
class CDeleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
CDeleter(CDeleter&);
|
||||
CDeleter& operator=(CDeleter&);
|
||||
public:
|
||||
|
||||
CDeleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int s) {state_ = s;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
CDeleter<A> d;
|
||||
std::unique_ptr<B, CDeleter<A>&> s(new B, d);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A, CDeleter<A>&> s2(std::move(s));
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
d.set_state(6);
|
||||
assert(s2.get_deleter().state() == d.state());
|
||||
assert(s.get_deleter().state() == d.state());
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// implicit version
|
||||
|
||||
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;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<B> s(new B);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A> 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);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../deleter.h"
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// Implicit version
|
||||
|
||||
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;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
std::unique_ptr<B, Deleter<B> > s(new B, Deleter<B>(5));
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A, Deleter<A> > s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
assert(s2.get_deleter().state() == 5);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// Explicit version
|
||||
|
||||
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;
|
||||
|
||||
template <class T>
|
||||
class CDeleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
CDeleter(CDeleter&);
|
||||
CDeleter& operator=(CDeleter&);
|
||||
public:
|
||||
|
||||
CDeleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int s) {state_ = s;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
CDeleter<A> d;
|
||||
std::unique_ptr<B, CDeleter<A>&> s(new B, d);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A, CDeleter<A>&> s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
d.set_state(6);
|
||||
assert(s2.get_deleter().state() == d.state());
|
||||
assert(s.get_deleter().state() == d.state());
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr converting move ctor
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../deleter.h"
|
||||
|
||||
// test converting move ctor. Should only require a MoveConstructible deleter, or if
|
||||
// deleter is a reference, not even that.
|
||||
// Implicit version
|
||||
|
||||
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;
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
CDeleter<B> b(5);
|
||||
std::unique_ptr<B, CDeleter<B>&> s(new B, b);
|
||||
A* p = s.get();
|
||||
std::unique_ptr<A, CDeleter<A> > s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
assert(s2.get_deleter().state() == 5);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 std::unique_ptr::unique_ptr()
|
||||
//
|
||||
// Concerns:
|
||||
// 1 The pointer constructor works for any default constructible deleter types.
|
||||
// 2 The pointer constructor accepts pointers to derived types.
|
||||
// 2 The stored type 'T' is allowed to be incomplete.
|
||||
//
|
||||
// Plan
|
||||
// 1 Construct unique_ptr<T, D>'s with a pointer to 'T' and various deleter
|
||||
// types (C-1)
|
||||
// 2 Construct unique_ptr<T, D>'s with a pointer to 'D' and various deleter
|
||||
// types where 'D' is derived from 'T'. (C-1,2)
|
||||
// 3 Construct a unique_ptr<T, D> with a pointer to 'T' and various deleter
|
||||
// types where 'T' is an incomplete type (C-1,3)
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
#include "../../deleter.h"
|
||||
|
||||
// unique_ptr(pointer) ctor should only require default Deleter ctor
|
||||
|
||||
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;
|
||||
|
||||
|
||||
struct IncompleteT;
|
||||
|
||||
IncompleteT* getIncomplete();
|
||||
void checkNumIncompleteTypeAlive(int i);
|
||||
|
||||
template <class Del = std::default_delete<IncompleteT> >
|
||||
struct StoresIncomplete {
|
||||
std::unique_ptr<IncompleteT, Del> m_ptr;
|
||||
StoresIncomplete() {}
|
||||
explicit StoresIncomplete(IncompleteT* ptr) : m_ptr(ptr) {}
|
||||
~StoresIncomplete();
|
||||
|
||||
IncompleteT* get() const { return m_ptr.get(); }
|
||||
Del& get_deleter() { return m_ptr.get_deleter(); }
|
||||
};
|
||||
|
||||
void test_pointer()
|
||||
{
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
std::unique_ptr<A> s(p);
|
||||
assert(s.get() == p);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
std::unique_ptr<A, NCDeleter<A> > s(p);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
}
|
||||
|
||||
void test_derived()
|
||||
{
|
||||
{
|
||||
B* p = new B;
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
std::unique_ptr<A> s(p);
|
||||
assert(s.get() == p);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
{
|
||||
B* p = new B;
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
std::unique_ptr<A, NCDeleter<A> > s(p);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
||||
|
||||
void test_incomplete()
|
||||
{
|
||||
{
|
||||
IncompleteT* p = getIncomplete();
|
||||
checkNumIncompleteTypeAlive(1);
|
||||
StoresIncomplete<> s(p);
|
||||
assert(s.get() == p);
|
||||
}
|
||||
checkNumIncompleteTypeAlive(0);
|
||||
{
|
||||
IncompleteT* p = getIncomplete();
|
||||
checkNumIncompleteTypeAlive(1);
|
||||
StoresIncomplete< NCDeleter<IncompleteT> > s(p);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 0);
|
||||
}
|
||||
checkNumIncompleteTypeAlive(0);
|
||||
}
|
||||
|
||||
struct IncompleteT {
|
||||
static int count;
|
||||
IncompleteT() { ++count; }
|
||||
~IncompleteT() {--count; }
|
||||
};
|
||||
|
||||
int IncompleteT::count = 0;
|
||||
|
||||
IncompleteT* getIncomplete() {
|
||||
return new IncompleteT;
|
||||
}
|
||||
|
||||
void checkNumIncompleteTypeAlive(int i) {
|
||||
assert(IncompleteT::count == i);
|
||||
}
|
||||
|
||||
template <class Del>
|
||||
StoresIncomplete<Del>::~StoresIncomplete() { }
|
||||
|
||||
int main()
|
||||
{
|
||||
test_pointer();
|
||||
test_derived();
|
||||
test_incomplete();
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr(pointer) ctor should only require default Deleter ctor
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
|
||||
public:
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
|
||||
void operator()(A* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
std::unique_ptr<A> s(p);
|
||||
assert(s.get() == p);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
std::unique_ptr<A, Deleter> s(p);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr(pointer) ctor shouldn't require complete type
|
||||
|
||||
struct A;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
|
||||
public:
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
|
||||
void operator()(A* p);
|
||||
};
|
||||
|
||||
void check(int i);
|
||||
|
||||
template <class D = std::default_delete<A> >
|
||||
struct B
|
||||
{
|
||||
std::unique_ptr<A, D> a_;
|
||||
explicit B(A*);
|
||||
~B();
|
||||
|
||||
A* get() const {return a_.get();}
|
||||
D& get_deleter() {return a_.get_deleter();}
|
||||
};
|
||||
|
||||
A* get();
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
A* p = get();
|
||||
check(1);
|
||||
B<> s(p);
|
||||
assert(s.get() == p);
|
||||
}
|
||||
check(0);
|
||||
{
|
||||
A* p = get();
|
||||
check(1);
|
||||
B<Deleter> s(p);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
check(0);
|
||||
}
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
A* get() {return new A;}
|
||||
|
||||
void Deleter::operator()(A* p) {delete p;}
|
||||
|
||||
void check(int i)
|
||||
{
|
||||
assert(A::count == i);
|
||||
}
|
||||
|
||||
template <class D>
|
||||
B<D>::B(A* a) : a_(a) {}
|
||||
|
||||
template <class D>
|
||||
B<D>::~B() {}
|
@ -1,78 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr(pointer) ctor should work with derived pointers
|
||||
|
||||
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;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
|
||||
public:
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
|
||||
void operator()(A* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
B* p = new B;
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
std::unique_ptr<A> s(p);
|
||||
assert(s.get() == p);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
{
|
||||
B* p = new B;
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
std::unique_ptr<A, Deleter> s(p);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
@ -0,0 +1,123 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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);
|
||||
}
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr(pointer, deleter()) only requires MoveConstructible deleter
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
template <class T>
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(const Deleter&);
|
||||
Deleter& operator=(const Deleter&);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&);
|
||||
Deleter& operator=(Deleter&);
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
public:
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
||||
Deleter& operator=(Deleter&& r)
|
||||
{
|
||||
state_ = r.state_;
|
||||
r.state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
operator std::__rv<Deleter>() {return std::__rv<Deleter>(*this);}
|
||||
Deleter(std::__rv<Deleter> r) : state_(r->state_) {r->state_ = 0;}
|
||||
Deleter& operator=(std::__rv<Deleter> r)
|
||||
{
|
||||
state_ = r->state_;
|
||||
r->state_ = 0;
|
||||
return *this;
|
||||
}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U>&& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
: state_(d.state()) {d.set_state(0);}
|
||||
|
||||
private:
|
||||
template <class U>
|
||||
Deleter(const Deleter<U>& d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0);
|
||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
Deleter(Deleter<U> d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
: state_(d.state()) {}
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
public:
|
||||
int state() const {return state_;}
|
||||
void set_state(int i) {state_ = i;}
|
||||
|
||||
void operator()(T* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
std::unique_ptr<A, Deleter<A> > s(p, Deleter<A>());
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr(pointer, d) requires CopyConstructible deleter
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
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) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
Deleter d;
|
||||
std::unique_ptr<A, Deleter> 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);
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr<T, D&>(pointer, d) does not requires CopyConstructible deleter
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
Deleter(const Deleter&);
|
||||
Deleter& operator=(const Deleter&);
|
||||
public:
|
||||
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int s) {state_ = s;}
|
||||
|
||||
void operator()(A* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
Deleter d;
|
||||
std::unique_ptr<A, Deleter&> s(p, d);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
d.set_state(6);
|
||||
assert(s.get_deleter().state() == 6);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr<T, const D&>(pointer, d) does not requires CopyConstructible deleter
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
Deleter(const Deleter&);
|
||||
Deleter& operator=(const Deleter&);
|
||||
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()
|
||||
{
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
Deleter d;
|
||||
std::unique_ptr<A, const Deleter&> s(p, d);
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer, deleter) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr(pointer, deleter) should work with derived pointers
|
||||
|
||||
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;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
public:
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
|
||||
void operator()(A* p) {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
B* p = new B;
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
std::unique_ptr<A, Deleter> s(p, Deleter());
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
|
||||
// Test unique_ptr(pointer, deleter) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr(pointer, deleter) should work with function pointers
|
||||
// unique_ptr<void> should work
|
||||
|
||||
bool my_free_called = false;
|
||||
|
||||
void my_free(void*)
|
||||
{
|
||||
my_free_called = true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user