Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / move / example / doc_clone_ptr.cpp
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:
20    Base(){}
21
22    Base(const Base &/*x*/) {/**/}            // Copy ctor
23
24    Base(BOOST_RV_REF(Base) /*x*/) {/**/}     // Move ctor
25
26    Base& operator=(BOOST_RV_REF(Base) /*x*/)
27    {/**/ return *this;}                      // Move assign
28
29    Base& operator=(BOOST_COPY_ASSIGN_REF(Base) /*x*/)
30    {/**/ return *this;}                      // Copy assign
31    
32    virtual Base *clone() const
33    {  return new Base(*this);  }
34
35    virtual ~Base(){}
36 };
37
38 class Member
39 {
40    BOOST_COPYABLE_AND_MOVABLE(Member)
41
42    public:
43    Member(){}
44
45    // Compiler-generated copy constructor...
46
47    Member(BOOST_RV_REF(Member))  {/**/}      // Move ctor
48
49    Member &operator=(BOOST_RV_REF(Member))   // Move assign
50    {/**/ return *this;  }
51
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:
62    Derived(){}
63
64    // Compiler-generated copy constructor...
65
66    Derived(BOOST_RV_REF(Derived) x)             // Move ctor
67       : Base(boost::move(static_cast<Base&>(x))), 
68         mem_(boost::move(x.mem_)) { }
69
70    Derived& operator=(BOOST_RV_REF(Derived) x)  // Move assign
71    {
72       Base::operator=(boost::move(static_cast<Base&>(x)));
73       mem_  = boost::move(x.mem_);
74       return *this;
75    }
76
77    Derived& operator=(BOOST_COPY_ASSIGN_REF(Derived) x)  // Copy assign
78    {
79       Base::operator=(static_cast<const Base&>(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
98    explicit clone_ptr(T* p = 0) : ptr(p) {}
99
100    // Destruction
101    ~clone_ptr() { delete ptr; }
102    
103    clone_ptr(const clone_ptr& p) // Copy constructor (as usual)
104       : ptr(p.ptr ? p.ptr->clone() : 0) {}
105
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...
117    clone_ptr(BOOST_RV_REF(clone_ptr) p)            //Move constructor
118       : ptr(p.ptr) { p.ptr = 0; }
119
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
132 int 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>