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