Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: third_party/smartany/shared_any.h

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/smartany/scoped_any.h ('k') | third_party/smartany/shared_any.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 //+---------------------------------------------------------------------------
2 //
3 // Copyright ( C ) Microsoft, 2002.
4 //
5 // File: shared_any.h
6 //
7 // Contents: automatic resource management
8 //
9 // Classes: shared_any<> and various typedefs
10 //
11 // Functions: get
12 // reset
13 // valid
14 //
15 // Author: Eric Niebler ( ericne@microsoft.com )
16 //
17 //----------------------------------------------------------------------------
18
19
20 #ifndef SHARED_ANY
21 #define SHARED_ANY
22
23 #include <cassert>
24 #include <functional> // for std::less
25 #include <algorithm> // for std::swap
26 #include "smart_any_fwd.h"
27
28 namespace detail
29 {
30 class ref_count_allocator
31 {
32 struct node;
33 node *m_list_blocks;
34 node *m_last_alloc;
35 node *m_last_free;
36
37 ref_count_allocator();
38 ~ref_count_allocator();
39 public:
40 void finalize();
41 long volatile *alloc();
42 long volatile *alloc( long val );
43 void free( long volatile *refcount );
44
45 static ref_count_allocator instance;
46 };
47
48 template<typename T,class close_policy,class invalid_value,int unique>
49 struct shared_any_helper;
50
51 template<typename Super>
52 struct shared_holder : Super
53 {
54 explicit shared_holder( typename Super::type t )
55 : Super( t )
56 {
57 }
58
59 shared_holder( shared_holder const & that )
60 : Super( that )
61 {
62 if( Super::valid() )
63 {
64 Super::inc_ref();
65 }
66 }
67
68 ~shared_holder()
69 {
70 if( Super::valid() )
71 {
72 Super::dec_ref();
73 }
74 }
75 };
76
77 template<typename T,class invalid_value_type>
78 struct intrusive
79 {
80 typedef T type;
81
82 explicit intrusive( T t )
83 : m_t( t )
84 {
85 }
86
87 bool valid() const
88 {
89 return m_t != static_cast<T>( invalid_value_type() );
90 }
91
92 void inc_ref()
93 {
94 m_t->AddRef();
95 }
96
97 void dec_ref()
98 {
99 if( 0 == m_t->Release() )
100 {
101 m_t = static_cast<T>( invalid_value_type() );
102 }
103 }
104
105 T m_t;
106 };
107
108 template<typename T,class close_policy,class invalid_value_type>
109 struct nonintrusive
110 {
111 typedef T type;
112
113 explicit nonintrusive( T t )
114 : m_t( t ),
115 m_ref( 0 )
116 {
117 if( valid() )
118 {
119 m_ref = ref_count_allocator::instance.alloc(1L);
120 if( ! m_ref )
121 {
122 m_t = static_cast<T>( invalid_value_type() );
123 throw std::bad_alloc();
124 }
125 }
126 }
127
128 bool valid() const
129 {
130 return m_t != static_cast<T>( invalid_value_type() );
131 }
132
133 void inc_ref()
134 {
135 ::InterlockedIncrement( m_ref );
136 }
137
138 void dec_ref()
139 {
140 if( 0L == ::InterlockedDecrement( m_ref ) )
141 {
142 ref_count_allocator::instance.free( m_ref );
143 m_ref = 0;
144 close_policy::close( m_t );
145 m_t = static_cast<T>( invalid_value_type() );
146 }
147 }
148
149 typename holder<T>::type m_t;
150 long volatile *m_ref;
151 };
152
153 template<class close_policy>
154 struct is_close_release_com
155 {
156 static bool const value = false;
157 };
158 template<>
159 struct is_close_release_com<close_release_com>
160 {
161 static bool const value = true;
162 };
163
164 // credit Rani Sharoni for showing me how to implement
165 // is_com_ptr on VC7. This is deeply magical code.
166 template<typename T>
167 struct is_com_ptr
168 {
169 private:
170 struct maybe
171 {
172 operator IUnknown*() const;
173 operator T();
174 };
175
176 template<typename U>
177 static yes check(T, U);
178 static no check(IUnknown*, int);
179 static maybe get();
180 public:
181 static bool const value = sizeof(check(get(),0)) == sizeof(yes);
182 };
183
184 template<>
185 struct is_com_ptr<IUnknown*>
186 {
187 static bool const value = true;
188 };
189 }
190
191 template<typename T,class close_policy,class invalid_value,int unique>
192 class shared_any
193 {
194 typedef detail::safe_types<T,close_policy> safe_types;
195
196 // disallow comparison of shared_any's
197 bool operator==( detail::safe_bool ) const;
198 bool operator!=( detail::safe_bool ) const;
199
200 public:
201 typedef typename detail::holder<T>::type element_type;
202 typedef close_policy close_policy_type;
203 typedef typename safe_types::pointer_type pointer_type;
204 typedef typename safe_types::reference_type reference_type;
205
206 // Fix-up the invalid_value type on older compilers
207 typedef typename detail::fixup_invalid_value<invalid_value>::
208 template rebind<T>::type invalid_value_type;
209
210 friend struct detail::shared_any_helper<T,close_policy,invalid_value,unique> ;
211
212 // default construct
213 shared_any()
214 : m_held( static_cast<T>( invalid_value_type() ) )
215 {
216 }
217
218 // construct from object. If we fail to allocate a reference count,
219 // then the T object is closed, and a bad_alloc exception is thrown.
220 explicit shared_any( T t )
221 try : m_held( t )
222 {
223 }
224 catch( std::bad_alloc & )
225 {
226 close_policy::close( t );
227 throw;
228 }
229
230 // construct from another shared_any, incrementing ref count.
231 // Only throws if T's copy-c'tor throws, in which case, ref-count
232 // is unchanged.
233 shared_any( shared_any<T,close_policy,invalid_value,unique> const & right )
234 : m_held( right.m_held )
235 {
236 }
237
238 // construct from an auto_any, taking ownership. If allocation
239 // fails, auto_any retains ownership.
240 shared_any( auto_any<T,close_policy,invalid_value,unique> & right )
241 : m_held( get( right ) )
242 {
243 release( right );
244 }
245
246 // assign from another shared_any
247 shared_any<T,close_policy,invalid_value,unique> & operator=(
248 shared_any<T,close_policy,invalid_value,unique> const & right )
249 {
250 shared_any<T,close_policy,invalid_value,unique>( right ).swap( *this );
251 return *this;
252 }
253
254 // assign from an auto_any
255 shared_any<T,close_policy,invalid_value,unique> & operator=(
256 auto_any<T,close_policy,invalid_value,unique> & right )
257 {
258 shared_any<T,close_policy,invalid_value,unique>( right ).swap( *this );
259 return *this;
260 }
261
262 operator detail::safe_bool() const
263 {
264 return m_held.valid() ? detail::safe_true : detail::safe_false;
265 }
266
267 bool operator!() const
268 {
269 return ! m_held.valid();
270 }
271
272 // return pointer to class object (assume pointer)
273 pointer_type operator->() const
274 {
275 #ifdef SMART_ANY_PTS
276 // You better not be applying operator-> to a handle!
277 static detail::static_assert<!detail::is_handle<T>::value> const cannot_ dereference_a_handle;
278 #endif
279 assert( m_held.valid() );
280 return safe_types::to_pointer( m_held.m_t );
281 }
282
283 #ifdef SMART_ANY_PTS
284 // if this shared_any is managing an array, we can use operator[] to index i t
285 typename detail::deref<T>::type operator[]( int i ) const
286 {
287 static detail::static_assert<!detail::is_handle<T>::value> const cannot_ dereference_a_handle;
288 static detail::static_assert<!detail::is_delete<close_policy>::value> co nst accessed_like_an_array_but_not_deleted_like_an_array;
289 assert( m_held.valid() );
290 return m_held.m_t[ i ];
291 }
292
293 // unary operator* lets you write code like:
294 // shared_any<foo*,close_delete> pfoo( new foo );
295 // foo & f = *pfoo;
296 reference_type operator*() const
297 {
298 static detail::static_assert<!detail::is_handle<T>::value> const cannot_ dereference_a_handle;
299 assert( m_held.valid() );
300 return safe_types::to_reference( m_held.m_t );
301 }
302 #endif
303
304 private:
305
306 void swap( shared_any<T,close_policy,invalid_value,unique> & right )
307 {
308 using std::swap;
309 swap( m_held, right.m_held );
310 }
311
312 // if we are wrapping a COM object, then use COM's reference counting.
313 // otherwise, use our own reference counting.
314 typedef typename detail::select<
315 detail::is_com_ptr<T>::value && detail::is_close_release_com<close_polic y>::value,
316 detail::intrusive<T,invalid_value_type>,
317 detail::nonintrusive<T,close_policy,invalid_value_type> >::type holder_p olicy;
318
319 detail::shared_holder<holder_policy> m_held;
320 };
321
322 namespace detail
323 {
324 template<typename T,class close_policy,class invalid_value,int unique>
325 struct shared_any_helper
326 {
327 static T get( shared_any<T,close_policy,invalid_value,unique> const & t )
328 {
329 return t.m_held.m_t;
330 }
331
332 static void reset( shared_any<T,close_policy,invalid_value,unique> & t, T newT )
333 {
334 shared_any<T,close_policy,invalid_value,unique>( newT ).swap( t );
335 }
336
337 static void swap( shared_any<T,close_policy,invalid_value,unique> & left ,
338 shared_any<T,close_policy,invalid_value,unique> & righ t )
339 {
340 left.swap( right );
341 }
342 };
343 }
344
345 // return wrapped resource
346 template<typename T,class close_policy,class invalid_value,int unique>
347 inline T get( shared_any<T,close_policy,invalid_value,unique> const & t )
348 {
349 return detail::shared_any_helper<T,close_policy,invalid_value,unique>::get( t );
350 }
351
352 // return true if the shared_any contains a currently valid resource
353 template<typename T,class close_policy,class invalid_value,int unique>
354 inline bool valid( shared_any<T,close_policy,invalid_value,unique> const & t )
355 {
356 return t;
357 }
358
359 // destroy designated object
360 template<typename T,class close_policy,class invalid_value,int unique>
361 inline void reset( shared_any<T,close_policy,invalid_value,unique> & t )
362 {
363 typedef typename detail::fixup_invalid_value<invalid_value>::
364 template rebind<T>::type invalid_value_type;
365 detail::shared_any_helper<T,close_policy,invalid_value,unique>::reset( t, in valid_value_type() );
366 }
367
368 // destroy designated object and store new resource
369 template<typename T,class close_policy,class invalid_value,int unique,typename U >
370 inline void reset( shared_any<T,close_policy,invalid_value,unique> & t, U newT )
371 {
372 detail::shared_any_helper<T,close_policy,invalid_value,unique>::reset( t, ne wT );
373 }
374
375 // swap the contents of two shared_any objects
376 template<typename T,class close_policy,class invalid_value,int unique>
377 inline void swap( shared_any<T,close_policy,invalid_value,unique> & left,
378 shared_any<T,close_policy,invalid_value,unique> & right )
379 {
380 detail::shared_any_helper<T,close_policy,invalid_value,unique>::swap( left, right );
381 }
382
383 // Define some relational operators on shared_* types so they
384 // can be used in hashes and maps
385 template<typename T,class close_policy,class invalid_value,int unique>
386 inline bool operator==(
387 shared_any<T,close_policy,invalid_value,unique> const & left,
388 shared_any<T,close_policy,invalid_value,unique> const & right )
389 {
390 return get( left ) == get( right );
391 }
392
393 template<typename T,class close_policy,class invalid_value,int unique>
394 inline bool operator!=(
395 shared_any<T,close_policy,invalid_value,unique> const & left,
396 shared_any<T,close_policy,invalid_value,unique> const & right )
397 {
398 return get( left ) != get( right );
399 }
400
401 template<typename T,class close_policy,class invalid_value,int unique>
402 inline bool operator<(
403 shared_any<T,close_policy,invalid_value,unique> const & left,
404 shared_any<T,close_policy,invalid_value,unique> const & right )
405 {
406 return std::less<T>( get( left ), get( right ) );
407 }
408
409 #endif // SHARED_ANY
410
411 // This causes the shared_* typedefs to be defined
412 DECLARE_SMART_ANY_TYPEDEFS(shared)
OLDNEW
« no previous file with comments | « third_party/smartany/scoped_any.h ('k') | third_party/smartany/shared_any.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698