1044 |
06 Feb 08 |
peter |
1 |
#ifndef _theplu_yat_utility_smart_ptr_ |
1044 |
06 Feb 08 |
peter |
2 |
#define _theplu_yat_utility_smart_ptr_ |
1044 |
06 Feb 08 |
peter |
3 |
|
1044 |
06 Feb 08 |
peter |
// $Id$ |
1044 |
06 Feb 08 |
peter |
5 |
|
1044 |
06 Feb 08 |
peter |
6 |
/* |
2119 |
12 Dec 09 |
peter |
Copyright (C) 2008 Jari Häkkinen, Peter Johansson |
3992 |
17 Sep 20 |
peter |
Copyright (C) 2012, 2014, 2020 Peter Johansson |
1044 |
06 Feb 08 |
peter |
9 |
|
1437 |
25 Aug 08 |
peter |
This file is part of the yat library, http://dev.thep.lu.se/yat |
1044 |
06 Feb 08 |
peter |
11 |
|
1044 |
06 Feb 08 |
peter |
The yat library is free software; you can redistribute it and/or |
1044 |
06 Feb 08 |
peter |
modify it under the terms of the GNU General Public License as |
1486 |
09 Sep 08 |
jari |
published by the Free Software Foundation; either version 3 of the |
1044 |
06 Feb 08 |
peter |
License, or (at your option) any later version. |
1044 |
06 Feb 08 |
peter |
16 |
|
1044 |
06 Feb 08 |
peter |
The yat library is distributed in the hope that it will be useful, |
1044 |
06 Feb 08 |
peter |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
1044 |
06 Feb 08 |
peter |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1044 |
06 Feb 08 |
peter |
General Public License for more details. |
1044 |
06 Feb 08 |
peter |
21 |
|
1044 |
06 Feb 08 |
peter |
You should have received a copy of the GNU General Public License |
1487 |
10 Sep 08 |
jari |
along with yat. If not, see <http://www.gnu.org/licenses/>. |
1044 |
06 Feb 08 |
peter |
24 |
*/ |
1044 |
06 Feb 08 |
peter |
25 |
|
1044 |
06 Feb 08 |
peter |
26 |
#include "yat_assert.h" |
1044 |
06 Feb 08 |
peter |
27 |
|
1044 |
06 Feb 08 |
peter |
28 |
namespace theplu { |
1044 |
06 Feb 08 |
peter |
29 |
namespace yat { |
1044 |
06 Feb 08 |
peter |
30 |
namespace utility { |
1044 |
06 Feb 08 |
peter |
31 |
|
1044 |
06 Feb 08 |
peter |
32 |
/** |
1125 |
22 Feb 08 |
peter |
SmartPtr is a wrapper around a pointer. Default SmartPtr is set |
1125 |
22 Feb 08 |
peter |
to be owner of pointer, which implies pointer will be deleted in |
1125 |
22 Feb 08 |
peter |
destructor. Pointer can be shared between many SmartPtr, in which |
1125 |
22 Feb 08 |
peter |
case a counter is kept updated in copying and assignment telling |
1125 |
22 Feb 08 |
peter |
how many owners there are. When the counter reaches zero, the |
1125 |
22 Feb 08 |
peter |
pointer is deleted. |
2778 |
19 Jul 12 |
peter |
39 |
|
2778 |
19 Jul 12 |
peter |
\internal This is an internal class kept for backward |
3992 |
17 Sep 20 |
peter |
compabitility. Users are adviced to use <a |
3992 |
17 Sep 20 |
peter |
href="http://www.cplusplus.com/reference/memory/shared_ptr/?kw=shared_ptr"> |
3992 |
17 Sep 20 |
peter |
std::shared_ptr</a>. |
3249 |
04 Jun 14 |
peter |
44 |
|
3249 |
04 Jun 14 |
peter |
\see Deleter |
1044 |
06 Feb 08 |
peter |
46 |
*/ |
1044 |
06 Feb 08 |
peter |
47 |
template<typename T> |
2778 |
19 Jul 12 |
peter |
48 |
class SmartPtr |
1044 |
06 Feb 08 |
peter |
49 |
{ |
1044 |
06 Feb 08 |
peter |
50 |
public: |
1044 |
06 Feb 08 |
peter |
51 |
/** |
1044 |
06 Feb 08 |
peter |
\brief Constructor |
1050 |
07 Feb 08 |
peter |
53 |
|
1050 |
07 Feb 08 |
peter |
\param p underlying pointer |
1050 |
07 Feb 08 |
peter |
\param owner if true SmartPtr will be owner of pointer and if |
1050 |
07 Feb 08 |
peter |
there is no more owner delete it in destructor. |
1050 |
07 Feb 08 |
peter |
57 |
|
1050 |
07 Feb 08 |
peter |
Never use this constructor to create two SmartPtr to the same |
1050 |
07 Feb 08 |
peter |
pointer such as |
1050 |
07 Feb 08 |
peter |
\code |
1050 |
07 Feb 08 |
peter |
MyClass* my_pointer = new MyClass; |
1050 |
07 Feb 08 |
peter |
SmartPtr<MyClass> sp(my_pointer); |
1050 |
07 Feb 08 |
peter |
SmartPtr<MyClass> sp2(my_pointer); // this is evil |
1050 |
07 Feb 08 |
peter |
\endcode |
1050 |
07 Feb 08 |
peter |
since this will cause multiple deletion. Instead use copy constructor |
1050 |
07 Feb 08 |
peter |
\code |
1050 |
07 Feb 08 |
peter |
MyClass* my_pointer = new MyClass; |
1050 |
07 Feb 08 |
peter |
SmartPtr<MyClass> sp(my_pointer); |
1050 |
07 Feb 08 |
peter |
SmartPtr<MyClass> sp2(sp); |
1050 |
07 Feb 08 |
peter |
\endcode |
1050 |
07 Feb 08 |
peter |
so the internal reference counter is updated. |
1044 |
06 Feb 08 |
peter |
72 |
*/ |
1044 |
06 Feb 08 |
peter |
73 |
explicit SmartPtr(T* p=NULL, bool owner=true) |
2778 |
19 Jul 12 |
peter |
74 |
: pointee_(p) |
1044 |
06 Feb 08 |
peter |
75 |
{ |
1044 |
06 Feb 08 |
peter |
76 |
if (owner) |
1271 |
09 Apr 08 |
peter |
77 |
ref_count_ = new unsigned int(1); |
1133 |
23 Feb 08 |
peter |
78 |
else |
1133 |
23 Feb 08 |
peter |
79 |
ref_count_ = NULL; |
1044 |
06 Feb 08 |
peter |
80 |
} |
1044 |
06 Feb 08 |
peter |
81 |
|
1044 |
06 Feb 08 |
peter |
82 |
/** |
1044 |
06 Feb 08 |
peter |
\brief Copy constructor |
1044 |
06 Feb 08 |
peter |
84 |
*/ |
1044 |
06 Feb 08 |
peter |
85 |
SmartPtr(const SmartPtr& other) |
1044 |
06 Feb 08 |
peter |
86 |
: pointee_(other.pointee_), ref_count_(other.ref_count_) |
1044 |
06 Feb 08 |
peter |
87 |
{ |
1044 |
06 Feb 08 |
peter |
88 |
if (ref_count_) |
1044 |
06 Feb 08 |
peter |
89 |
++(*ref_count_); |
1044 |
06 Feb 08 |
peter |
90 |
} |
2778 |
19 Jul 12 |
peter |
91 |
|
1044 |
06 Feb 08 |
peter |
92 |
/** |
1044 |
06 Feb 08 |
peter |
\brief Destructor |
1044 |
06 Feb 08 |
peter |
94 |
|
1044 |
06 Feb 08 |
peter |
If SmartPtr is owner and the only owner, underlying pointer is deleted. |
1044 |
06 Feb 08 |
peter |
96 |
*/ |
1044 |
06 Feb 08 |
peter |
97 |
virtual ~SmartPtr() |
1044 |
06 Feb 08 |
peter |
98 |
{ |
1048 |
07 Feb 08 |
peter |
99 |
detach(); |
1044 |
06 Feb 08 |
peter |
100 |
} |
1044 |
06 Feb 08 |
peter |
101 |
|
1044 |
06 Feb 08 |
peter |
102 |
/** |
1044 |
06 Feb 08 |
peter |
If SmartPtr is owner and the only owner, underlying pointer is deleted. |
1044 |
06 Feb 08 |
peter |
104 |
|
1044 |
06 Feb 08 |
peter |
If rhs is owner, lhs become also owner. |
1044 |
06 Feb 08 |
peter |
106 |
*/ |
1044 |
06 Feb 08 |
peter |
107 |
SmartPtr& operator=(const SmartPtr& rhs) |
1044 |
06 Feb 08 |
peter |
108 |
{ |
1044 |
06 Feb 08 |
peter |
109 |
if (pointee_!=rhs.pointee_){ |
1048 |
07 Feb 08 |
peter |
110 |
detach(); |
1044 |
06 Feb 08 |
peter |
111 |
pointee_ = rhs.pointee_; |
1044 |
06 Feb 08 |
peter |
112 |
ref_count_= rhs.ref_count_; |
1044 |
06 Feb 08 |
peter |
113 |
if (ref_count_) |
1044 |
06 Feb 08 |
peter |
114 |
++(*ref_count_); |
1044 |
06 Feb 08 |
peter |
115 |
} |
1044 |
06 Feb 08 |
peter |
116 |
return *this; |
1044 |
06 Feb 08 |
peter |
117 |
} |
1044 |
06 Feb 08 |
peter |
118 |
|
1044 |
06 Feb 08 |
peter |
119 |
/** |
1044 |
06 Feb 08 |
peter |
\return underlying pointer |
1044 |
06 Feb 08 |
peter |
121 |
*/ |
1044 |
06 Feb 08 |
peter |
122 |
T* operator->(void) const |
1044 |
06 Feb 08 |
peter |
123 |
{ |
1044 |
06 Feb 08 |
peter |
124 |
return pointee_; |
1044 |
06 Feb 08 |
peter |
125 |
} |
1044 |
06 Feb 08 |
peter |
126 |
|
1044 |
06 Feb 08 |
peter |
127 |
/** |
1044 |
06 Feb 08 |
peter |
\return reference to underlying object |
1044 |
06 Feb 08 |
peter |
129 |
*/ |
1044 |
06 Feb 08 |
peter |
130 |
T& operator*(void) const |
1044 |
06 Feb 08 |
peter |
131 |
{ |
1044 |
06 Feb 08 |
peter |
132 |
return *pointee_; |
1044 |
06 Feb 08 |
peter |
133 |
} |
1044 |
06 Feb 08 |
peter |
134 |
|
1044 |
06 Feb 08 |
peter |
135 |
private: |
1044 |
06 Feb 08 |
peter |
136 |
T* pointee_; |
1271 |
09 Apr 08 |
peter |
137 |
unsigned int* ref_count_; |
1044 |
06 Feb 08 |
peter |
138 |
|
1048 |
07 Feb 08 |
peter |
139 |
void detach(void) |
1044 |
06 Feb 08 |
peter |
140 |
{ |
1044 |
06 Feb 08 |
peter |
141 |
if (ref_count_) |
1044 |
06 Feb 08 |
peter |
142 |
if (!--(*ref_count_)) |
1044 |
06 Feb 08 |
peter |
143 |
delete pointee_; |
2778 |
19 Jul 12 |
peter |
144 |
} |
1044 |
06 Feb 08 |
peter |
145 |
}; |
1044 |
06 Feb 08 |
peter |
146 |
|
1044 |
06 Feb 08 |
peter |
147 |
}}} // of namespace utility, yat, and theplu |
1044 |
06 Feb 08 |
peter |
148 |
#endif |