rev |
line source |
nuclear@0
|
1
|
nuclear@0
|
2 #ifndef INCLUDED_AI_BOOST_SHARED_PTR
|
nuclear@0
|
3 #define INCLUDED_AI_BOOST_SHARED_PTR
|
nuclear@0
|
4
|
nuclear@0
|
5 #ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
|
nuclear@0
|
6
|
nuclear@0
|
7 // ------------------------------
|
nuclear@0
|
8 // Internal stub
|
nuclear@0
|
9 namespace boost {
|
nuclear@0
|
10 namespace detail {
|
nuclear@0
|
11 class controller {
|
nuclear@0
|
12 public:
|
nuclear@0
|
13
|
nuclear@0
|
14 controller()
|
nuclear@0
|
15 : cnt(1)
|
nuclear@0
|
16 {}
|
nuclear@0
|
17
|
nuclear@0
|
18 public:
|
nuclear@0
|
19
|
nuclear@0
|
20 template <typename T>
|
nuclear@0
|
21 controller* decref(T* pt) {
|
nuclear@0
|
22 if (--cnt <= 0) {
|
nuclear@0
|
23 delete this;
|
nuclear@0
|
24 delete pt;
|
nuclear@0
|
25 }
|
nuclear@0
|
26 return NULL;
|
nuclear@0
|
27 }
|
nuclear@0
|
28
|
nuclear@0
|
29 controller* incref() {
|
nuclear@0
|
30 ++cnt;
|
nuclear@0
|
31 return this;
|
nuclear@0
|
32 }
|
nuclear@0
|
33
|
nuclear@0
|
34 long get() const {
|
nuclear@0
|
35 return cnt;
|
nuclear@0
|
36 }
|
nuclear@0
|
37
|
nuclear@0
|
38 private:
|
nuclear@0
|
39 long cnt;
|
nuclear@0
|
40 };
|
nuclear@0
|
41
|
nuclear@0
|
42 struct empty {};
|
nuclear@0
|
43
|
nuclear@0
|
44 template <typename DEST, typename SRC>
|
nuclear@0
|
45 struct is_convertible_stub {
|
nuclear@0
|
46
|
nuclear@0
|
47 struct yes {char s[1];};
|
nuclear@0
|
48 struct no {char s[2];};
|
nuclear@0
|
49
|
nuclear@0
|
50 static yes foo(DEST*);
|
nuclear@0
|
51 static no foo(...);
|
nuclear@0
|
52
|
nuclear@0
|
53 enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
|
nuclear@0
|
54 };
|
nuclear@0
|
55
|
nuclear@0
|
56 template <bool> struct enable_if {};
|
nuclear@0
|
57 template <> struct enable_if<true> {
|
nuclear@0
|
58 typedef empty result;
|
nuclear@0
|
59 };
|
nuclear@0
|
60
|
nuclear@0
|
61 template <typename DEST, typename SRC>
|
nuclear@0
|
62 struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
|
nuclear@0
|
63 };
|
nuclear@0
|
64 }
|
nuclear@0
|
65
|
nuclear@0
|
66 // ------------------------------
|
nuclear@0
|
67 // Small replacement for boost::shared_ptr, not threadsafe because no
|
nuclear@0
|
68 // atomic reference counter is in use.
|
nuclear@0
|
69 // ------------------------------
|
nuclear@0
|
70 template <class T>
|
nuclear@0
|
71 class shared_ptr
|
nuclear@0
|
72 {
|
nuclear@0
|
73 template <typename TT> friend class shared_ptr;
|
nuclear@0
|
74
|
nuclear@0
|
75 template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr);
|
nuclear@0
|
76 template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr);
|
nuclear@0
|
77 template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
|
nuclear@0
|
78
|
nuclear@0
|
79 template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
nuclear@0
|
80 template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
nuclear@0
|
81 template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
nuclear@0
|
82
|
nuclear@0
|
83 public:
|
nuclear@0
|
84
|
nuclear@0
|
85 typedef T element_type;
|
nuclear@0
|
86
|
nuclear@0
|
87 public:
|
nuclear@0
|
88
|
nuclear@0
|
89 // provide a default constructor
|
nuclear@0
|
90 shared_ptr()
|
nuclear@0
|
91 : ptr()
|
nuclear@0
|
92 , ctr(NULL)
|
nuclear@0
|
93 {
|
nuclear@0
|
94 }
|
nuclear@0
|
95
|
nuclear@0
|
96 // construction from an existing object of type T
|
nuclear@0
|
97 explicit shared_ptr(T* ptr)
|
nuclear@0
|
98 : ptr(ptr)
|
nuclear@0
|
99 , ctr(ptr ? new detail::controller() : NULL)
|
nuclear@0
|
100 {
|
nuclear@0
|
101 }
|
nuclear@0
|
102
|
nuclear@0
|
103 shared_ptr(const shared_ptr& r)
|
nuclear@0
|
104 : ptr(r.ptr)
|
nuclear@0
|
105 , ctr(r.ctr ? r.ctr->incref() : NULL)
|
nuclear@0
|
106 {
|
nuclear@0
|
107 }
|
nuclear@0
|
108
|
nuclear@0
|
109 template <typename Y>
|
nuclear@0
|
110 shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
|
nuclear@0
|
111 : ptr(r.ptr)
|
nuclear@0
|
112 , ctr(r.ctr ? r.ctr->incref() : NULL)
|
nuclear@0
|
113 {
|
nuclear@0
|
114 }
|
nuclear@0
|
115
|
nuclear@0
|
116 // automatic destruction of the wrapped object when all
|
nuclear@0
|
117 // references are freed.
|
nuclear@0
|
118 ~shared_ptr() {
|
nuclear@0
|
119 if (ctr) {
|
nuclear@0
|
120 ctr = ctr->decref(ptr);
|
nuclear@0
|
121 }
|
nuclear@0
|
122 }
|
nuclear@0
|
123
|
nuclear@0
|
124 shared_ptr& operator=(const shared_ptr& r) {
|
nuclear@0
|
125 if (this == &r) {
|
nuclear@0
|
126 return *this;
|
nuclear@0
|
127 }
|
nuclear@0
|
128 if (ctr) {
|
nuclear@0
|
129 ctr->decref(ptr);
|
nuclear@0
|
130 }
|
nuclear@0
|
131 ptr = r.ptr;
|
nuclear@0
|
132 ctr = ptr?r.ctr->incref():NULL;
|
nuclear@0
|
133 return *this;
|
nuclear@0
|
134 }
|
nuclear@0
|
135
|
nuclear@0
|
136 template <typename Y>
|
nuclear@0
|
137 shared_ptr& operator=(const shared_ptr<Y>& r) {
|
nuclear@0
|
138 if (this == &r) {
|
nuclear@0
|
139 return *this;
|
nuclear@0
|
140 }
|
nuclear@0
|
141 if (ctr) {
|
nuclear@0
|
142 ctr->decref(ptr);
|
nuclear@0
|
143 }
|
nuclear@0
|
144 ptr = r.ptr;
|
nuclear@0
|
145 ctr = ptr?r.ctr->incref():NULL;
|
nuclear@0
|
146 return *this;
|
nuclear@0
|
147 }
|
nuclear@0
|
148
|
nuclear@0
|
149 // pointer access
|
nuclear@0
|
150 inline operator T*() const {
|
nuclear@0
|
151 return ptr;
|
nuclear@0
|
152 }
|
nuclear@0
|
153
|
nuclear@0
|
154 inline T* operator-> () const {
|
nuclear@0
|
155 return ptr;
|
nuclear@0
|
156 }
|
nuclear@0
|
157
|
nuclear@0
|
158 // standard semantics
|
nuclear@0
|
159 inline T* get() {
|
nuclear@0
|
160 return ptr;
|
nuclear@0
|
161 }
|
nuclear@0
|
162
|
nuclear@0
|
163 inline const T* get() const {
|
nuclear@0
|
164 return ptr;
|
nuclear@0
|
165 }
|
nuclear@0
|
166
|
nuclear@0
|
167 inline operator bool () const {
|
nuclear@0
|
168 return ptr != NULL;
|
nuclear@0
|
169 }
|
nuclear@0
|
170
|
nuclear@0
|
171 inline bool unique() const {
|
nuclear@0
|
172 return use_count() == 1;
|
nuclear@0
|
173 }
|
nuclear@0
|
174
|
nuclear@0
|
175 inline long use_count() const {
|
nuclear@0
|
176 return ctr->get();
|
nuclear@0
|
177 }
|
nuclear@0
|
178
|
nuclear@0
|
179 inline void reset (T* t = 0) {
|
nuclear@0
|
180 if (ctr) {
|
nuclear@0
|
181 ctr->decref(ptr);
|
nuclear@0
|
182 }
|
nuclear@0
|
183 ptr = t;
|
nuclear@0
|
184 ctr = ptr?new detail::controller():NULL;
|
nuclear@0
|
185 }
|
nuclear@0
|
186
|
nuclear@0
|
187 void swap(shared_ptr & b) {
|
nuclear@0
|
188 std::swap(ptr, b.ptr);
|
nuclear@0
|
189 std::swap(ctr, b.ctr);
|
nuclear@0
|
190 }
|
nuclear@0
|
191
|
nuclear@0
|
192 private:
|
nuclear@0
|
193
|
nuclear@0
|
194
|
nuclear@0
|
195 // for use by the various xxx_pointer_cast helper templates
|
nuclear@0
|
196 explicit shared_ptr(T* ptr, detail::controller* ctr)
|
nuclear@0
|
197 : ptr(ptr)
|
nuclear@0
|
198 , ctr(ctr->incref())
|
nuclear@0
|
199 {
|
nuclear@0
|
200 }
|
nuclear@0
|
201
|
nuclear@0
|
202 private:
|
nuclear@0
|
203
|
nuclear@0
|
204 // encapsulated object pointer
|
nuclear@0
|
205 T* ptr;
|
nuclear@0
|
206
|
nuclear@0
|
207 // control block
|
nuclear@0
|
208 detail::controller* ctr;
|
nuclear@0
|
209 };
|
nuclear@0
|
210
|
nuclear@0
|
211 template<class T>
|
nuclear@0
|
212 inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
nuclear@0
|
213 {
|
nuclear@0
|
214 a.swap(b);
|
nuclear@0
|
215 }
|
nuclear@0
|
216
|
nuclear@0
|
217 template<class T>
|
nuclear@0
|
218 bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) {
|
nuclear@0
|
219 return a.ptr == b.ptr;
|
nuclear@0
|
220 }
|
nuclear@0
|
221 template<class T>
|
nuclear@0
|
222 bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) {
|
nuclear@0
|
223 return a.ptr != b.ptr;
|
nuclear@0
|
224 }
|
nuclear@0
|
225
|
nuclear@0
|
226 template<class T>
|
nuclear@0
|
227 bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
|
nuclear@0
|
228 return a.ptr < b.ptr;
|
nuclear@0
|
229 }
|
nuclear@0
|
230
|
nuclear@0
|
231
|
nuclear@0
|
232 template<class T, class U>
|
nuclear@0
|
233 inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
|
nuclear@0
|
234 {
|
nuclear@0
|
235 return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
|
nuclear@0
|
236 }
|
nuclear@0
|
237
|
nuclear@0
|
238 template<class T, class U>
|
nuclear@0
|
239 inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
|
nuclear@0
|
240 {
|
nuclear@0
|
241 return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
|
nuclear@0
|
242 }
|
nuclear@0
|
243
|
nuclear@0
|
244 template<class T, class U>
|
nuclear@0
|
245 inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
|
nuclear@0
|
246 {
|
nuclear@0
|
247 return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
|
nuclear@0
|
248 }
|
nuclear@0
|
249
|
nuclear@0
|
250
|
nuclear@0
|
251
|
nuclear@0
|
252 } // end of namespace boost
|
nuclear@0
|
253
|
nuclear@0
|
254 #else
|
nuclear@0
|
255 # error "shared_ptr.h was already included"
|
nuclear@0
|
256 #endif
|
nuclear@0
|
257 #endif // INCLUDED_AI_BOOST_SCOPED_PTR
|