Chris@16
|
1 #ifndef BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED
|
Chris@16
|
2 #define BOOST_DETAIL_SHARED_COUNT_132_HPP_INCLUDED
|
Chris@16
|
3
|
Chris@16
|
4 // MS compatible compilers support #pragma once
|
Chris@16
|
5
|
Chris@101
|
6 #if defined(_MSC_VER)
|
Chris@16
|
7 # pragma once
|
Chris@16
|
8 #endif
|
Chris@16
|
9
|
Chris@16
|
10 //
|
Chris@16
|
11 // detail/shared_count.hpp
|
Chris@16
|
12 //
|
Chris@16
|
13 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
|
Chris@16
|
14 //
|
Chris@16
|
15 // Distributed under the Boost Software License, Version 1.0. (See
|
Chris@16
|
16 // accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
17 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
18 //
|
Chris@16
|
19
|
Chris@16
|
20 #include <boost/config.hpp>
|
Chris@16
|
21
|
Chris@16
|
22 #if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
Chris@16
|
23 # error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
|
Chris@16
|
24 #endif
|
Chris@16
|
25
|
Chris@16
|
26 #include <boost/checked_delete.hpp>
|
Chris@16
|
27 #include <boost/serialization/throw_exception.hpp>
|
Chris@16
|
28 #include <boost/detail/lightweight_mutex.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
Chris@16
|
31 #include <boost/detail/quick_allocator.hpp>
|
Chris@16
|
32 #endif
|
Chris@16
|
33
|
Chris@16
|
34 #include <memory> // std::auto_ptr, std::allocator
|
Chris@16
|
35 #include <functional> // std::less
|
Chris@16
|
36 #include <exception> // std::exception
|
Chris@16
|
37 #include <new> // std::bad_alloc
|
Chris@16
|
38 #include <typeinfo> // std::type_info in get_deleter
|
Chris@16
|
39 #include <cstddef> // std::size_t
|
Chris@16
|
40
|
Chris@16
|
41 #include <boost/config.hpp> // msvc 6.0 needs this for warning suppression
|
Chris@16
|
42 #if defined(BOOST_NO_STDC_NAMESPACE)
|
Chris@16
|
43 namespace std{
|
Chris@16
|
44 using ::size_t;
|
Chris@16
|
45 } // namespace std
|
Chris@16
|
46 #endif
|
Chris@16
|
47
|
Chris@16
|
48 #ifdef __BORLANDC__
|
Chris@16
|
49 # pragma warn -8026 // Functions with excep. spec. are not expanded inline
|
Chris@16
|
50 # pragma warn -8027 // Functions containing try are not expanded inline
|
Chris@16
|
51 #endif
|
Chris@16
|
52
|
Chris@16
|
53 namespace boost_132 {
|
Chris@16
|
54
|
Chris@16
|
55 // Debug hooks
|
Chris@16
|
56
|
Chris@16
|
57 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
58
|
Chris@16
|
59 void sp_scalar_constructor_hook(void * px, std::size_t size, void * pn);
|
Chris@16
|
60 void sp_array_constructor_hook(void * px);
|
Chris@16
|
61 void sp_scalar_destructor_hook(void * px, std::size_t size, void * pn);
|
Chris@16
|
62 void sp_array_destructor_hook(void * px);
|
Chris@16
|
63
|
Chris@16
|
64 #endif
|
Chris@16
|
65
|
Chris@16
|
66
|
Chris@16
|
67 // The standard library that comes with Borland C++ 5.5.1
|
Chris@16
|
68 // defines std::exception and its members as having C calling
|
Chris@16
|
69 // convention (-pc). When the definition of bad_weak_ptr
|
Chris@16
|
70 // is compiled with -ps, the compiler issues an error.
|
Chris@16
|
71 // Hence, the temporary #pragma option -pc below. The version
|
Chris@16
|
72 // check is deliberately conservative.
|
Chris@16
|
73
|
Chris@16
|
74 #if defined(__BORLANDC__) && __BORLANDC__ == 0x551
|
Chris@16
|
75 # pragma option push -pc
|
Chris@16
|
76 #endif
|
Chris@16
|
77
|
Chris@16
|
78 class bad_weak_ptr: public std::exception
|
Chris@16
|
79 {
|
Chris@16
|
80 public:
|
Chris@16
|
81
|
Chris@16
|
82 virtual char const * what() const throw()
|
Chris@16
|
83 {
|
Chris@16
|
84 return "boost::bad_weak_ptr";
|
Chris@16
|
85 }
|
Chris@16
|
86 };
|
Chris@16
|
87
|
Chris@16
|
88 #if defined(__BORLANDC__) && __BORLANDC__ == 0x551
|
Chris@16
|
89 # pragma option pop
|
Chris@16
|
90 #endif
|
Chris@16
|
91
|
Chris@16
|
92 namespace detail{
|
Chris@16
|
93
|
Chris@16
|
94 class sp_counted_base
|
Chris@16
|
95 {
|
Chris@16
|
96 //private:
|
Chris@16
|
97
|
Chris@16
|
98 typedef boost::detail::lightweight_mutex mutex_type;
|
Chris@16
|
99
|
Chris@16
|
100 public:
|
Chris@16
|
101
|
Chris@16
|
102 sp_counted_base(): use_count_(1), weak_count_(1)
|
Chris@16
|
103 {
|
Chris@16
|
104 }
|
Chris@16
|
105
|
Chris@16
|
106 virtual ~sp_counted_base() // nothrow
|
Chris@16
|
107 {
|
Chris@16
|
108 }
|
Chris@16
|
109
|
Chris@16
|
110 // dispose() is called when use_count_ drops to zero, to release
|
Chris@16
|
111 // the resources managed by *this.
|
Chris@16
|
112
|
Chris@16
|
113 virtual void dispose() = 0; // nothrow
|
Chris@16
|
114
|
Chris@16
|
115 // destruct() is called when weak_count_ drops to zero.
|
Chris@16
|
116
|
Chris@16
|
117 virtual void destruct() // nothrow
|
Chris@16
|
118 {
|
Chris@16
|
119 delete this;
|
Chris@16
|
120 }
|
Chris@16
|
121
|
Chris@16
|
122 virtual void * get_deleter(std::type_info const & ti) = 0;
|
Chris@16
|
123
|
Chris@16
|
124 void add_ref_copy()
|
Chris@16
|
125 {
|
Chris@16
|
126 #if defined(BOOST_HAS_THREADS)
|
Chris@16
|
127 mutex_type::scoped_lock lock(mtx_);
|
Chris@16
|
128 #endif
|
Chris@16
|
129 ++use_count_;
|
Chris@16
|
130 }
|
Chris@16
|
131
|
Chris@16
|
132 void add_ref_lock()
|
Chris@16
|
133 {
|
Chris@16
|
134 #if defined(BOOST_HAS_THREADS)
|
Chris@16
|
135 mutex_type::scoped_lock lock(mtx_);
|
Chris@16
|
136 #endif
|
Chris@16
|
137 if(use_count_ == 0) boost::serialization::throw_exception(bad_weak_ptr());
|
Chris@16
|
138 ++use_count_;
|
Chris@16
|
139 }
|
Chris@16
|
140
|
Chris@16
|
141 void release() // nothrow
|
Chris@16
|
142 {
|
Chris@16
|
143 {
|
Chris@16
|
144 #if defined(BOOST_HAS_THREADS)
|
Chris@16
|
145 mutex_type::scoped_lock lock(mtx_);
|
Chris@16
|
146 #endif
|
Chris@16
|
147 long new_use_count = --use_count_;
|
Chris@16
|
148
|
Chris@16
|
149 if(new_use_count != 0) return;
|
Chris@16
|
150 }
|
Chris@16
|
151
|
Chris@16
|
152 dispose();
|
Chris@16
|
153 weak_release();
|
Chris@16
|
154 }
|
Chris@16
|
155
|
Chris@16
|
156 void weak_add_ref() // nothrow
|
Chris@16
|
157 {
|
Chris@16
|
158 #if defined(BOOST_HAS_THREADS)
|
Chris@16
|
159 mutex_type::scoped_lock lock(mtx_);
|
Chris@16
|
160 #endif
|
Chris@16
|
161 ++weak_count_;
|
Chris@16
|
162 }
|
Chris@16
|
163
|
Chris@16
|
164 void weak_release() // nothrow
|
Chris@16
|
165 {
|
Chris@16
|
166 long new_weak_count;
|
Chris@16
|
167
|
Chris@16
|
168 {
|
Chris@16
|
169 #if defined(BOOST_HAS_THREADS)
|
Chris@16
|
170 mutex_type::scoped_lock lock(mtx_);
|
Chris@16
|
171 #endif
|
Chris@16
|
172 new_weak_count = --weak_count_;
|
Chris@16
|
173 }
|
Chris@16
|
174
|
Chris@16
|
175 if(new_weak_count == 0)
|
Chris@16
|
176 {
|
Chris@16
|
177 destruct();
|
Chris@16
|
178 }
|
Chris@16
|
179 }
|
Chris@16
|
180
|
Chris@16
|
181 long use_count() const // nothrow
|
Chris@16
|
182 {
|
Chris@16
|
183 #if defined(BOOST_HAS_THREADS)
|
Chris@16
|
184 mutex_type::scoped_lock lock(mtx_);
|
Chris@16
|
185 #endif
|
Chris@16
|
186 return use_count_;
|
Chris@16
|
187 }
|
Chris@16
|
188
|
Chris@16
|
189 //private:
|
Chris@16
|
190 public:
|
Chris@16
|
191 sp_counted_base(sp_counted_base const &);
|
Chris@16
|
192 sp_counted_base & operator= (sp_counted_base const &);
|
Chris@16
|
193
|
Chris@16
|
194 long use_count_; // #shared
|
Chris@16
|
195 long weak_count_; // #weak + (#shared != 0)
|
Chris@16
|
196
|
Chris@16
|
197 #if defined(BOOST_HAS_THREADS) || defined(BOOST_LWM_WIN32)
|
Chris@16
|
198 mutable mutex_type mtx_;
|
Chris@16
|
199 #endif
|
Chris@16
|
200 };
|
Chris@16
|
201
|
Chris@16
|
202 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
203
|
Chris@101
|
204 template<class T> void cbi_call_constructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &, int)
|
Chris@16
|
205 {
|
Chris@16
|
206 boost::sp_scalar_constructor_hook(px, sizeof(T), pn);
|
Chris@16
|
207 }
|
Chris@16
|
208
|
Chris@101
|
209 template<class T> void cbi_call_constructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &, int)
|
Chris@16
|
210 {
|
Chris@16
|
211 boost::sp_array_constructor_hook(px);
|
Chris@16
|
212 }
|
Chris@16
|
213
|
Chris@16
|
214 template<class P, class D> void cbi_call_constructor_hook(sp_counted_base *, P const &, D const &, long)
|
Chris@16
|
215 {
|
Chris@16
|
216 }
|
Chris@16
|
217
|
Chris@101
|
218 template<class T> void cbi_call_destructor_hook(sp_counted_base * pn, T * px, boost::checked_deleter< T > const &, int)
|
Chris@16
|
219 {
|
Chris@16
|
220 boost::sp_scalar_destructor_hook(px, sizeof(T), pn);
|
Chris@16
|
221 }
|
Chris@16
|
222
|
Chris@101
|
223 template<class T> void cbi_call_destructor_hook(sp_counted_base *, T * px, boost::checked_array_deleter< T > const &, int)
|
Chris@16
|
224 {
|
Chris@16
|
225 boost::sp_array_destructor_hook(px);
|
Chris@16
|
226 }
|
Chris@16
|
227
|
Chris@16
|
228 template<class P, class D> void cbi_call_destructor_hook(sp_counted_base *, P const &, D const &, long)
|
Chris@16
|
229 {
|
Chris@16
|
230 }
|
Chris@16
|
231
|
Chris@16
|
232 #endif
|
Chris@16
|
233
|
Chris@16
|
234 //
|
Chris@16
|
235 // Borland's Codeguard trips up over the -Vx- option here:
|
Chris@16
|
236 //
|
Chris@16
|
237 #ifdef __CODEGUARD__
|
Chris@16
|
238 # pragma option push -Vx-
|
Chris@16
|
239 #endif
|
Chris@16
|
240
|
Chris@16
|
241 template<class P, class D> class sp_counted_base_impl: public sp_counted_base
|
Chris@16
|
242 {
|
Chris@16
|
243 //private:
|
Chris@16
|
244 public:
|
Chris@16
|
245 P ptr; // copy constructor must not throw
|
Chris@16
|
246 D del; // copy constructor must not throw
|
Chris@16
|
247
|
Chris@16
|
248 sp_counted_base_impl(sp_counted_base_impl const &);
|
Chris@16
|
249 sp_counted_base_impl & operator= (sp_counted_base_impl const &);
|
Chris@16
|
250
|
Chris@16
|
251 typedef sp_counted_base_impl<P, D> this_type;
|
Chris@16
|
252
|
Chris@16
|
253 public:
|
Chris@16
|
254
|
Chris@16
|
255 // pre: initial_use_count <= initial_weak_count, d(p) must not throw
|
Chris@16
|
256
|
Chris@16
|
257 sp_counted_base_impl(P p, D d): ptr(p), del(d)
|
Chris@16
|
258 {
|
Chris@16
|
259 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
260 detail::cbi_call_constructor_hook(this, p, d, 0);
|
Chris@16
|
261 #endif
|
Chris@16
|
262 }
|
Chris@16
|
263
|
Chris@16
|
264 virtual void dispose() // nothrow
|
Chris@16
|
265 {
|
Chris@16
|
266 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
267 detail::cbi_call_destructor_hook(this, ptr, del, 0);
|
Chris@16
|
268 #endif
|
Chris@16
|
269 del(ptr);
|
Chris@16
|
270 }
|
Chris@16
|
271
|
Chris@16
|
272 virtual void * get_deleter(std::type_info const & ti)
|
Chris@16
|
273 {
|
Chris@16
|
274 return ti == typeid(D)? &del: 0;
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277 #if defined(BOOST_SP_USE_STD_ALLOCATOR)
|
Chris@16
|
278
|
Chris@16
|
279 void * operator new(std::size_t)
|
Chris@16
|
280 {
|
Chris@16
|
281 return std::allocator<this_type>().allocate(1, static_cast<this_type *>(0));
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 void operator delete(void * p)
|
Chris@16
|
285 {
|
Chris@16
|
286 std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1);
|
Chris@16
|
287 }
|
Chris@16
|
288
|
Chris@16
|
289 #endif
|
Chris@16
|
290
|
Chris@16
|
291 #if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
|
Chris@16
|
292
|
Chris@16
|
293 void * operator new(std::size_t)
|
Chris@16
|
294 {
|
Chris@16
|
295 return boost::detail::quick_allocator<this_type>::alloc();
|
Chris@16
|
296 }
|
Chris@16
|
297
|
Chris@16
|
298 void operator delete(void * p)
|
Chris@16
|
299 {
|
Chris@16
|
300 boost::detail::quick_allocator<this_type>::dealloc(p);
|
Chris@16
|
301 }
|
Chris@16
|
302
|
Chris@16
|
303 #endif
|
Chris@16
|
304 };
|
Chris@16
|
305
|
Chris@16
|
306 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
307
|
Chris@16
|
308 int const shared_count_id = 0x2C35F101;
|
Chris@16
|
309 int const weak_count_id = 0x298C38A4;
|
Chris@16
|
310
|
Chris@16
|
311 #endif
|
Chris@16
|
312
|
Chris@16
|
313 class weak_count;
|
Chris@16
|
314
|
Chris@16
|
315 class shared_count
|
Chris@16
|
316 {
|
Chris@16
|
317 //private:
|
Chris@16
|
318 public:
|
Chris@16
|
319 sp_counted_base * pi_;
|
Chris@16
|
320
|
Chris@16
|
321 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
322 int id_;
|
Chris@16
|
323 #endif
|
Chris@16
|
324
|
Chris@16
|
325 friend class weak_count;
|
Chris@16
|
326
|
Chris@16
|
327 public:
|
Chris@16
|
328
|
Chris@16
|
329 shared_count(): pi_(0) // nothrow
|
Chris@16
|
330 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
331 , id_(shared_count_id)
|
Chris@16
|
332 #endif
|
Chris@16
|
333 {
|
Chris@16
|
334 }
|
Chris@16
|
335
|
Chris@16
|
336 template<class P, class D> shared_count(P p, D d): pi_(0)
|
Chris@16
|
337 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
338 , id_(shared_count_id)
|
Chris@16
|
339 #endif
|
Chris@16
|
340 {
|
Chris@16
|
341 #ifndef BOOST_NO_EXCEPTIONS
|
Chris@16
|
342
|
Chris@16
|
343 try
|
Chris@16
|
344 {
|
Chris@16
|
345 pi_ = new sp_counted_base_impl<P, D>(p, d);
|
Chris@16
|
346 }
|
Chris@16
|
347 catch(...)
|
Chris@16
|
348 {
|
Chris@16
|
349 d(p); // delete p
|
Chris@16
|
350 throw;
|
Chris@16
|
351 }
|
Chris@16
|
352
|
Chris@16
|
353 #else
|
Chris@16
|
354
|
Chris@16
|
355 pi_ = new sp_counted_base_impl<P, D>(p, d);
|
Chris@16
|
356
|
Chris@16
|
357 if(pi_ == 0)
|
Chris@16
|
358 {
|
Chris@16
|
359 d(p); // delete p
|
Chris@16
|
360 boost::serialization::throw_exception(std::bad_alloc());
|
Chris@16
|
361 }
|
Chris@16
|
362
|
Chris@16
|
363 #endif
|
Chris@16
|
364 }
|
Chris@16
|
365
|
Chris@16
|
366 #ifndef BOOST_NO_AUTO_PTR
|
Chris@16
|
367
|
Chris@16
|
368 // auto_ptr<Y> is special cased to provide the strong guarantee
|
Chris@16
|
369
|
Chris@16
|
370 template<class Y>
|
Chris@16
|
371 explicit shared_count(std::auto_ptr<Y> & r): pi_(
|
Chris@16
|
372 new sp_counted_base_impl<
|
Chris@16
|
373 Y *,
|
Chris@16
|
374 boost::checked_deleter<Y>
|
Chris@16
|
375 >(r.get(), boost::checked_deleter<Y>()))
|
Chris@16
|
376 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
377 , id_(shared_count_id)
|
Chris@16
|
378 #endif
|
Chris@16
|
379 {
|
Chris@16
|
380 r.release();
|
Chris@16
|
381 }
|
Chris@16
|
382
|
Chris@16
|
383 #endif
|
Chris@16
|
384
|
Chris@16
|
385 ~shared_count() // nothrow
|
Chris@16
|
386 {
|
Chris@16
|
387 if(pi_ != 0) pi_->release();
|
Chris@16
|
388 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
389 id_ = 0;
|
Chris@16
|
390 #endif
|
Chris@16
|
391 }
|
Chris@16
|
392
|
Chris@16
|
393 shared_count(shared_count const & r): pi_(r.pi_) // nothrow
|
Chris@16
|
394 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
395 , id_(shared_count_id)
|
Chris@16
|
396 #endif
|
Chris@16
|
397 {
|
Chris@16
|
398 if(pi_ != 0) pi_->add_ref_copy();
|
Chris@16
|
399 }
|
Chris@16
|
400
|
Chris@16
|
401 explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
|
Chris@16
|
402
|
Chris@16
|
403 shared_count & operator= (shared_count const & r) // nothrow
|
Chris@16
|
404 {
|
Chris@16
|
405 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
406
|
Chris@16
|
407 if(tmp != pi_)
|
Chris@16
|
408 {
|
Chris@16
|
409 if(tmp != 0) tmp->add_ref_copy();
|
Chris@16
|
410 if(pi_ != 0) pi_->release();
|
Chris@16
|
411 pi_ = tmp;
|
Chris@16
|
412 }
|
Chris@16
|
413
|
Chris@16
|
414 return *this;
|
Chris@16
|
415 }
|
Chris@16
|
416
|
Chris@16
|
417 void swap(shared_count & r) // nothrow
|
Chris@16
|
418 {
|
Chris@16
|
419 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
420 r.pi_ = pi_;
|
Chris@16
|
421 pi_ = tmp;
|
Chris@16
|
422 }
|
Chris@16
|
423
|
Chris@16
|
424 long use_count() const // nothrow
|
Chris@16
|
425 {
|
Chris@16
|
426 return pi_ != 0? pi_->use_count(): 0;
|
Chris@16
|
427 }
|
Chris@16
|
428
|
Chris@16
|
429 bool unique() const // nothrow
|
Chris@16
|
430 {
|
Chris@16
|
431 return use_count() == 1;
|
Chris@16
|
432 }
|
Chris@16
|
433
|
Chris@16
|
434 friend inline bool operator==(shared_count const & a, shared_count const & b)
|
Chris@16
|
435 {
|
Chris@16
|
436 return a.pi_ == b.pi_;
|
Chris@16
|
437 }
|
Chris@16
|
438
|
Chris@16
|
439 friend inline bool operator<(shared_count const & a, shared_count const & b)
|
Chris@16
|
440 {
|
Chris@16
|
441 return std::less<sp_counted_base *>()(a.pi_, b.pi_);
|
Chris@16
|
442 }
|
Chris@16
|
443
|
Chris@16
|
444 void * get_deleter(std::type_info const & ti) const
|
Chris@16
|
445 {
|
Chris@16
|
446 return pi_? pi_->get_deleter(ti): 0;
|
Chris@16
|
447 }
|
Chris@16
|
448 };
|
Chris@16
|
449
|
Chris@16
|
450 #ifdef __CODEGUARD__
|
Chris@16
|
451 # pragma option pop
|
Chris@16
|
452 #endif
|
Chris@16
|
453
|
Chris@16
|
454
|
Chris@16
|
455 class weak_count
|
Chris@16
|
456 {
|
Chris@16
|
457 private:
|
Chris@16
|
458
|
Chris@16
|
459 sp_counted_base * pi_;
|
Chris@16
|
460
|
Chris@16
|
461 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
462 int id_;
|
Chris@16
|
463 #endif
|
Chris@16
|
464
|
Chris@16
|
465 friend class shared_count;
|
Chris@16
|
466
|
Chris@16
|
467 public:
|
Chris@16
|
468
|
Chris@16
|
469 weak_count(): pi_(0) // nothrow
|
Chris@16
|
470 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
471 , id_(weak_count_id)
|
Chris@16
|
472 #endif
|
Chris@16
|
473 {
|
Chris@16
|
474 }
|
Chris@16
|
475
|
Chris@16
|
476 weak_count(shared_count const & r): pi_(r.pi_) // nothrow
|
Chris@16
|
477 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
478 , id_(shared_count_id)
|
Chris@16
|
479 #endif
|
Chris@16
|
480 {
|
Chris@16
|
481 if(pi_ != 0) pi_->weak_add_ref();
|
Chris@16
|
482 }
|
Chris@16
|
483
|
Chris@16
|
484 weak_count(weak_count const & r): pi_(r.pi_) // nothrow
|
Chris@16
|
485 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
486 , id_(shared_count_id)
|
Chris@16
|
487 #endif
|
Chris@16
|
488 {
|
Chris@16
|
489 if(pi_ != 0) pi_->weak_add_ref();
|
Chris@16
|
490 }
|
Chris@16
|
491
|
Chris@16
|
492 ~weak_count() // nothrow
|
Chris@16
|
493 {
|
Chris@16
|
494 if(pi_ != 0) pi_->weak_release();
|
Chris@16
|
495 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
496 id_ = 0;
|
Chris@16
|
497 #endif
|
Chris@16
|
498 }
|
Chris@16
|
499
|
Chris@16
|
500 weak_count & operator= (shared_count const & r) // nothrow
|
Chris@16
|
501 {
|
Chris@16
|
502 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
503 if(tmp != 0) tmp->weak_add_ref();
|
Chris@16
|
504 if(pi_ != 0) pi_->weak_release();
|
Chris@16
|
505 pi_ = tmp;
|
Chris@16
|
506
|
Chris@16
|
507 return *this;
|
Chris@16
|
508 }
|
Chris@16
|
509
|
Chris@16
|
510 weak_count & operator= (weak_count const & r) // nothrow
|
Chris@16
|
511 {
|
Chris@16
|
512 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
513 if(tmp != 0) tmp->weak_add_ref();
|
Chris@16
|
514 if(pi_ != 0) pi_->weak_release();
|
Chris@16
|
515 pi_ = tmp;
|
Chris@16
|
516
|
Chris@16
|
517 return *this;
|
Chris@16
|
518 }
|
Chris@16
|
519
|
Chris@16
|
520 void swap(weak_count & r) // nothrow
|
Chris@16
|
521 {
|
Chris@16
|
522 sp_counted_base * tmp = r.pi_;
|
Chris@16
|
523 r.pi_ = pi_;
|
Chris@16
|
524 pi_ = tmp;
|
Chris@16
|
525 }
|
Chris@16
|
526
|
Chris@16
|
527 long use_count() const // nothrow
|
Chris@16
|
528 {
|
Chris@16
|
529 return pi_ != 0? pi_->use_count(): 0;
|
Chris@16
|
530 }
|
Chris@16
|
531
|
Chris@16
|
532 friend inline bool operator==(weak_count const & a, weak_count const & b)
|
Chris@16
|
533 {
|
Chris@16
|
534 return a.pi_ == b.pi_;
|
Chris@16
|
535 }
|
Chris@16
|
536
|
Chris@16
|
537 friend inline bool operator<(weak_count const & a, weak_count const & b)
|
Chris@16
|
538 {
|
Chris@16
|
539 return std::less<sp_counted_base *>()(a.pi_, b.pi_);
|
Chris@16
|
540 }
|
Chris@16
|
541 };
|
Chris@16
|
542
|
Chris@16
|
543 inline shared_count::shared_count(weak_count const & r): pi_(r.pi_)
|
Chris@16
|
544 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
|
Chris@16
|
545 , id_(shared_count_id)
|
Chris@16
|
546 #endif
|
Chris@16
|
547 {
|
Chris@16
|
548 if(pi_ != 0)
|
Chris@16
|
549 {
|
Chris@16
|
550 pi_->add_ref_lock();
|
Chris@16
|
551 }
|
Chris@16
|
552 else
|
Chris@16
|
553 {
|
Chris@16
|
554 boost::serialization::throw_exception(bad_weak_ptr());
|
Chris@16
|
555 }
|
Chris@16
|
556 }
|
Chris@16
|
557
|
Chris@16
|
558 } // namespace detail
|
Chris@16
|
559
|
Chris@16
|
560 } // namespace boost
|
Chris@16
|
561
|
Chris@16
|
562 BOOST_SERIALIZATION_ASSUME_ABSTRACT(boost_132::detail::sp_counted_base)
|
Chris@16
|
563
|
Chris@16
|
564 #ifdef __BORLANDC__
|
Chris@16
|
565 # pragma warn .8027 // Functions containing try are not expanded inline
|
Chris@16
|
566 # pragma warn .8026 // Functions with excep. spec. are not expanded inline
|
Chris@16
|
567 #endif
|
Chris@16
|
568
|
Chris@16
|
569 #endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED
|