//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. 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.
structA{staticintcount;A(){++count;}A(constA&){++count;}~A(){--count;}};intA::count=0;template<classT>classDeleter{intstate_;#ifdef _LIBCPP_MOVEDeleter(constDeleter&);Deleter&operator=(constDeleter&);#elseDeleter(Deleter&);Deleter&operator=(Deleter&);#endifpublic:#ifdef _LIBCPP_MOVEDeleter(Deleter&&r):state_(r.state_){r.state_=0;}Deleter&operator=(Deleter&&r){state_=r.state_;r.state_=0;return*this;}#elseoperatorstd::__rv<Deleter>(){returnstd::__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;}#endifDeleter():state_(5){}#ifdef _LIBCPP_MOVEtemplate<classU>Deleter(Deleter<U>&&d,typenamestd::enable_if<!std::is_same<U,T>::value>::type*=0):state_(d.state()){d.set_state(0);}private:template<classU>Deleter(constDeleter<U>&d,typenamestd::enable_if<!std::is_same<U,T>::value>::type*=0);#elsetemplate<classU>Deleter(Deleter<U>d,typenamestd::enable_if<!std::is_same<U,T>::value>::type*=0):state_(d.state()){}#endifpublic:intstate()const{returnstate_;}voidset_state(inti){state_=i;}voidoperator()(T*p){deletep;}};classCDeleter{intstate_;CDeleter(CDeleter&);CDeleter&operator=(CDeleter&);public:CDeleter():state_(5){}intstate()const{returnstate_;}voidset_state(ints){state_=s;}voidoperator()(A*p){deletep;}};intmain(){{std::unique_ptr<A>s(newA);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(newA);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);{CDeleterd;std::unique_ptr<A,CDeleter&>s(newA,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);}