diff --git a/Loki.workspace b/Loki.workspace
index 1a22fb4..52d4ab1 100644
--- a/Loki.workspace
+++ b/Loki.workspace
@@ -2,46 +2,46 @@
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
diff --git a/include/loki/StrongPtr.h b/include/loki/StrongPtr.h
index 37efb57..4624272 100644
--- a/include/loki/StrongPtr.h
+++ b/include/loki/StrongPtr.h
@@ -85,7 +85,10 @@
/// If you write your own policy, you must implement these 3 functions:
/// -# void static Delete( const P * p )
/// -# static P * Default( void )
-/// -# void Swap( YourResetPolicy & )
+/// -# Default constructor.
+/// -# Copy constructor.
+/// -# Templated copy constructor.
+/// -# void Swap( YourDeletePolicy & )
///
/// \par ResetPolicy
/// A reset policy tells the ReleaseAll and ResetAll functions whether they
@@ -235,45 +238,6 @@ protected:
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
///
@@ -2068,19 +2032,27 @@ public:
return * GetPointer();
}
+ /** operator[] returns a reference to an modifiable object. If the index is greater than or
+ equal to the number of elements, the function will throw a std::out_of_range exception.
+ This only works with DeleteArray policy. Any other policy will cause a compiler error.
+ */
ReferenceType operator [] ( size_t index )
{
- KP::OnDereference( GetPointer() );
- DP::OnCheckRange( index );
PointerType p = GetPointer();
+ KP::OnDereference( p );
+ DP::OnCheckRange( index );
return p[ index ];
}
+ /** operator[] returns a reference to a const object. If the index is greater than or
+ equal to the number of elements, the function will throw a std::out_of_range exception.
+ This only works with DeleteArray policy. Any other policy will cause a compiler error.
+ */
ConstReferenceType operator [] ( size_t index ) const
{
- KP::OnDereference( GetPointer() );
- DP::OnCheckRange( index );
ConstPointerType p = GetPointer();
+ KP::OnDereference( p );
+ DP::OnCheckRange( index );
return p[ index ];
}
diff --git a/include/loki/ThreadLocal.h b/include/loki/ThreadLocal.h
index f03a87f..d9936d8 100644
--- a/include/loki/ThreadLocal.h
+++ b/include/loki/ThreadLocal.h
@@ -28,21 +28,29 @@
// The __APPLE__ macro does not refer to a compiler, but to the Apple OSX operating system.
#if defined( __APPLE__ )
#warning "GCC for Apple does not allow thread_local storage, so you can not use some parts of Loki."
- #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE
+ #undef LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE
#elif defined( __CYGWIN__ )
#if ( __GNUC__ <= 3 )
#warning "Older versions of GCC for Cygwin do not allow thread_local storage, so you can not use some parts of Loki."
- #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE
+ #undef LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE
#endif
#elif ( __GNUC__ == 4 ) // GNU versions other than Cygwin.
- #if ( __GNUC_MINOR__ == 4 )
- #warning "GCC version 4.4 implements thread_local storage incorrectly, so you can not use some parts of Loki."
- #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE
+ #if ( __GNUC_MINOR__ < 4 )
+ #warning "GCC versions before 4.4 implements thread_local storage incorrectly, so you can not use some parts of Loki."
+ #undef LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE
+ #else
+ #warning "Versions 4.4 through 4.6 of GCC implemented thread_local storage for some platforms, but not others. Run ThreadLocal test project."
#endif
#endif
-#endif
+
+#elif defined( _MSC_VER )
+ #if ( _MSC_VER < 1300 )
+ #warning "Only Visual Studio versions 7.0 and after support thread local storage properly, so you can not use some parts of Loki."
+ #undef LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE
+ #endif
+#endif
#if defined( LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE ) && !defined( LOKI_THREAD_LOCAL )
@@ -57,11 +65,7 @@
you can't use some parts of Loki.
*/
#if defined( _MSC_VER )
- #if ( _MSC_VER >= 1300 )
- #define LOKI_THREAD_LOCAL __declspec( thread )
- #else
- #error "Only Visual Studio versions 7.0 and after supported."
- #endif
+ #define LOKI_THREAD_LOCAL __declspec( thread )
#elif ( __GNUC__ )
#define LOKI_THREAD_LOCAL __thread
diff --git a/include/loki/flex/flex_string_shell.h b/include/loki/flex/flex_string_shell.h
index ecdfb7b..63c73b3 100644
--- a/include/loki/flex/flex_string_shell.h
+++ b/include/loki/flex/flex_string_shell.h
@@ -1339,17 +1339,17 @@ getline(
typename flex_string::value_type delim)
{
size_t nread = 0;
- typename basic_istream::value_type,
+ typename std::basic_istream::value_type,
typename flex_string::traits_type>::sentry sentry(is, true);
if (sentry) {
- basic_streambuf::value_type,
+ ::std::basic_streambuf::value_type,
typename flex_string::traits_type>* buf = is.rdbuf();
str.clear();
while (nread < str.max_size()) {
int c1 = buf->sbumpc();
if (flex_string::traits_type::eq_int_type(c1, flex_string::traits_type::eof())) {
- is.setstate(ios_base::eofbit);
+ is.setstate(::std::ios_base::eofbit);
break;
}
else {
@@ -1363,7 +1363,7 @@ getline(
}
}
if (nread == 0 || nread >= str.max_size())
- is.setstate(ios_base::failbit);
+ is.setstate(::std::ios_base::failbit);
return is;
}
diff --git a/src/StrongPtr.cpp b/src/StrongPtr.cpp
index cdabcb0..1f3b5c5 100644
--- a/src/StrongPtr.cpp
+++ b/src/StrongPtr.cpp
@@ -15,9 +15,6 @@
#include
-#include
-#include
-
#include
#ifdef DO_EXTRA_LOKI_TESTS
#include
@@ -41,45 +38,6 @@ namespace Private
// ----------------------------------------------------------------------------
-void DeleteArrayBase::Swap( DeleteArrayBase & rhs )
-{
- assert( NULL != this );
-
- const size_t temp = m_itemCount;
- m_itemCount = rhs.m_itemCount;
- rhs.m_itemCount = temp;
-}
-
-// ----------------------------------------------------------------------------
-
-void DeleteArrayBase::OnInit( const void * p ) const
-{
- assert( NULL != this );
- if ( NULL == p )
- {
- assert( 0 == m_itemCount );
- }
- else
- {
- assert( 0 < m_itemCount );
- }
-}
-
-// ----------------------------------------------------------------------------
-
-void DeleteArrayBase::OnCheckRange( size_t index ) const
-{
- assert( NULL != this );
-
- if ( index < m_itemCount )
- return;
-
- const ::std::string message( "index out of range in ::Loki::DeleteArrayBase::OnCheckRange" );
- throw ::std::out_of_range( message );
-}
-
-// ----------------------------------------------------------------------------
-
OneOwnerRefCountInfo::OneOwnerRefCountInfo( SingleOwnerRefCount * ptr )
: m_pointer( NULL )
, m_strongPtr( ptr )
diff --git a/test/LevelMutex/LevelMutex.cbp b/test/LevelMutex/LevelMutex.cbp
index a5c37a8..a81ea37 100644
--- a/test/LevelMutex/LevelMutex.cbp
+++ b/test/LevelMutex/LevelMutex.cbp
@@ -6,24 +6,24 @@
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
@@ -31,33 +31,33 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
@@ -65,12 +65,12 @@
-
-
+
+
-
-
+
+
diff --git a/test/LevelMutex/MultiThreadTests.cpp b/test/LevelMutex/MultiThreadTests.cpp
index 06713c0..b7f5b2e 100644
--- a/test/LevelMutex/MultiThreadTests.cpp
+++ b/test/LevelMutex/MultiThreadTests.cpp
@@ -4,9 +4,9 @@
// Copyright (c) 2008, 2009 Richard 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
@@ -22,7 +22,7 @@
#include "MultiThreadTests.hpp"
#include
-#include
+//#include
#include
#include
@@ -239,6 +239,8 @@ void * ValueUnsafeThread( void * p )
void MultiThreadSimpleTest( void )
{
+ cout << "Starting MultiThreadSimpleTest." << endl;
+
Thing::Init( 0 );
const unsigned int threadCount = 5;
ThreadPool pool( threadCount );
@@ -262,6 +264,8 @@ void MultiThreadSimpleTest( void )
pool.JoinAll();
Thing::Destroy();
+
+ cout << "Finished MultiThreadSimpleTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -299,13 +303,17 @@ void * TryLockThread( void * p )
void MultiThreadTryLockTest( void )
{
+ cout << "Starting MultiThreadTryLockTest." << endl;
+
static const unsigned int threadCount = 3;
Thing::Init( 0 );
volatile Thing & thing = Thing::GetIt();
volatile SleepMutex & mutex = thing.GetMutex();
cout << endl << "Doing multi-threaded TryLock test. This test should not deadlock." << endl;
- ::system( "pause" );
+ cout << "Press enter key to continue." << endl;
+ char theKey = 0;
+ cin.get( theKey );
// First step is to lock the mutex in the main thread so no child thread
// can ever lock it, change the value, or anything like that.
MutexErrors::Type result = mutex.Lock();
@@ -313,36 +321,46 @@ void MultiThreadTryLockTest( void )
bool okay = mutex.IsLockedByCurrentThread();
assert( okay );
thing.SetValue( threadCount );
- ThreadPool pool( threadCount );
- for ( unsigned int ii = 0; ii < threadCount; ++ii )
+
{
- void * p = reinterpret_cast< void * >( ii );
- pool.Start( TryLockThread, p );
+ ThreadPool pool( threadCount );
+ for ( unsigned int ii = 0; ii < threadCount; ++ii )
+ {
+ void * p = reinterpret_cast< void * >( ii );
+ pool.Start( TryLockThread, p );
+ }
+ pool.JoinAll();
}
- pool.JoinAll();
- const unsigned int value = thing.GetValue();
- assert( value == threadCount );
- result = mutex.Unlock();
- assert( MutexErrors::Success == result );
- okay = !mutex.IsLockedByCurrentThread();
- assert( okay );
- okay = !mutex.IsLocked();
- assert( okay );
+
+ const unsigned int value = thing.GetValue();
+ assert( value == threadCount );
+ result = mutex.Unlock();
+ assert( MutexErrors::Success == result );
+ okay = !mutex.IsLockedByCurrentThread();
+ assert( okay );
+ okay = !mutex.IsLocked();
+ assert( okay );
Thing::Destroy();
+
+ cout << "Finished MultiThreadTryLockTest." << endl;
}
// ----------------------------------------------------------------------------
void MultiThreadReentrantTest( void )
{
+ cout << "Starting MultiThreadReentrantTest." << endl;
+
Thing::Init( 0 );
const unsigned int threadCount = 8;
TestResults::Create( threadCount );
ThreadPool pool( threadCount );
cout << endl << "Doing thread-safe value test. This test should pass and not deadlock." << endl;
- ::system( "pause" );
+ cout << "Press enter key to continue." << endl;
+ char theKey = 0;
+ cin.get( theKey );
for ( unsigned int ii = 0; ii < threadCount; ++ii )
{
void * p = reinterpret_cast< void * >( ii );
@@ -352,7 +370,8 @@ void MultiThreadReentrantTest( void )
TestResults::GetIt()->OutputResults();
cout << endl << "Doing thread-unsafe value test. This test may fail." << endl;
- ::system( "pause" );
+ cout << "Press enter key to continue." << endl;
+ cin.get( theKey );
for ( unsigned int ii = 0; ii < threadCount; ++ii )
{
void * p = reinterpret_cast< void * >( ii );
@@ -363,6 +382,8 @@ void MultiThreadReentrantTest( void )
TestResults::Destroy();
Thing::Destroy();
+
+ cout << "Finished MultiThreadReentrantTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -646,6 +667,8 @@ void * MultiLockUnsafeThread( void * p )
void MultiThreadMultiLockTest( void )
{
+ cout << "Starting MultiThreadMultiLockTest." << endl;
+
Thing::MakePool( thingCount );
const unsigned int threadCount = 8;
TestResults::Create( threadCount );
@@ -674,6 +697,8 @@ void MultiThreadMultiLockTest( void )
TestResults::Destroy();
Thing::DestroyPool();
+
+ cout << "Finished MultiThreadMultiLockTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -808,6 +833,8 @@ void * MultiLockRandomUnsafeThread( void * p )
void MultiThreadRandomMultiLockTest( void )
{
+ cout << "Starting MultiThreadRandomMultiLockTest." << endl;
+
Thing::MakePool( thingCount );
const unsigned int threadCount = 8;
TestResults::Create( threadCount );
@@ -836,6 +863,8 @@ void MultiThreadRandomMultiLockTest( void )
TestResults::Destroy();
Thing::DestroyPool();
+
+ cout << "Finished MultiThreadRandomMultiLockTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -936,6 +965,8 @@ void * UnsafeHierarchyTest( void * p )
void MultiThreadHierarchySingleLockTest( void )
{
+ cout << "Starting MultiThreadHierarchySingleLockTest." << endl;
+
LevelThing::MakePool( thingCount );
const unsigned int threadCount = 8;
TestResults::Create( threadCount );
@@ -964,6 +995,8 @@ void MultiThreadHierarchySingleLockTest( void )
TestResults::Destroy();
LevelThing::DestroyPool();
+
+ cout << "Finished MultiThreadHierarchySingleLockTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -1065,6 +1098,8 @@ void * UnsafeHierarchyMultiLockTest( void * p )
void MultiThreadHierarchyMultiLockTest( void )
{
+ cout << "Starting MultiThreadHierarchyMultiLockTest." << endl;
+
MultiLevelPool::MakePool( 10, thingCount );
const unsigned int threadCount = 8;
TestResults::Create( threadCount );
@@ -1093,6 +1128,8 @@ void MultiThreadHierarchyMultiLockTest( void )
TestResults::Destroy();
MultiLevelPool::DestroyPool();
+
+ cout << "Finished MultiThreadHierarchyMultiLockTest." << endl;
}
// ----------------------------------------------------------------------------
diff --git a/test/LevelMutex/ThreadPool.cpp b/test/LevelMutex/ThreadPool.cpp
index 8d30c30..79f6a2a 100644
--- a/test/LevelMutex/ThreadPool.cpp
+++ b/test/LevelMutex/ThreadPool.cpp
@@ -20,7 +20,7 @@
#include
-#include
+//#include
#if !defined( _MSC_VER )
#include // needed for the usleep function.
#endif
@@ -86,11 +86,13 @@ Thread::~Thread( void )
bool Thread::WaitForThread( void ) volatile
{
assert( IsValid( m_owner ) );
+
const volatile Thread * current = Thread::GetCurrentThread();
if ( this == current )
return false;
if ( m_status == Thread::Dead )
return false;
+
while ( this->m_status == Thread::Active )
{
// Call the wait policy.
@@ -100,6 +102,8 @@ bool Thread::WaitForThread( void ) volatile
::usleep( 1000 );
#endif
}
+
+ m_status = Thread::Idle;
return true;
}
diff --git a/test/LevelMutex/main.cpp b/test/LevelMutex/main.cpp
index a9ecf0a..aa863ca 100644
--- a/test/LevelMutex/main.cpp
+++ b/test/LevelMutex/main.cpp
@@ -48,6 +48,8 @@ typedef ::Loki::LevelMutex< ::Loki::SpinLevelMutex, 1,
void SingleThreadSimpleTest( void )
{
+ cout << "Starting SingleThreadSimpleTest." << endl;
+
const unsigned int priorLevel = GetCurrentThreadsLevel();
const unsigned int priorLockCount = CountLocksInCurrentThread();
const unsigned int priorMutexCount = CountMutexesInCurrentThread();
@@ -171,6 +173,8 @@ void SingleThreadSimpleTest( void )
assert( okay );
okay = ( CountMutexesAtCurrentLevel() == priorLevelMutexCount );
assert( okay );
+
+ cout << "Finished SingleThreadSimpleTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -178,6 +182,8 @@ void SingleThreadSimpleTest( void )
void SingleThreadReentrantTest( void )
{
+ cout << "Starting SingleThreadReentrantTest." << endl;
+
const unsigned int priorLevel = GetCurrentThreadsLevel();
const unsigned int priorLockCount = CountLocksInCurrentThread();
const unsigned int priorMutexCount = CountMutexesInCurrentThread();
@@ -283,6 +289,8 @@ void SingleThreadReentrantTest( void )
assert( okay );
okay = ( CountMutexesAtCurrentLevel() == priorLevelMutexCount );
assert( okay );
+
+ cout << "Finished SingleThreadReentrantTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -290,6 +298,8 @@ void SingleThreadReentrantTest( void )
void SingleThreadSimpleMultiLockTest( void )
{
+ cout << "Starting SingleThreadSimpleMultiLockTest." << endl;
+
const unsigned int priorLevel = GetCurrentThreadsLevel();
const unsigned int priorLockCount = CountLocksInCurrentThread();
const unsigned int priorMutexCount = CountMutexesInCurrentThread();
@@ -481,6 +491,8 @@ void SingleThreadSimpleMultiLockTest( void )
assert( okay );
okay = ( CountMutexesAtCurrentLevel() == priorLevelMutexCount );
assert( okay );
+
+ cout << "Finished SingleThreadSimpleMultiLockTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -488,6 +500,8 @@ void SingleThreadSimpleMultiLockTest( void )
void SingleThreadExceptionTest( void )
{
+ cout << "Starting SingleThreadExceptionTest." << endl;
+
const unsigned int priorLevel = GetCurrentThreadsLevel();
const unsigned int priorLockCount = CountLocksInCurrentThread();
const unsigned int priorMutexCount = CountMutexesInCurrentThread();
@@ -636,6 +650,8 @@ void SingleThreadExceptionTest( void )
assert( okay );
okay = ( CountMutexesAtCurrentLevel() == priorLevelMutexCount );
assert( okay );
+
+ cout << "Finished SingleThreadExceptionTest." << endl;
}
// ----------------------------------------------------------------------------
@@ -660,6 +676,7 @@ int main( int argc, const char * const argv[] )
MultiThreadSimpleTest();
MultiThreadTryLockTest();
+ cout << "main 679" << endl;
MultiThreadReentrantTest();
MultiThreadMultiLockTest();
MultiThreadRandomMultiLockTest();
diff --git a/test/LockingPtr/LockingPtr.cbp b/test/LockingPtr/LockingPtr.cbp
index 7e5f4ad..0631956 100644
--- a/test/LockingPtr/LockingPtr.cbp
+++ b/test/LockingPtr/LockingPtr.cbp
@@ -3,26 +3,27 @@
-
+
-
-
+
+
-
-
-
+
+
+
-
+
+
-
-
+
+
@@ -30,43 +31,44 @@
-
-
+
+
-
+
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
-
-
+
+
-
+
diff --git a/test/SmartPtr/SmartPtr.cbp b/test/SmartPtr/SmartPtr.cbp
index 69ea208..256aef7 100644
--- a/test/SmartPtr/SmartPtr.cbp
+++ b/test/SmartPtr/SmartPtr.cbp
@@ -6,23 +6,25 @@
-
-
+
+
-
-
-
+
+
+
-
+
+
+
-
-
+
+
@@ -30,31 +32,33 @@
-
-
+
+
-
+
+
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
@@ -62,11 +66,11 @@
-
-
+
+
-
+
@@ -74,6 +78,7 @@
+
diff --git a/test/SmartPtr/base.h b/test/SmartPtr/base.h
index c54889d..aa481af 100644
--- a/test/SmartPtr/base.h
+++ b/test/SmartPtr/base.h
@@ -73,9 +73,10 @@ public:
return s_destructions;
}
+protected:
+ BaseClass( const BaseClass & that ) : m_refCount( that.m_refCount ) {}
+
private:
- /// Not implemented.
- BaseClass( const BaseClass & );
/// Not implemented.
BaseClass & operator = ( const BaseClass & );
@@ -110,6 +111,44 @@ public:
}
};
+// ----------------------------------------------------------------------------
+
+/** @class Feline - The feline family of classes are to test dynamic_cast. Also used to test
+ pointers to arrays of objects.
+ */
+class Feline : public BaseClass
+{
+public:
+ virtual ~Feline() {}
+ virtual Feline * Clone( void ) const = 0;
+};
+
+class Lion : public Feline
+{
+public:
+ virtual ~Lion() {}
+ virtual Lion * Clone( void ) const { return new Lion( *this ); }
+};
+
+class Tiger : public Feline
+{
+public:
+ Tiger( void ) : m_stripes( 100 ) {}
+ virtual ~Tiger() {}
+ virtual Tiger * Clone( void ) const { return new Tiger( *this ); }
+ unsigned int GetStripes( void ) const { return m_stripes; }
+ void SetStripes( unsigned int s ) { m_stripes = s; }
+private:
+ unsigned int m_stripes;
+};
+
+class Dog
+{
+public:
+ virtual ~Dog() {}
+ virtual Dog * Clone( void ) const { return new Dog( *this ); }
+};
+
// ----------------------------------------------------------------------------
diff --git a/test/SmartPtr/main.cpp b/test/SmartPtr/main.cpp
index 66f9248..35e134a 100644
--- a/test/SmartPtr/main.cpp
+++ b/test/SmartPtr/main.cpp
@@ -1205,75 +1205,6 @@ void DoForwardReferenceTest( void )
// ----------------------------------------------------------------------------
-namespace
-{
-
- class Feline
- {
- public:
-
- static inline bool AllDestroyed( void )
- {
- return ( s_constructions == s_destructions );
- }
-
- static inline bool ExtraConstructions( void )
- {
- return ( s_constructions > s_destructions );
- }
-
- static inline bool ExtraDestructions( void )
- {
- return ( s_constructions < s_destructions );
- }
-
- static inline unsigned int GetCtorCount( void )
- {
- return s_constructions;
- }
-
- static inline unsigned int GetDtorCount( void )
- {
- return s_destructions;
- }
-
- Feline( void ) { s_constructions++; }
- virtual ~Feline() { s_destructions++; }
- virtual Feline * Clone( void ) const = 0;
-
- private:
- static unsigned int s_constructions;
- static unsigned int s_destructions;
- };
-
- unsigned int Feline::s_constructions = 0;
- unsigned int Feline::s_destructions = 0;
-
- class Tiger : public Feline
- {
- public:
- virtual ~Tiger() {}
- virtual Tiger * Clone( void ) const { return new Tiger( *this ); }
- };
-
- class Lion : public Feline
- {
- public:
- virtual ~Lion() {}
- virtual Lion * Clone( void ) const { return new Lion( *this ); }
- };
-
- class Dog
- {
- public:
- virtual ~Dog() {}
- virtual Dog * Clone( void ) const { return new Dog( *this ); }
- };
-
-}
-
-// ----------------------------------------------------------------------------
-
void DoSmartPtrDynamicCastTests( void )
{
cout << "Starting DoSmartPtrDynamicCastTests." << endl;
@@ -1359,9 +1290,9 @@ void DoSmartPtrDynamicCastTests( void )
assert( !pDog );
}
- assert( Feline::AllDestroyed() );
- assert( !Feline::ExtraConstructions() );
- assert( !Feline::ExtraDestructions() );
+ assert( BaseClass::AllDestroyed() );
+ assert( !BaseClass::ExtraConstructions() );
+ assert( !BaseClass::ExtraDestructions() );
cout << "Finished DoSmartPtrDynamicCastTests." << endl;
}
@@ -1518,6 +1449,161 @@ void DoDestructiveCopyTest( void )
// ----------------------------------------------------------------------------
+/// Use these typedefs to test DeleteArray policy.
+
+typedef Loki::SmartPtr< Tiger, RefCounted, DisallowConversion,
+ AssertCheck, ArrayStorage, DontPropagateConst >
+ TigerArray_RefCounted_ptr;
+
+typedef Loki::SmartPtr< Tiger, RefLinked, DisallowConversion,
+ AssertCheck, ArrayStorage, DontPropagateConst >
+ TigerArray_2RefLinks_ptr;
+
+// ----------------------------------------------------------------------------
+
+void DoSmartArrayTests( void )
+{
+ cout << "Starting DoSmartArrayTests." << endl;
+
+ {
+ // test default construction.
+ TigerArray_RefCounted_ptr sp1;
+ assert( !sp1 );
+ assert( 0 == sp1.GetArrayCount() );
+
+ // test assignment.
+ sp1.Assign( new Tiger[ 8 ], 8 );
+ assert( sp1 );
+ assert( 8 == sp1.GetArrayCount() );
+ sp1[ 0 ].SetStripes( 8 );
+ sp1[ 1 ].SetStripes( 16 );
+ sp1[ 2 ].SetStripes( 24 );
+ sp1[ 3 ].SetStripes( 32 );
+ sp1[ 4 ].SetStripes( 40);
+ sp1[ 5 ].SetStripes( 48 );
+ sp1[ 6 ].SetStripes( 56 );
+ sp1[ 7 ].SetStripes( 64 );
+
+ // test initialization construction.
+ TigerArray_RefCounted_ptr sp2( new Tiger[ 4 ], 4 );
+ assert( sp2 );
+ assert( 4 == sp2.GetArrayCount() );
+ sp2[ 0 ].SetStripes( 5 );
+ sp2[ 1 ].SetStripes( 10 );
+ sp2[ 2 ].SetStripes( 15 );
+ sp2[ 3 ].SetStripes( 20 );
+
+ // test range checking.
+ try
+ {
+ Tiger & p4 = sp2[ 4 ];
+ assert( false );
+ }
+ catch ( const ::std::out_of_range & ex )
+ {
+ assert( true );
+ }
+
+ // test range checking.
+ try
+ {
+ Tiger & p8 = sp1[ 8 ];
+ assert( false );
+ }
+ catch ( const ::std::out_of_range & ex )
+ {
+ assert( true );
+ }
+
+ // test swap.
+ sp2.Swap( sp1 );
+ assert( sp1 );
+ assert( sp2 );
+ // test checking of item count.
+ assert( 4 == sp1.GetArrayCount() );
+ assert( 8 == sp2.GetArrayCount() );
+
+ // test that operator[] returns reference to
+ assert( 5 == sp1[ 0 ].GetStripes() );
+ assert( 10 == sp1[ 1 ].GetStripes() );
+ assert( 15 == sp1[ 2 ].GetStripes() );
+ assert( 20 == sp1[ 3 ].GetStripes() );
+ assert( 8 == sp2[ 0 ].GetStripes() );
+ assert( 16 == sp2[ 1 ].GetStripes() );
+ assert( 24 == sp2[ 2 ].GetStripes() );
+ assert( 32 == sp2[ 3 ].GetStripes() );
+ assert( 40 == sp2[ 4 ].GetStripes() );
+ assert( 48 == sp2[ 5 ].GetStripes() );
+ assert( 56 == sp2[ 6 ].GetStripes() );
+ assert( 64 == sp2[ 7 ].GetStripes() );
+
+ try
+ {
+ Tiger & p4 = sp1[ 4 ];
+ assert( false );
+ }
+ catch ( const ::std::out_of_range & ex )
+ {
+ assert( true );
+ }
+
+ try
+ {
+ Tiger & p8 = sp2[ 8 ];
+ assert( false );
+ }
+ catch ( const ::std::out_of_range & ex )
+ {
+ assert( true );
+ }
+
+ const TigerArray_RefCounted_ptr sp3( sp1 );
+ assert( sp3 == sp1 );
+ assert( sp3.GetArrayCount() == sp1.GetArrayCount() );
+ try
+ {
+ const Tiger & p4 = sp3[ 4 ];
+ assert( false );
+ }
+ catch ( const ::std::out_of_range & ex )
+ {
+ assert( true );
+ }
+
+ const TigerArray_RefCounted_ptr sp5( sp2 );
+ assert( sp5 == sp2 );
+ assert( sp5.GetArrayCount() == sp2.GetArrayCount() );
+ try
+ {
+ const Tiger & p8 = sp5[ 8 ];
+ assert( false );
+ }
+ catch ( const ::std::out_of_range & ex )
+ {
+ assert( true );
+ }
+
+ sp2 = sp1;
+ assert( sp1 == sp2 );
+ assert( sp3 == sp2 );
+ assert( sp2.GetArrayCount() == sp1.GetArrayCount() );
+ assert( sp2.GetArrayCount() == sp1.GetArrayCount() );
+ assert( sp1 != sp5 );
+ assert( sp2 != sp5 );
+ assert( sp3 != sp5 );
+ assert( sp1.GetArrayCount() != sp5.GetArrayCount() );
+ assert( sp2.GetArrayCount() != sp5.GetArrayCount() );
+ assert( sp3.GetArrayCount() != sp5.GetArrayCount() );
+ }
+
+ assert( BaseClass::AllDestroyed() );
+ assert( !BaseClass::ExtraConstructions() );
+ assert( !BaseClass::ExtraDestructions() );
+ cout << "Finished DoSmartArrayTests." << endl;
+}
+
+// ----------------------------------------------------------------------------
+
int main( int argc, const char * argv[] )
{
bool doThreadTest = false;
@@ -1556,6 +1642,7 @@ int main( int argc, const char * argv[] )
DoSmartPtrDynamicCastTests();
DoStrongPtrDynamicCastTests();
DoStrongArrayTests();
+ DoSmartArrayTests();
#if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING)
if ( doThreadTest )
diff --git a/test/SmartPtr/strong.cpp b/test/SmartPtr/strong.cpp
index c7053f5..a859edc 100644
--- a/test/SmartPtr/strong.cpp
+++ b/test/SmartPtr/strong.cpp
@@ -1778,42 +1778,6 @@ void DoStrongCompareTests( void )
// ----------------------------------------------------------------------------
-namespace
-{
-
- class Feline : public BaseClass
- {
- public:
- virtual ~Feline() {}
- };
-
- class Lion : public Feline
- {
- public:
- virtual ~Lion() {}
- };
-
- class Tiger : public Feline
- {
- public:
- Tiger( void ) : m_stripes( 100 ) {}
- virtual ~Tiger() {}
- unsigned int GetStripes( void ) const { return m_stripes; }
- void SetStripes( unsigned int s ) { m_stripes = s; }
- private:
- unsigned int m_stripes;
- };
-
- class Dog
- {
- public:
- virtual ~Dog() {}
- };
-
-}
-
-// ----------------------------------------------------------------------------
-
void DoStrongPtrDynamicCastTests( void )
{
typedef ::Loki::StrongPtr< Feline, true, ::Loki::TwoRefCounts > FelineCountPtr;
diff --git a/test/ThreadLocal/ThreadLocal.cbp b/test/ThreadLocal/ThreadLocal.cbp
index 4132b68..fbe87dd 100644
--- a/test/ThreadLocal/ThreadLocal.cbp
+++ b/test/ThreadLocal/ThreadLocal.cbp
@@ -7,28 +7,37 @@
-
-
+
+
-
-
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
@@ -41,6 +50,7 @@
+
diff --git a/test/ThreadLocal/main.cpp b/test/ThreadLocal/main.cpp
index b304ab5..ab088da 100644
--- a/test/ThreadLocal/main.cpp
+++ b/test/ThreadLocal/main.cpp
@@ -26,18 +26,7 @@
#include
#include
-
-using namespace ::std;
-
-#if !defined( NULL )
- #define NULL 0
-#endif
-
-// define nullptr even though new compilers will have this keyword just so we
-// have a consistent and easy way of identifying which uses of 0 mean null.
-#if !defined( nullptr )
- #define nullptr NULL
-#endif
+#include
#if defined(_WIN32)
@@ -56,6 +45,8 @@ using namespace ::std;
#else
+ #include
+
#define LOKI_pthread_t \
pthread_t
#define LOKI_pthread_create(handle,attr,func,arg) \
@@ -65,6 +56,19 @@ using namespace ::std;
#endif
+
+using namespace ::std;
+
+#if !defined( NULL )
+ #define NULL 0
+#endif
+
+// define nullptr even though new compilers will have this keyword just so we
+// have a consistent and easy way of identifying which uses of 0 mean null.
+#if !defined( nullptr )
+ #define nullptr NULL
+#endif
+
// ----------------------------------------------------------------------------
class Thread
@@ -364,7 +368,10 @@ bool TestThreadLocalClassStaticValue( void )
// ----------------------------------------------------------------------------
int main( int argc, const char * const argv[] )
-{
+{
+ (void)argc;
+ (void)argv;
+
bool okay = true;
cout << "Starting ThreadLocal tests." << endl;
cout << "If any tests fail, or any assertions fail," << endl