mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-07 18:10:24 +00:00
More unique_ptr test cleanup. Fixes in <memory> to come later.
llvm-svn: 245512
This commit is contained in:
parent
1b7bf7a2a7
commit
2228a8a3f2
@ -112,7 +112,6 @@ public:
|
||||
|
||||
~Deleter() {assert(state_ >= 0); state_ = -1;}
|
||||
|
||||
private:
|
||||
template <class U>
|
||||
Deleter(Deleter<U> d,
|
||||
typename std::enable_if<!std::is_same<U, T>::value>::type* = 0)
|
||||
|
@ -32,5 +32,5 @@ int main()
|
||||
{
|
||||
std::unique_ptr<A[], Deleter> s;
|
||||
std::unique_ptr<A, Deleter> s2;
|
||||
s2 = std::move(s);
|
||||
s2 = std::move(s); // expected-error {{no viable overloaded '='}}
|
||||
}
|
||||
|
@ -7,17 +7,21 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// libc++ cannot safely provide the auto_ptr constructor without rvalue
|
||||
// references.
|
||||
// XFAIL: c++98, c++03
|
||||
|
||||
// <memory>
|
||||
|
||||
// unique_ptr
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
// template <class U> unique_ptr(auto_ptr<U>&&) noexcept
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
// template <class U> explicit unique_ptr(auto_ptr<U>&);
|
||||
#include "test_macros.h"
|
||||
|
||||
struct A
|
||||
{
|
||||
@ -65,4 +69,12 @@ int main()
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
#if TEST_STD_VER >= 11
|
||||
{
|
||||
static_assert(std::is_nothrow_constructible<
|
||||
std::unique_ptr<A>,
|
||||
std::auto_ptr<B>&&
|
||||
>::value, "");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
// XFAIL: c++98, c++03
|
||||
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@ -50,126 +51,121 @@ struct B
|
||||
|
||||
int B::count = 0;
|
||||
|
||||
template <class OrigPtr, class NewPtr>
|
||||
void checkDeleter(OrigPtr& O, NewPtr& N, int OrigState, int NewState) {
|
||||
typedef typename NewPtr::deleter_type NewDel;
|
||||
if (std::is_reference<NewDel>::value) {
|
||||
O.get_deleter().set_state(42);
|
||||
assert(O.get_deleter().state() == 42);
|
||||
assert(N.get_deleter().state() == 42);
|
||||
O.get_deleter().set_state(99);
|
||||
assert(O.get_deleter().state() == 99);
|
||||
assert(N.get_deleter().state() == 99);
|
||||
} else {
|
||||
// TODO(EricWF) Enable this?
|
||||
// assert(OrigState != NewState);
|
||||
assert(O.get_deleter().state() == OrigState);
|
||||
assert(N.get_deleter().state() == NewState);
|
||||
}
|
||||
|
||||
template <class LHS, class RHS>
|
||||
void checkReferenceDeleter(LHS& lhs, RHS& rhs) {
|
||||
typedef typename LHS::deleter_type NewDel;
|
||||
static_assert(std::is_reference<NewDel>::value, "");
|
||||
rhs.get_deleter().set_state(42);
|
||||
assert(rhs.get_deleter().state() == 42);
|
||||
assert(lhs.get_deleter().state() == 42);
|
||||
lhs.get_deleter().set_state(99);
|
||||
assert(lhs.get_deleter().state() == 99);
|
||||
assert(rhs.get_deleter().state() == 99);
|
||||
}
|
||||
|
||||
template <class APtr, class BPtr>
|
||||
void testMoveConvertExplicit()
|
||||
{
|
||||
{ // Test explicit constructor
|
||||
BPtr s(new B);
|
||||
A* p = s.get();
|
||||
APtr s2(std::move(s));
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
}
|
||||
template <class LHS, class RHS>
|
||||
void checkDeleter(LHS& lhs, RHS& rhs, int LHSVal, int RHSVal) {
|
||||
assert(lhs.get_deleter().state() == LHSVal);
|
||||
assert(rhs.get_deleter().state() == RHSVal);
|
||||
}
|
||||
|
||||
template <class LHS, class RHS>
|
||||
void checkCtor(LHS& lhs, RHS& rhs, A* RHSVal) {
|
||||
assert(lhs.get() == RHSVal);
|
||||
assert(rhs.get() == nullptr);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
}
|
||||
|
||||
void checkNoneAlive() {
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
||||
|
||||
template <class APtr, class BPtr>
|
||||
void testMoveConvertImplicit() {
|
||||
|
||||
{ // Test implicit constructor
|
||||
BPtr s(new B);
|
||||
A* p = s.get();
|
||||
APtr s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
||||
|
||||
template <class APtr, class BPtr, class Deleter>
|
||||
#if TEST_STD_VER >= 11
|
||||
void testMoveConvertExplicit(Deleter&& del) {
|
||||
#else
|
||||
void testMoveConvert(Deleter& del) {
|
||||
#endif
|
||||
int old_val = del.state();
|
||||
{ // Test Explicit constructor
|
||||
BPtr s(new B, std::forward<Deleter>(del));
|
||||
A* p = s.get();
|
||||
APtr s2(std::move(s));
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
checkDeleter(s, s2, del.state(), old_val);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
||||
|
||||
|
||||
template <class APtr, class BPtr, class Deleter>
|
||||
#if TEST_STD_VER >= 11
|
||||
void testMoveConvertImplicit(Deleter&& del) {
|
||||
#else
|
||||
void testMoveConvertImplicit(Deleter& del) {
|
||||
#endif
|
||||
int old_val = del.state();
|
||||
{ // Test Implicit constructor
|
||||
BPtr s(new B, std::forward<Deleter>(del));
|
||||
A* p = s.get();
|
||||
APtr s2 = std::move(s);
|
||||
assert(s2.get() == p);
|
||||
assert(s.get() == 0);
|
||||
checkDeleter(s, s2, del.state(), old_val);
|
||||
assert(A::count == 1);
|
||||
assert(B::count == 1);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
assert(B::count == 0);
|
||||
}
|
||||
int main()
|
||||
{
|
||||
{
|
||||
typedef std::unique_ptr<A> APtr;
|
||||
typedef std::unique_ptr<B> BPtr;
|
||||
testMoveConvertExplicit<APtr, BPtr>();
|
||||
testMoveConvertImplicit<APtr, BPtr>();
|
||||
{ // explicit
|
||||
BPtr b(new B);
|
||||
A* p = b.get();
|
||||
APtr a(std::move(b));
|
||||
checkCtor(a, b, p);
|
||||
}
|
||||
checkNoneAlive();
|
||||
{ // implicit
|
||||
BPtr b(new B);
|
||||
A* p = b.get();
|
||||
APtr a = std::move(b);
|
||||
checkCtor(a, b, p);
|
||||
}
|
||||
checkNoneAlive();
|
||||
}
|
||||
{
|
||||
{ // test with moveable deleters
|
||||
typedef std::unique_ptr<A, Deleter<A> > APtr;
|
||||
typedef std::unique_ptr<B, Deleter<B> > BPtr;
|
||||
Deleter<B> del(5);
|
||||
testMoveConvertExplicit<APtr, BPtr>(std::move(del));
|
||||
del.set_state(5);
|
||||
testMoveConvertImplicit<APtr, BPtr>(std::move(del));
|
||||
{
|
||||
Deleter<B> del(5);
|
||||
BPtr b(new B, std::move(del));
|
||||
A* p = b.get();
|
||||
APtr a(std::move(b));
|
||||
checkCtor(a, b, p);
|
||||
checkDeleter(a, b, 5, 0);
|
||||
}
|
||||
checkNoneAlive();
|
||||
{
|
||||
Deleter<B> del(5);
|
||||
BPtr b(new B, std::move(del));
|
||||
A* p = b.get();
|
||||
APtr a = std::move(b);
|
||||
checkCtor(a, b, p);
|
||||
checkDeleter(a, b, 5, 0);
|
||||
}
|
||||
checkNoneAlive();
|
||||
|
||||
}
|
||||
{
|
||||
{ // test with reference deleters
|
||||
typedef std::unique_ptr<A, NCDeleter<A>& > APtr;
|
||||
typedef std::unique_ptr<B, NCDeleter<A>& > BPtr;
|
||||
NCDeleter<A> del(5);
|
||||
testMoveConvertExplicit<APtr, BPtr>(del);
|
||||
testMoveConvertImplicit<APtr, BPtr>(del);
|
||||
{
|
||||
BPtr b(new B, del);
|
||||
A* p = b.get();
|
||||
APtr a(std::move(b));
|
||||
checkCtor(a, b, p);
|
||||
checkReferenceDeleter(a, b);
|
||||
}
|
||||
checkNoneAlive();
|
||||
{
|
||||
BPtr b(new B, del);
|
||||
A* p = b.get();
|
||||
APtr a = std::move(b);
|
||||
checkCtor(a, b, p);
|
||||
checkReferenceDeleter(a, b);
|
||||
}
|
||||
checkNoneAlive();
|
||||
}
|
||||
{
|
||||
typedef std::unique_ptr<A, CDeleter<A> > APtr;
|
||||
typedef std::unique_ptr<B, CDeleter<B>& > BPtr;
|
||||
CDeleter<B> del(5);
|
||||
testMoveConvertImplicit<APtr, BPtr>(del);
|
||||
testMoveConvertExplicit<APtr, BPtr>(del);
|
||||
{
|
||||
BPtr b(new B, del);
|
||||
A* p = b.get();
|
||||
APtr a(std::move(b));
|
||||
checkCtor(a, b, p);
|
||||
checkDeleter(a, b, 5, 5);
|
||||
}
|
||||
checkNoneAlive();
|
||||
{
|
||||
BPtr b(new B, del);
|
||||
A* p = b.get();
|
||||
APtr a = std::move(b);
|
||||
checkCtor(a, b, p);
|
||||
checkDeleter(a, b, 5, 5);
|
||||
}
|
||||
checkNoneAlive();
|
||||
}
|
||||
}
|
||||
|
@ -7,49 +7,24 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Without rvalue references it is impossible to detect when a rvalue deleter
|
||||
// is given.
|
||||
// XFAIL: c++98, c++03
|
||||
|
||||
// <memory>
|
||||
|
||||
// unique_ptr
|
||||
|
||||
// Test unique_ptr(pointer) ctor
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
// unique_ptr<T, const D&>(pointer, D()) should not compile
|
||||
|
||||
struct A
|
||||
{
|
||||
static int count;
|
||||
A() {++count;}
|
||||
A(const A&) {++count;}
|
||||
~A() {--count;}
|
||||
};
|
||||
#include <memory>
|
||||
|
||||
int A::count = 0;
|
||||
|
||||
class Deleter
|
||||
{
|
||||
int state_;
|
||||
|
||||
public:
|
||||
|
||||
Deleter() : state_(5) {}
|
||||
|
||||
int state() const {return state_;}
|
||||
void set_state(int s) {state_ = s;}
|
||||
|
||||
void operator()(A* p) const {delete p;}
|
||||
struct Deleter {
|
||||
void operator()(int* p) const {delete p;}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
A* p = new A;
|
||||
assert(A::count == 1);
|
||||
std::unique_ptr<A, const Deleter&> s(p, Deleter());
|
||||
assert(s.get() == p);
|
||||
assert(s.get_deleter().state() == 5);
|
||||
}
|
||||
assert(A::count == 0);
|
||||
// expected-error@memory:* {{static_assert failed "rvalue deleter bound to reference"}}
|
||||
std::unique_ptr<int, const Deleter&> s((int*)nullptr, Deleter()); // expected-note {{requested here}}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user