From 9f532a3ea09ad0aef8a9bfe1a4bb2547f33487d4 Mon Sep 17 00:00:00 2001 From: rich_sposato Date: Sat, 25 Feb 2006 01:52:17 +0000 Subject: [PATCH] Moved a monolithic base class from header file to new source file. git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@548 7ec92016-0320-0410-acc4-a06ded1c099a --- include/loki/SmartPtr.h | 170 +++++++++++++++------------------------- src/Library.vcproj | 4 + src/SmartPtr.cpp | 123 +++++++++++++++++++++++++++++ 3 files changed, 191 insertions(+), 106 deletions(-) create mode 100644 src/SmartPtr.cpp diff --git a/include/loki/SmartPtr.h b/include/loki/SmartPtr.h index 321f9de..4fb6b6e 100644 --- a/include/loki/SmartPtr.h +++ b/include/loki/SmartPtr.h @@ -207,6 +207,7 @@ namespace Loki if (!--*pCount_) { SmallObject<>::operator delete(pCount_, sizeof(uintptr_t)); + pCount_ = NULL; return true; } return false; @@ -353,7 +354,7 @@ namespace Loki static P Clone(const P& val) { return val->Clone(); } - static bool Release(const P& val) + static bool Release(const P&) { return true; } static void Swap(DeepCopy&) @@ -377,79 +378,13 @@ namespace Loki public: RefLinkedBase() { prev_ = next_ = this; } - - RefLinkedBase(const RefLinkedBase& rhs) - { - prev_ = &rhs; - next_ = rhs.next_; - prev_->next_ = this; - next_->prev_ = this; - } - - bool Release() - { - if ( NULL == next_ ) - { - assert( NULL == prev_ ); - // Return false so it does not try to destroy shared object - // more than once. - return false; - } - else if (next_ == this) - { - assert(prev_ == this); - // Set these to NULL to prevent re-entrancy. - prev_ = NULL; - next_ = NULL; - return true; - } - assert( this != prev_ ); - assert( NULL != prev_ ); - prev_->next_ = next_; - next_->prev_ = prev_; - return false; - } - void Swap(RefLinkedBase& rhs) - { - if (next_ == this) - { - assert(prev_ == this); - if (rhs.next_ == &rhs) - { - assert(rhs.prev_ == &rhs); - // both lists are empty, nothing 2 do - return; - } - prev_ = rhs.prev_; - next_ = rhs.next_; - prev_->next_ = next_->prev_ = this; - rhs.next_ = rhs.prev_ = &rhs; - return; - } - if (rhs.next_ == &rhs) - { - rhs.Swap(*this); - return; - } - if (next_ == &rhs ) // neighbours - { - std::swap(prev_, next_); - std::swap(rhs.prev_, rhs.next_); - std::swap(rhs.prev_, next_); - std::swap(rhs.prev_->next_,next_->prev_); - } - else - { - std::swap(prev_, rhs.prev_); - std::swap(next_, rhs.next_); - std::swap(prev_->next_, rhs.prev_->next_); - std::swap(next_->prev_, rhs.next_->prev_); - } - - assert( next_ == this ? prev_ == this : prev_ != this); - } - + RefLinkedBase(const RefLinkedBase& rhs); + + bool Release(); + + void Swap(RefLinkedBase& rhs); + enum { destructiveCopy = false }; private: @@ -890,7 +825,7 @@ namespace Loki class ConversionPolicy, template class CheckingPolicy, template class StoragePolicy, - template class ConstnessPolicy + template class ConstnessPolicy > class SmartPtr : public StoragePolicy @@ -948,9 +883,10 @@ namespace Loki template class OP1, class CP1, template class KP1, - template class SP1 + template class SP1, + template class CNP1 > - SmartPtr(const SmartPtr& rhs) + SmartPtr(const SmartPtr& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } @@ -960,9 +896,10 @@ namespace Loki template class OP1, class CP1, template class KP1, - template class SP1 + template class SP1, + template class CNP1 > - SmartPtr(SmartPtr& rhs) + SmartPtr(SmartPtr& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } @@ -986,9 +923,10 @@ namespace Loki template class OP1, class CP1, template class KP1, - template class SP1 + template class SP1, + template class CNP1 > - SmartPtr& operator=(const SmartPtr& rhs) + SmartPtr& operator=(const SmartPtr& rhs) { SmartPtr temp(rhs); temp.Swap(*this); @@ -1001,9 +939,10 @@ namespace Loki template class OP1, class CP1, template class KP1, - template class SP1 + template class SP1, + template class CNP1 > - SmartPtr& operator=(SmartPtr& rhs) + SmartPtr& operator=(SmartPtr& rhs) { SmartPtr temp(rhs); temp.Swap(*this); @@ -1070,9 +1009,10 @@ namespace Loki template class OP1, class CP1, template class KP1, - template class SP1 + template class SP1, + template class CNP1 > - bool operator==(const SmartPtr& rhs) const + bool operator==(const SmartPtr& rhs) const { return GetImpl(*this) == GetImpl(rhs); } // Ambiguity buster @@ -1082,9 +1022,10 @@ namespace Loki template class OP1, class CP1, template class KP1, - template class SP1 + template class SP1, + template class CNP1 > - bool operator!=(const SmartPtr& rhs) const + bool operator!=(const SmartPtr& rhs) const { return !(*this == rhs); } // Ambiguity buster @@ -1094,9 +1035,10 @@ namespace Loki template class OP1, class CP1, template class KP1, - template class SP1 + template class SP1, + template class CNP1 > - bool operator<(const SmartPtr& rhs) const + bool operator<(const SmartPtr& rhs) const { return GetImpl(*this) < GetImpl(rhs); } private: @@ -1150,9 +1092,10 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > - inline bool operator==(const SmartPtr& lhs, + inline bool operator==(const SmartPtr& lhs, U* rhs) { return GetImpl(lhs) == rhs; } @@ -1168,10 +1111,11 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > inline bool operator==(U* lhs, - const SmartPtr& rhs) + const SmartPtr& rhs) { return rhs == lhs; } //////////////////////////////////////////////////////////////////////////////// @@ -1186,9 +1130,10 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > - inline bool operator!=(const SmartPtr& lhs, + inline bool operator!=(const SmartPtr& lhs, U* rhs) { return !(lhs == rhs); } @@ -1204,10 +1149,11 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > inline bool operator!=(U* lhs, - const SmartPtr& rhs) + const SmartPtr& rhs) { return rhs != lhs; } //////////////////////////////////////////////////////////////////////////////// @@ -1222,9 +1168,10 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > - inline bool operator<(const SmartPtr& lhs, + inline bool operator<(const SmartPtr& lhs, U* rhs); //////////////////////////////////////////////////////////////////////////////// @@ -1239,10 +1186,11 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > inline bool operator<(U* lhs, - const SmartPtr& rhs); + const SmartPtr& rhs); //////////////////////////////////////////////////////////////////////////////// // operator> for lhs = SmartPtr, rhs = raw pointer -- NOT DEFINED @@ -1256,9 +1204,10 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > - inline bool operator>(const SmartPtr& lhs, + inline bool operator>(const SmartPtr& lhs, U* rhs) { return rhs < lhs; } @@ -1274,10 +1223,11 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > inline bool operator>(U* lhs, - const SmartPtr& rhs) + const SmartPtr& rhs) { return rhs < lhs; } //////////////////////////////////////////////////////////////////////////////// @@ -1292,9 +1242,10 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > - inline bool operator<=(const SmartPtr& lhs, + inline bool operator<=(const SmartPtr& lhs, U* rhs) { return !(rhs < lhs); } @@ -1310,10 +1261,11 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > inline bool operator<=(U* lhs, - const SmartPtr& rhs) + const SmartPtr& rhs) { return !(rhs < lhs); } //////////////////////////////////////////////////////////////////////////////// @@ -1328,9 +1280,10 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > - inline bool operator>=(const SmartPtr& lhs, + inline bool operator>=(const SmartPtr& lhs, U* rhs) { return !(lhs < rhs); } @@ -1346,10 +1299,11 @@ namespace Loki class CP, template class KP, template class SP, + template class CNP1, typename U > inline bool operator>=(U* lhs, - const SmartPtr& rhs) + const SmartPtr& rhs) { return !(lhs < rhs); } } // namespace Loki @@ -1367,14 +1321,15 @@ namespace std template class OP, class CP, template class KP, - template class SP + template class SP, + template class CNP1 > - struct less< Loki::SmartPtr > - : public binary_function, - Loki::SmartPtr, bool> + struct less< Loki::SmartPtr > + : public binary_function, + Loki::SmartPtr, bool> { - bool operator()(const Loki::SmartPtr& lhs, - const Loki::SmartPtr& rhs) const + bool operator()(const Loki::SmartPtr& lhs, + const Loki::SmartPtr& rhs) const { return less()(GetImpl(lhs), GetImpl(rhs)); } }; } @@ -1398,6 +1353,9 @@ namespace std #endif // SMARTPTR_INC_ // $Log$ +// Revision 1.18 2006/02/25 01:52:17 rich_sposato +// Moved a monolithic base class from header file to new source file. +// // Revision 1.17 2006/02/19 22:04:28 rich_sposato // Moved Const-policy structs from SmartPtr.h to ConstPolicy.h. // diff --git a/src/Library.vcproj b/src/Library.vcproj index 6f0a75b..4adf636 100755 --- a/src/Library.vcproj +++ b/src/Library.vcproj @@ -311,6 +311,10 @@ RelativePath=".\SmallObj.cpp" > + + diff --git a/src/SmartPtr.cpp b/src/SmartPtr.cpp new file mode 100644 index 0000000..593ebfc --- /dev/null +++ b/src/SmartPtr.cpp @@ -0,0 +1,123 @@ +//////////////////////////////////////////////////////////////////////////////// +// The Loki Library +// Copyright (c) 2001 by Andrei Alexandrescu +// Copyright (c) 2006 Richard Sposato +// This code accompanies the book: +// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// Patterns Applied". Copyright (c) 2001. Addison-Wesley. +// 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 or Addison-Wesley Longman make no representations about the +// suitability of this software for any purpose. It is provided "as is" +// without express or implied warranty. +//////////////////////////////////////////////////////////////////////////////// + +// $Header$ + +#include + +#include + + +// ---------------------------------------------------------------------------- + +namespace Loki +{ + +namespace Private +{ + +// ---------------------------------------------------------------------------- + +RefLinkedBase::RefLinkedBase(const RefLinkedBase& rhs) +{ + prev_ = &rhs; + next_ = rhs.next_; + prev_->next_ = this; + next_->prev_ = this; +} + +// ---------------------------------------------------------------------------- + +bool RefLinkedBase::Release() +{ + if ( NULL == next_ ) + { + assert( NULL == prev_ ); + // Return false so it does not try to destroy shared object + // more than once. + return false; + } + else if (next_ == this) + { + assert(prev_ == this); + // Set these to NULL to prevent re-entrancy. + prev_ = NULL; + next_ = NULL; + return true; + } + assert( this != prev_ ); + assert( NULL != prev_ ); + prev_->next_ = next_; + next_->prev_ = prev_; + return false; +} + +// ---------------------------------------------------------------------------- + +void RefLinkedBase::Swap(RefLinkedBase& rhs) +{ + if (next_ == this) + { + assert(prev_ == this); + if (rhs.next_ == &rhs) + { + assert(rhs.prev_ == &rhs); + // both lists are empty, nothing 2 do + return; + } + prev_ = rhs.prev_; + next_ = rhs.next_; + prev_->next_ = next_->prev_ = this; + rhs.next_ = rhs.prev_ = &rhs; + return; + } + if (rhs.next_ == &rhs) + { + rhs.Swap(*this); + return; + } + if (next_ == &rhs ) // neighbours + { + if ( prev_ == &rhs ) + return; // cycle of 2 pointers - no need to swap. + std::swap(prev_, next_); + std::swap(rhs.prev_, rhs.next_); + std::swap(rhs.prev_, next_); + std::swap(rhs.prev_->next_,next_->prev_); + } + else + { + std::swap(prev_, rhs.prev_); + std::swap(next_, rhs.next_); + std::swap(prev_->next_, rhs.prev_->next_); + std::swap(next_->prev_, rhs.next_->prev_); + } + + assert( next_ == this ? prev_ == this : prev_ != this); +} + +// ---------------------------------------------------------------------------- + +}; // end namespace Private + +}; // end namespace Loki + +// ---------------------------------------------------------------------------- + +// $Log$ +// Revision 1.1 2006/02/25 01:52:17 rich_sposato +// Moved a monolithic base class from header file to new source file. +//