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 <utility>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "test_macros.h"
|
||||||
|
|
||||||
|
#if TEST_STD_VER >= 11
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class Deleter
|
class Deleter
|
||||||
{
|
{
|
||||||
int state_;
|
int state_;
|
||||||
|
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
Deleter(const Deleter&);
|
Deleter(const Deleter&);
|
||||||
Deleter& operator=(const Deleter&);
|
Deleter& operator=(const Deleter&);
|
||||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
Deleter(Deleter&);
|
|
||||||
Deleter& operator=(Deleter&);
|
|
||||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
||||||
Deleter& operator=(Deleter&& r)
|
Deleter& operator=(Deleter&& r)
|
||||||
{
|
{
|
||||||
@ -42,22 +40,12 @@ public:
|
|||||||
r.state_ = 0;
|
r.state_ = 0;
|
||||||
return *this;
|
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) {}
|
Deleter() : state_(0) {}
|
||||||
explicit Deleter(int s) : state_(s) {}
|
explicit Deleter(int s) : state_(s) {}
|
||||||
~Deleter() {assert(state_ >= 0); state_ = -1;}
|
~Deleter() {assert(state_ >= 0); state_ = -1;}
|
||||||
|
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
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)
|
||||||
@ -67,12 +55,6 @@ private:
|
|||||||
template <class U>
|
template <class U>
|
||||||
Deleter(const Deleter<U>& d,
|
Deleter(const 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);
|
||||||
#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:
|
public:
|
||||||
int state() const {return state_;}
|
int state() const {return state_;}
|
||||||
void set_state(int i) {state_ = i;}
|
void set_state(int i) {state_ = i;}
|
||||||
@ -85,16 +67,11 @@ class Deleter<T[]>
|
|||||||
{
|
{
|
||||||
int state_;
|
int state_;
|
||||||
|
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
Deleter(const Deleter&);
|
Deleter(const Deleter&);
|
||||||
Deleter& operator=(const Deleter&);
|
Deleter& operator=(const Deleter&);
|
||||||
#else // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
Deleter(Deleter&);
|
|
||||||
Deleter& operator=(Deleter&);
|
|
||||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;}
|
||||||
Deleter& operator=(Deleter&& r)
|
Deleter& operator=(Deleter&& r)
|
||||||
{
|
{
|
||||||
@ -102,16 +79,6 @@ public:
|
|||||||
r.state_ = 0;
|
r.state_ = 0;
|
||||||
return *this;
|
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) {}
|
Deleter() : state_(0) {}
|
||||||
explicit Deleter(int s) : state_(s) {}
|
explicit Deleter(int s) : state_(s) {}
|
||||||
@ -123,6 +90,69 @@ public:
|
|||||||
void operator()(T* p) {delete [] p;}
|
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>
|
template <class T>
|
||||||
void
|
void
|
||||||
swap(Deleter<T>& x, Deleter<T>& y)
|
swap(Deleter<T>& x, Deleter<T>& y)
|
||||||
@ -132,6 +162,7 @@ swap(Deleter<T>& x, Deleter<T>& y)
|
|||||||
y = std::move(t);
|
y = std::move(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class CDeleter
|
class CDeleter
|
||||||
{
|
{
|
||||||
@ -179,4 +210,130 @@ swap(CDeleter<T>& x, CDeleter<T>& y)
|
|||||||
y = std::move(t);
|
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
|
#endif // DELETER_H
|
||||||
|
@ -14,26 +14,15 @@
|
|||||||
// Test unique_ptr move assignment
|
// Test unique_ptr move assignment
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
// Can't copy from lvalue
|
#include "test_macros.h"
|
||||||
|
|
||||||
struct A
|
|
||||||
{
|
|
||||||
static int count;
|
|
||||||
A() {++count;}
|
|
||||||
A(const A&) {++count;}
|
|
||||||
~A() {--count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
int A::count = 0;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
{
|
std::unique_ptr<int> s, s2;
|
||||||
std::unique_ptr<A> s(new A);
|
#if TEST_STD_VER >= 11
|
||||||
std::unique_ptr<A> s2;
|
s2 = s; // expected-error {{cannot be assigned because its copy assignment operator is implicitly deleted}}
|
||||||
s2 = s;
|
#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>
|
// <memory>
|
||||||
|
|
||||||
// unique_ptr
|
// unique_ptr
|
||||||
@ -16,40 +18,16 @@
|
|||||||
// unique_ptr<T, const D&>(pointer, D()) should not compile
|
// unique_ptr<T, const D&>(pointer, D()) should not compile
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
struct A
|
|
||||||
{
|
|
||||||
static int count;
|
|
||||||
A() {++count;}
|
|
||||||
A(const A&) {++count;}
|
|
||||||
~A() {--count;}
|
|
||||||
};
|
|
||||||
|
|
||||||
int A::count = 0;
|
|
||||||
|
|
||||||
class Deleter
|
class Deleter
|
||||||
{
|
{
|
||||||
int state_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Deleter() {}
|
||||||
Deleter() : state_(5) {}
|
void operator()(int* p) const {delete [] p;}
|
||||||
|
|
||||||
int state() const {return state_;}
|
|
||||||
void set_state(int s) {state_ = s;}
|
|
||||||
|
|
||||||
void operator()(A* p) const {delete [] p;}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
{
|
int* p = nullptr;
|
||||||
A* p = new A[3];
|
std::unique_ptr<int[], const Deleter&> s(p, Deleter()); // expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
@ -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