blob: e0fa73c76906b671e4d29247d6e53c9ba6ea7a7e [file] [log] [blame]
Brian Silverman1f5d3982018-08-04 23:37:52 -07001//////////////////////////////////////////////////////////////////////////////
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
15class 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
38class 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
56class 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_BASE(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_BASE(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=(x);
80 mem_ = x.mem_;
81 return *this;
82 }
83 // ...
84};
85//]
86
87//[clone_ptr_def
88template <class T>
89class 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
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>