|
From: <ric...@us...> - 2008-11-10 06:00:03
|
Revision: 904
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=904&view=rev
Author: rich_sposato
Date: 2008-11-10 05:59:59 +0000 (Mon, 10 Nov 2008)
Log Message:
-----------
Fixed variation of bug 2022935 by changing when functions check if strong-count is zero.
Modified Paths:
--------------
trunk/include/loki/StrongPtr.h
Modified: trunk/include/loki/StrongPtr.h
===================================================================
--- trunk/include/loki/StrongPtr.h 2008-11-10 05:55:12 UTC (rev 903)
+++ trunk/include/loki/StrongPtr.h 2008-11-10 05:59:59 UTC (rev 904)
@@ -3,12 +3,12 @@
// Copyright (c) 2006 Rich Sposato
// The copyright on this file is protected under the terms of the MIT license.
//
-// Permission to use, copy, modify, distribute and sell this software for any
-// purpose is hereby granted without fee, provided that the above copyright
-// notice appear in all copies and that both that copyright notice and this
+// Permission to use, copy, modify, distribute and sell this software for any
+// purpose is hereby granted without fee, provided that the above copyright
+// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
-// The author makes no representations about the
-// suitability of this software for any purpose. It is provided "as is"
+// The author makes no representations about the
+// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_STRONG_PTR_INC_
@@ -117,7 +117,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class DeleteUsingFree
///
-/// \ingroup StrongPointerDeleteGroup
+/// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. Uses explicit call
/// to T's destructor followed by call to free. This policy is useful for
/// managing the lifetime of pointers to structs returned by C functions.
@@ -148,7 +148,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class DeleteNothing
///
-/// \ingroup StrongPointerDeleteGroup
+/// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. This will never
/// delete anything. You can use this policy with pointers to an undefined
/// type or a pure interface class with a protected destructor.
@@ -174,7 +174,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class DeleteSingle
///
-/// \ingroup StrongPointerDeleteGroup
+/// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. This deletes just
/// one shared object. This is the default class for the DeletePolicy.
////////////////////////////////////////////////////////////////////////////////
@@ -205,7 +205,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class DeleteArray
///
-/// \ingroup StrongPointerDeleteGroup
+/// \ingroup StrongPointerDeleteGroup
/// Implementation of the DeletePolicy used by StrongPtr. This deletes an
/// array of shared objects.
////////////////////////////////////////////////////////////////////////////////
@@ -236,7 +236,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class CantResetWithStrong
///
-/// \ingroup StrongPointerResetGroup
+/// \ingroup StrongPointerResetGroup
/// Implementation of the ResetPolicy used by StrongPtr. This is the default
/// ResetPolicy for StrongPtr. It forbids reset and release only if a strong
/// copointer exists.
@@ -259,7 +259,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class AllowReset
///
-/// \ingroup StrongPointerResetGroup
+/// \ingroup StrongPointerResetGroup
/// Implementation of the ResetPolicy used by StrongPtr. It allows reset and
/// release under any circumstance.
////////////////////////////////////////////////////////////////////////////////
@@ -280,7 +280,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class NeverReset
///
-/// \ingroup StrongPointerResetGroup
+/// \ingroup StrongPointerResetGroup
/// Implementation of the ResetPolicy used by StrongPtr. It forbids reset and
/// release under any circumstance.
////////////////////////////////////////////////////////////////////////////////
@@ -359,10 +359,12 @@
++m_weakCount;
}
- inline void DecStrongCount( void )
+ inline bool DecStrongCount( void )
{
assert( 0 < m_strongCount );
--m_strongCount;
+ const bool isZero = ( 0 == m_strongCount );
+ return isZero;
}
inline void DecWeakCount( void )
@@ -483,11 +485,12 @@
m_Mutex.Unlock();
}
- inline void DecStrongCount( void )
+ inline bool DecStrongCount( void )
{
m_Mutex.Lock();
- TwoRefCountInfo::DecStrongCount();
+ const bool isZero = TwoRefCountInfo::DecStrongCount();
m_Mutex.Unlock();
+ return isZero;
}
inline void DecWeakCount( void )
@@ -572,10 +575,6 @@
return Decrement( strong );
}
- void Increment( bool strong );
-
- bool Decrement( bool strong );
-
bool HasStrongPointer( void ) const
{
return m_counts->HasStrongPointer();
@@ -604,6 +603,10 @@
TwoRefCounts( void );
TwoRefCounts & operator = ( const TwoRefCounts & );
+ void Increment( bool strong );
+
+ bool Decrement( bool strong );
+
/// Pointer to all shared data.
Loki::Private::TwoRefCountInfo * m_counts;
};
@@ -696,15 +699,17 @@
bool Decrement( bool strong )
{
+ bool noStrongPointers = false;
if ( strong )
{
- m_counts->DecStrongCount();
+ noStrongPointers = m_counts->DecStrongCount();
}
else
{
m_counts->DecWeakCount();
+ noStrongPointers = !m_counts->HasStrongPointer();
}
- return !m_counts->HasStrongPointer();
+ return noStrongPointers;
}
bool HasStrongPointer( void ) const
@@ -832,7 +837,7 @@
////////////////////////////////////////////////////////////////////////////////
/// \class StrongPtr
///
-/// \ingroup SmartPointerGroup
+/// \ingroup SmartPointerGroup
///
/// \param Strong default = true,
/// \param OwnershipPolicy default = TwoRefCounts,
@@ -855,7 +860,7 @@
template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
>
class StrongPtr
- : public OwnershipPolicy
+ : protected OwnershipPolicy
, public ConversionPolicy
, public CheckingPolicy< T * >
, public ResetPolicy< T >
@@ -1059,7 +1064,7 @@
}
#else
-
+
template
<
typename T1,
@@ -1073,8 +1078,8 @@
>
friend bool ReleaseAll( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & sp,
typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::StoredType & p );
-
+
template
<
typename T1,
@@ -1320,7 +1325,7 @@
Tester(int) {}
void dummy() {}
};
-
+
typedef void (Tester::*unspecified_boolean_type_)();
typedef typename Select< CP::allow, Tester, unspecified_boolean_type_ >::Result
@@ -1339,11 +1344,11 @@
{
Insipid(PointerType) {}
};
-
+
typedef typename Select< CP::allow, PointerType, Insipid >::Result
AutomaticConversionResult;
-public:
+public:
operator AutomaticConversionResult() const
{
return GetPointer();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2008-12-19 00:39:31
|
Revision: 914
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=914&view=rev
Author: rich_sposato
Date: 2008-12-19 00:39:29 +0000 (Fri, 19 Dec 2008)
Log Message:
-----------
Corrected inheritance for ownership policy.
Modified Paths:
--------------
trunk/include/loki/StrongPtr.h
Modified: trunk/include/loki/StrongPtr.h
===================================================================
--- trunk/include/loki/StrongPtr.h 2008-12-15 22:23:44 UTC (rev 913)
+++ trunk/include/loki/StrongPtr.h 2008-12-19 00:39:29 UTC (rev 914)
@@ -860,7 +860,7 @@
template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
>
class StrongPtr
- : protected OwnershipPolicy
+ : public OwnershipPolicy
, public ConversionPolicy
, public CheckingPolicy< T * >
, public ResetPolicy< T >
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <syn...@us...> - 2009-11-21 10:31:54
|
Revision: 1058
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1058&view=rev
Author: syntheticpp
Date: 2009-11-21 10:31:47 +0000 (Sat, 21 Nov 2009)
Log Message:
-----------
seems this was removed by accident
Modified Paths:
--------------
trunk/include/loki/StrongPtr.h
Modified: trunk/include/loki/StrongPtr.h
===================================================================
--- trunk/include/loki/StrongPtr.h 2009-11-20 06:37:12 UTC (rev 1057)
+++ trunk/include/loki/StrongPtr.h 2009-11-21 10:31:47 UTC (rev 1058)
@@ -1,4 +1,4 @@
-////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2006 Rich Sposato
// The copyright on this file is protected under the terms of the MIT license.
@@ -1778,4 +1778,36 @@
namespace std
{
////////////////////////////////////////////////////////////////////////////////
- /// specialization of std::less for StroeTracker@Private@Loki@@@std@@@std@@QBEXABV123@@Z |
|
From: <ric...@us...> - 2010-09-16 17:28:59
|
Revision: 1077
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1077&view=rev
Author: rich_sposato
Date: 2010-09-16 17:28:52 +0000 (Thu, 16 Sep 2010)
Log Message:
-----------
Used initialization instead of assignment within constructor.
Modified Paths:
--------------
trunk/include/loki/StrongPtr.h
Modified: trunk/include/loki/StrongPtr.h
===================================================================
--- trunk/include/loki/StrongPtr.h 2010-09-16 17:26:29 UTC (rev 1076)
+++ trunk/include/loki/StrongPtr.h 2010-09-16 17:28:52 UTC (rev 1077)
@@ -22,7 +22,12 @@
#include <loki/Threads.h>
#endif
+#if defined( _MSC_VER )
+ #pragma warning( push )
+ #pragma warning( disable: 4355 )
+#endif
+
////////////////////////////////////////////////////////////////////////////////
///
/// \par Terminology
@@ -801,8 +806,9 @@
inline explicit TwoRefLinks( bool strong )
: m_pointer( 0 )
, m_strong( strong )
+ , m_prev( this )
+ , m_next( this )
{
- m_prev = m_next = this;
}
TwoRefLinks( const void * p, bool strong );
@@ -1808,5 +1814,8 @@
////////////////////////////////////////////////////////////////////////////////
+#if defined( _MSC_VER )
+ #pragma warning( pop )
+#endif
+
#endif // end file guardian
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ric...@us...> - 2010-10-30 03:09:32
|
Revision: 1079
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1079&view=rev
Author: rich_sposato
Date: 2010-10-30 03:09:25 +0000 (Sat, 30 Oct 2010)
Log Message:
-----------
Added 3 new policy classes to support single-owner smart
pointers. Changed how ResetPolicy classes get called.
Modified Paths:
--------------
trunk/include/loki/StrongPtr.h
Modified: trunk/include/loki/StrongPtr.h
===================================================================
--- trunk/include/loki/StrongPtr.h 2010-09-16 17:32:24 UTC (rev 1078)
+++ trunk/include/loki/StrongPtr.h 2010-10-30 03:09:25 UTC (rev 1079)
@@ -58,9 +58,9 @@
/// -# explicit YourPolicy( bool strong )
/// -# YourPolicy( void * p, bool strong )
/// -# YourPolicy( const YourPolicy & rhs, bool strong )
+/// -# YourPolicy( const YourPolicy & rhs, bool isNull, bool strong )
+/// -# ~YourPolicy( void )
/// -# bool Release( bool strong )
-/// -# void Increment( bool strong )
-/// -# bool Decrement( bool strong )
/// -# bool HasStrongPointer( void ) const
/// -# void Swap( YourPolicy & rhs )
/// -# void SetPointer( void * p )
@@ -100,11 +100,11 @@
///
/// \par Writing Your Own ResetPolicy
/// If you write your own policy, you must implement these 2 functions:
-/// -# bool OnReleaseAll( bool ) const
-/// -# bool OnResetAll( bool ) const
-/// The bool parameter means that this was called with a strong pointer or
-/// one of its copointers is strong. The return value means the pointer
-/// can be reset or released.
+/// -# bool OnReleaseAll( bool, bool ) const
+/// -# bool OnResetAll( bool, bool ) const
+/// The first bool parameter is true if the pointer which called the function
+/// is strong. The second parameter is true if any copointer is strong. The
+/// return value means the pointer can be reset or released.
///
/// \defgroup StrongPointerOwnershipGroup StrongPtr Ownership policies
/// \ingroup SmartPointerGroup
@@ -118,7 +118,10 @@
namespace Loki
{
+static const char * const StrongPtr_Single_Owner_Exception_Message =
+ "Object has more than one Owner - which violates the single owner policy for StrongPtr!";
+
////////////////////////////////////////////////////////////////////////////////
/// \class DeleteUsingFree
///
@@ -250,18 +253,45 @@
template < class P >
struct CantResetWithStrong
{
- inline bool OnReleaseAll( bool hasStrongPtr ) const
+ inline bool OnReleaseAll( bool isThisStrong, bool isAnyStrong ) const
{
- return ! hasStrongPtr;
+ (void)isThisStrong;
+ return ! isAnyStrong;
}
- inline bool OnResetAll( bool hasStrongPtr ) const
+ inline bool OnResetAll( bool isThisStrong, bool isAnyStrong ) const
{
- return ! hasStrongPtr;
+ (void)isThisStrong;
+ return ! isAnyStrong;
}
};
////////////////////////////////////////////////////////////////////////////////
+/// \class OnlyStrongMayReset
+///
+/// \ingroup StrongPointerResetGroup
+/// Implementation of the ResetPolicy used by StrongPtr. It only allows a
+/// a strong co-pointer to reset or release. This policy was made for use with
+/// the single-owner policies.
+////////////////////////////////////////////////////////////////////////////////
+
+template < class P >
+struct OnlyStrongMayReset
+{
+ inline bool OnReleaseAll( bool isThisStrong, bool isAnyStrong ) const
+ {
+ (void)isAnyStrong;
+ return isThisStrong;
+ }
+
+ inline bool OnResetAll( bool isThisStrong, bool isAnyStrong ) const
+ {
+ (void)isAnyStrong;
+ return isThisStrong;
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
/// \class AllowReset
///
/// \ingroup StrongPointerResetGroup
@@ -272,12 +302,16 @@
template < class P >
struct AllowReset
{
- inline bool OnReleaseAll( bool ) const
+ inline bool OnReleaseAll( bool isThisStrong, bool isAnyStrong ) const
{
+ (void)isThisStrong;
+ (void)isAnyStrong;
return true;
}
- inline bool OnResetAll( bool ) const
+ inline bool OnResetAll( bool isThisStrong, bool isAnyStrong ) const
{
+ (void)isThisStrong;
+ (void)isAnyStrong;
return true;
}
};
@@ -293,18 +327,26 @@
template < class P >
struct NeverReset
{
- inline bool OnReleaseAll( bool ) const
+ inline bool OnReleaseAll( bool isThisStrong, bool isAnyStrong ) const
{
+ (void)isThisStrong;
+ (void)isAnyStrong;
return false;
}
- inline bool OnResetAll( bool ) const
+ inline bool OnResetAll( bool isThisStrong, bool isAnyStrong ) const
{
+ (void)isThisStrong;
+ (void)isAnyStrong;
return false;
}
};
// ----------------------------------------------------------------------------
+// Forward declaration needed for pointer to single-owner strong pointer.
+class SingleOwnerRefCount;
+class Lockable1OwnerRefCount;
+
namespace Private
{
@@ -399,6 +441,8 @@
}
private:
+ /// Default constructor not implemented.
+ TwoRefCountInfo( void );
/// Copy-constructor not implemented.
TwoRefCountInfo( const TwoRefCountInfo & );
/// Copy-assignment operator not implemented.
@@ -410,6 +454,105 @@
};
////////////////////////////////////////////////////////////////////////////////
+/// \class OneOwnerRefCountInfo
+///
+/// \ingroup StrongPointerOwnershipGroup
+/// Implementation detail for reference counting strong and weak pointers.
+/// It maintains a void pointer and 2 reference counts. Since it is just a
+/// class for managing implementation details, it is not intended to be used
+/// directly - which is why it is in a private namespace. Each instance is a
+/// shared resource for all copointers, and there should be only one of these
+/// for each set of copointers. This class is small, trivial, and inline.
+////////////////////////////////////////////////////////////////////////////////
+
+class LOKI_EXPORT OneOwnerRefCountInfo
+{
+public:
+
+ explicit OneOwnerRefCountInfo( SingleOwnerRefCount * ptr );
+
+ OneOwnerRefCountInfo( const void * p, SingleOwnerRefCount * ptr );
+
+ inline ~OneOwnerRefCountInfo( void )
+ {
+ assert( NULL == m_strongPtr );
+ assert( 0 == m_weakCount );
+ }
+
+ inline bool HasStrongPointer( void ) const
+ {
+ return ( NULL != m_strongPtr );
+ }
+
+ inline const SingleOwnerRefCount * GetStrongCoPointer( void ) const
+ {
+ return m_strongPtr;
+ }
+
+ inline SingleOwnerRefCount * GetStrongCoPointer( void )
+ {
+ return m_strongPtr;
+ }
+
+ void SetStrongCoPtr( SingleOwnerRefCount * ptr );
+
+ inline bool HasWeakPointer( void ) const
+ {
+ return ( 0 < m_weakCount );
+ }
+
+ inline unsigned int GetWeakCount( void ) const
+ {
+ return m_weakCount;
+ }
+
+ inline void IncWeakCount( void )
+ {
+ ++m_weakCount;
+ }
+
+ inline void DecWeakCount( void )
+ {
+ assert( 0 < m_weakCount );
+ --m_weakCount;
+ }
+
+ inline void ZapPointer( void )
+ {
+ m_pointer = NULL;
+ }
+
+ void SetPointer( void * p )
+ {
+ m_pointer = p;
+ }
+
+ inline void * GetPointer( void ) const
+ {
+ return const_cast< void * >( m_pointer );
+ }
+
+ inline void * & GetPointerRef( void ) const
+ {
+ return const_cast< void * & >( m_pointer );
+ }
+
+private:
+ /// Default constructor not implemented.
+ OneOwnerRefCountInfo( void );
+ /// Copy constructor not implemented.
+ OneOwnerRefCountInfo( const OneOwnerRefCountInfo & );
+ /// Copy-assignment operator not implemented.
+ OneOwnerRefCountInfo & operator = ( const OneOwnerRefCountInfo & );
+
+ const void * m_pointer;
+ SingleOwnerRefCount * m_strongPtr;
+ unsigned int m_weakCount;
+};
+
+#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
+
+////////////////////////////////////////////////////////////////////////////////
/// \class LockableTwoRefCountInfo
///
/// \ingroup StrongPointerOwnershipGroup
@@ -427,8 +570,6 @@
/// do run properly.
////////////////////////////////////////////////////////////////////////////////
-#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
-
class LOKI_EXPORT LockableTwoRefCountInfo
: private Loki::Private::TwoRefCountInfo
{
@@ -540,6 +681,154 @@
mutable LOKI_DEFAULT_MUTEX m_Mutex;
};
+////////////////////////////////////////////////////////////////////////////////
+/// \class Lockable1OwnerRefCountInfo
+///
+/// \ingroup StrongPointerOwnershipGroup
+/// Implementation detail for thread-safe reference counting for 1 strong and
+/// multiple weak pointers. It uses OneOwnerRefCountInfo to manage the pointers
+/// and count. All this does is provide a thread safety mechanism. Since it
+/// is just a class for managing implementation details, it is not intended to
+/// be used directly - which is why it is in a private namespace. Each instance
+/// is a shared resource for all copointers, and there should be only one of
+/// these for each set of copointers. This class is small, trivial, and inline.
+///
+/// \note This class is not designed for use with a single-threaded model.
+/// Tests using a single-threaded model will not run properly, but tests in a
+/// multi-threaded model with either class-level-locking or object-level-locking
+/// do run properly.
+////////////////////////////////////////////////////////////////////////////////
+
+class LOKI_EXPORT Lockable1OwnerRefCountInfo
+ : private Loki::Private::OneOwnerRefCountInfo
+{
+public:
+
+ explicit Lockable1OwnerRefCountInfo( Lockable1OwnerRefCount * ptr )
+ : OneOwnerRefCountInfo( reinterpret_cast< SingleOwnerRefCount * >( ptr ) )
+ , m_Mutex()
+ {
+ }
+
+ Lockable1OwnerRefCountInfo( const void * p, Lockable1OwnerRefCount * ptr )
+ : OneOwnerRefCountInfo( p,
+ reinterpret_cast< SingleOwnerRefCount * >( ptr ) )
+ , m_Mutex()
+ {
+ }
+
+ inline ~Lockable1OwnerRefCountInfo( void )
+ {
+ }
+
+ inline void Lock( void ) const
+ {
+ m_Mutex.Lock();
+ }
+
+ inline void Unlock( void ) const
+ {
+ m_Mutex.Unlock();
+ }
+
+ inline const Lockable1OwnerRefCount * GetStrongCoPointer( void ) const
+ {
+ m_Mutex.Lock();
+ const SingleOwnerRefCount * ptr =
+ OneOwnerRefCountInfo::GetStrongCoPointer();
+ m_Mutex.Unlock();
+ return reinterpret_cast< const Lockable1OwnerRefCount * >( ptr );
+ }
+
+ inline Lockable1OwnerRefCount * GetStrongCoPointer( void )
+ {
+ m_Mutex.Lock();
+ SingleOwnerRefCount * ptr = OneOwnerRefCountInfo::GetStrongCoPointer();
+ m_Mutex.Unlock();
+ return reinterpret_cast< Lockable1OwnerRefCount * >( ptr );
+ }
+
+ inline void SetStrongCoPtr( Lockable1OwnerRefCount * ptr )
+ {
+ m_Mutex.Lock();
+ SingleOwnerRefCount * p = reinterpret_cast< SingleOwnerRefCount * >( ptr );
+ OneOwnerRefCountInfo::SetStrongCoPtr( p );
+ m_Mutex.Unlock();
+ }
+
+ inline bool HasStrongPointer( void ) const
+ {
+ m_Mutex.Lock();
+ const bool has = OneOwnerRefCountInfo::HasStrongPointer();
+ m_Mutex.Unlock();
+ return has;
+ }
+
+ inline unsigned int GetWeakCount( void ) const
+ {
+ m_Mutex.Lock();
+ const unsigned int weakCount = OneOwnerRefCountInfo::HasWeakPointer();
+ m_Mutex.Unlock();
+ return weakCount;
+ }
+
+ inline bool HasWeakPointer( void ) const
+ {
+ m_Mutex.Lock();
+ const bool has = OneOwnerRefCountInfo::HasWeakPointer();
+ m_Mutex.Unlock();
+ return has;
+ }
+
+ inline void IncWeakCount( void )
+ {
+ m_Mutex.Lock();
+ OneOwnerRefCountInfo::IncWeakCount();
+ m_Mutex.Unlock();
+ }
+
+ inline void DecWeakCount( void )
+ {
+ m_Mutex.Lock();
+ OneOwnerRefCountInfo::DecWeakCount();
+ m_Mutex.Unlock();
+ }
+
+ inline void ZapPointer( void )
+ {
+ m_Mutex.Lock();
+ OneOwnerRefCountInfo::ZapPointer();
+ m_Mutex.Unlock();
+ }
+
+ void SetPointer( void * p )
+ {
+ m_Mutex.Lock();
+ OneOwnerRefCountInfo::SetPointer( p );
+ m_Mutex.Unlock();
+ }
+
+ inline void * GetPointer( void ) const
+ {
+ return OneOwnerRefCountInfo::GetPointer();
+ }
+
+ inline void * & GetPointerRef( void ) const
+ {
+ return OneOwnerRefCountInfo::GetPointerRef();
+ }
+
+private:
+ /// Default constructor is not available.
+ Lockable1OwnerRefCountInfo( void );
+ /// Copy constructor is not available.
+ Lockable1OwnerRefCountInfo( const Lockable1OwnerRefCountInfo & );
+ /// Copy-assignment operator is not available.
+ Lockable1OwnerRefCountInfo & operator = ( const Lockable1OwnerRefCountInfo & );
+
+ mutable LOKI_DEFAULT_MUTEX m_Mutex;
+};
+
#endif // if object-level-locking or class-level-locking
} // end namespace Private
@@ -582,7 +871,7 @@
return Decrement( strong );
}
- bool HasStrongPointer( void ) const
+ inline bool HasStrongPointer( void ) const
{
return m_counts->HasStrongPointer();
}
@@ -607,7 +896,12 @@
}
private:
+
+ /// Default constructor is not implemented.
TwoRefCounts( void );
+ /// Copy constructor is not implemented.
+ TwoRefCounts( const TwoRefCounts & );
+ /// Copy-assignment operator is not implemented.
TwoRefCounts & operator = ( const TwoRefCounts & );
void Increment( bool strong );
@@ -619,6 +913,93 @@
};
////////////////////////////////////////////////////////////////////////////////
+/// \class SingleOwnerRefCount
+///
+/// \ingroup StrongPointerOwnershipGroup
+/// This implementation of StrongPtr's OwnershipPolicy extends the ownership
+/// policy class, TwoRefCounts, to enforce that only one StrongPtr may "own" a
+/// resource. The resource is destroyed only when its sole owner dies even if
+/// weak pointers access it. The constructors enforce the single-owner policy
+/// by throwing a bad_logic exception if more than one strong pointer claims to
+/// own the resource. Use this policy when you want the code to specify that
+/// only one object owns a resource.
+///
+/// \note This class is not designed for use with a multi-threaded model.
+/// Tests using a multi-threaded model may not run properly.
+///
+/// \note If you use any single-owner class, you should also use the
+/// OnlyStrongMayReset class for the ResetPolicy in StrongPtr.
+///
+/// \note All single-owner policies do not allow programmers to return a
+/// a StrongPtr by value from a function, since that would temporarily create
+/// an additional strong co-pointer. Nor can programmers store any strong
+/// co-pointers in a container that uses copy-in and copy-out semantics. Once
+/// C++ allows for move constructors, these limitations go away.
+////////////////////////////////////////////////////////////////////////////////
+
+class LOKI_EXPORT SingleOwnerRefCount
+{
+protected:
+
+ explicit SingleOwnerRefCount( bool strong );
+
+ SingleOwnerRefCount( const void * p, bool strong );
+
+ SingleOwnerRefCount( const SingleOwnerRefCount & rhs,
+ bool strong );
+
+ SingleOwnerRefCount( const SingleOwnerRefCount & rhs,
+ bool isNull, bool strong );
+
+ /** The destructor should not anything since the call to ZapPointer inside
+ StrongPtr::~StrongPtr will do the cleanup which this dtor would have done.
+ By the time the dtor is called, the underlying pointer, m_info, is NULL.
+ */
+ inline ~SingleOwnerRefCount( void ) {}
+
+ bool Release( bool strong );
+
+ inline bool HasStrongPointer( void ) const
+ {
+ return ( NULL != m_info->GetStrongCoPointer() );
+ }
+
+ void Swap( SingleOwnerRefCount & rhs );
+
+ void SetPointer( void * p );
+
+ void ZapPointer( void );
+
+ inline void * GetPointer( void ) const
+ {
+ return m_info->GetPointer();
+ }
+
+ inline void * & GetPointerRef( void ) const
+ {
+ return m_info->GetPointerRef();
+ }
+
+private:
+ /// Default constructor is not implemented.
+ SingleOwnerRefCount( void );
+ /// Copy constructor is not implemented.
+ SingleOwnerRefCount( const SingleOwnerRefCount & );
+ /// Copy-assignment operator is not implemented.
+ SingleOwnerRefCount & operator = ( const SingleOwnerRefCount & );
+
+ inline bool IsStrong( void ) const
+ {
+ return ( this == m_info->GetStrongCoPointer() );
+ }
+
+ ::Loki::Private::OneOwnerRefCountInfo * m_info;
+
+};
+
+#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
+
+////////////////////////////////////////////////////////////////////////////////
/// \class LockableTwoRefCounts
///
/// \ingroup StrongPointerOwnershipGroup
@@ -633,8 +1014,6 @@
/// do run properly.
////////////////////////////////////////////////////////////////////////////////
-#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
-
class LOKI_EXPORT LockableTwoRefCounts
{
typedef SmallValueObject< ::Loki::ClassLevelLockable > ThreadSafePointerAllocator;
@@ -744,7 +1123,7 @@
void Swap( LockableTwoRefCounts & rhs )
{
- std::swap( m_counts, rhs.m_counts );
+ ::std::swap( m_counts, rhs.m_counts );
}
void SetPointer( void * p )
@@ -780,13 +1159,250 @@
}
private:
+ /// Default constructor is not implemented.
LockableTwoRefCounts( void );
+ /// Copy constructor is not implemented.
+ LockableTwoRefCounts( const LockableTwoRefCounts & );
+ /// Copy-assignment operator is not implemented.
LockableTwoRefCounts & operator = ( const LockableTwoRefCounts & );
/// Pointer to all shared data.
Loki::Private::LockableTwoRefCountInfo * m_counts;
};
+////////////////////////////////////////////////////////////////////////////////
+/// \class Lockable1OwnerRefCount
+///
+/// \ingroup StrongPointerOwnershipGroup
+/// This implementation of StrongPtr's OwnershipPolicy extends the ownership
+/// policy class, LockableTwoRefCounts, to enforce that only one StrongPtr
+/// may "own" a resource. The resource is destroyed only when its sole owner
+/// dies regardless of how many weak pointers access it. The constructors
+/// enforce the single-owner policy by throwing a bad_logic exception if more
+/// than one strong pointer claims to own the resource. Use this policy when
+/// you want the code to specify that only one object owns a resource.
+///
+/// \note This class is not designed for use with a single-threaded model.
+/// Tests using a single-threaded model will not run properly, but tests in a
+/// multi-threaded model with either class-level-locking or object-level-locking
+/// do run properly.
+///
+/// \note If you use any single-owner class, you should also use the
+/// OnlyStrongMayReset class for the ResetPolicy in StrongPtr.
+///
+/// \note All single-owner policies do not allow programmers to return a
+/// a StrongPtr by value from a function, since that would temporarily create
+/// an additional strong co-pointer. Nor can programmers store any strong
+/// co-pointers in a container that uses copy-in and copy-out semantics. Once
+/// C++ allows for move constructors, these limitations go away.
+////////////////////////////////////////////////////////////////////////////////
+
+class LOKI_EXPORT Lockable1OwnerRefCount
+{
+ typedef SmallValueObject< ::Loki::ClassLevelLockable > ThreadSafePointerAllocator;
+
+protected:
+
+ explicit Lockable1OwnerRefCount( bool strong )
+ : m_info( NULL )
+ {
+ assert( NULL != this );
+
+ void * temp = SmallObject<>::operator new(
+ sizeof(Loki::Private::Lockable1OwnerRefCountInfo) );
+#ifdef DO_EXTRA_LOKI_TESTS
+ assert( temp != 0 );
+#endif
+
+ Lockable1OwnerRefCount * ptr = ( strong ) ? this : NULL;
+ m_info = new ( temp )
+ ::Loki::Private::Lockable1OwnerRefCountInfo( ptr );
+ }
+
+ Lockable1OwnerRefCount( const void * p, bool strong )
+ : m_info( NULL )
+ {
+ assert( NULL != this );
+
+ void * temp = SmallObject<>::operator new(
+ sizeof(Loki::Private::Lockable1OwnerRefCountInfo) );
+#ifdef DO_EXTRA_LOKI_TESTS
+ assert( temp != 0 );
+#endif
+
+ Lockable1OwnerRefCount * ptr = ( strong ) ? this : NULL;
+ m_info = new ( temp )
+ ::Loki::Private::Lockable1OwnerRefCountInfo( p, ptr );
+ }
+
+ Lockable1OwnerRefCount( const Lockable1OwnerRefCount & rhs, bool strong ) :
+ m_info( rhs.m_info )
+ {
+ assert( NULL != this );
+
+ if ( strong && rhs.HasStrongPointer() )
+ {
+ throw ::std::logic_error( StrongPtr_Single_Owner_Exception_Message );
+ }
+
+ m_info = rhs.m_info;
+ if ( strong )
+ {
+ m_info->SetStrongCoPtr( this );
+ }
+ else
+ {
+ m_info->IncWeakCount();
+ }
+ }
+
+ Lockable1OwnerRefCount( const Lockable1OwnerRefCount & rhs,
+ bool isNull, bool strong ) :
+ m_info( ( isNull ) ? NULL : rhs.m_info )
+ {
+ assert( NULL != this );
+
+ if ( isNull )
+ {
+ void * temp = SmallObject<>::operator new(
+ sizeof(Loki::Private::Lockable1OwnerRefCountInfo) );
+#ifdef DO_EXTRA_LOKI_TESTS
+ assert( temp != 0 );
+#endif
+
+ Lockable1OwnerRefCount * ptr = ( strong ) ? this : NULL;
+ m_info = new ( temp )
+ ::Loki::Private::Lockable1OwnerRefCountInfo( ptr );
+ return;
+ }
+
+ if ( strong && rhs.HasStrongPointer() )
+ {
+ throw ::std::logic_error( StrongPtr_Single_Owner_Exception_Message );
+ }
+
+ m_info = rhs.m_info;
+ if ( strong )
+ {
+ m_info->SetStrongCoPtr( this );
+ }
+ else
+ {
+ m_info->IncWeakCount();
+ }
+ }
+
+ /** The destructor does not need to do anything since the call to
+ ZapPointer inside StrongPtr::~StrongPtr will do the cleanup which
+ this dtor would have done.
+ */
+ inline ~Lockable1OwnerRefCount( void ) {}
+
+ inline void Lock( void ) const
+ {
+ m_info->Lock();
+ }
+
+ inline void Unlock( void ) const
+ {
+ m_info->Unlock();
+ }
+
+ inline bool Release( bool strong )
+ {
+ assert( NULL != this );
+ assert( strong == IsStrong() );
+
+ if ( strong )
+ {
+ m_info->SetStrongCoPtr( NULL );
+ return true;
+ }
+
+ m_info->Lock();
+ assert( 0 < m_info->GetWeakCount() );
+ m_info->DecWeakCount();
+ const bool noOwner = ( !m_info->HasStrongPointer() );
+ const bool doRelease = ( ( 0 == m_info->GetWeakCount() ) && noOwner );
+ m_info->Unlock();
+ return doRelease;
+ }
+
+ bool HasStrongPointer( void ) const
+ {
+ return m_info->HasStrongPointer();
+ }
+
+ void Swap( Lockable1OwnerRefCount & rhs )
+ {
+ assert( NULL != this );
+ m_info->Lock();
+ rhs.m_info->Lock();
+
+ if ( IsStrong() && rhs.IsStrong() )
+ {
+ // These two strong pointers are trading resources.
+ rhs.m_info->SetStrongCoPtr( this );
+ m_info->SetStrongCoPtr( &rhs );
+ }
+ ::std::swap( m_info, rhs.m_info );
+ m_info->Unlock();
+ rhs.m_info->Unlock();
+ }
+
+ void SetPointer( void * p )
+ {
+ assert( NULL != this );
+ if ( IsStrong() || ( 1 == m_info->GetWeakCount() ) )
+ {
+ // Only a strong pointer or the last weak pointer may change a resource.
+ m_info->SetPointer( p );
+ }
+ }
+
+ void ZapPointer( void )
+ {
+ assert( !m_info->HasStrongPointer() );
+ if ( m_info->HasWeakPointer() )
+ {
+ m_info->ZapPointer();
+ }
+ else
+ {
+ SmallObject<>::operator delete ( m_info,
+ sizeof(Loki::Private::Lockable1OwnerRefCountInfo) );
+ m_info = NULL;
+ }
+ }
+
+ inline void * GetPointer( void ) const
+ {
+ return m_info->GetPointer();
+ }
+
+ inline void * & GetPointerRef( void ) const
+ {
+ return m_info->GetPointerRef();
+ }
+
+private:
+ /// Default constructor is not implemented.
+ Lockable1OwnerRefCount( void );
+ /// Copy constructor is not implemented.
+ Lockable1OwnerRefCount( const Lockable1OwnerRefCount & );
+ /// Copy-assignment operator is not implemented.
+ Lockable1OwnerRefCount & operator = ( const Lockable1OwnerRefCount & );
+
+ inline bool IsStrong( void ) const
+ {
+ return ( this == m_info->GetStrongCoPointer() );
+ }
+
+ /// Pointer to shared info about resource.
+ ::Loki::Private::Lockable1OwnerRefCountInfo * m_info;
+
+};
+
#endif // if object-level-locking or class-level-locking
////////////////////////////////////////////////////////////////////////////////
@@ -817,14 +1433,21 @@
TwoRefLinks( const TwoRefLinks & rhs, bool isNull, bool strong );
+ ~TwoRefLinks( void );
+
bool Release( bool strong );
void Swap( TwoRefLinks & rhs );
bool Merge( TwoRefLinks & rhs );
+ /// Returns pointer to next link in cycle is a strong pointer.
+ const TwoRefLinks * GetNextStrongPointer( void ) const;
+
bool HasStrongPointer( void ) const;
+ unsigned int GetStrongPointerCount( void ) const;
+
inline void ZapPointer( void )
{
ZapAllNodes();
@@ -842,13 +1465,20 @@
return const_cast< void * & >( m_pointer );
}
+ inline bool IsStrong( void ) const
+ {
+ return m_strong;
+ }
+
private:
static unsigned int CountPrevCycle( const TwoRefLinks * pThis );
static unsigned int CountNextCycle( const TwoRefLinks * pThis );
- /// Not implemented.
+ /// Default constructor is not implemented.
TwoRefLinks( void );
- /// Not implemented.
+ /// Copy constructor is not implemented.
+ TwoRefLinks( const TwoRefLinks & );
+ /// Copy-assignment operator is not implemented.
TwoRefLinks & operator = ( const TwoRefLinks & );
bool HasPrevNode( const TwoRefLinks * p ) const;
@@ -856,6 +1486,8 @@
bool AllNodesHaveSamePointer( void ) const;
void ZapAllNodes( void );
+ bool IsValid( void ) const;
+
void * m_pointer;
mutable TwoRefLinks * m_prev;
mutable TwoRefLinks * m_next;
@@ -863,6 +1495,61 @@
};
////////////////////////////////////////////////////////////////////////////////
+/// \class SingleOwnerRefLinks
+///
+/// \ingroup StrongPointerOwnershipGroup
+/// This implementation of StrongPtr's OwnershipPolicy extends the ownership
+/// policy class, TwoRefLinks, to enforce that only one StrongPtr may "own" a
+/// resource. The resource is destroyed only when its sole owner dies even if
+/// weak pointers access it. The constructors enforce the single-owner policy
+/// by throwing a bad_logic exception if more than one strong pointer claims to
+/// own the resource. Use this policy when you want the code to specify that
+/// only one object owns a resource.
+///
+/// \note This class is not designed for use with a multi-threaded model.
+/// Tests using a multi-threaded model may not run properly.
+///
+/// \note If you use any single-owner class, you should also use the
+/// OnlyStrongMayReset class for the ResetPolicy in StrongPtr.
+///
+/// \note All single-owner policies do not allow programmers to return a
+/// a StrongPtr by value from a function, since that would temporarily create
+/// an additional strong co-pointer. Nor can programmers store any strong
+/// co-pointers in a container that uses copy-in and copy-out semantics. Once
+/// C++ allows for move constructors, these limitations go away.
+////////////////////////////////////////////////////////////////////////////////
+
+class LOKI_EXPORT SingleOwnerRefLinks : public TwoRefLinks
+{
+protected:
+
+ explicit SingleOwnerRefLinks( bool strong );
+
+ SingleOwnerRefLinks( const void * p, bool strong );
+
+ SingleOwnerRefLinks( const SingleOwnerRefLinks & rhs, bool strong );
+
+ SingleOwnerRefLinks( const SingleOwnerRefLinks & rhs, bool isNull, bool strong );
+
+ ~SingleOwnerRefLinks( void );
+
+ void Swap( SingleOwnerRefLinks & rhs );
+
+ bool Merge( SingleOwnerRefLinks & rhs );
+
+ bool Release( bool strong );
+
+private:
+
+ /// Default constructor is not implemented.
+ SingleOwnerRefLinks( void );
+ /// Copy constructor is not implemented.
+ SingleOwnerRefLinks( const SingleOwnerRefLinks & );
+ /// Copy-assignment operator is not implemented.
+ SingleOwnerRefLinks & operator = ( const SingleOwnerRefLinks & );
+};
+
+////////////////////////////////////////////////////////////////////////////////
/// \class StrongPtr
///
/// \ingroup SmartPointerGroup
@@ -880,11 +1567,11 @@
<
typename T,
bool Strong = true,
- class OwnershipPolicy = Loki::TwoRefCounts,
- class ConversionPolicy = Loki::DisallowConversion,
- template < class > class CheckingPolicy = Loki::AssertCheck,
- template < class > class ResetPolicy = Loki::CantResetWithStrong,
- template < class > class DeletePolicy = Loki::DeleteSingle,
+ class OwnershipPolicy = ::Loki::TwoRefCounts,
+ class ConversionPolicy = ::Loki::DisallowConversion,
+ template < class > class CheckingPolicy = ::Loki::AssertCheck,
+ template < class > class ResetPolicy = ::Loki::CantResetWithStrong,
+ template < class > class DeletePolicy = ::Loki::DeleteSingle,
template < class > class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
>
class StrongPtr
@@ -1072,7 +1759,7 @@
return *this;
}
- bool IsStrong( void ) const
+ inline bool IsStrong( vo...
[truncated message content] |
|
From: <ric...@us...> - 2011-09-20 17:51:32
|
Revision: 1104
http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1104&view=rev
Author: rich_sposato
Date: 2011-09-20 17:51:26 +0000 (Tue, 20 Sep 2011)
Log Message:
-----------
Added ability for StrongPtr to handle arrays.
Modified Paths:
--------------
trunk/include/loki/StrongPtr.h
Modified: trunk/include/loki/StrongPtr.h
===================================================================
--- trunk/include/loki/StrongPtr.h 2011-09-17 02:25:43 UTC (rev 1103)
+++ trunk/include/loki/StrongPtr.h 2011-09-20 17:51:26 UTC (rev 1104)
@@ -134,7 +134,15 @@
template < class P >
class DeleteUsingFree
{
-public:
+protected:
+
+ inline DeleteUsingFree( void ) {}
+
+ inline DeleteUsingFree( const DeleteUsingFree & ) {}
+
+ template < class P1 >
+ inline DeleteUsingFree( const DeleteUsingFree< P1 > & ) {}
+
inline void static Delete( const P * p )
{
if ( 0 != p )
@@ -165,7 +173,15 @@
template < class P >
class DeleteNothing
{
-public:
+protected:
+
+ inline DeleteNothing( void ) {}
+
+ inline DeleteNothing( const DeleteNothing & ) {}
+
+ template < class P1 >
+ inline DeleteNothing( const DeleteNothing< P1 > & ) {}
+
inline static void Delete( const P * )
{
// Do nothing at all!
@@ -177,6 +193,7 @@
}
inline void Swap( DeleteNothing & ) {}
+
};
////////////////////////////////////////////////////////////////////////////////
@@ -190,7 +207,15 @@
template < class P >
class DeleteSingle
{
-public:
+protected:
+
+ inline DeleteSingle( void ) {}
+
+ inline DeleteSingle( const DeleteSingle & ) {}
+
+ template < class P1 >
+ inline DeleteSingle( const DeleteSingle< P1 > & ) {}
+
inline static void Delete( const P * p )
{
/** @note If you see an error message about a negative subscript, that
@@ -210,7 +235,46 @@
inline void Swap( DeleteSingle & ) {}
};
+namespace Private
+{
+
////////////////////////////////////////////////////////////////////////////////
+/// \class DeleteArrayBase
+///
+/// \ingroup StrongPointerDeleteGroup
+/// Base class used only by the DeleteArray policy class. This stores the
+/// number of elements in an array of shared objects.
+////////////////////////////////////////////////////////////////////////////////
+
+class DeleteArrayBase
+{
+public:
+
+ inline size_t GetArrayCount( void ) const { return m_itemCount; }
+
+protected:
+
+ DeleteArrayBase( void ) : m_itemCount( 0 ) {}
+
+ explicit DeleteArrayBase( size_t itemCount ) : m_itemCount( itemCount ) {}
+
+ DeleteArrayBase( const DeleteArrayBase & that ) : m_itemCount( that.m_itemCount ) {}
+
+ void Swap( DeleteArrayBase & rhs );
+
+ void OnInit( const void * p ) const;
+
+ void OnCheckRange( size_t index ) const;
+
+private:
+
+ size_t m_itemCount;
+
+};
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
/// \class DeleteArray
///
/// \ingroup StrongPointerDeleteGroup
@@ -219,9 +283,19 @@
////////////////////////////////////////////////////////////////////////////////
template < class P >
-class DeleteArray
+class DeleteArray : public ::Loki::Private::DeleteArrayBase
{
public:
+
+ DeleteArray( void ) : DeleteArrayBase() {}
+
+ explicit DeleteArray( size_t itemCount ) : DeleteArrayBase( itemCount ) {}
+
+ DeleteArray( const DeleteArray & that ) : DeleteArrayBase( that ) {}
+
+ template < class P1 >
+ inline DeleteArray( const DeleteArray< P1 > & that ) : DeleteArrayBase( that ) {}
+
inline static void Delete( const P * p )
{
/** @note If you see an error message about a negative subscript, that
@@ -238,7 +312,6 @@
return 0;
}
- inline void Swap( DeleteArray & ) {}
};
////////////////////////////////////////////////////////////////////////////////
@@ -1653,21 +1726,32 @@
public:
- StrongPtr( void ) : OP( Strong )
+ StrongPtr( void ) : OP( Strong ), DP()
{
KP::OnDefault( GetPointer() );
}
- explicit StrongPtr( ExplicitArg p ) : OP( p, Strong )
+ explicit StrongPtr( ExplicitArg p ) : OP( p, Strong ), DP()
{
KP::OnInit( GetPointer() );
}
- StrongPtr( ImplicitArg p ) : OP( p, Strong )
+ StrongPtr( ImplicitArg p ) : OP( p, Strong ), DP()
{
KP::OnInit( GetPointer() );
}
+ /** This constructor was designed to only work with the DeleteArray policy. Using it with any
+ other Delete policies will cause compiler errors. Call it with this syntax:
+ "ThingyPtr sp2( new Thingy[ 4 ], 4 );" so the StrongPtr knows how many elements are in the
+ array for range checking.
+ */
+ StrongPtr( ImplicitArg p, size_t itemCount ) : OP( p, Strong ), DP( itemCount )
+ {
+ KP::OnInit( GetPointer() );
+ DP::OnInit( GetPointer() );
+ }
+
StrongPtr( const StrongPtr & rhs )
: OP( rhs, Strong ), CP( rhs ), KP( rhs ), DP( rhs )
{
@@ -1686,7 +1770,7 @@
>
StrongPtr(
const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
- : OP( rhs, Strong )
+ : OP( rhs, Strong ), CP( rhs ), DP( rhs )
{
}
@@ -1703,7 +1787,7 @@
>
StrongPtr(
StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs )
- : OP( rhs, Strong )
+ : OP( rhs, Strong ), CP( rhs ), DP( rhs )
{
}
@@ -1737,6 +1821,21 @@
return *this;
}
+ /** This function is equivalent to an assignment operator for StrongPtr's that use the
+ DeleteArray policy where the programmer needs to write the equivalent of "sp = new P;".
+ With DeleteArray, the programmer should write "sp.Assign( new [5] Thingy, 5 );" so the
+ StrongPtr knows how many elements are in the array.
+ */
+ StrongPtr & Assign( T * p, size_t itemCount )
+ {
+ if ( GetPointer() != p )
+ {
+ StrongPtr temp( p, itemCount );
+ Swap( temp );
+ }
+ return *this;
+ }
+
template
<
typename T1,
@@ -1969,6 +2068,22 @@
return * GetPointer();
}
+ ReferenceType operator [] ( size_t index )
+ {
+ KP::OnDereference( GetPointer() );
+ DP::OnCheckRange( index );
+ PointerType p = GetPointer();
+ return p[ index ];
+ }
+
+ ConstReferenceType operator [] ( size_t index ) const
+ {
+ KP::OnDereference( GetPointer() );
+ DP::OnCheckRange( index );
+ ConstPointerType p = GetPointer();
+ return p[ index ];
+ }
+
/// Helper function which can be called to avoid exposing GetPointer function.
template < class T1 >
bool Equals( const T1 * p ) const
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|