File: doc_clone_ptr.cpp

package info (click to toggle)
boost1.83 1.83.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 545,632 kB
  • sloc: cpp: 3,857,086; xml: 125,552; ansic: 34,414; python: 25,887; asm: 5,276; sh: 4,799; ada: 1,681; makefile: 1,629; perl: 1,212; pascal: 1,139; sql: 810; yacc: 478; ruby: 102; lisp: 24; csh: 6
file content (154 lines) | stat: -rw-r--r-- 3,492 bytes parent folder | download | duplicates (7)
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;
}