libzypp  11.13.5
PtrTypes.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
13 #ifndef ZYPP_BASE_PTRTYPES_H
14 #define ZYPP_BASE_PTRTYPES_H
15 
16 #include <string>
17 
18 #include <boost/scoped_ptr.hpp>
19 #include <boost/shared_ptr.hpp>
20 #include <boost/weak_ptr.hpp>
21 #include <boost/intrusive_ptr.hpp>
22 
24 namespace zypp
25 {
26 
43 
75  struct NullDeleter
76  {
77  void operator()( const void *const ) const
78  {}
79  };
80 
82  using boost::scoped_ptr;
83 
85  using boost::shared_ptr;
86 
88  using boost::weak_ptr;
89 
91  using boost::intrusive_ptr;
92 
94  using boost::static_pointer_cast;
96  using boost::const_pointer_cast;
98  using boost::dynamic_pointer_cast;
99 
101 } // namespace zypp
104 namespace std
105 {
106 
107  // namespace sub {
108  // class Foo;
109  // typedef zypp::intrusive_ptr<Foo> Foo_Ptr; // see DEFINE_PTR_TYPE(NAME) macro below
110  // }
111 
112  // Defined in namespace std g++ finds the output operator (König-Lookup),
113  // even if we typedef the pointer in a different namespace than ::zypp.
114  // Otherwise we had to define an output operator always in the same namespace
115  // as the typedef (else g++ will just print the pointer value).
116 
118  template<class _D>
119  inline std::ostream & operator<<( std::ostream & str, const zypp::shared_ptr<_D> & obj )
120  {
121  if ( obj )
122  return str << *obj;
123  return str << std::string("NULL");
124  }
126  template<class _D>
127  inline std::ostream & dumpOn( std::ostream & str, const zypp::shared_ptr<_D> & obj )
128  {
129  if ( obj )
130  return dumpOn( str, *obj );
131  return str << std::string("NULL");
132  }
133 
135  template<class _D>
136  inline std::ostream & operator<<( std::ostream & str, const zypp::intrusive_ptr<_D> & obj )
137  {
138  if ( obj )
139  return str << *obj;
140  return str << std::string("NULL");
141  }
143  template<class _D>
144  inline std::ostream & dumpOn( std::ostream & str, const zypp::intrusive_ptr<_D> & obj )
145  {
146  if ( obj )
147  return dumpOn( str, *obj );
148  return str << std::string("NULL");
149  }
151 } // namespace std
154 namespace zypp
155 {
156 
158  //
159  // RW_pointer traits
160  //
162 
167  namespace rw_pointer {
168 
169  template<class _D>
170  struct Shared
171  {
172  typedef shared_ptr<_D> _Ptr;
173  typedef shared_ptr<const _D> _constPtr;
175  bool unique( const _constPtr & ptr_r )
176  { return !ptr_r || ptr_r.unique(); }
177  bool unique( const _Ptr & ptr_r )
178  { return !ptr_r || ptr_r.unique(); }
180  long use_count( const _constPtr & ptr_r ) const
181  { return ptr_r.use_count(); }
182  long use_count( const _Ptr & ptr_r ) const
183  { return ptr_r.use_count(); }
184  };
185 
186  template<class _D>
187  struct Intrusive
188  {
189  typedef intrusive_ptr<_D> _Ptr;
190  typedef intrusive_ptr<const _D> _constPtr;
192  bool unique( const _constPtr & ptr_r )
193  { return !ptr_r || (ptr_r->refCount() <= 1); }
194  bool unique( const _Ptr & ptr_r )
195  { return !ptr_r || (ptr_r->refCount() <= 1); }
197  long use_count( const _constPtr & ptr_r ) const
198  { return ptr_r ? ptr_r->refCount() : 0; }
199  long use_count( const _Ptr & ptr_r ) const
200  { return ptr_r ? ptr_r->refCount() : 0; }
201  };
202 
203  template<class _D>
204  struct Scoped
205  {
206  typedef scoped_ptr<_D> _Ptr;
207  typedef scoped_ptr<const _D> _constPtr;
209  bool unique( const _constPtr & ptr_r )
210  { return true; }
211  bool unique( const _Ptr & ptr_r )
212  { return true; }
214  long use_count( const _constPtr & ptr_r ) const
215  { return ptr_r ? 1 : 0; }
216  long use_count( const _Ptr & ptr_r ) const
217  { return ptr_r ? 1 : 0; }
218  };
219 
220  }
222 
224  //
225  // CLASS NAME : RW_pointer
226  //
264  template<class _D, class _Traits = rw_pointer::Shared<_D> >
265  struct RW_pointer
266  {
267  typedef typename _Traits::_Ptr _Ptr;
268  typedef typename _Traits::_constPtr _constPtr;
269  typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
270 
271  explicit
272  RW_pointer( typename _Ptr::element_type * dptr = 0 )
273  : _dptr( dptr )
274  {}
275 
276  explicit
277  RW_pointer( _Ptr dptr )
278  : _dptr( dptr )
279  {}
280 
281  void reset()
282  { _Ptr().swap( _dptr ); }
283 
284  void reset( typename _Ptr::element_type * dptr )
285  { _Ptr( dptr ).swap( _dptr ); }
286 
287  void swap( RW_pointer & rhs )
288  { _dptr.swap( rhs._dptr ); }
289 
290  void swap( _Ptr & rhs )
291  { _dptr.swap( rhs ); }
292 
293  operator unspecified_bool_type() const
294  { return _dptr; }
295 
296  const _D & operator*() const
297  { return *_dptr; };
298 
299  const _D * operator->() const
300  { return _dptr.operator->(); }
301 
302  const _D * get() const
303  { return _dptr.get(); }
304 
305  _D & operator*()
306  { return *_dptr; }
307 
308  _D * operator->()
309  { return _dptr.operator->(); }
310 
311  _D * get()
312  { return _dptr.get(); }
313 
314  public:
315  bool unique() const
316  { return _Traits().unique( _dptr ); }
317 
318  long use_count() const
319  { return _Traits().use_count( _dptr ); }
320 
322  { return _dptr; }
323 
325  { return _dptr; }
326 
328  { return _dptr; }
329 
330  private:
332  };
334 
340  template<class _D, class _Ptr>
341  inline std::ostream & operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
342  {
343  if ( obj.get() )
344  return str << *obj.get();
345  return str << std::string("NULL");
346  }
347 
349  template<class _D, class _Ptr>
350  inline bool operator==( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
351  { return( lhs.get() == rhs.get() ); }
353  template<class _D, class _Ptr>
354  inline bool operator==( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs )
355  { return( lhs.get() == rhs.get() ); }
357  template<class _D, class _Ptr>
358  inline bool operator==( const typename _Ptr::_Ptr & lhs, const RW_pointer<_D, _Ptr> & rhs )
359  { return( lhs.get() == rhs.get() ); }
361  template<class _D, class _Ptr>
362  inline bool operator==( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs )
363  { return( lhs.get() == rhs.get() ); }
365  template<class _D, class _Ptr>
366  inline bool operator==( const typename _Ptr::_constPtr & lhs, const RW_pointer<_D, _Ptr> & rhs )
367  { return( lhs.get() == rhs.get() ); }
368 
369 
371  template<class _D, class _Ptr>
372  inline bool operator!=( const RW_pointer<_D, _Ptr> & lhs, const RW_pointer<_D, _Ptr> & rhs )
373  { return ! ( lhs == rhs ); }
375  template<class _D, class _Ptr>
376  inline bool operator!=( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs )
377  { return ! ( lhs == rhs ); }
379  template<class _D, class _Ptr>
380  inline bool operator!=( const typename _Ptr::_Ptr & lhs, const RW_pointer<_D, _Ptr> & rhs )
381  { return ! ( lhs == rhs ); }
383  template<class _D, class _Ptr>
384  inline bool operator!=( const RW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs )
385  { return ! ( lhs == rhs ); }
387  template<class _D, class _Ptr>
388  inline bool operator!=( const typename _Ptr::_constPtr & lhs, const RW_pointer<_D, _Ptr> & rhs )
389  { return ! ( lhs == rhs ); }
390 
392 
398  template<class _D>
399  inline _D * rwcowClone( const _D * rhs )
400  { return rhs->clone(); }
401 
403  //
404  // CLASS NAME : RWCOW_pointer
405  //
413  template<class _D, class _Traits = rw_pointer::Shared<_D> >
415  {
416  typedef typename _Traits::_Ptr _Ptr;
417  typedef typename _Traits::_constPtr _constPtr;
418  typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
419 
420  explicit
421  RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
422  : _dptr( dptr )
423  {}
424 
425  explicit
427  : _dptr( dptr )
428  {}
429 
430  void reset()
431  { _Ptr().swap( _dptr ); }
432 
433  void reset( typename _Ptr::element_type * dptr )
434  { _Ptr( dptr ).swap( _dptr ); }
435 
436  void swap( RWCOW_pointer & rhs )
437  { _dptr.swap( rhs._dptr ); }
438 
439  void swap( _Ptr & rhs )
440  { _dptr.swap( rhs ); }
441 
442  operator unspecified_bool_type() const
443  { return _dptr; }
444 
445  const _D & operator*() const
446  { return *_dptr; };
447 
448  const _D * operator->() const
449  { return _dptr.operator->(); }
450 
451  const _D * get() const
452  { return _dptr.get(); }
453 
454  _D & operator*()
455  { assertUnshared(); return *_dptr; }
456 
457  _D * operator->()
458  { assertUnshared(); return _dptr.operator->(); }
459 
460  _D * get()
461  { assertUnshared(); return _dptr.get(); }
462 
463  public:
464  bool unique() const
465  { return _Traits().unique( _dptr ); }
466 
467  long use_count() const
468  { return _Traits().use_count( _dptr ); }
469 
471  { return _dptr; }
472 
474  { assertUnshared(); return _dptr; }
475 
477  { return _dptr; }
478 
479  private:
480 
482  {
483  if ( !unique() )
484  _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr );
485  }
486 
487  private:
489  };
491 
497  template<class _D, class _Ptr>
498  inline std::ostream & operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
499  {
500  if ( obj.get() )
501  return str << *obj.get();
502  return str << std::string("NULL");
503  }
504 
506  template<class _D, class _Ptr>
507  inline bool operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
508  { return( lhs.get() == rhs.get() ); }
510  template<class _D, class _Ptr>
511  inline bool operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs )
512  { return( lhs.get() == rhs.get() ); }
514  template<class _D, class _Ptr>
515  inline bool operator==( const typename _Ptr::_Ptr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
516  { return( lhs.get() == rhs.get() ); }
518  template<class _D, class _Ptr>
519  inline bool operator==( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs )
520  { return( lhs.get() == rhs.get() ); }
522  template<class _D, class _Ptr>
523  inline bool operator==( const typename _Ptr::_constPtr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
524  { return( lhs.get() == rhs.get() ); }
525 
527  template<class _D, class _Ptr>
528  inline bool operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
529  { return ! ( lhs == rhs ); }
531  template<class _D, class _Ptr>
532  inline bool operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_Ptr & rhs )
533  { return ! ( lhs == rhs ); }
535  template<class _D, class _Ptr>
536  inline bool operator!=( const typename _Ptr::_Ptr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
537  { return ! ( lhs == rhs ); }
539  template<class _D, class _Ptr>
540  inline bool operator!=( const RWCOW_pointer<_D, _Ptr> & lhs, const typename _Ptr::_constPtr & rhs )
541  { return ! ( lhs == rhs ); }
543  template<class _D, class _Ptr>
544  inline bool operator!=( const typename _Ptr::_constPtr & lhs, const RWCOW_pointer<_D, _Ptr> & rhs )
545  { return ! ( lhs == rhs ); }
546 
548 
550 
551 } // namespace zypp
553 
555 #define DEFINE_PTR_TYPE(NAME) \
556 class NAME; \
557 extern void intrusive_ptr_add_ref( const NAME * ); \
558 extern void intrusive_ptr_release( const NAME * ); \
559 typedef zypp::intrusive_ptr<NAME> NAME##_Ptr; \
560 typedef zypp::intrusive_ptr<const NAME> NAME##_constPtr;
561 
563 #endif // ZYPP_BASE_PTRTYPES_H