libcamgm
PtrTypes.hpp
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
11 #ifndef CA_MGM_BASE_PTRTYPES_H
12 #define CA_MGM_BASE_PTRTYPES_H
13 
14 #include <string>
15 
16 #include <boost/scoped_ptr.hpp>
17 #include <boost/shared_ptr.hpp>
18 #include <boost/weak_ptr.hpp>
19 #include <boost/intrusive_ptr.hpp>
20 
22 namespace ca_mgm
23 {
24 
41 
73  struct NullDeleter
74  {
75  void operator()( const void *const ) const
76  {}
77  };
78 
80  using boost::scoped_ptr;
81 
83  using boost::shared_ptr;
84 
86  using boost::weak_ptr;
87 
89  using boost::intrusive_ptr;
90 
92  using boost::static_pointer_cast;
94  using boost::const_pointer_cast;
96  using boost::dynamic_pointer_cast;
97 
99 } // namespace ca_mgm
102 namespace std
103 {
104 
105  // namespace sub {
106  // class Foo;
107  // typedef ca_mgm::intrusive_ptr<Foo> Foo_Ptr; // see DEFINE_PTR_TYPE(NAME) macro below
108  // }
109 
110  // Defined in namespace std g++ finds the output operator (König-Lookup),
111  // even if we typedef the pointer in a different namespace than ::ca_mgm.
112  // Otherwise we had to define an output operator always in the same namespace
113  // as the typedef (else g++ will just print the pointer value).
114 
116  template<class _D>
117  inline std::ostream & operator<<( std::ostream & str, const ca_mgm::shared_ptr<_D> & obj )
118  {
119  if ( obj )
120  return str << *obj;
121  return str << std::string("NULL");
122  }
124  template<class _D>
125  inline std::ostream & dumpOn( std::ostream & str, const ca_mgm::shared_ptr<_D> & obj )
126  {
127  if ( obj )
128  return dumpOn( str, *obj );
129  return str << std::string("NULL");
130  }
131 
133  template<class _D>
134  inline std::ostream & operator<<( std::ostream & str, const ca_mgm::intrusive_ptr<_D> & obj )
135  {
136  if ( obj )
137  return str << *obj;
138  return str << std::string("NULL");
139  }
141  template<class _D>
142  inline std::ostream & dumpOn( std::ostream & str, const ca_mgm::intrusive_ptr<_D> & obj )
143  {
144  if ( obj )
145  return dumpOn( str, *obj );
146  return str << std::string("NULL");
147  }
149 } // namespace std
152 namespace ca_mgm
153 {
154 
156  //
157  // RW_pointer traits
158  //
160 
165  namespace rw_pointer {
166 
167  template<class _D>
168  struct Shared
169  {
170  typedef shared_ptr<_D> _Ptr;
171  typedef shared_ptr<const _D> _constPtr;
173  bool unique( const _constPtr & ptr_r )
174  { return !ptr_r || ptr_r.unique(); }
175  bool unique( const _Ptr & ptr_r )
176  { return !ptr_r || ptr_r.unique(); }
178  long use_count( const _constPtr & ptr_r ) const
179  { return ptr_r.use_count(); }
180  long use_count( const _Ptr & ptr_r ) const
181  { return ptr_r.use_count(); }
182  };
183 
184  template<class _D>
185  struct Intrusive
186  {
187  typedef intrusive_ptr<_D> _Ptr;
188  typedef intrusive_ptr<const _D> _constPtr;
190  bool unique( const _constPtr & ptr_r )
191  { return !ptr_r || (ptr_r->refCount() <= 1); }
192  bool unique( const _Ptr & ptr_r )
193  { return !ptr_r || (ptr_r->refCount() <= 1); }
195  long use_count( const _constPtr & ptr_r ) const
196  { return ptr_r ? ptr_r->refCount() : 0; }
197  long use_count( const _Ptr & ptr_r ) const
198  { return ptr_r ? ptr_r->refCount() : 0; }
199  };
200 
201  template<class _D>
202  struct Scoped
203  {
204  typedef scoped_ptr<_D> _Ptr;
205  typedef scoped_ptr<const _D> _constPtr;
207  bool unique( const _constPtr & ptr_r )
208  { return true; }
209  bool unique( const _Ptr & ptr_r )
210  { return true; }
212  long use_count( const _constPtr & ptr_r ) const
213  { return ptr_r ? 1 : 0; }
214  long use_count( const _Ptr & ptr_r ) const
215  { return ptr_r ? 1 : 0; }
216  };
217 
218  }
220 
222  //
223  // CLASS NAME : RW_pointer
224  //
262  template<class _D, class _Traits = rw_pointer::Shared<_D> >
263  struct RW_pointer
264  {
265  typedef typename _Traits::_Ptr _Ptr;
266  typedef typename _Traits::_constPtr _constPtr;
267  typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
268 
269  explicit
270  RW_pointer( typename _Ptr::element_type * dptr = 0 )
271  : _dptr( dptr )
272  {}
273 
274  explicit
275  RW_pointer( _Ptr dptr )
276  : _dptr( dptr )
277  {}
278 
279  void reset()
280  { _Ptr().swap( _dptr ); }
281 
282  void reset( typename _Ptr::element_type * dptr )
283  { _Ptr( dptr ).swap( _dptr ); }
284 
285  void swap( RW_pointer & rhs )
286  { _dptr.swap( rhs._dptr ); }
287 
288  void swap( _Ptr & rhs )
289  { _dptr.swap( rhs ); }
290 
291  operator unspecified_bool_type() const
292  { return _dptr; }
293 
294  const _D & operator*() const
295  { return *_dptr; };
296 
297  const _D * operator->() const
298  { return _dptr.get(); }
299 
300  const _D * get() const
301  { return _dptr.get(); }
302 
303  _D & operator*()
304  { return *_dptr; }
305 
306  _D * operator->()
307  { return _dptr.get(); }
308 
309  _D * get()
310  { return _dptr.get(); }
311 
312  public:
313  bool unique() const
314  { return _Traits().unique( _dptr ); }
315 
316  long use_count() const
317  { return _Traits().use_count( _dptr ); }
318 
320  { return _dptr; }
321 
323  { return _dptr; }
324 
325  private:
327  };
329 
335  template<class _D, class _Ptr>
336  inline std::ostream &
337  operator<<( std::ostream & str, const RW_pointer<_D, _Ptr> & obj )
338  {
339  if ( obj.get() )
340  return str << *obj.get();
341  return str << std::string("NULL");
342  }
343 
345  template<class _D, class _Ptr>
346  inline bool
348  {
349  return( lhs.get() == rhs.get() );
350  }
351 
353  template<class _D, class _Ptr>
354  inline bool
356  {
357  return ! ( lhs == rhs );
358  }
359 
361 
367  template<class _D>
368  inline _D * rwcowClone( const _D * rhs )
369  { return rhs->clone(); }
370 
371 
373  //
374  // CLASS NAME : RWCOW_pointer
375  //
383  template<class _D, class _Traits = rw_pointer::Shared<_D> >
385  {
386  typedef typename _Traits::_Ptr _Ptr;
387  typedef typename _Traits::_constPtr _constPtr;
388  typedef typename _Ptr::unspecified_bool_type unspecified_bool_type;
389 
390  explicit
391  RWCOW_pointer( typename _Ptr::element_type * dptr = 0 )
392  : _dptr( dptr )
393  {}
394 
395  explicit
397  : _dptr( dptr )
398  {}
399 
400  void reset()
401  { _Ptr().swap( _dptr ); }
402 
403  void reset( typename _Ptr::element_type * dptr )
404  { _Ptr( dptr ).swap( _dptr ); }
405 
406  void swap( RWCOW_pointer & rhs )
407  { _dptr.swap( rhs._dptr ); }
408 
409  void swap( _Ptr & rhs )
410  { _dptr.swap( rhs ); }
411 
412  operator unspecified_bool_type() const
413  { return _dptr; }
414 
415  const _D & operator*() const
416  { return *_dptr; };
417 
418  const _D * operator->() const
419  { return _dptr.get(); }
420 
421  const _D * get() const
422  { return _dptr.get(); }
423 
424  _D & operator*()
425  { assertUnshared(); return *_dptr; }
426 
427  _D * operator->()
428  { assertUnshared(); return _dptr.get(); }
429 
430  _D * get()
431  { assertUnshared(); return _dptr.get(); }
432 
433  public:
434  bool unique() const
435  { return _Traits().unique( _dptr ); }
436 
437  long use_count() const
438  { return _Traits().use_count( _dptr ); }
439 
441  { return _dptr; }
442 
444  { assertUnshared(); return _dptr; }
445 
446  private:
447 
449  {
450  if ( !unique() )
451  _Ptr( rwcowClone( _dptr.get() ) ).swap( _dptr );
452  }
453 
454  private:
456  };
458 
464  template<class _D, class _Ptr>
465  inline std::ostream &
466  operator<<( std::ostream & str, const RWCOW_pointer<_D, _Ptr> & obj )
467  {
468  if ( obj.get() )
469  return str << *obj.get();
470  return str << std::string("NULL");
471  }
472 
474  template<class _D, class _Ptr>
475  inline bool
477  {
478  return( lhs.get() == rhs.get() );
479  }
480 
482  template<class _D, class _Ptr>
483  inline bool
485  {
486  return ! ( lhs == rhs );
487  }
488 
490 
492 
493 } // namespace ca_mgm
495 
497 #define DEFINE_PTR_TYPE(NAME) \
498 class NAME; \
499 extern void intrusive_ptr_add_ref( const NAME * ); \
500 extern void intrusive_ptr_release( const NAME * ); \
501 typedef ca_mgm::intrusive_ptr<NAME> NAME##_Ptr; \
502 typedef ca_mgm::intrusive_ptr<const NAME> NAME##_constPtr;
503 
505 #endif // CA_MGM_BASE_PTRTYPES_H