Teh first one
[mldemos:kalians-mldemos.git] / _AlgorithmsPlugins / KernelMethods / dlib / smart_pointers / shared_ptr_abstract.h
1 // Copyright (C) 2007  Davis E. King (davis@dlib.net)\r
2 // License: Boost Software License   See LICENSE.txt for the full license.\r
3 #undef DLIB_SHARED_PTr_ABSTRACT_\r
4 #ifdef DLIB_SHARED_PTr_ABSTRACT_ \r
5 \r
6 #include "weak_ptr_abstract.h"\r
7 #include <exception>     \r
8 \r
9 namespace dlib \r
10 {\r
11 \r
12 // ----------------------------------------------------------------------------------------\r
13 \r
14     class bad_weak_ptr: public std::exception {}\r
15 \r
16 // ----------------------------------------------------------------------------------------\r
17 \r
18     template <\r
19         typename T\r
20         > \r
21     class shared_ptr \r
22     {\r
23         /*!\r
24             INITIAL VALUE\r
25                 defined by constructors\r
26 \r
27             WHAT THIS OBJECT REPRESENTS\r
28                 This object represents a reference counted smart pointer.  Each shared_ptr\r
29                 contains a pointer to some object and when the last shared_ptr that points\r
30                 to the object is destructed or reset() then the object is guaranteed to be \r
31                 deleted.\r
32 \r
33                 This is an implementation of the std::tr1::shared_ptr template from the \r
34                 document ISO/IEC PDTR 19768, Proposed Draft Technical Report on C++\r
35                 Library Extensions.  The only deviation from that document is that this \r
36                 shared_ptr is declared inside the dlib namespace rather than std::tr1.\r
37 \r
38             THREAD SAFETY\r
39                 This object is not thread safe.  Especially so since it is\r
40                 reference counted.  So you should take care to not have two shared_ptr\r
41                 objects in different threads that point to the same object.\r
42 \r
43                 If you want a thread safe version of this object you should use the\r
44                 dlib::shared_ptr_thread_safe object instead.\r
45         !*/\r
46 \r
47     public:\r
48 \r
49         typedef T element_type;\r
50 \r
51         shared_ptr(\r
52         );\r
53         /*!\r
54             ensures\r
55                 - #get() == 0\r
56                 - #use_count() == 0\r
57         !*/\r
58 \r
59         template<typename Y> \r
60         explicit shared_ptr(\r
61             Y* p\r
62         );\r
63         /*!\r
64             requires\r
65                 - p is convertible to a T* type pointer\r
66                 - p can be deleted by calling "delete p;" and doing so will not throw exceptions\r
67                 - p != 0\r
68             ensures\r
69                 - #get() == p\r
70                 - #use_count() == 1\r
71                 - #*this object owns the pointer p\r
72             throws\r
73                 - std::bad_alloc\r
74                   if this exception is thrown then "delete p;" is called\r
75         !*/\r
76 \r
77         template<typename Y, typename D> \r
78         shared_ptr(\r
79             Y* p, \r
80             const D& d\r
81         );\r
82         /*!\r
83             requires\r
84                 - p is convertible to a T* type pointer\r
85                 - D is copy constructable (and the copy constructor of D doesn't throw) \r
86                 - p can be deleted by calling "d(p);" and doing so will not throw exceptions\r
87                 - p != 0\r
88             ensures\r
89                 - #get() == p\r
90                 - #use_count() == 1\r
91                 - #*this object owns the pointer p\r
92             throws\r
93                 - std::bad_alloc\r
94                   if this exception is thrown then "d(p);" is called\r
95         !*/\r
96 \r
97         shared_ptr( \r
98             const shared_ptr& r\r
99         );\r
100         /*!\r
101             ensures\r
102                 - #get() == #r.get()\r
103                 - #use_count() == #r.use_count()\r
104                 - If r is empty, constructs an empty shared_ptr object; otherwise, constructs \r
105                   a shared_ptr object that shares ownership with r.\r
106         !*/\r
107 \r
108         template<typename Y> \r
109         shared_ptr(\r
110             const shared_ptr<Y>& r\r
111         );\r
112         /*!\r
113             requires\r
114                 - Y* is convertible to T* \r
115             ensures\r
116                 - #get() == #r.get()\r
117                 - #use_count() == #r.use_count()\r
118                 - If r is empty, constructs an empty shared_ptr object; otherwise, constructs \r
119                   a shared_ptr object that shares ownership with r.\r
120         !*/\r
121 \r
122         template<typename Y> \r
123         explicit shared_ptr(\r
124             const weak_ptr<Y>& r\r
125         );\r
126         /*!\r
127             requires\r
128                 - Y* is convertible to T* \r
129             ensures\r
130                 - #get() == #r.get()\r
131                 - #use_count() == #r.use_count()\r
132                 - If r is empty, constructs an empty shared_ptr object; otherwise, constructs \r
133                   a shared_ptr object that shares ownership with r.\r
134             throws\r
135                 - bad_weak_ptr\r
136                   this exception is thrown if r.expired() == true\r
137         !*/\r
138 \r
139         template<typename Y>\r
140         explicit shared_ptr(\r
141             std::auto_ptr<Y>& r\r
142         );\r
143         /*!\r
144             requires\r
145                 - p.get() != 0\r
146                 - p.release() is convertible to a T* type pointer\r
147                 - p.release() can be deleted by calling "delete p.release();" and doing so will not throw exceptions\r
148             ensures\r
149                 - #get() == p.release()\r
150                 - #use_count() == 1\r
151                 - #r.get() == 0\r
152                 - #*this object owns the pointer p.release()\r
153             throws\r
154                 - std::bad_alloc\r
155         !*/\r
156 \r
157         ~shared_ptr(\r
158         );\r
159         /*!\r
160             ensures\r
161                 - if (use_count() > 1)\r
162                     - this object destroys itself but otherwise has no effect (i.e. \r
163                       the pointer get() is still valid and shared between the remaining\r
164                       shared_ptr objects)\r
165                 - else if (use_count() == 1)\r
166                     - deletes the pointer get() by calling delete (or using the deleter passed\r
167                       to the constructor if one was passed in)\r
168                 - else\r
169                     - in this case get() == 0 so there is nothing to do so nothing occurs\r
170         !*/\r
171 \r
172         shared_ptr& operator= (\r
173             const shared_ptr& r\r
174         );\r
175         /*!\r
176             ensures\r
177                 - equivalent to shared_ptr(r).swap(*this).\r
178                 - returns #*this\r
179         !*/\r
180 \r
181         template<typename Y> \r
182         shared_ptr& operator= (\r
183             const shared_ptr<Y>& r\r
184         );\r
185         /*!\r
186             requires\r
187                 - Y* is convertible to T* \r
188             ensures\r
189                 - equivalent to shared_ptr(r).swap(*this).\r
190                 - returns #*this\r
191         !*/\r
192 \r
193         template<typename Y> \r
194         shared_ptr& operator= (\r
195             std::auto_ptr<Y>& r\r
196         );\r
197         /*!\r
198             requires\r
199                 - p.get() != 0\r
200                 - p.release() is convertible to a T* type pointer\r
201                 - p.release() can be deleted by calling "delete p.release();" and doing so will not throw exceptions\r
202             ensures\r
203                 - equivalent to shared_ptr(r).swap(*this).\r
204                 - returns #*this\r
205         !*/\r
206 \r
207         void reset(\r
208         );\r
209         /*!\r
210             ensures\r
211                 - equivalent to shared_ptr().swap(*this)\r
212         !*/\r
213 \r
214         template<typename Y> \r
215         void reset(\r
216             Y* p\r
217         );\r
218         /*!\r
219             requires\r
220                 - p is convertible to a T* type pointer\r
221                 - p can be deleted by calling "delete p;" and doing so will not throw exceptions\r
222                 - p != 0\r
223             ensures\r
224                 - equivalent to shared_ptr(p).swap(*this)\r
225         !*/\r
226 \r
227         template<typename Y, typename D> \r
228         void reset(\r
229             Y* p, \r
230             const D& d\r
231         );\r
232         /*!\r
233             requires\r
234                 - p is convertible to a T* type pointer\r
235                 - D is copy constructable (and the copy constructor of D doesn't throw) \r
236                 - p can be deleted by calling "d(p);" and doing so will not throw exceptions\r
237                 - p != 0\r
238             ensures\r
239                 - equivalent to shared_ptr(p,d).swap(*this)\r
240         !*/\r
241 \r
242         T* get(\r
243         ) const; \r
244         /*!\r
245             ensures\r
246                 - returns the stored pointer\r
247         !*/\r
248 \r
249         T& operator*(\r
250         ) const; \r
251         /*!\r
252             requires\r
253                 - get() != 0\r
254             ensures\r
255                 - returns a reference to *get()\r
256         !*/\r
257 \r
258         T* operator->(\r
259         ) const; \r
260         /*!\r
261             requires\r
262                 - get() != 0\r
263             ensures\r
264                 - returns get()\r
265         !*/\r
266 \r
267         bool unique(\r
268         ) const;\r
269         /*!\r
270             ensures\r
271                 - returns (use_count() == 1)\r
272         !*/\r
273 \r
274         long use_count(\r
275         ) const;\r
276         /*!\r
277             ensures\r
278                 - The number of shared_ptr objects, *this included, that share ownership with *this, or 0 when *this\r
279                   is empty.\r
280         !*/\r
281 \r
282         operator bool(\r
283         ) const;\r
284         /*!\r
285             ensures\r
286                 - returns (get() != 0)\r
287         !*/\r
288 \r
289         void swap(\r
290             shared_ptr& b\r
291         );\r
292         /*!\r
293             ensures\r
294                 - swaps *this and item\r
295         !*/\r
296 \r
297     };\r
298 \r
299 // ----------------------------------------------------------------------------------------\r
300 \r
301     template<typename T, typename U>\r
302     bool operator== (\r
303         const shared_ptr<T>& a, \r
304         const shared_ptr<U>& b\r
305     );\r
306     /*!\r
307         ensures\r
308             - returns a.get() == b.get()\r
309     !*/\r
310 \r
311     template<typename T, typename U>\r
312     bool operator!= (\r
313         const shared_ptr<T>& a, \r
314         const shared_ptr<U>& b\r
315     ) { return a.get() != b.get(); }\r
316     /*!\r
317         ensures\r
318             - returns a.get() != b.get()\r
319     !*/\r
320 \r
321     template<typename T, typename U>\r
322     bool operator< (\r
323         const shared_ptr<T>& a, \r
324         const shared_ptr<U>& b\r
325     );\r
326     /*!\r
327         ensures\r
328             - Defines an operator< on shared_ptr types appropriate for use in the associative \r
329               containers.  \r
330     !*/\r
331 \r
332     template<typename T> \r
333     void swap(\r
334         shared_ptr<T>& a, \r
335         shared_ptr<T>& b\r
336     ) { a.swap(b); }\r
337     /*!\r
338         provides a global swap function\r
339     !*/\r
340 \r
341     template<typename T, typename U>\r
342     shared_ptr<T> static_pointer_cast(\r
343         const shared_ptr<U>& r\r
344     );\r
345     /*!\r
346         - if (r.get() == 0) then\r
347             - returns shared_ptr<T>()\r
348         - else\r
349             - returns a shared_ptr<T> object that stores static_cast<T*>(r.get()) and shares \r
350               ownership with r.\r
351     !*/\r
352 \r
353     template<typename T, typename U>\r
354     shared_ptr<T> const_pointer_cast(\r
355         const shared_ptr<U>& r\r
356     );\r
357     /*!\r
358         - if (r.get() == 0) then\r
359             - returns shared_ptr<T>()\r
360         - else\r
361             - returns a shared_ptr<T> object that stores const_cast<T*>(r.get()) and shares \r
362               ownership with r.\r
363     !*/\r
364 \r
365     template<typename T, typename U>\r
366     shared_ptr<T> dynamic_pointer_cast(\r
367         const shared_ptr<U>& r\r
368     );\r
369     /*!\r
370         ensures\r
371             - if (dynamic_cast<T*>(r.get()) returns a nonzero value) then\r
372                 - returns a shared_ptr<T> object that stores a copy of \r
373                   dynamic_cast<T*>(r.get()) and shares ownership with r\r
374             - else\r
375                 - returns an empty shared_ptr<T> object.\r
376     !*/\r
377 \r
378     template<typename E, typename T, typename Y>\r
379     std::basic_ostream<E, T> & operator<< (\r
380         std::basic_ostream<E, T> & os, \r
381         const shared_ptr<Y>& p\r
382     );\r
383     /*!\r
384         ensures\r
385             - performs os << p.get()\r
386             - returns os \r
387     !*/\r
388 \r
389     template<typename D, typename T>\r
390     D* get_deleter(\r
391         const shared_ptr<T>& p\r
392     );\r
393     /*!\r
394         ensures\r
395             - if (*this owns a deleter d of type cv-unqualified D) then\r
396                 - returns &d\r
397             - else\r
398                 - returns 0\r
399     !*/\r
400 \r
401 // ----------------------------------------------------------------------------------------\r
402 \r
403 }\r
404 \r
405 #endif // DLIB_SHARED_PTr_ABSTRACT_\r
406 \r