CppCMS

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

shared_count.h
1 #ifndef BOOSTER_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
2 #define BOOSTER_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
3 //
4 // detail/shared_count.hpp
5 //
6 // Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
7 // Copyright 2004-2005 Peter Dimov
8 //
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
12 //
13
14 #ifdef __BORLANDC__
15 # pragma warn -8027 // Functions containing try are not expanded inline
16 #endif
17
18 #include <booster/config.h>
19 #include <booster/checked_delete.h>
20 #include <booster/bad_weak_ptr.h>
21 #include <booster/smart_ptr/sp_counted_base.h>
22 #include <booster/smart_ptr/sp_counted_impl.h>
23 #include <booster/auto_ptr_inc.h>
24 #include <functional> // std::less
25 #include <new> // std::bad_alloc
26
27 namespace booster
28 {
29
30 namespace detail
31 {
32
33 struct sp_nothrow_tag {};
34
35 class weak_count;
36
37 class shared_count
38 {
39 private:
40
41 sp_counted_base * pi_;
42
43 friend class weak_count;
44
45 public:
46
47 shared_count(): pi_(0) // nothrow
48 {
49 }
50
51 template<class Y> explicit shared_count( Y * p ): pi_( 0 )
52 {
53 try
54 {
55 pi_ = new sp_counted_impl_p<Y>( p );
56 }
57 catch(...)
58 {
59 booster::checked_delete( p );
60 throw;
61 }
62 }
63
64 template<class P, class D> shared_count( P p, D d ): pi_(0)
65 {
66 try
67 {
68 pi_ = new sp_counted_impl_pd<P, D>(p, d);
69 }
70 catch(...)
71 {
72 d(p); // delete p
73 throw;
74 }
75 }
76
77 template<class P, class D, class A> shared_count( P p, D d, A a ): pi_( 0 )
78 {
79 typedef sp_counted_impl_pda<P, D, A> impl_type;
80 typedef typename A::template rebind< impl_type >::other A2;
81
82 A2 a2( a );
83
84 try
85 {
86 pi_ = a2.allocate( 1, static_cast< impl_type* >( 0 ) );
87 new( static_cast< void* >( pi_ ) ) impl_type( p, d, a );
88 }
89 catch(...)
90 {
91 d( p );
92
93 if( pi_ != 0 )
94 {
95 a2.deallocate( static_cast< impl_type* >( pi_ ), 1 );
96 }
97
98 throw;
99 }
100
101 }
102
103 // auto_ptr<Y> is special cased to provide the strong guarantee
104
105 template<class Y>
106 explicit shared_count( std::auto_ptr<Y> & r ): pi_( new sp_counted_impl_p<Y>( r.get() ) )
107 {
108
109 r.release();
110 }
111
112
113 ~shared_count() // nothrow
114 {
115 if( pi_ != 0 ) pi_->release();
116 }
117
118 shared_count(shared_count const & r): pi_(r.pi_) // nothrow
119 {
120 if( pi_ != 0 ) pi_->add_ref_copy();
121 }
122
123 explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
124 shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
125
126 shared_count & operator= (shared_count const & r) // nothrow
127 {
128 sp_counted_base * tmp = r.pi_;
129
130 if( tmp != pi_ )
131 {
132 if( tmp != 0 ) tmp->add_ref_copy();
133 if( pi_ != 0 ) pi_->release();
134 pi_ = tmp;
135 }
136
137 return *this;
138 }
139
140 void swap(shared_count & r) // nothrow
141 {
142 sp_counted_base * tmp = r.pi_;
143 r.pi_ = pi_;
144 pi_ = tmp;
145 }
146
147 long use_count() const // nothrow
148 {
149 return pi_ != 0? pi_->use_count(): 0;
150 }
151
152 bool unique() const // nothrow
153 {
154 return use_count() == 1;
155 }
156
157 bool empty() const // nothrow
158 {
159 return pi_ == 0;
160 }
161
162 friend inline bool operator==(shared_count const & a, shared_count const & b)
163 {
164 return a.pi_ == b.pi_;
165 }
166
167 friend inline bool operator<(shared_count const & a, shared_count const & b)
168 {
169 return std::less<sp_counted_base *>()( a.pi_, b.pi_ );
170 }
171
172 void * get_deleter( sp_typeinfo const & ti ) const
173 {
174 return pi_? pi_->get_deleter( ti ): 0;
175 }
176 };
177
178
179 class weak_count
180 {
181 private:
182
183 sp_counted_base * pi_;
184
185 friend class shared_count;
186
187 public:
188
189 weak_count(): pi_(0) // nothrow
190 {
191 }
192
193 weak_count(shared_count const & r): pi_(r.pi_) // nothrow
194 {
195 if(pi_ != 0) pi_->weak_add_ref();
196 }
197
198 weak_count(weak_count const & r): pi_(r.pi_) // nothrow
199 {
200 if(pi_ != 0) pi_->weak_add_ref();
201 }
202
203
204 ~weak_count() // nothrow
205 {
206 if(pi_ != 0) pi_->weak_release();
207 }
208
209 weak_count & operator= (shared_count const & r) // nothrow
210 {
211 sp_counted_base * tmp = r.pi_;
212
213 if( tmp != pi_ )
214 {
215 if(tmp != 0) tmp->weak_add_ref();
216 if(pi_ != 0) pi_->weak_release();
217 pi_ = tmp;
218 }
219
220 return *this;
221 }
222
223 weak_count & operator= (weak_count const & r) // nothrow
224 {
225 sp_counted_base * tmp = r.pi_;
226
227 if( tmp != pi_ )
228 {
229 if(tmp != 0) tmp->weak_add_ref();
230 if(pi_ != 0) pi_->weak_release();
231 pi_ = tmp;
232 }
233
234 return *this;
235 }
236
237 void swap(weak_count & r) // nothrow
238 {
239 sp_counted_base * tmp = r.pi_;
240 r.pi_ = pi_;
241 pi_ = tmp;
242 }
243
244 long use_count() const // nothrow
245 {
246 return pi_ != 0? pi_->use_count(): 0;
247 }
248
249 bool empty() const // nothrow
250 {
251 return pi_ == 0;
252 }
253
254 friend inline bool operator==(weak_count const & a, weak_count const & b)
255 {
256 return a.pi_ == b.pi_;
257 }
258
259 friend inline bool operator<(weak_count const & a, weak_count const & b)
260 {
261 return std::less<sp_counted_base *>()(a.pi_, b.pi_);
262 }
263 };
264
265 inline shared_count::shared_count( weak_count const & r ): pi_( r.pi_ )
266 {
267 if( pi_ == 0 || !pi_->add_ref_lock() )
268 {
269 throw booster::bad_weak_ptr();
270 }
271 }
272
273 inline shared_count::shared_count( weak_count const & r, sp_nothrow_tag ): pi_( r.pi_ )
274 {
275 if( pi_ != 0 && !pi_->add_ref_lock() )
276 {
277 pi_ = 0;
278 }
279 }
280
281 } // namespace detail
282
283 } // namespace boost
284
285 #ifdef __BORLANDC__
286 # pragma warn .8027 // Functions containing try are not expanded inline
287 #endif
288
289 #endif // #ifndef BOOST_SMART_PTR_DETAIL_SHARED_COUNT_HPP_INCLUDED
booster::detail::shared_count
Definition: shared_count.h:37
booster::detail::sp_counted_base
Definition: sp_counted_base.h:39
booster::detail::sp_counted_impl_pd
Definition: sp_counted_impl.h:77
booster::detail::weak_count
Definition: shared_count.h:179
booster::detail::sp_counted_impl_p
Definition: sp_counted_impl.h:32
booster::detail::sp_counted_impl_pda
Definition: sp_counted_impl.h:119
booster::detail::sp_nothrow_tag
Definition: shared_count.h:33
booster
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23
booster::bad_weak_ptr
Definition: bad_weak_ptr.h:36