Fixed bug 2082935 using overloaded version of AtomicDecrement.

git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@903 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
rich_sposato 2008-11-10 05:55:12 +00:00
parent c661dfc348
commit 464f643e19

View file

@ -2,14 +2,14 @@
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// 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 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"
// 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.
////////////////////////////////////////////////////////////////////////////////
#ifndef LOKI_SMARTPTR_INC_
@ -61,7 +61,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class HeapStorage
///
/// \ingroup SmartPointerStorageGroup
/// \ingroup SmartPointerStorageGroup
/// Implementation of the StoragePolicy used by SmartPtr. Uses explicit call
/// to T's destructor followed by call to free.
////////////////////////////////////////////////////////////////////////////////
@ -76,10 +76,10 @@ namespace Loki
typedef T* PointerType; /// type returned by operator->
typedef T& ReferenceType; /// type returned by operator*
HeapStorage() : pointee_(Default())
HeapStorage() : pointee_(Default())
{}
// The storage policy doesn't initialize the stored pointer
// The storage policy doesn't initialize the stored pointer
// which will be initialized by the OwnershipPolicy's Clone fn
HeapStorage(const HeapStorage&) : pointee_(0)
{}
@ -87,16 +87,16 @@ namespace Loki
template <class U>
HeapStorage(const HeapStorage<U>&) : pointee_(0)
{}
HeapStorage(const StoredType& p) : pointee_(p) {}
PointerType operator->() const { return pointee_; }
ReferenceType operator*() const { return *pointee_; }
void Swap(HeapStorage& rhs)
{ std::swap(pointee_, rhs.pointee_); }
// Accessors
template <class F>
friend typename HeapStorage<F>::PointerType GetImpl(const HeapStorage<F>& sp);
@ -122,7 +122,7 @@ namespace Loki
// Default value to initialize the pointer
static StoredType Default()
{ return 0; }
private:
// Data
StoredType pointee_;
@ -144,7 +144,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class DefaultSPStorage
///
/// \ingroup SmartPointerStorageGroup
/// \ingroup SmartPointerStorageGroup
/// Implementation of the StoragePolicy used by SmartPtr
////////////////////////////////////////////////////////////////////////////////
@ -158,10 +158,10 @@ namespace Loki
typedef T* PointerType; // type returned by operator->
typedef T& ReferenceType; // type returned by operator*
DefaultSPStorage() : pointee_(Default())
DefaultSPStorage() : pointee_(Default())
{}
// The storage policy doesn't initialize the stored pointer
// The storage policy doesn't initialize the stored pointer
// which will be initialized by the OwnershipPolicy's Clone fn
DefaultSPStorage(const DefaultSPStorage&) : pointee_(0)
{}
@ -169,16 +169,16 @@ namespace Loki
template <class U>
DefaultSPStorage(const DefaultSPStorage<U>&) : pointee_(0)
{}
DefaultSPStorage(const StoredType& p) : pointee_(p) {}
PointerType operator->() const { return pointee_; }
ReferenceType operator*() const { return *pointee_; }
void Swap(DefaultSPStorage& rhs)
{ std::swap(pointee_, rhs.pointee_); }
// Accessors
template <class F>
friend typename DefaultSPStorage<F>::PointerType GetImpl(const DefaultSPStorage<F>& sp);
@ -203,7 +203,7 @@ namespace Loki
// Default value to initialize the pointer
static StoredType Default()
{ return 0; }
private:
// Data
StoredType pointee_;
@ -225,7 +225,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class LockedStorage
///
/// \ingroup SmartPointerStorageGroup
/// \ingroup SmartPointerStorageGroup
/// Implementation of the StoragePolicy used by SmartPtr.
///
/// Each call to operator-> locks the object for the duration of a call to a
@ -351,7 +351,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class ArrayStorage
///
/// \ingroup SmartPointerStorageGroup
/// \ingroup SmartPointerStorageGroup
/// Implementation of the ArrayStorage used by SmartPtr
////////////////////////////////////////////////////////////////////////////////
@ -365,10 +365,10 @@ namespace Loki
typedef T* PointerType; // type returned by operator->
typedef T& ReferenceType; // type returned by operator*
ArrayStorage() : pointee_(Default())
ArrayStorage() : pointee_(Default())
{}
// The storage policy doesn't initialize the stored pointer
// The storage policy doesn't initialize the stored pointer
// which will be initialized by the OwnershipPolicy's Clone fn
ArrayStorage(const ArrayStorage&) : pointee_(0)
{}
@ -376,16 +376,16 @@ namespace Loki
template <class U>
ArrayStorage(const ArrayStorage<U>&) : pointee_(0)
{}
ArrayStorage(const StoredType& p) : pointee_(p) {}
PointerType operator->() const { return pointee_; }
ReferenceType operator*() const { return *pointee_; }
void Swap(ArrayStorage& rhs)
{ std::swap(pointee_, rhs.pointee_); }
// Accessors
template <class F>
friend typename ArrayStorage<F>::PointerType GetImpl(const ArrayStorage<F>& sp);
@ -401,11 +401,11 @@ namespace Loki
// (Destruction might be taken over by the OwnershipPolicy)
void Destroy()
{ delete [] pointee_; }
// Default value to initialize the pointer
static StoredType Default()
{ return 0; }
private:
// Data
StoredType pointee_;
@ -427,7 +427,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class RefCounted
///
/// \ingroup SmartPointerOwnershipGroup
/// \ingroup SmartPointerOwnershipGroup
/// Implementation of the OwnershipPolicy used by SmartPtr
/// Provides a classic external reference counting implementation
////////////////////////////////////////////////////////////////////////////////
@ -436,30 +436,30 @@ namespace Loki
class RefCounted
{
public:
RefCounted()
RefCounted()
: pCount_(static_cast<uintptr_t*>(
SmallObject<>::operator new(sizeof(uintptr_t))))
{
assert(pCount_!=0);
*pCount_ = 1;
}
RefCounted(const RefCounted& rhs)
RefCounted(const RefCounted& rhs)
: pCount_(rhs.pCount_)
{}
// MWCW lacks template friends, hence the following kludge
template <typename P1>
RefCounted(const RefCounted<P1>& rhs)
RefCounted(const RefCounted<P1>& rhs)
: pCount_(reinterpret_cast<const RefCounted&>(rhs).pCount_)
{}
P Clone(const P& val)
{
++*pCount_;
return val;
}
bool Release(const P&)
{
if (!--*pCount_)
@ -470,21 +470,21 @@ namespace Loki
}
return false;
}
void Swap(RefCounted& rhs)
{ std::swap(pCount_, rhs.pCount_); }
enum { destructiveCopy = false };
private:
// Data
uintptr_t* pCount_;
};
////////////////////////////////////////////////////////////////////////////////
/// \struct RefCountedMT
///
/// \ingroup SmartPointerOwnershipGroup
/// \ingroup SmartPointerOwnershipGroup
/// Implementation of the OwnershipPolicy used by SmartPtr
/// Implements external reference counting for multithreaded programs
/// Policy Usage: RefCountedMTAdj<ThreadingModel>::RefCountedMT
@ -499,7 +499,7 @@ namespace Loki
/// implies a design flaw at a higher level. That race condition must be
/// fixed at a higher design level, and no change to this class could fix it.
////////////////////////////////////////////////////////////////////////////////
template <template <class, class> class ThreadingModel,
class MX = LOKI_DEFAULT_MUTEX >
struct RefCountedMTAdj
@ -512,7 +512,7 @@ namespace Loki
typedef volatile CountType *CountPtrType;
public:
RefCountedMT()
RefCountedMT()
{
pCount_ = static_cast<CountPtrType>(
SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator new(
@ -522,13 +522,13 @@ namespace Loki
ThreadingModel<RefCountedMT, MX>::AtomicAssign(*pCount_, 1);
}
RefCountedMT(const RefCountedMT& rhs)
RefCountedMT(const RefCountedMT& rhs)
: pCount_(rhs.pCount_)
{}
//MWCW lacks template friends, hence the following kludge
template <typename P1>
RefCountedMT(const RefCountedMT<P1>& rhs)
RefCountedMT(const RefCountedMT<P1>& rhs)
: pCount_(reinterpret_cast<const RefCountedMT<P>&>(rhs).pCount_)
{}
@ -540,10 +540,12 @@ namespace Loki
bool Release(const P&)
{
if (!ThreadingModel<RefCountedMT, MX>::AtomicDecrement(*pCount_))
bool isZero = false;
ThreadingModel< RefCountedMT, MX >::AtomicDecrement( *pCount_, 0, isZero );
if ( isZero )
{
SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator delete(
const_cast<CountType *>(pCount_),
const_cast<CountType *>(pCount_),
sizeof(*pCount_));
return true;
}
@ -564,7 +566,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class COMRefCounted
///
/// \ingroup SmartPointerOwnershipGroup
/// \ingroup SmartPointerOwnershipGroup
/// Implementation of the OwnershipPolicy used by SmartPtr
/// Adapts COM intrusive reference counting to OwnershipPolicy-specific syntax
////////////////////////////////////////////////////////////////////////////////
@ -575,27 +577,27 @@ namespace Loki
public:
COMRefCounted()
{}
template <class U>
COMRefCounted(const COMRefCounted<U>&)
{}
static P Clone(const P& val)
{
if(val!=0)
val->AddRef();
return val;
}
static bool Release(const P& val)
{
if(val!=0)
val->Release();
return false;
{
if(val!=0)
val->Release();
return false;
}
enum { destructiveCopy = false };
static void Swap(COMRefCounted&)
{}
};
@ -603,9 +605,9 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \struct DeepCopy
///
/// \ingroup SmartPointerOwnershipGroup
/// \ingroup SmartPointerOwnershipGroup
/// Implementation of the OwnershipPolicy used by SmartPtr
/// Implements deep copy semantics, assumes existence of a Clone() member
/// Implements deep copy semantics, assumes existence of a Clone() member
/// function of the pointee type
////////////////////////////////////////////////////////////////////////////////
@ -614,27 +616,27 @@ namespace Loki
{
DeepCopy()
{}
template <class P1>
DeepCopy(const DeepCopy<P1>&)
{}
static P Clone(const P& val)
{ return val->Clone(); }
static bool Release(const P&)
{ return true; }
static void Swap(DeepCopy&)
{}
enum { destructiveCopy = false };
};
////////////////////////////////////////////////////////////////////////////////
/// \class RefLinked
///
/// \ingroup SmartPointerOwnershipGroup
/// \ingroup SmartPointerOwnershipGroup
/// Implementation of the OwnershipPolicy used by SmartPtr
/// Implements reference linking
////////////////////////////////////////////////////////////////////////////////
@ -644,7 +646,7 @@ namespace Loki
class LOKI_EXPORT RefLinkedBase
{
public:
RefLinkedBase()
RefLinkedBase()
{ prev_ = next_ = this; }
RefLinkedBase(const RefLinkedBase& rhs);
@ -667,16 +669,16 @@ namespace Loki
mutable const RefLinkedBase* next_;
};
}
template <class P>
class RefLinked : public Private::RefLinkedBase
{
public:
RefLinked()
{}
template <class P1>
RefLinked(const RefLinked<P1>& rhs)
RefLinked(const RefLinked<P1>& rhs)
: Private::RefLinkedBase(rhs)
{}
@ -692,11 +694,11 @@ namespace Loki
return Private::RefLinkedBase::Merge( rhs );
}
};
////////////////////////////////////////////////////////////////////////////////
/// \class DestructiveCopy
///
/// \ingroup SmartPointerOwnershipGroup
/// \ingroup SmartPointerOwnershipGroup
/// Implementation of the OwnershipPolicy used by SmartPtr
/// Implements destructive copy semantics (a la std::auto_ptr)
////////////////////////////////////////////////////////////////////////////////
@ -707,11 +709,11 @@ namespace Loki
public:
DestructiveCopy()
{}
template <class P1>
DestructiveCopy(const DestructiveCopy<P1>&)
{}
template <class P1>
static P Clone(P1& val)
{
@ -719,20 +721,20 @@ namespace Loki
val = P1();
return result;
}
static bool Release(const P&)
{ return true; }
static void Swap(DestructiveCopy&)
{}
enum { destructiveCopy = true };
};
////////////////////////////////////////////////////////////////////////////////
/// \class NoCopy
///
/// \ingroup SmartPointerOwnershipGroup
/// \ingroup SmartPointerOwnershipGroup
/// Implementation of the OwnershipPolicy used by SmartPtr
/// Implements a policy that doesn't allow copying objects
////////////////////////////////////////////////////////////////////////////////
@ -743,11 +745,11 @@ namespace Loki
public:
NoCopy()
{}
template <class P1>
NoCopy(const NoCopy<P1>&)
{}
static P Clone(const P&)
{
// Make it depended on template parameter
@ -755,20 +757,20 @@ namespace Loki
LOKI_STATIC_CHECK(DependedFalse, This_Policy_Disallows_Value_Copying);
}
static bool Release(const P&)
{ return true; }
static void Swap(NoCopy&)
{}
enum { destructiveCopy = false };
};
////////////////////////////////////////////////////////////////////////////////
/// \struct AllowConversion
///
/// \ingroup SmartPointerConversionGroup
///
/// \ingroup SmartPointerConversionGroup
/// Implementation of the ConversionPolicy used by SmartPtr
/// Allows implicit conversion from SmartPtr to the pointee type
////////////////////////////////////////////////////////////////////////////////
@ -784,7 +786,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \struct DisallowConversion
///
/// \ingroup SmartPointerConversionGroup
/// \ingroup SmartPointerConversionGroup
/// Implementation of the ConversionPolicy used by SmartPtr
/// Does not allow implicit conversion from SmartPtr to the pointee type
/// You can initialize a DisallowConversion with an AllowConversion
@ -794,10 +796,10 @@ namespace Loki
{
DisallowConversion()
{}
DisallowConversion(const AllowConversion&)
{}
enum { allow = false };
void Swap(DisallowConversion&)
@ -807,7 +809,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \struct NoCheck
///
/// \ingroup SmartPointerCheckingGroup
/// \ingroup SmartPointerCheckingGroup
/// Implementation of the CheckingPolicy used by SmartPtr
/// Well, it's clear what it does :o)
////////////////////////////////////////////////////////////////////////////////
@ -817,11 +819,11 @@ namespace Loki
{
NoCheck()
{}
template <class P1>
NoCheck(const NoCheck<P1>&)
{}
static void OnDefault(const P&)
{}
@ -839,7 +841,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \struct AssertCheck
///
/// \ingroup SmartPointerCheckingGroup
/// \ingroup SmartPointerCheckingGroup
/// Implementation of the CheckingPolicy used by SmartPtr
/// Checks the pointer before dereference
////////////////////////////////////////////////////////////////////////////////
@ -849,15 +851,15 @@ namespace Loki
{
AssertCheck()
{}
template <class P1>
AssertCheck(const AssertCheck<P1>&)
{}
template <class P1>
AssertCheck(const NoCheck<P1>&)
{}
static void OnDefault(const P&)
{}
@ -874,10 +876,10 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \struct AssertCheckStrict
///
/// \ingroup SmartPointerCheckingGroup
/// \ingroup SmartPointerCheckingGroup
/// Implementation of the CheckingPolicy used by SmartPtr
/// Checks the pointer against zero upon initialization and before dereference
/// You can initialize an AssertCheckStrict with an AssertCheck
/// You can initialize an AssertCheckStrict with an AssertCheck
////////////////////////////////////////////////////////////////////////////////
template <class P>
@ -885,28 +887,28 @@ namespace Loki
{
AssertCheckStrict()
{}
template <class U>
AssertCheckStrict(const AssertCheckStrict<U>&)
{}
template <class U>
AssertCheckStrict(const AssertCheck<U>&)
{}
template <class P1>
AssertCheckStrict(const NoCheck<P1>&)
{}
static void OnDefault(P val)
{ assert(val); }
static void OnInit(P val)
{ assert(val); }
static void OnDereference(P val)
{ assert(val); }
static void Swap(AssertCheckStrict&)
{}
};
@ -914,7 +916,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \struct NullPointerException
///
/// \ingroup SmartPointerGroup
/// \ingroup SmartPointerGroup
/// Used by some implementations of the CheckingPolicy used by SmartPtr
////////////////////////////////////////////////////////////////////////////////
@ -925,11 +927,11 @@ namespace Loki
const char* what() const throw()
{ return "Null Pointer Exception"; }
};
////////////////////////////////////////////////////////////////////////////////
/// \struct RejectNullStatic
///
/// \ingroup SmartPointerCheckingGroup
/// \ingroup SmartPointerCheckingGroup
/// Implementation of the CheckingPolicy used by SmartPtr
/// Checks the pointer upon initialization and before dereference
////////////////////////////////////////////////////////////////////////////////
@ -939,23 +941,23 @@ namespace Loki
{
RejectNullStatic()
{}
template <class P1>
RejectNullStatic(const RejectNullStatic<P1>&)
{}
template <class P1>
RejectNullStatic(const NoCheck<P1>&)
{}
template <class P1>
RejectNullStatic(const AssertCheck<P1>&)
{}
template <class P1>
RejectNullStatic(const AssertCheckStrict<P1>&)
{}
static void OnDefault(const P&)
{
// Make it depended on template parameter
@ -963,13 +965,13 @@ namespace Loki
LOKI_STATIC_CHECK(DependedFalse, ERROR_This_Policy_Does_Not_Allow_Default_Initialization);
}
static void OnInit(const P& val)
{ if (!val) throw NullPointerException(); }
static void OnDereference(const P& val)
{ if (!val) throw NullPointerException(); }
static void Swap(RejectNullStatic&)
{}
};
@ -977,7 +979,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \struct RejectNull
///
/// \ingroup SmartPointerCheckingGroup
/// \ingroup SmartPointerCheckingGroup
/// Implementation of the CheckingPolicy used by SmartPtr
/// Checks the pointer before dereference
////////////////////////////////////////////////////////////////////////////////
@ -987,31 +989,31 @@ namespace Loki
{
RejectNull()
{}
template <class P1>
RejectNull(const RejectNull<P1>&)
{}
static void OnInit(P)
{}
static void OnDefault(P)
{}
void OnDereference(P val)
{ if (!val) throw NullPointerException(); }
void OnDereference(P val) const
{ if (!val) throw NullPointerException(); }
void Swap(RejectNull&)
{}
{}
};
////////////////////////////////////////////////////////////////////////////////
/// \struct RejectNullStrict
///
/// \ingroup SmartPointerCheckingGroup
/// \ingroup SmartPointerCheckingGroup
/// Implementation of the CheckingPolicy used by SmartPtr
/// Checks the pointer upon initialization and before dereference
////////////////////////////////////////////////////////////////////////////////
@ -1021,15 +1023,15 @@ namespace Loki
{
RejectNullStrict()
{}
template <class P1>
RejectNullStrict(const RejectNullStrict<P1>&)
{}
template <class P1>
RejectNullStrict(const RejectNull<P1>&)
{}
static void OnInit(P val)
{ if (!val) throw NullPointerException(); }
@ -1040,7 +1042,7 @@ namespace Loki
{ OnInit(val); }
void Swap(RejectNullStrict&)
{}
{}
};
@ -1056,13 +1058,13 @@ namespace Loki
class ConversionPolicy = DisallowConversion,
template <class> class CheckingPolicy = AssertCheck,
template <class> class StoragePolicy = DefaultSPStorage,
template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
>
class SmartPtr;
////////////////////////////////////////////////////////////////////////////////
// class template SmartPtrDef (definition)
// this class added to unify the usage of SmartPtr
// this class added to unify the usage of SmartPtr
// instead of writing SmartPtr<T,OP,CP,KP,SP> write SmartPtrDef<T,OP,CP,KP,SP>::type
////////////////////////////////////////////////////////////////////////////////
@ -1073,7 +1075,7 @@ namespace Loki
class ConversionPolicy = DisallowConversion,
template <class> class CheckingPolicy = AssertCheck,
template <class> class StoragePolicy = DefaultSPStorage,
template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
>
struct SmartPtrDef
{
@ -1092,7 +1094,7 @@ namespace Loki
////////////////////////////////////////////////////////////////////////////////
/// \class SmartPtr
///
/// \ingroup SmartPointerGroup
/// \ingroup SmartPointerGroup
///
/// \param OwnershipPolicy default = RefCounted,
/// \param ConversionPolicy default = DisallowConversion,
@ -1127,7 +1129,7 @@ namespace Loki
typedef OwnershipPolicy<typename StoragePolicy<T>::InitPointerType> OP;
typedef CheckingPolicy<typename StoragePolicy<T>::StoredType> KP;
typedef ConversionPolicy CP;
public:
typedef typename ConstnessPolicy<T>::Type* ConstPointerType;
typedef typename ConstnessPolicy<T>::Type& ConstReferenceType;
@ -1135,13 +1137,13 @@ namespace Loki
typedef typename SP::PointerType PointerType;
typedef typename SP::StoredType StoredType;
typedef typename SP::ReferenceType ReferenceType;
typedef typename Select<OP::destructiveCopy,SmartPtr, const SmartPtr>::Result
CopyArg;
private:
struct NeverMatched {};
#ifdef LOKI_SMARTPTR_CONVERSION_CONSTRUCTOR_POLICY
typedef typename Select< CP::allow, const StoredType&, NeverMatched>::Result ImplicitArg;
typedef typename Select<!CP::allow, const StoredType&, NeverMatched>::Result ExplicitArg;
@ -1156,7 +1158,7 @@ namespace Loki
{
KP::OnDefault(GetImpl(*this));
}
explicit
SmartPtr(ExplicitArg p) : SP(p)
{
@ -1204,7 +1206,7 @@ namespace Loki
SmartPtr(RefToValue<SmartPtr> rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{}
operator RefToValue<SmartPtr>()
{ return RefToValue<SmartPtr>(*this); }
@ -1230,7 +1232,7 @@ namespace Loki
temp.Swap(*this);
return *this;
}
template
<
typename T1,
@ -1246,7 +1248,7 @@ namespace Loki
temp.Swap(*this);
return *this;
}
void Swap(SmartPtr& rhs)
{
OP::Swap(rhs);
@ -1254,7 +1256,7 @@ namespace Loki
KP::Swap(rhs);
SP::Swap(rhs);
}
~SmartPtr()
{
if (OP::Release(GetImpl(*static_cast<SP*>(this))))
@ -1271,7 +1273,7 @@ namespace Loki
p = GetImplRef(sp);
GetImplRef(sp) = SP::Default();
}
friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
{ SmartPtr(p).Swap(sp); }
@ -1338,13 +1340,13 @@ namespace Loki
KP::OnDereference(GetImplRef(*this));
return SP::operator*();
}
ConstReferenceType operator*() const
{
KP::OnDereference(GetImplRef(*this));
return SP::operator*();
}
bool operator!() const // Enables "if (!sp) ..."
{ return GetImpl(*this) == 0; }
@ -1442,7 +1444,7 @@ namespace Loki
Tester(int) {}
void dummy() {}
};
typedef void (Tester::*unspecified_boolean_type_)();
typedef typename Select<CP::allow, Tester, unspecified_boolean_type_>::Result
@ -1461,11 +1463,11 @@ namespace Loki
{
Insipid(PointerType) {}
};
typedef typename Select<CP::allow, PointerType, Insipid>::Result
AutomaticConversionResult;
public:
public:
operator AutomaticConversionResult() const
{ return GetImpl(*this); }
};
@ -1568,7 +1570,7 @@ namespace Loki
inline bool operator!=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
U* rhs)
{ return !(lhs == rhs); }
////////////////////////////////////////////////////////////////////////////////
/// operator!= for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
@ -1648,7 +1650,7 @@ namespace Loki
inline bool operator>(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
U* rhs)
{ return rhs < lhs; }
////////////////////////////////////////////////////////////////////////////////
/// operator> for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
@ -1667,7 +1669,7 @@ namespace Loki
inline bool operator>(U* lhs,
const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
{ return rhs < lhs; }
////////////////////////////////////////////////////////////////////////////////
/// operator<= for lhs = SmartPtr, rhs = raw pointer
/// \ingroup SmartPointerGroup
@ -1686,7 +1688,7 @@ namespace Loki
inline bool operator<=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
U* rhs)
{ return !(rhs < lhs); }
////////////////////////////////////////////////////////////////////////////////
/// operator<= for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup
@ -1724,7 +1726,7 @@ namespace Loki
inline bool operator>=(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
U* rhs)
{ return !(lhs < rhs); }
////////////////////////////////////////////////////////////////////////////////
/// operator>= for lhs = raw pointer, rhs = SmartPtr
/// \ingroup SmartPointerGroup