00001 #ifndef OBTSmartPointer_H_
00002 #define OBTSmartPointer_H_
00003
00004 #include "OBT.h"
00005
00006 namespace OBT
00007 {
00015 template< class TPointeeType >
00016 class SmartPointer
00017 {
00018
00019 public:
00020
00021 typedef TPointeeType pointee_type ;
00022
00026 SmartPointer() ;
00027
00031 SmartPointer( TPointeeType* pointer ) ;
00032
00036 SmartPointer( const SmartPointer<TPointeeType>& SmartPointer ) ;
00037
00041 virtual ~SmartPointer() ;
00042
00049 const SmartPointer<TPointeeType>& operator=( const SmartPointer<TPointeeType>& pointer ) ;
00050
00056 TPointeeType* operator->() const ;
00057
00064 TPointeeType& operator*() const ;
00065
00071 bool operator!() const ;
00072
00076 operator TPointeeType*() ;
00077
00081 operator void*() ;
00082
00092 template< class TTo, class TFrom >
00093 friend const SmartPointer< TTo >& staticCast( const SmartPointer< TFrom >& from ) ;
00094
00102 template< class TTo, class TFrom >
00103 friend SmartPointer< TTo >& constCast( const SmartPointer< TFrom >& from ) ;
00104
00116 template <class TPointeeType, class U>
00117 friend bool operator==( const SmartPointer<TPointeeType>& lhs, const U* rhs ) ;
00118
00124 template <class U, class TPointeeType>
00125 friend bool operator==( const U* lhs, const SmartPointer<TPointeeType>& rhs ) ;
00126
00131 template <class U>
00132 bool operator==( const SmartPointer<U>& rhs ) const;
00133
00139 template <class U>
00140 friend bool operator!=( const SmartPointer<TPointeeType>& lhs, const U* rhs ) ;
00141
00147 template <class U>
00148 friend bool operator!=( const U* lhs, const SmartPointer<TPointeeType>& rhs ) ;
00149
00154 template <class U>
00155 bool operator!=( const SmartPointer<U>& rhs ) const ;
00157
00178 friend bool operator==( const SmartPointer<TPointeeType>& lhs, const TPointeeType* rhs )
00179 {
00180 return lhs._pointee == rhs ;
00181 }
00182
00188 friend bool operator==( const TPointeeType* lhs, const SmartPointer<TPointeeType>& rhs )
00189 {
00190 return lhs == rhs._pointee ;
00191 }
00192
00198 friend bool operator!=( const SmartPointer<TPointeeType>& lhs, const TPointeeType* rhs )
00199 {
00200 return lhs._pointee != rhs ;
00201 }
00202
00208 friend bool operator!=( const TPointeeType* lhs, const SmartPointer<TPointeeType>& rhs )
00209 {
00210 return lhs != rhs._pointee ;
00211 }
00213
00214
00219 unsigned int getReferenceCount() const ;
00220
00221 private:
00222
00228 SmartPointer( TPointeeType* pointer, unsigned long instance ) ;
00229
00233 void increaseCounter() ;
00234
00238 void decreaseCounter() ;
00239
00249 unsigned int* _referenceCounter ;
00250
00252 TPointeeType* _pointee ;
00253 } ;
00254
00255
00256
00257
00258 template< class TPointeeType >
00259 SmartPointer<TPointeeType>::SmartPointer()
00260 :
00261 _referenceCounter( NULL ),
00262 _pointee( NULL )
00263 {
00264 increaseCounter() ;
00265 }
00266
00267
00268
00269
00270 template< class TPointeeType >
00271 SmartPointer<TPointeeType>::SmartPointer( TPointeeType* pointer )
00272 :
00273 _referenceCounter( NULL ),
00274 _pointee( pointer )
00275 {
00276 increaseCounter() ;
00277 }
00278
00279
00280
00281
00282 template< class TPointeeType >
00283 SmartPointer<TPointeeType>::SmartPointer( const SmartPointer<TPointeeType>& SmartPointer )
00284 :
00285
00286 _referenceCounter( NULL ),
00287 _pointee( NULL )
00288 {
00289 *this = SmartPointer ;
00290 }
00291
00292
00293
00294
00295 template< class TPointeeType >
00296 SmartPointer<TPointeeType>::~SmartPointer()
00297 {
00298 decreaseCounter() ;
00299 _pointee = NULL ;
00300 _referenceCounter = NULL ;
00301 }
00302
00303
00304
00305
00306 template< class TPointeeType >
00307 inline const SmartPointer<TPointeeType>&
00308 SmartPointer<TPointeeType>::operator=( const SmartPointer<TPointeeType>& pointer )
00309 {
00310 if ( this != &pointer )
00311 {
00312
00313
00314 decreaseCounter() ;
00315
00316 _referenceCounter = pointer._referenceCounter ;
00317
00318 _pointee = pointer._pointee ;
00319 increaseCounter() ;
00320 }
00321 return( *this ) ;
00322 }
00323
00324
00325
00326
00327 template< class TPointeeType >
00328 TPointeeType*
00329 SmartPointer<TPointeeType>::operator->() const
00330 {
00331 return _pointee ;
00332 }
00333
00334
00335
00336
00337 template< class TPointeeType >
00338 inline void
00339 SmartPointer<TPointeeType>::increaseCounter()
00340 {
00341 if ( _referenceCounter == NULL )
00342 {
00343
00344 _referenceCounter = new unsigned int( 0 ) ;
00345 }
00346 ++*_referenceCounter ;
00347 }
00348
00349
00350
00351
00352 template< class TPointeeType >
00353 inline void
00354 SmartPointer<TPointeeType>::decreaseCounter()
00355 {
00356 if ( _referenceCounter != NULL )
00357 {
00358 --*_referenceCounter ;
00359
00360 if ( *_referenceCounter == 0 )
00361 {
00362 delete _pointee ;
00363 delete _referenceCounter ;
00364 }
00365 }
00366 }
00367
00368
00369
00370
00371 template< class TTo, class TFrom >
00372 inline SmartPointer< TTo >&
00373 ConstCast( const SmartPointer< TFrom >& from )
00374 {
00375 return const_cast<SmartPointer< TTo >&>( reinterpret_cast<const SmartPointer< TTo >&>( from ) ) ;
00376 }
00377
00378
00379
00380
00381 template< class TTo, class TFrom >
00382 inline const SmartPointer< TTo >&
00383 StaticCast( const SmartPointer< TFrom >& from )
00384 {
00385 return reinterpret_cast<const SmartPointer< TTo >&>( from ) ;
00386 }
00387
00388
00389
00390
00391 template< class TPointeeType >
00392 inline TPointeeType&
00393 SmartPointer<TPointeeType>::operator*() const
00394 {
00395 return *_pointee ;
00396 }
00397
00398
00399
00400
00401 template< class TPointeeType >
00402 inline bool
00403 SmartPointer<TPointeeType>::operator!() const
00404 {
00405 return !_pointee ;
00406 }
00407
00408
00409
00410
00411 template <class TPointeeType, class U>
00412 inline bool
00413 operator==( const SmartPointer<TPointeeType>& lhs, const U* rhs )
00414 {
00415 return lhs._pointee == rhs ;
00416 }
00417
00418
00419
00420
00421 template <class U, class TPointeeType>
00422 inline bool
00423 operator==( const U* lhs, const SmartPointer<TPointeeType>& rhs )
00424 {
00425 return lhs == rhs._pointee ;
00426 }
00427
00428
00429
00430
00431 template <class TPointeeType>
00432 template <class U>
00433 inline bool
00434 SmartPointer<TPointeeType>::operator==( const SmartPointer<U>& rhs ) const
00435 {
00436 return _pointee == rhs._pointee ;
00437 }
00438
00439
00440
00441
00442 template <class TPointeeType, class U>
00443 inline bool operator!=( const SmartPointer<TPointeeType>& lhs, const U* rhs )
00444 {
00445 return lhs._pointee != rhs ;
00446 }
00447
00448
00449
00450
00451 template <class U, class TPointeeType>
00452 inline bool operator!=( const U* lhs, const SmartPointer<TPointeeType>& rhs )
00453 {
00454 return lhs != rhs._pointee ;
00455 }
00456
00457
00458
00459
00460 template <class TPointeeType>
00461 template <class U> bool
00462 inline
00463 SmartPointer<TPointeeType>::operator!=( const SmartPointer<U>& rhs ) const
00464 {
00465 return _pointee != rhs._pointee ;
00466 }
00467
00468
00469
00470
00471 template <class TPointeeType>
00472 inline
00473 SmartPointer<TPointeeType>::operator TPointeeType*()
00474 {
00475 return _pointee ;
00476 }
00477
00478
00479
00480
00481 template <class TPointeeType>
00482 inline
00483 SmartPointer<TPointeeType>::operator void*()
00484 {
00485 return _pointee ;
00486 }
00487
00488
00489
00490
00491 template <class TPointeeType>
00492 inline unsigned int
00493 SmartPointer<TPointeeType>::getReferenceCount() const
00494 {
00495 return *_referenceCounter ;
00496 }
00497 }
00498
00499 #endif