00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00014 #ifndef LOKI_STRONG_PTR_INC_
00015 #define LOKI_STRONG_PTR_INC_
00016
00017
00018
00019
00020 #include <loki/SmartPtr.h>
00021 #if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
00022 #include <loki/Threads.h>
00023 #endif
00024
00025
00111
00112
00113 namespace Loki
00114 {
00115
00116
00125
00126 template < class P >
00127 class DeleteUsingFree
00128 {
00129 public:
00130 inline void static Delete( const P * p )
00131 {
00132 if ( 0 != p )
00133 {
00134 p->~P();
00135 ::free( p );
00136 }
00137 }
00138
00140 inline static P * Default( void )
00141 {
00142 return 0;
00143 }
00144
00145 inline void Swap( DeleteUsingFree & ) {}
00146 };
00147
00156
00157 template < class P >
00158 class DeleteNothing
00159 {
00160 public:
00161 inline static void Delete( const P * )
00162 {
00163
00164 }
00165
00166 inline static P * Default( void )
00167 {
00168 return 0;
00169 }
00170
00171 inline void Swap( DeleteNothing & ) {}
00172 };
00173
00181
00182 template < class P >
00183 class DeleteSingle
00184 {
00185 public:
00186 inline static void Delete( const P * p )
00187 {
00193 typedef char Type_Must_Be_Defined[ sizeof(P) ? 1 : -1 ];
00194 delete p;
00195 }
00196
00197 inline static P * Default( void )
00198 {
00199 return 0;
00200 }
00201
00202 inline void Swap( DeleteSingle & ) {}
00203 };
00204
00212
00213 template < class P >
00214 class DeleteArray
00215 {
00216 public:
00217 inline static void Delete( const P * p )
00218 {
00224 typedef char Type_Must_Be_Defined[ sizeof(P) ? 1 : -1 ];
00225 delete [] p;
00226 }
00227
00228 inline static P * Default( void )
00229 {
00230 return 0;
00231 }
00232
00233 inline void Swap( DeleteArray & ) {}
00234 };
00235
00244
00245 template < class P >
00246 struct CantResetWithStrong
00247 {
00248 inline bool OnReleaseAll( bool hasStrongPtr ) const
00249 {
00250 return ! hasStrongPtr;
00251 }
00252
00253 inline bool OnResetAll( bool hasStrongPtr ) const
00254 {
00255 return ! hasStrongPtr;
00256 }
00257 };
00258
00266
00267 template < class P >
00268 struct AllowReset
00269 {
00270 inline bool OnReleaseAll( bool ) const
00271 {
00272 return true;
00273 }
00274 inline bool OnResetAll( bool ) const
00275 {
00276 return true;
00277 }
00278 };
00279
00287
00288 template < class P >
00289 struct NeverReset
00290 {
00291 inline bool OnReleaseAll( bool ) const
00292 {
00293 return false;
00294 }
00295 inline bool OnResetAll( bool ) const
00296 {
00297 return false;
00298 }
00299 };
00300
00301
00302
00303 namespace Private
00304 {
00305
00317
00318 class LOKI_EXPORT TwoRefCountInfo
00319 {
00320 public:
00321
00322 inline explicit TwoRefCountInfo( bool strong )
00323 : m_pointer( 0 )
00324 , m_strongCount( strong ? 1 : 0 )
00325 , m_weakCount( strong ? 0 : 1 )
00326 {
00327 }
00328
00329 inline TwoRefCountInfo( void * p, bool strong )
00330 : m_pointer( p )
00331 , m_strongCount( strong ? 1 : 0 )
00332 , m_weakCount( strong ? 0 : 1 )
00333 {
00334 }
00335
00336 inline ~TwoRefCountInfo( void )
00337 {
00338 assert( 0 == m_strongCount );
00339 assert( 0 == m_weakCount );
00340 }
00341
00342 inline bool HasStrongPointer( void ) const
00343 {
00344 return ( 0 < m_strongCount );
00345 }
00346
00347 inline bool HasWeakPointer( void ) const
00348 {
00349 return ( 0 < m_weakCount );
00350 }
00351
00352 inline void IncStrongCount( void )
00353 {
00354 ++m_strongCount;
00355 }
00356
00357 inline void IncWeakCount( void )
00358 {
00359 ++m_weakCount;
00360 }
00361
00362 inline void DecStrongCount( void )
00363 {
00364 assert( 0 < m_strongCount );
00365 --m_strongCount;
00366 }
00367
00368 inline void DecWeakCount( void )
00369 {
00370 assert( 0 < m_weakCount );
00371 --m_weakCount;
00372 }
00373
00374 inline void ZapPointer( void )
00375 {
00376 m_pointer = 0;
00377 }
00378
00379 void SetPointer( void * p )
00380 {
00381 m_pointer = p;
00382 }
00383
00384 inline void * GetPointer( void ) const
00385 {
00386 return m_pointer;
00387 }
00388
00389 inline void * & GetPointerRef( void ) const
00390 {
00391 return const_cast< void * & >( m_pointer );
00392 }
00393
00394 private:
00396 TwoRefCountInfo( const TwoRefCountInfo & );
00398 TwoRefCountInfo & operator = ( const TwoRefCountInfo & );
00399
00400 void * m_pointer;
00401 unsigned int m_strongCount;
00402 unsigned int m_weakCount;
00403 };
00404
00422
00423 #if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
00424
00425 class LOKI_EXPORT LockableTwoRefCountInfo
00426 : private Loki::Private::TwoRefCountInfo
00427 {
00428 public:
00429
00430 inline explicit LockableTwoRefCountInfo( bool strong )
00431 : TwoRefCountInfo( strong )
00432 , m_Mutex()
00433 {
00434 }
00435
00436 LockableTwoRefCountInfo( void * p, bool strong )
00437 : TwoRefCountInfo( p, strong )
00438 , m_Mutex()
00439 {
00440 }
00441
00442 inline ~LockableTwoRefCountInfo( void )
00443 {
00444 }
00445
00446 inline void Lock( void ) const
00447 {
00448 m_Mutex.Lock();
00449 }
00450
00451 inline void Unlock( void ) const
00452 {
00453 m_Mutex.Unlock();
00454 }
00455
00456 inline bool HasStrongPointer( void ) const
00457 {
00458 m_Mutex.Lock();
00459 const bool has = TwoRefCountInfo::HasStrongPointer();
00460 m_Mutex.Unlock();
00461 return has;
00462 }
00463
00464 inline bool HasWeakPointer( void ) const
00465 {
00466 m_Mutex.Lock();
00467 const bool has = TwoRefCountInfo::HasWeakPointer();
00468 m_Mutex.Unlock();
00469 return has;
00470 }
00471
00472 inline void IncStrongCount( void )
00473 {
00474 m_Mutex.Lock();
00475 TwoRefCountInfo::IncStrongCount();
00476 m_Mutex.Unlock();
00477 }
00478
00479 inline void IncWeakCount( void )
00480 {
00481 m_Mutex.Lock();
00482 TwoRefCountInfo::IncWeakCount();
00483 m_Mutex.Unlock();
00484 }
00485
00486 inline void DecStrongCount( void )
00487 {
00488 m_Mutex.Lock();
00489 TwoRefCountInfo::DecStrongCount();
00490 m_Mutex.Unlock();
00491 }
00492
00493 inline void DecWeakCount( void )
00494 {
00495 m_Mutex.Lock();
00496 TwoRefCountInfo::DecWeakCount();
00497 m_Mutex.Unlock();
00498 }
00499
00500 inline void ZapPointer( void )
00501 {
00502 m_Mutex.Lock();
00503 TwoRefCountInfo::ZapPointer();
00504 m_Mutex.Unlock();
00505 }
00506
00507 void SetPointer( void * p )
00508 {
00509 m_Mutex.Lock();
00510 TwoRefCountInfo::SetPointer( p );
00511 m_Mutex.Unlock();
00512 }
00513
00514 inline void * GetPointer( void ) const
00515 {
00516 return TwoRefCountInfo::GetPointer();
00517 }
00518
00519 inline void * & GetPointerRef( void ) const
00520 {
00521 return TwoRefCountInfo::GetPointerRef();
00522 }
00523
00524 private:
00526 LockableTwoRefCountInfo( void );
00528 LockableTwoRefCountInfo( const LockableTwoRefCountInfo & );
00530 LockableTwoRefCountInfo & operator = ( const LockableTwoRefCountInfo & );
00531
00532 mutable LOKI_DEFAULT_MUTEX m_Mutex;
00533 };
00534
00535 #endif // if object-level-locking or class-level-locking
00536
00537 }
00538
00549
00550 class LOKI_EXPORT TwoRefCounts
00551 {
00552 protected:
00553
00554 explicit TwoRefCounts( bool strong );
00555
00556 TwoRefCounts( const void * p, bool strong );
00557
00558 TwoRefCounts( const TwoRefCounts & rhs, bool strong ) :
00559 m_counts( rhs.m_counts )
00560 {
00561 Increment( strong );
00562 }
00563
00564 inline bool Release( bool strong )
00565 {
00566 return Decrement( strong );
00567 }
00568
00569 void Increment( bool strong );
00570
00571 bool Decrement( bool strong );
00572
00573 bool HasStrongPointer( void ) const
00574 {
00575 return m_counts->HasStrongPointer();
00576 }
00577
00578 void Swap( TwoRefCounts & rhs );
00579
00580 void SetPointer( void * p )
00581 {
00582 m_counts->SetPointer( p );
00583 }
00584
00585 void ZapPointer( void );
00586
00587 inline void * & GetPointerRef( void ) const
00588 {
00589 return m_counts->GetPointerRef();
00590 }
00591
00592 inline void * GetPointer( void ) const
00593 {
00594 return m_counts->GetPointer();
00595 }
00596
00597 private:
00598 TwoRefCounts( void );
00599 TwoRefCounts & operator = ( const TwoRefCounts & );
00600
00602 Loki::Private::TwoRefCountInfo * m_counts;
00603 };
00604
00619
00620 #if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
00621
00622 class LOKI_EXPORT LockableTwoRefCounts
00623 {
00624 typedef SmallValueObject< ::Loki::ClassLevelLockable > ThreadSafePointerAllocator;
00625
00626 protected:
00627
00628 explicit LockableTwoRefCounts( bool strong )
00629 : m_counts( NULL )
00630 {
00631 void * temp = ThreadSafePointerAllocator::operator new(
00632 sizeof(Loki::Private::LockableTwoRefCountInfo) );
00633 #ifdef DO_EXTRA_LOKI_TESTS
00634 assert( temp != 0 );
00635 #endif
00636 m_counts = new ( temp ) Loki::Private::LockableTwoRefCountInfo( strong );
00637 }
00638
00639 LockableTwoRefCounts( const void * p, bool strong )
00640 : m_counts( NULL )
00641 {
00642 void * temp = ThreadSafePointerAllocator::operator new(
00643 sizeof(Loki::Private::LockableTwoRefCountInfo) );
00644 #ifdef DO_EXTRA_LOKI_TESTS
00645 assert( temp != 0 );
00646 #endif
00647 void * p2 = const_cast< void * >( p );
00648 m_counts = new ( temp )
00649 Loki::Private::LockableTwoRefCountInfo( p2, strong );
00650 }
00651
00652 LockableTwoRefCounts( const LockableTwoRefCounts & rhs, bool strong ) :
00653 m_counts( rhs.m_counts )
00654 {
00655 Increment( strong );
00656 }
00657
00658 inline void Lock( void ) const
00659 {
00660 m_counts->Lock();
00661 }
00662
00663 inline void Unlock( void ) const
00664 {
00665 m_counts->Unlock();
00666 }
00667
00668 inline bool Release( bool strong )
00669 {
00670 return Decrement( strong );
00671 }
00672
00673 void Increment( bool strong )
00674 {
00675 if ( strong )
00676 {
00677 m_counts->IncStrongCount();
00678 }
00679 else
00680 {
00681 m_counts->IncWeakCount();
00682 }
00683 }
00684
00685 bool Decrement( bool strong )
00686 {
00687 if ( strong )
00688 {
00689 m_counts->DecStrongCount();
00690 }
00691 else
00692 {
00693 m_counts->DecWeakCount();
00694 }
00695 return !m_counts->HasStrongPointer();
00696 }
00697
00698 bool HasStrongPointer( void ) const
00699 {
00700 return m_counts->HasStrongPointer();
00701 }
00702
00703 void Swap( LockableTwoRefCounts & rhs )
00704 {
00705 std::swap( m_counts, rhs.m_counts );
00706 }
00707
00708 void SetPointer( void * p )
00709 {
00710 m_counts->SetPointer( p );
00711 }
00712
00713 void ZapPointer( void )
00714 {
00715 #ifdef DO_EXTRA_LOKI_TESTS
00716 assert( !m_counts->HasStrongPointer() );
00717 #endif
00718 if ( m_counts->HasWeakPointer() )
00719 {
00720 m_counts->ZapPointer();
00721 }
00722 else
00723 {
00724 ThreadSafePointerAllocator::operator delete ( m_counts,
00725 sizeof(Loki::Private::LockableTwoRefCountInfo) );
00726 m_counts = NULL;
00727 }
00728 }
00729
00730 inline void * GetPointer( void ) const
00731 {
00732 return m_counts->GetPointer();
00733 }
00734
00735 inline void * & GetPointerRef( void ) const
00736 {
00737 return m_counts->GetPointerRef();
00738 }
00739
00740 private:
00741 LockableTwoRefCounts( void );
00742 LockableTwoRefCounts & operator = ( const LockableTwoRefCounts & );
00743
00745 Loki::Private::LockableTwoRefCountInfo * m_counts;
00746 };
00747
00748 #endif // if object-level-locking or class-level-locking
00749
00759
00760 class LOKI_EXPORT TwoRefLinks
00761 {
00762 protected:
00763
00764 inline explicit TwoRefLinks( bool strong )
00765 : m_pointer( 0 )
00766 , m_strong( strong )
00767 {
00768 m_prev = m_next = this;
00769 }
00770
00771 TwoRefLinks( const void * p, bool strong );
00772
00773 TwoRefLinks( const TwoRefLinks & rhs, bool strong );
00774
00775 bool Release( bool strong );
00776
00777 void Swap( TwoRefLinks & rhs );
00778
00779 bool Merge( TwoRefLinks & rhs );
00780
00781 bool HasStrongPointer( void ) const;
00782
00783 inline void ZapPointer( void )
00784 {
00785 ZapAllNodes();
00786 }
00787
00788 void SetPointer( void * p );
00789
00790 inline void * GetPointer( void ) const
00791 {
00792 return m_pointer;
00793 }
00794
00795 inline void * & GetPointerRef( void ) const
00796 {
00797 return const_cast< void * & >( m_pointer );
00798 }
00799
00800 private:
00801 static unsigned int CountPrevCycle( const TwoRefLinks * pThis );
00802 static unsigned int CountNextCycle( const TwoRefLinks * pThis );
00803
00805 TwoRefLinks( void );
00807 TwoRefLinks & operator = ( const TwoRefLinks & );
00808
00809 bool HasPrevNode( const TwoRefLinks * p ) const;
00810 bool HasNextNode( const TwoRefLinks * p ) const;
00811 bool AllNodesHaveSamePointer( void ) const;
00812 void ZapAllNodes( void );
00813
00814 void * m_pointer;
00815 mutable TwoRefLinks * m_prev;
00816 mutable TwoRefLinks * m_next;
00817 const bool m_strong;
00818 };
00819
00833
00834 template
00835 <
00836 typename T,
00837 bool Strong = true,
00838 class OwnershipPolicy = Loki::TwoRefCounts,
00839 class ConversionPolicy = Loki::DisallowConversion,
00840 template < class > class CheckingPolicy = Loki::AssertCheck,
00841 template < class > class ResetPolicy = Loki::CantResetWithStrong,
00842 template < class > class DeletePolicy = Loki::DeleteSingle,
00843 template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
00844 >
00845 class StrongPtr
00846 : public OwnershipPolicy
00847 , public ConversionPolicy
00848 , public CheckingPolicy< T * >
00849 , public ResetPolicy< T >
00850 , public DeletePolicy< T >
00851 {
00852 typedef ConversionPolicy CP;
00853 typedef CheckingPolicy< T * > KP;
00854 typedef ResetPolicy< T > RP;
00855 typedef DeletePolicy< T > DP;
00856
00857 public:
00858
00859 typedef OwnershipPolicy OP;
00860
00861 typedef T * StoredType;
00862 typedef T * PointerType;
00863 typedef T & ReferenceType;
00864
00865 typedef typename ConstnessPolicy< T >::Type * ConstPointerType;
00866 typedef typename ConstnessPolicy< T >::Type & ConstReferenceType;
00867
00868 private:
00869 struct NeverMatched {};
00870
00871 #ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY
00872 typedef typename Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg;
00873 typedef typename Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;
00874 #else
00875 typedef const StoredType& ImplicitArg;
00876 typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
00877 #endif
00878
00879 public:
00880
00881 StrongPtr( void ) : OP( Strong )
00882 {
00883 KP::OnDefault( GetPointer() );
00884 }
00885
00886 explicit StrongPtr( ExplicitArg p ) : OP( p, Strong )
00887 {
00888 KP::OnInit( GetPointer() );
00889 }
00890
00891 StrongPtr( ImplicitArg p ) : OP( p, Strong )
00892 {
00893 KP::OnInit( GetPointer() );
00894 }
00895
00896 StrongPtr( const StrongPtr & rhs )
00897 : OP( rhs, Strong ), CP( rhs ), KP( rhs ), DP( rhs )
00898 {
00899 }
00900
00901 template
00902 <
00903 typename T1,
00904 bool S1,
00905 class OP1,
00906 class CP1,
00907 template < class > class KP1,
00908 template < class > class RP1,
00909 template < class > class DP1,
00910 template < class > class CNP1
00911 >
00912 StrongPtr(
00913 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
00914 : OP( rhs, Strong )
00915 {
00916 }
00917
00918 template
00919 <
00920 typename T1,
00921 bool S1,
00922 class OP1,
00923 class CP1,
00924 template < class > class KP1,
00925 template < class > class RP1,
00926 template < class > class DP1,
00927 template < class > class CNP1
00928 >
00929 StrongPtr(
00930 StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
00931 : OP( rhs, Strong )
00932 {
00933 }
00934
00935 StrongPtr( RefToValue< StrongPtr > rhs )
00936 : OP( rhs, Strong ), KP( rhs ), CP( rhs ), DP( rhs )
00937 {
00938 }
00939
00940 operator RefToValue< StrongPtr >( void )
00941 {
00942 return RefToValue< StrongPtr >( *this );
00943 }
00944
00945 StrongPtr & operator = ( const StrongPtr & rhs )
00946 {
00947 if ( GetPointer() != rhs.GetPointer() )
00948 {
00949 StrongPtr temp( rhs );
00950 temp.Swap( *this );
00951 }
00952 return *this;
00953 }
00954
00955 StrongPtr & operator = ( T * p )
00956 {
00957 if ( GetPointer() != p )
00958 {
00959 StrongPtr temp( p );
00960 Swap( temp );
00961 }
00962 return *this;
00963 }
00964
00965 template
00966 <
00967 typename T1,
00968 bool S1,
00969 class OP1,
00970 class CP1,
00971 template < class > class KP1,
00972 template < class > class RP1,
00973 template < class > class DP1,
00974 template < class > class CNP1
00975 >
00976 StrongPtr & operator = (
00977 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
00978 {
00979 if ( !rhs.Equals( GetPointer() ) )
00980 {
00981 StrongPtr temp( rhs );
00982 temp.Swap( *this );
00983 }
00984 return *this;
00985 }
00986
00987 bool IsStrong( void ) const
00988 {
00989 return Strong;
00990 }
00991
00992 void Swap( StrongPtr & rhs )
00993 {
00994 OP::Swap( rhs );
00995 CP::Swap( rhs );
00996 KP::Swap( rhs );
00997 DP::Swap( rhs );
00998 }
00999
01000 ~StrongPtr()
01001 {
01002 if ( OP::Release( Strong ) )
01003 {
01004
01005
01006
01007
01008
01009 T * p = GetPointer();
01010 if ( p != 0 )
01011 {
01012 OP::ZapPointer();
01013 DP::Delete( p );
01014 }
01015 }
01016 }
01017
01018 #ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
01019
01020
01021 friend bool ReleaseAll( StrongPtr & sp,
01022 typename StrongPtr::StoredType & p )
01023 {
01024 if ( !sp.RP::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
01025 {
01026 return false;
01027 }
01028 p = sp.GetPointer();
01029 sp.OP::SetPointer( sp.DP::Default() );
01030 return true;
01031 }
01032
01033 friend bool ResetAll( StrongPtr & sp,
01034 typename StrongPtr::StoredType p )
01035 {
01036 if ( sp.OP::GetPointer() == p )
01037 {
01038 return true;
01039 }
01040 if ( !sp.RP::OnResetAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
01041 {
01042 return false;
01043 }
01044 sp.DP::Delete( sp.GetPointer() );
01045 sp.OP::SetPointer( p );
01046 return true;
01047 }
01048
01049 #else
01050
01051 template
01052 <
01053 typename T1,
01054 bool S1,
01055 class OP1,
01056 class CP1,
01057 template < class > class KP1,
01058 template < class > class RP1,
01059 template < class > class DP1,
01060 template < class > class CNP1
01061 >
01062 friend bool ReleaseAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
01063 typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType & p );
01064
01065
01066 template
01067 <
01068 typename T1,
01069 bool S1,
01070 class OP1,
01071 class CP1,
01072 template < class > class KP1,
01073 template < class > class RP1,
01074 template < class > class DP1,
01075 template < class > class CNP1
01076 >
01077 friend bool ResetAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
01078 typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType p );
01079
01080 #endif
01081
01082
01087 template
01088 <
01089 typename T1,
01090 bool S1,
01091 class OP1,
01092 class CP1,
01093 template < class > class KP1,
01094 template < class > class RP1,
01095 template < class > class DP1,
01096 template < class > class CNP1
01097 >
01098 bool Merge( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
01099 {
01100 if ( OP::GetPointer() != rhs.OP::GetPointer() )
01101 {
01102 return false;
01103 }
01104 return OP::Merge( rhs );
01105 }
01106
01110 void Lock( void )
01111 {
01112 OP::Lock();
01113 }
01114
01118 void Unlock( void )
01119 {
01120 OP::Unlock();
01121 }
01122
01123 PointerType operator -> ()
01124 {
01125 KP::OnDereference( GetPointer() );
01126 return GetPointer();
01127 }
01128
01129 ConstPointerType operator -> () const
01130 {
01131 KP::OnDereference( GetPointer() );
01132 return GetPointer();
01133 }
01134
01135 ReferenceType operator * ()
01136 {
01137 KP::OnDereference( GetPointer() );
01138 return * GetPointer();
01139 }
01140
01141 ConstReferenceType operator * () const
01142 {
01143 KP::OnDereference( GetPointer() );
01144 return * GetPointer();
01145 }
01146
01148 template < class T1 >
01149 bool Equals( const T1 * p ) const
01150 {
01151 return ( GetPointer() == p );
01152 }
01153
01155 template < class T1 >
01156 bool LessThan( const T1 * p ) const
01157 {
01158 return ( GetPointer() < p );
01159 }
01160
01162 template < class T1 >
01163 bool GreaterThan( const T1 * p ) const
01164 {
01165 return ( GetPointer() > p );
01166 }
01167
01169 template
01170 <
01171 typename T1,
01172 bool S1,
01173 class OP1,
01174 class CP1,
01175 template < class > class KP1,
01176 template < class > class RP1,
01177 template < class > class DP1,
01178 template < class > class CNP1
01179 >
01180 bool operator == (
01181 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
01182 {
01183 return ( rhs.Equals( GetPointer() ) );
01184 }
01185
01187 template
01188 <
01189 typename T1,
01190 bool S1,
01191 class OP1,
01192 class CP1,
01193 template < class > class KP1,
01194 template < class > class RP1,
01195 template < class > class DP1,
01196 template < class > class CNP1
01197 >
01198 bool operator != (
01199 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
01200 {
01201 return !( rhs.Equals( GetPointer() ) );
01202 }
01203
01205 template
01206 <
01207 typename T1,
01208 bool S1,
01209 class OP1,
01210 class CP1,
01211 template < class > class KP1,
01212 template < class > class RP1,
01213 template < class > class DP1,
01214 template < class > class CNP1
01215 >
01216 bool operator < (
01217 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
01218 {
01219 return ( rhs.GreaterThan( GetPointer() ) );
01220 }
01221
01223 template
01224 <
01225 typename T1,
01226 bool S1,
01227 class OP1,
01228 class CP1,
01229 template < class > class KP1,
01230 template < class > class RP1,
01231 template < class > class DP1,
01232 template < class > class CNP1
01233 >
01234 inline bool operator > (
01235 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
01236 {
01237 return ( rhs.LessThan( GetPointer() ) );
01238 }
01239
01241 template
01242 <
01243 typename T1,
01244 bool S1,
01245 class OP1,
01246 class CP1,
01247 template < class > class KP1,
01248 template < class > class RP1,
01249 template < class > class DP1,
01250 template < class > class CNP1
01251 >
01252 inline bool operator <= (
01253 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
01254 {
01255 return !( rhs.LessThan( GetPointer() ) );
01256 }
01257
01259 template
01260 <
01261 typename T1,
01262 bool S1,
01263 class OP1,
01264 class CP1,
01265 template < class > class KP1,
01266 template < class > class RP1,
01267 template < class > class DP1,
01268 template < class > class CNP1
01269 >
01270 inline bool operator >= (
01271 const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) const
01272 {
01273 return !( rhs.GreaterThan( GetPointer() ) );
01274 }
01275
01276 inline bool operator ! () const
01277 {
01278 return ( 0 == OP::GetPointer() );
01279 }
01280
01281 protected:
01282
01283 inline PointerType GetPointer( void )
01284 {
01285 return reinterpret_cast< PointerType >( OP::GetPointer() );
01286 }
01287
01288 inline ConstPointerType GetPointer( void ) const
01289 {
01290 return reinterpret_cast< ConstPointerType >( OP::GetPointer() );
01291 }
01292
01293 private:
01294
01295 inline ReferenceType GetPointerRef( void )
01296 {
01297 return reinterpret_cast< ReferenceType >( OP::GetPointerRef() );
01298 }
01299
01300 inline ConstReferenceType GetPointerRef( void ) const
01301 {
01302 return reinterpret_cast< ConstReferenceType >( OP::GetPointerRef() );
01303 }
01304
01305
01306 struct Tester
01307 {
01308 Tester(int) {}
01309 void dummy() {}
01310 };
01311
01312 typedef void (Tester::*unspecified_boolean_type_)();
01313
01314 typedef typename Select< CP::allow, Tester, unspecified_boolean_type_ >::Result
01315 unspecified_boolean_type;
01316
01317 public:
01318
01319 operator unspecified_boolean_type() const
01320 {
01321 return !*this ? 0 : &Tester::dummy;
01322 }
01323
01324 private:
01325
01326 struct Insipid
01327 {
01328 Insipid(PointerType) {}
01329 };
01330
01331 typedef typename Select< CP::allow, PointerType, Insipid >::Result
01332 AutomaticConversionResult;
01333
01334 public:
01335 operator AutomaticConversionResult() const
01336 {
01337 return GetPointer();
01338 }
01339
01340 };
01341
01342
01343
01344
01345
01346 #ifndef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
01347
01348 template
01349 <
01350 typename U,
01351 typename T,
01352 bool S,
01353 class OP,
01354 class CP,
01355 template < class > class KP,
01356 template < class > class RP,
01357 template < class > class DP,
01358 template < class > class CNP
01359 >
01360 bool ReleaseAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp,
01361 typename StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >::StoredType & p )
01362 {
01363 if ( !sp.RP<T>::OnReleaseAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
01364 {
01365 return false;
01366 }
01367 p = sp.GetPointer();
01368 sp.OP::SetPointer( sp.DP<T>::Default() );
01369 return true;
01370 }
01371
01372 template
01373 <
01374 typename U,
01375 typename T,
01376 bool S,
01377 class OP,
01378 class CP,
01379 template < class > class KP,
01380 template < class > class RP,
01381 template < class > class DP,
01382 template < class > class CNP
01383 >
01384 bool ResetAll( StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & sp,
01385 typename StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >::StoredType p )
01386 {
01387 if ( sp.OP::GetPointer() == p )
01388 {
01389 return true;
01390 }
01391 if ( !sp.RP<T>::OnResetAll( sp.IsStrong() || sp.OP::HasStrongPointer() ) )
01392 {
01393 return false;
01394 }
01395 sp.DP<T>::Delete( sp.GetPointer() );
01396 sp.OP::SetPointer( p );
01397 return true;
01398 }
01399 #endif
01400
01401
01402
01403
01406 template
01407 <
01408 typename U,
01409 typename T,
01410 bool S,
01411 class OP,
01412 class CP,
01413 template < class > class KP,
01414 template < class > class RP,
01415 template < class > class DP,
01416 template < class > class CNP
01417 >
01418 inline bool operator == (
01419 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
01420 {
01421 return ( lhs.Equals( rhs ) );
01422 }
01423
01426 template
01427 <
01428 typename U,
01429 typename T,
01430 bool S,
01431 class OP,
01432 class CP,
01433 template < class > class KP,
01434 template < class > class RP,
01435 template < class > class DP,
01436 template < class > class CNP
01437 >
01438 inline bool operator == ( U * lhs,
01439 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
01440 {
01441 return ( rhs.Equals( lhs ) );
01442 }
01443
01446 template
01447 <
01448 typename U,
01449 typename T,
01450 bool S,
01451 class OP,
01452 class CP,
01453 template < class > class KP,
01454 template < class > class RP,
01455 template < class > class DP,
01456 template < class > class CNP
01457 >
01458 inline bool operator != (
01459 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
01460 {
01461 return !( lhs.Equals( rhs ) );
01462 }
01463
01466 template
01467 <
01468 typename U,
01469 typename T,
01470 bool S,
01471 class OP,
01472 class CP,
01473 template < class > class KP,
01474 template < class > class RP,
01475 template < class > class DP,
01476 template < class > class CNP
01477 >
01478 inline bool operator != ( U * lhs,
01479 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
01480 {
01481 return !( rhs.Equals( lhs ) );
01482 }
01483
01486 template
01487 <
01488 typename U,
01489 typename T,
01490 bool S,
01491 class OP,
01492 class CP,
01493 template < class > class KP,
01494 template < class > class RP,
01495 template < class > class DP,
01496 template < class > class CNP
01497 >
01498 inline bool operator < (
01499 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
01500 {
01501 return ( lhs.LessThan( rhs ) );
01502 }
01503
01506 template
01507 <
01508 typename U,
01509 typename T,
01510 bool S,
01511 class OP,
01512 class CP,
01513 template < class > class KP,
01514 template < class > class RP,
01515 template < class > class DP,
01516 template < class > class CNP
01517 >
01518 inline bool operator < ( U * lhs,
01519 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
01520 {
01521 return ( rhs.GreaterThan( lhs ) );
01522 }
01523
01524
01526 template
01527 <
01528 typename U,
01529 typename T,
01530 bool S,
01531 class OP,
01532 class CP,
01533 template < class > class KP,
01534 template < class > class RP,
01535 template < class > class DP,
01536 template < class > class CNP
01537 >
01538 inline bool operator > (
01539 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
01540 {
01541 return ( lhs.GreaterThan( rhs ) );
01542 }
01543
01546 template
01547 <
01548 typename U,
01549 typename T,
01550 bool S,
01551 class OP,
01552 class CP,
01553 template < class > class KP,
01554 template < class > class RP,
01555 template < class > class DP,
01556 template < class > class CNP
01557 >
01558 inline bool operator > ( U * lhs,
01559 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
01560 {
01561 return ( rhs.LessThan( lhs ) );
01562 }
01563
01566 template
01567 <
01568 typename U,
01569 typename T,
01570 bool S,
01571 class OP,
01572 class CP,
01573 template < class > class KP,
01574 template < class > class RP,
01575 template < class > class DP,
01576 template < class > class CNP
01577 >
01578 inline bool operator <= (
01579 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
01580 {
01581 return !( lhs.GreaterThan( rhs ) );
01582 }
01583
01586 template
01587 <
01588 typename U,
01589 typename T,
01590 bool S,
01591 class OP,
01592 class CP,
01593 template < class > class KP,
01594 template < class > class RP,
01595 template < class > class DP,
01596 template < class > class CNP
01597 >
01598 inline bool operator <= ( U * lhs,
01599 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
01600 {
01601 return !( rhs.LessThan( lhs ) );
01602 }
01603
01606 template
01607 <
01608 typename U,
01609 typename T,
01610 bool S,
01611 class OP,
01612 class CP,
01613 template < class > class KP,
01614 template < class > class RP,
01615 template < class > class DP,
01616 template < class > class CNP
01617 >
01618 inline bool operator >= (
01619 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, U * rhs )
01620 {
01621 return !( lhs.LessThan( rhs ) );
01622 }
01623
01626 template
01627 <
01628 typename U,
01629 typename T,
01630 bool S,
01631 class OP,
01632 class CP,
01633 template < class > class KP,
01634 template < class > class RP,
01635 template < class > class DP,
01636 template < class > class CNP
01637 >
01638 inline bool operator >= ( U * lhs,
01639 const StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs )
01640 {
01641 return !( rhs.GreaterThan( lhs ) );
01642 }
01643
01644 }
01645
01646 namespace std
01647 {
01652 template
01653 <
01654 typename T,
01655 bool S,
01656 class OP,
01657 class CP,
01658 template < class > class KP,
01659 template < class > class RP,
01660 template < class > class DP,
01661 template < class > class CNP
01662 >
01663 struct less< Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > >
01664 : public binary_function<
01665 Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >,
01666 Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >, bool >
01667 {
01668 bool operator () (
01669 const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs,
01670 const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs ) const
01671 {
01672 return ( lhs < rhs );
01673 }
01674 };
01675 }
01676
01678
01679 #endif // end file guardian
01680