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