1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2009. 4 // Distributed under the Boost Software License, Version 1.0. 5 // (See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt) 7 // 8 // See http://www.boost.org/libs/move for documentation. 9 // 10 ////////////////////////////////////////////////////////////////////////////// 11 #include <boost/move/detail/config_begin.hpp> 12 #include <boost/move/utility_core.hpp> 13 14 //[clone_ptr_base_derived 15 class Base 16 { 17 BOOST_COPYABLE_AND_MOVABLE(Base) 18 19 public: Base()20 Base(){} 21 Base(const Base &)22 Base(const Base &/*x*/) {/**/} // Copy ctor 23 Base(BOOST_RV_REF (Base))24 Base(BOOST_RV_REF(Base) /*x*/) {/**/} // Move ctor 25 operator =(BOOST_RV_REF (Base))26 Base& operator=(BOOST_RV_REF(Base) /*x*/) 27 {/**/ return *this;} // Move assign 28 operator =(BOOST_COPY_ASSIGN_REF (Base))29 Base& operator=(BOOST_COPY_ASSIGN_REF(Base) /*x*/) 30 {/**/ return *this;} // Copy assign 31 clone() const32 virtual Base *clone() const 33 { return new Base(*this); } 34 ~Base()35 virtual ~Base(){} 36 }; 37 38 class Member 39 { 40 BOOST_COPYABLE_AND_MOVABLE(Member) 41 42 public: Member()43 Member(){} 44 45 // Compiler-generated copy constructor... 46 Member(BOOST_RV_REF (Member))47 Member(BOOST_RV_REF(Member)) {/**/} // Move ctor 48 operator =(BOOST_RV_REF (Member))49 Member &operator=(BOOST_RV_REF(Member)) // Move assign 50 {/**/ return *this; } 51 operator =(BOOST_COPY_ASSIGN_REF (Member))52 Member &operator=(BOOST_COPY_ASSIGN_REF(Member)) // Copy assign 53 {/**/ return *this; } 54 }; 55 56 class Derived : public Base 57 { 58 BOOST_COPYABLE_AND_MOVABLE(Derived) 59 Member mem_; 60 61 public: Derived()62 Derived(){} 63 64 // Compiler-generated copy constructor... 65 Derived(BOOST_RV_REF (Derived)x)66 Derived(BOOST_RV_REF(Derived) x) // Move ctor 67 : Base(BOOST_MOVE_BASE(Base, x)), 68 mem_(boost::move(x.mem_)) { } 69 operator =(BOOST_RV_REF (Derived)x)70 Derived& operator=(BOOST_RV_REF(Derived) x) // Move assign 71 { 72 Base::operator=(BOOST_MOVE_BASE(Base, x)); 73 mem_ = boost::move(x.mem_); 74 return *this; 75 } 76 operator =(BOOST_COPY_ASSIGN_REF (Derived)x)77 Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x) // Copy assign 78 { 79 Base::operator=(x); 80 mem_ = x.mem_; 81 return *this; 82 } 83 // ... 84 }; 85 //] 86 87 //[clone_ptr_def 88 template <class T> 89 class clone_ptr 90 { 91 private: 92 // Mark this class copyable and movable 93 BOOST_COPYABLE_AND_MOVABLE(clone_ptr) 94 T* ptr; 95 96 public: 97 // Construction clone_ptr(T * p=0)98 explicit clone_ptr(T* p = 0) : ptr(p) {} 99 100 // Destruction ~clone_ptr()101 ~clone_ptr() { delete ptr; } 102 clone_ptr(const clone_ptr & p)103 clone_ptr(const clone_ptr& p) // Copy constructor (as usual) 104 : ptr(p.ptr ? p.ptr->clone() : 0) {} 105 operator =(BOOST_COPY_ASSIGN_REF (clone_ptr)p)106 clone_ptr& operator=(BOOST_COPY_ASSIGN_REF(clone_ptr) p) // Copy assignment 107 { 108 if (this != &p){ 109 T *tmp_p = p.ptr ? p.ptr->clone() : 0; 110 delete ptr; 111 ptr = tmp_p; 112 } 113 return *this; 114 } 115 116 //Move semantics... clone_ptr(BOOST_RV_REF (clone_ptr)p)117 clone_ptr(BOOST_RV_REF(clone_ptr) p) //Move constructor 118 : ptr(p.ptr) { p.ptr = 0; } 119 operator =(BOOST_RV_REF (clone_ptr)p)120 clone_ptr& operator=(BOOST_RV_REF(clone_ptr) p) //Move assignment 121 { 122 if (this != &p){ 123 delete ptr; 124 ptr = p.ptr; 125 p.ptr = 0; 126 } 127 return *this; 128 } 129 }; 130 //] 131 main()132int main() 133 { 134 { 135 //[copy_clone_ptr 136 clone_ptr<Base> p1(new Derived()); 137 // ... 138 clone_ptr<Base> p2 = p1; // p2 and p1 each own their own pointer 139 //] 140 } 141 { 142 //[move_clone_ptr 143 clone_ptr<Base> p1(new Derived()); 144 // ... 145 clone_ptr<Base> p2 = boost::move(p1); // p2 now owns the pointer instead of p1 146 p2 = clone_ptr<Base>(new Derived()); // temporary is moved to p2 147 } 148 //] 149 //[clone_ptr_move_derived 150 Derived d; 151 Derived d2(boost::move(d)); 152 d2 = boost::move(d); 153 //] 154 return 0; 155 } 156 157 #include <boost/move/detail/config_end.hpp> 158