1//===----------------------------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// UNSUPPORTED: c++98, c++03 11 12// <memory> 13 14// unique_ptr 15 16// Test unique_ptr converting move ctor 17 18#include <memory> 19#include <utility> 20#include <cassert> 21 22// test converting move ctor. Should only require a MoveConstructible deleter, or if 23// deleter is a reference, not even that. 24// Explicit version 25 26struct A 27{ 28 static int count; 29 A() {++count;} 30 A(const A&) {++count;} 31 virtual ~A() {--count;} 32}; 33 34int A::count = 0; 35 36struct B 37 : public A 38{ 39 static int count; 40 B() {++count;} 41 B(const B&) {++count;} 42 virtual ~B() {--count;} 43}; 44 45int B::count = 0; 46 47template <class T> 48class Deleter 49{ 50 int state_; 51 Deleter(const Deleter&); 52 Deleter& operator=(const Deleter&); 53 54public: 55 Deleter(Deleter&& r) : state_(r.state_) {r.state_ = 0;} 56 Deleter& operator=(Deleter&& r) 57 { 58 state_ = r.state_; 59 r.state_ = 0; 60 return *this; 61 } 62 63 Deleter() : state_(5) {} 64 65 template <class U> 66 Deleter(Deleter<U>&& d, 67 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0) 68 : state_(d.state()) {d.set_state(0);} 69 70private: 71 template <class U> 72 Deleter(const Deleter<U>& d, 73 typename std::enable_if<!std::is_same<U, T>::value>::type* = 0); 74 75public: 76 int state() const {return state_;} 77 void set_state(int i) {state_ = i;} 78 79 void operator()(T* p) {delete p;} 80}; 81 82int main() 83{ 84 const std::unique_ptr<B, Deleter<B> > s; 85 std::unique_ptr<A, Deleter<A> > s2(s); // expected-error {{no matching constructor}} 86} 87