summaryrefslogtreecommitdiff
path: root/shared/loki/SmartPtr.h
diff options
context:
space:
mode:
authorDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:16 +0200
committerDaniel Wilhelm <daniel@wili.li>2014-04-18 17:15:16 +0200
commitbd6336c629841c6db3a6ca53a936d629d34db53b (patch)
tree3721ef997864108df175ce677a8a7d4342a6f1d2 /shared/loki/SmartPtr.h
parent4.0 (diff)
downloadFreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.tar.gz
FreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.tar.bz2
FreeFileSync-bd6336c629841c6db3a6ca53a936d629d34db53b.zip
4.1
Diffstat (limited to 'shared/loki/SmartPtr.h')
-rw-r--r--shared/loki/SmartPtr.h1778
1 files changed, 0 insertions, 1778 deletions
diff --git a/shared/loki/SmartPtr.h b/shared/loki/SmartPtr.h
deleted file mode 100644
index 6f6f9996..00000000
--- a/shared/loki/SmartPtr.h
+++ /dev/null
@@ -1,1778 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// The Loki Library
-// Copyright (c) 2001 by Andrei Alexandrescu
-// 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.
-////////////////////////////////////////////////////////////////////////////////
-#ifndef LOKI_SMARTPTR_INC_
-#define LOKI_SMARTPTR_INC_
-
-// $Id: SmartPtr.h 903 2008-11-10 05:55:12Z rich_sposato $
-
-
-/// \defgroup SmartPointerGroup Smart pointers
-/// Policy based implementation of a smart pointer
-/// \defgroup SmartPointerOwnershipGroup Ownership policies
-/// \ingroup SmartPointerGroup
-/// \defgroup SmartPointerStorageGroup Storage policies
-/// \ingroup SmartPointerGroup
-/// \defgroup SmartPointerConversionGroup Conversion policies
-/// \ingroup SmartPointerGroup
-/// \defgroup SmartPointerCheckingGroup Checking policies
-/// \ingroup SmartPointerGroup
-
-#include "LokiExport.h"
-#include "SmallObj.h"
-#include "TypeManip.h"
-#include "static_check.h"
-#include "RefToValue.h"
-#include "ConstPolicy.h"
-
-#include <functional>
-#include <stdexcept>
-#include <cassert>
-#include <string>
-
-#if !defined(_MSC_VER)
-# if defined(__sparc__)
-# include <inttypes.h>
-# else
-# include <stdint.h>
-# endif
-#endif
-
-#if defined(_MSC_VER) || defined(__GNUC__)
-// GCC>=4.1 must use -ffriend-injection due to a bug in GCC
-#define LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
-#endif
-
-
-namespace Loki
-{
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class HeapStorage
-///
-/// \ingroup SmartPointerStorageGroup
-/// Implementation of the StoragePolicy used by SmartPtr. Uses explicit call
-/// to T's destructor followed by call to free.
-////////////////////////////////////////////////////////////////////////////////
-
-
-template <class T>
-class HeapStorage
-{
-public:
- typedef T* StoredType; /// the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef T* PointerType; /// type returned by operator->
- typedef T& ReferenceType; /// type returned by operator*
-
- HeapStorage() : pointee_(Default())
- {}
-
- // The storage policy doesn't initialize the stored pointer
- // which will be initialized by the OwnershipPolicy's Clone fn
- HeapStorage(const HeapStorage&) : pointee_(0)
- {}
-
- 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);
-
- template <class F>
- friend const typename HeapStorage<F>::StoredType& GetImplRef(const HeapStorage<F>& sp);
-
- template <class F>
- friend typename HeapStorage<F>::StoredType& GetImplRef(HeapStorage<F>& sp);
-
-protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- void Destroy()
- {
- if ( 0 != pointee_ )
- {
- pointee_->~T();
- ::free( pointee_ );
- }
- }
-
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
-
-private:
- // Data
- StoredType pointee_;
-};
-
-template <class T>
-inline typename HeapStorage<T>::PointerType GetImpl(const HeapStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline const typename HeapStorage<T>::StoredType& GetImplRef(const HeapStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline typename HeapStorage<T>::StoredType& GetImplRef(HeapStorage<T>& sp)
-{ return sp.pointee_; }
-
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class DefaultSPStorage
-///
-/// \ingroup SmartPointerStorageGroup
-/// Implementation of the StoragePolicy used by SmartPtr
-////////////////////////////////////////////////////////////////////////////////
-
-
-template <class T>
-class DefaultSPStorage
-{
-public:
- typedef T* StoredType; // the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef T* PointerType; // type returned by operator->
- typedef T& ReferenceType; // type returned by operator*
-
- DefaultSPStorage() : pointee_(Default())
- {}
-
- // The storage policy doesn't initialize the stored pointer
- // which will be initialized by the OwnershipPolicy's Clone fn
- DefaultSPStorage(const DefaultSPStorage&) : pointee_(0)
- {}
-
- 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);
-
- template <class F>
- friend const typename DefaultSPStorage<F>::StoredType& GetImplRef(const DefaultSPStorage<F>& sp);
-
- template <class F>
- friend typename DefaultSPStorage<F>::StoredType& GetImplRef(DefaultSPStorage<F>& sp);
-
-protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- //
- // If your compiler gives you a warning in this area while
- // compiling the tests, it is on purpose, please ignore it.
- void Destroy()
- {
- delete pointee_;
- }
-
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
-
-private:
- // Data
- StoredType pointee_;
-};
-
-template <class T>
-inline typename DefaultSPStorage<T>::PointerType GetImpl(const DefaultSPStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline const typename DefaultSPStorage<T>::StoredType& GetImplRef(const DefaultSPStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline typename DefaultSPStorage<T>::StoredType& GetImplRef(DefaultSPStorage<T>& sp)
-{ return sp.pointee_; }
-
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class LockedStorage
-///
-/// \ingroup SmartPointerStorageGroup
-/// Implementation of the StoragePolicy used by SmartPtr.
-///
-/// Each call to operator-> locks the object for the duration of a call to a
-/// member function of T.
-///
-/// \par How It Works
-/// LockedStorage has a helper class called Locker, which acts as a smart
-/// pointer with limited abilities. LockedStorage::operator-> returns an
-/// unnamed temporary of type Locker<T> that exists for the duration of the
-/// call to a member function of T. The unnamed temporary locks the object
-/// when it is constructed by operator-> and unlocks the object when it is
-/// destructed.
-///
-/// \note This storage policy requires class T to have member functions Lock
-/// and Unlock. If your class does not have Lock or Unlock functions, you may
-/// either make a child class which does, or make a policy class similar to
-/// LockedStorage which calls other functions to lock the object.
-////////////////////////////////////////////////////////////////////////////////
-
-template <class T>
-class Locker
-{
-public:
- Locker( const T* p ) : pointee_( const_cast< T* >( p ) )
- {
- if ( pointee_ != 0 )
- pointee_->Lock();
- }
-
- ~Locker( void )
- {
- if ( pointee_ != 0 )
- pointee_->Unlock();
- }
-
- operator T* ()
- {
- return pointee_;
- }
-
- T* operator->()
- {
- return pointee_;
- }
-
-private:
- Locker( void );
- Locker& operator = ( const Locker& );
- T* pointee_;
-};
-
-template <class T>
-class LockedStorage
-{
-public:
-
- typedef T* StoredType; /// the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef Locker< T > PointerType; /// type returned by operator->
- typedef T& ReferenceType; /// type returned by operator*
-
- LockedStorage() : pointee_( Default() ) {}
-
- ~LockedStorage( void ) {}
-
- LockedStorage( const LockedStorage&) : pointee_( 0 ) {}
-
- LockedStorage( const StoredType& p ) : pointee_( p ) {}
-
- PointerType operator->()
- {
- return Locker< T >( pointee_ );
- }
-
- void Swap(LockedStorage& rhs)
- {
- std::swap( pointee_, rhs.pointee_ );
- }
-
- // Accessors
- template <class F>
- friend typename LockedStorage<F>::InitPointerType GetImpl(const LockedStorage<F>& sp);
-
- template <class F>
- friend const typename LockedStorage<F>::StoredType& GetImplRef(const LockedStorage<F>& sp);
-
- template <class F>
- friend typename LockedStorage<F>::StoredType& GetImplRef(LockedStorage<F>& sp);
-
-protected:
- // Destroys the data stored
- // (Destruction might be taken over by the OwnershipPolicy)
- void Destroy()
- {
- delete pointee_;
- }
-
- // Default value to initialize the pointer
- static StoredType Default()
- { return 0; }
-
-private:
- /// Dereference operator is not implemented.
- ReferenceType operator*();
-
- // Data
- StoredType pointee_;
-};
-
-template <class T>
-inline typename LockedStorage<T>::InitPointerType GetImpl(const LockedStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline const typename LockedStorage<T>::StoredType& GetImplRef(const LockedStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline typename LockedStorage<T>::StoredType& GetImplRef(LockedStorage<T>& sp)
-{ return sp.pointee_; }
-
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class ArrayStorage
-///
-/// \ingroup SmartPointerStorageGroup
-/// Implementation of the ArrayStorage used by SmartPtr
-////////////////////////////////////////////////////////////////////////////////
-
-
-template <class T>
-class ArrayStorage
-{
-public:
- typedef T* StoredType; // the type of the pointee_ object
- typedef T* InitPointerType; /// type used to declare OwnershipPolicy type.
- typedef T* PointerType; // type returned by operator->
- typedef T& ReferenceType; // type returned by operator*
-
- ArrayStorage() : pointee_(Default())
- {}
-
- // The storage policy doesn't initialize the stored pointer
- // which will be initialized by the OwnershipPolicy's Clone fn
- ArrayStorage(const ArrayStorage&) : pointee_(0)
- {}
-
- 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);
-
- template <class F>
- friend const typename ArrayStorage<F>::StoredType& GetImplRef(const ArrayStorage<F>& sp);
-
- template <class F>
- friend typename ArrayStorage<F>::StoredType& GetImplRef(ArrayStorage<F>& sp);
-
-protected:
- // Destroys the data stored
- // (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_;
-};
-
-template <class T>
-inline typename ArrayStorage<T>::PointerType GetImpl(const ArrayStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline const typename ArrayStorage<T>::StoredType& GetImplRef(const ArrayStorage<T>& sp)
-{ return sp.pointee_; }
-
-template <class T>
-inline typename ArrayStorage<T>::StoredType& GetImplRef(ArrayStorage<T>& sp)
-{ return sp.pointee_; }
-
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class RefCounted
-///
-/// \ingroup SmartPointerOwnershipGroup
-/// Implementation of the OwnershipPolicy used by SmartPtr
-/// Provides a classic external reference counting implementation
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-class RefCounted
-{
-public:
- RefCounted()
- : pCount_(static_cast<uintptr_t*>(
- SmallObject<>::operator new(sizeof(uintptr_t))))
- {
- assert(pCount_ != 0);
- *pCount_ = 1;
- }
-
- RefCounted(const RefCounted& rhs)
- : pCount_(rhs.pCount_)
- {}
-
- // MWCW lacks template friends, hence the following kludge
- template <typename P1>
- 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_)
- {
- SmallObject<>::operator delete(pCount_, sizeof(uintptr_t));
- pCount_ = NULL;
- return true;
- }
- return false;
- }
-
- void Swap(RefCounted& rhs)
- { std::swap(pCount_, rhs.pCount_); }
-
- enum { destructiveCopy = false };
-
-private:
- // Data
- uintptr_t* pCount_;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct RefCountedMT
-///
-/// \ingroup SmartPointerOwnershipGroup
-/// Implementation of the OwnershipPolicy used by SmartPtr
-/// Implements external reference counting for multithreaded programs
-/// Policy Usage: RefCountedMTAdj<ThreadingModel>::RefCountedMT
-///
-/// \par Warning
-/// There could be a race condition, see bug "Race condition in RefCountedMTAdj::Release"
-/// http://sourceforge.net/tracker/index.php?func=detail&aid=1408845&group_id=29557&atid=396644
-/// As stated in bug 1408845, the Release function is not thread safe if a
-/// SmartPtr copy-constructor tries to copy the last pointer to an object in
-/// one thread, while the destructor is acting on the last pointer in another
-/// thread. The existence of a race between a copy-constructor and destructor
-/// 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
-{
- template <class P>
- class RefCountedMT : public ThreadingModel< RefCountedMT<P>, MX >
- {
- typedef ThreadingModel< RefCountedMT<P>, MX > base_type;
- typedef typename base_type::IntType CountType;
- typedef volatile CountType* CountPtrType;
-
- public:
- RefCountedMT()
- {
- pCount_ = static_cast<CountPtrType>(
- SmallObject<LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL>::operator new(
- sizeof(*pCount_)));
- assert(pCount_);
- //*pCount_ = 1;
- ThreadingModel<RefCountedMT, MX>::AtomicAssign(*pCount_, 1);
- }
-
- RefCountedMT(const RefCountedMT& rhs)
- : pCount_(rhs.pCount_)
- {}
-
- //MWCW lacks template friends, hence the following kludge
- template <typename P1>
- RefCountedMT(const RefCountedMT<P1>& rhs)
- : pCount_(reinterpret_cast<const RefCountedMT<P>&>(rhs).pCount_)
- {}
-
- P Clone(const P& val)
- {
- ThreadingModel<RefCountedMT, MX>::AtomicIncrement(*pCount_);
- return val;
- }
-
- bool Release(const P&)
- {
- 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_),
- sizeof(*pCount_));
- return true;
- }
- return false;
- }
-
- void Swap(RefCountedMT& rhs)
- { std::swap(pCount_, rhs.pCount_); }
-
- enum { destructiveCopy = false };
-
- private:
- // Data
- CountPtrType pCount_;
- };
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class COMRefCounted
-///
-/// \ingroup SmartPointerOwnershipGroup
-/// Implementation of the OwnershipPolicy used by SmartPtr
-/// Adapts COM intrusive reference counting to OwnershipPolicy-specific syntax
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-class COMRefCounted
-{
-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;
- }
-
- enum { destructiveCopy = false };
-
- static void Swap(COMRefCounted&)
- {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct DeepCopy
-///
-/// \ingroup SmartPointerOwnershipGroup
-/// Implementation of the OwnershipPolicy used by SmartPtr
-/// Implements deep copy semantics, assumes existence of a Clone() member
-/// function of the pointee type
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-struct DeepCopy
-{
- 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
-/// Implementation of the OwnershipPolicy used by SmartPtr
-/// Implements reference linking
-////////////////////////////////////////////////////////////////////////////////
-
-namespace Private
-{
-class LOKI_EXPORT RefLinkedBase
-{
-public:
- RefLinkedBase()
- { prev_ = next_ = this; }
-
- RefLinkedBase(const RefLinkedBase& rhs);
-
- bool Release();
-
- void Swap(RefLinkedBase& rhs);
-
- bool Merge( RefLinkedBase& rhs );
-
- enum { destructiveCopy = false };
-
-private:
- static unsigned int CountPrevCycle( const RefLinkedBase* pThis );
- static unsigned int CountNextCycle( const RefLinkedBase* pThis );
- bool HasPrevNode( const RefLinkedBase* p ) const;
- bool HasNextNode( const RefLinkedBase* p ) const;
-
- mutable const RefLinkedBase* prev_;
- mutable const RefLinkedBase* next_;
-};
-}
-
-template <class P>
-class RefLinked : public Private::RefLinkedBase
-{
-public:
- RefLinked()
- {}
-
- template <class P1>
- RefLinked(const RefLinked<P1>& rhs)
- : Private::RefLinkedBase(rhs)
- {}
-
- static P Clone(const P& val)
- { return val; }
-
- bool Release(const P&)
- { return Private::RefLinkedBase::Release(); }
-
- template < class P1 >
- bool Merge( RefLinked< P1 > & rhs )
- {
- return Private::RefLinkedBase::Merge( rhs );
- }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class DestructiveCopy
-///
-/// \ingroup SmartPointerOwnershipGroup
-/// Implementation of the OwnershipPolicy used by SmartPtr
-/// Implements destructive copy semantics (a la std::auto_ptr)
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-class DestructiveCopy
-{
-public:
- DestructiveCopy()
- {}
-
- template <class P1>
- DestructiveCopy(const DestructiveCopy<P1>&)
- {}
-
- template <class P1>
- static P Clone(P1& val)
- {
- P result(val);
- val = P1();
- return result;
- }
-
- static bool Release(const P&)
- { return true; }
-
- static void Swap(DestructiveCopy&)
- {}
-
- enum { destructiveCopy = true };
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class NoCopy
-///
-/// \ingroup SmartPointerOwnershipGroup
-/// Implementation of the OwnershipPolicy used by SmartPtr
-/// Implements a policy that doesn't allow copying objects
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-class NoCopy
-{
-public:
- NoCopy()
- {}
-
- template <class P1>
- NoCopy(const NoCopy<P1>&)
- {}
-
- static P Clone(const P&)
- {
- // Make it depended on template parameter
- static const bool DependedFalse = sizeof(P*) == 0;
-
- 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
-/// Implementation of the ConversionPolicy used by SmartPtr
-/// Allows implicit conversion from SmartPtr to the pointee type
-////////////////////////////////////////////////////////////////////////////////
-
-struct AllowConversion
-{
- enum { allow = true };
-
- void Swap(AllowConversion&)
- {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct DisallowConversion
-///
-/// \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
-////////////////////////////////////////////////////////////////////////////////
-
-struct DisallowConversion
-{
- DisallowConversion()
- {}
-
- DisallowConversion(const AllowConversion&)
- {}
-
- enum { allow = false };
-
- void Swap(DisallowConversion&)
- {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct NoCheck
-///
-/// \ingroup SmartPointerCheckingGroup
-/// Implementation of the CheckingPolicy used by SmartPtr
-/// Well, it's clear what it does :o)
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-struct NoCheck
-{
- NoCheck()
- {}
-
- template <class P1>
- NoCheck(const NoCheck<P1>&)
- {}
-
- static void OnDefault(const P&)
- {}
-
- static void OnInit(const P&)
- {}
-
- static void OnDereference(const P&)
- {}
-
- static void Swap(NoCheck&)
- {}
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct AssertCheck
-///
-/// \ingroup SmartPointerCheckingGroup
-/// Implementation of the CheckingPolicy used by SmartPtr
-/// Checks the pointer before dereference
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-struct AssertCheck
-{
- AssertCheck()
- {}
-
- template <class P1>
- AssertCheck(const AssertCheck<P1>&)
- {}
-
- template <class P1>
- AssertCheck(const NoCheck<P1>&)
- {}
-
- static void OnDefault(const P&)
- {}
-
- static void OnInit(const P&)
- {}
-
- static void OnDereference(P val)
- { assert(val); (void)val; }
-
- static void Swap(AssertCheck&)
- {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct AssertCheckStrict
-///
-/// \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
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-struct AssertCheckStrict
-{
- 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&)
- {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct NullPointerException
-///
-/// \ingroup SmartPointerGroup
-/// Used by some implementations of the CheckingPolicy used by SmartPtr
-////////////////////////////////////////////////////////////////////////////////
-
-struct NullPointerException : public std::runtime_error
-{
- NullPointerException() : std::runtime_error(std::string(""))
- { }
- const char* what() const throw()
- { return "Null Pointer Exception"; }
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct RejectNullStatic
-///
-/// \ingroup SmartPointerCheckingGroup
-/// Implementation of the CheckingPolicy used by SmartPtr
-/// Checks the pointer upon initialization and before dereference
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-struct RejectNullStatic
-{
- 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
- static const bool DependedFalse = sizeof(P*) == 0;
-
- 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&)
- {}
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \struct RejectNull
-///
-/// \ingroup SmartPointerCheckingGroup
-/// Implementation of the CheckingPolicy used by SmartPtr
-/// Checks the pointer before dereference
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-struct RejectNull
-{
- 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
-/// Implementation of the CheckingPolicy used by SmartPtr
-/// Checks the pointer upon initialization and before dereference
-////////////////////////////////////////////////////////////////////////////////
-
-template <class P>
-struct RejectNullStrict
-{
- RejectNullStrict()
- {}
-
- template <class P1>
- RejectNullStrict(const RejectNullStrict<P1>&)
- {}
-
- template <class P1>
- RejectNullStrict(const RejectNull<P1>&)
- {}
-
- static void OnInit(P val)
- { if (!val) throw NullPointerException(); }
-
- void OnDereference(P val)
- { OnInit(val); }
-
- void OnDereference(P val) const
- { OnInit(val); }
-
- void Swap(RejectNullStrict&)
- {}
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-// class template SmartPtr (declaration)
-// The reason for all the fuss above
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OwnershipPolicy = RefCounted,
- class ConversionPolicy = DisallowConversion,
- template <class> class CheckingPolicy = AssertCheck,
- template <class> class StoragePolicy = DefaultSPStorage,
- template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
- >
-class SmartPtr;
-
-////////////////////////////////////////////////////////////////////////////////
-// class template SmartPtrDef (definition)
-// 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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OwnershipPolicy = RefCounted,
- class ConversionPolicy = DisallowConversion,
- template <class> class CheckingPolicy = AssertCheck,
- template <class> class StoragePolicy = DefaultSPStorage,
- template<class> class ConstnessPolicy = LOKI_DEFAULT_CONSTNESS
- >
-struct SmartPtrDef
-{
- typedef SmartPtr
- <
- T,
- OwnershipPolicy,
- ConversionPolicy,
- CheckingPolicy,
- StoragePolicy,
- ConstnessPolicy
- >
- type;
-};
-
-////////////////////////////////////////////////////////////////////////////////
-/// \class SmartPtr
-///
-/// \ingroup SmartPointerGroup
-///
-/// \param OwnershipPolicy default = RefCounted,
-/// \param ConversionPolicy default = DisallowConversion,
-/// \param CheckingPolicy default = AssertCheck,
-/// \param StoragePolicy default = DefaultSPStorage
-/// \param ConstnessPolicy default = LOKI_DEFAULT_CONSTNESS
-///
-/// \par IMPORTANT NOTE
-/// Due to threading issues, the OwnershipPolicy has been changed as follows:
-///
-/// - Release() returns a boolean saying if that was the last release
-/// so the pointer can be deleted by the StoragePolicy
-/// - IsUnique() was removed
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OwnershipPolicy,
- class ConversionPolicy,
- template <class> class CheckingPolicy,
- template <class> class StoragePolicy,
- template <class> class ConstnessPolicy
- >
-class SmartPtr
- : public StoragePolicy<T>
- , public OwnershipPolicy<typename StoragePolicy<T>::InitPointerType>
- , public CheckingPolicy<typename StoragePolicy<T>::StoredType>
- , public ConversionPolicy
-{
- typedef StoragePolicy<T> SP;
- 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;
-
- 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;
-#else
- typedef const StoredType& ImplicitArg;
- typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg;
-#endif
-
-public:
-
- SmartPtr()
- {
- KP::OnDefault(GetImpl(*this));
- }
-
- explicit
- SmartPtr(ExplicitArg p) : SP(p)
- {
- KP::OnInit(GetImpl(*this));
- }
-
- SmartPtr(ImplicitArg p) : SP(p)
- {
- KP::OnInit(GetImpl(*this));
- }
-
- SmartPtr(CopyArg& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- {
- GetImplRef(*this) = OP::Clone(GetImplRef(rhs));
- }
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
- : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
- : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- {
- GetImplRef(*this) = OP::Clone(GetImplRef(rhs));
- }
-
- SmartPtr(RefToValue<SmartPtr> rhs)
- : SP(rhs), OP(rhs), KP(rhs), CP(rhs)
- {}
-
- operator RefToValue<SmartPtr>()
- { return RefToValue<SmartPtr>(*this); }
-
- SmartPtr& operator=(CopyArg& rhs)
- {
- SmartPtr temp(rhs);
- temp.Swap(*this);
- return *this;
- }
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
- {
- SmartPtr temp(rhs);
- temp.Swap(*this);
- return *this;
- }
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs)
- {
- SmartPtr temp(rhs);
- temp.Swap(*this);
- return *this;
- }
-
- void Swap(SmartPtr& rhs)
- {
- OP::Swap(rhs);
- CP::Swap(rhs);
- KP::Swap(rhs);
- SP::Swap(rhs);
- }
-
- ~SmartPtr()
- {
- if (OP::Release(GetImpl(*static_cast<SP*>(this))))
- {
- SP::Destroy();
- }
- }
-
-#ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
-
- // old non standard in class definition of friends
- friend inline void Release(SmartPtr& sp, typename SP::StoredType& p)
- {
- p = GetImplRef(sp);
- GetImplRef(sp) = SP::Default();
- }
-
- friend inline void Reset(SmartPtr& sp, typename SP::StoredType p)
- { SmartPtr(p).Swap(sp); }
-
-#else
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- friend void Release(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
- typename SP1<T1>::StoredType& p);
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- friend void Reset(SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1>& sp,
- typename SP1<T1>::StoredType p);
-#endif
-
-
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool Merge( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
- {
- if ( GetImpl( *this ) != GetImpl( rhs ) )
- {
- return false;
- }
- return OP::template Merge( rhs );
- }
-
- PointerType operator->()
- {
- KP::OnDereference(GetImplRef(*this));
- return SP::operator->();
- }
-
- ConstPointerType operator->() const
- {
- KP::OnDereference(GetImplRef(*this));
- return SP::operator->();
- }
-
- ReferenceType operator*()
- {
- 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; }
-
- static inline T* GetPointer( const SmartPtr& sp )
- { return GetImpl( sp ); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool operator==(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
- { return GetImpl(*this) == GetImpl(rhs); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool operator!=(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
- { return !(*this == rhs); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- bool operator<(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) const
- { return GetImpl(*this) < GetImpl(rhs); }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- inline bool operator > ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
- {
- return ( GetImpl( rhs ) < GetImpl( *this ) );
- }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- inline bool operator <= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
- {
- return !( GetImpl( rhs ) < GetImpl( *this ) );
- }
-
- // Ambiguity buster
- template
- <
- typename T1,
- template <class> class OP1,
- class CP1,
- template <class> class KP1,
- template <class> class SP1,
- template <class> class CNP1
- >
- inline bool operator >= ( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs )
- {
- return !( GetImpl( *this ) < GetImpl( rhs ) );
- }
-
-private:
- // Helper for enabling 'if (sp)'
- struct Tester
- {
- Tester(int) {}
- void dummy() {}
- };
-
- typedef void (Tester::*unspecified_boolean_type_)();
-
- typedef typename Select<CP::allow, Tester, unspecified_boolean_type_>::Result
- unspecified_boolean_type;
-
-public:
- // enable 'if (sp)'
- operator unspecified_boolean_type() const
- {
- return !*this ? 0 : &Tester::dummy;
- }
-
-private:
- // Helper for disallowing automatic conversion
- struct Insipid
- {
- Insipid(PointerType) {}
- };
-
- typedef typename Select<CP::allow, PointerType, Insipid>::Result
- AutomaticConversionResult;
-
-public:
- operator AutomaticConversionResult() const
- { return GetImpl(*this); }
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-// friends
-////////////////////////////////////////////////////////////////////////////////
-
-#ifndef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP
- >
-inline void Release(SmartPtr<T, OP, CP, KP, SP, CNP>& sp,
- typename SP<T>::StoredType& p)
-{
- p = GetImplRef(sp);
- GetImplRef(sp) = SP<T>::Default();
-}
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP
- >
-inline void Reset(SmartPtr<T, OP, CP, KP, SP, CNP>& sp,
- typename SP<T>::StoredType p)
-{ SmartPtr<T, OP, CP, KP, SP, CNP>(p).Swap(sp); }
-
-#endif
-
-////////////////////////////////////////////////////////////////////////////////
-// free comparison operators for class template SmartPtr
-////////////////////////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////////////////////////
-/// operator== for lhs = SmartPtr, rhs = raw pointer
-/// \ingroup SmartPointerGroup
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP1,
- typename U
- >
-inline bool operator==(const SmartPtr<T, OP, CP, KP, SP, CNP1 >& lhs,
- U* rhs)
-{ return GetImpl(lhs) == rhs; }
-
-////////////////////////////////////////////////////////////////////////////////
-/// operator== for lhs = raw pointer, rhs = SmartPtr
-/// \ingroup SmartPointerGroup
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP1,
- typename U
- >
-inline bool operator==(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP1 >& rhs)
-{ return rhs == lhs; }
-
-////////////////////////////////////////////////////////////////////////////////
-/// operator!= for lhs = SmartPtr, rhs = raw pointer
-/// \ingroup SmartPointerGroup
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-inline bool operator<(const SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- U* rhs)
-{
- return ( GetImpl( lhs ) < rhs );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-/// operator< for lhs = raw pointer, rhs = SmartPtr
-/// \ingroup SmartPointerGroup
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-inline bool operator<(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
-{
- return ( GetImpl( rhs ) < lhs );
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// operator> for lhs = SmartPtr, rhs = raw pointer
-/// \ingroup SmartPointerGroup
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-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
-////////////////////////////////////////////////////////////////////////////////
-
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP,
- typename U
- >
-inline bool operator>=(U* lhs,
- const SmartPtr<T, OP, CP, KP, SP, CNP >& rhs)
-{ return !(lhs < rhs); }
-
-} // namespace Loki
-
-////////////////////////////////////////////////////////////////////////////////
-/// specialization of std::less for SmartPtr
-/// \ingroup SmartPointerGroup
-////////////////////////////////////////////////////////////////////////////////
-
-namespace std
-{
-template
-<
-typename T,
- template <class> class OP,
- class CP,
- template <class> class KP,
- template <class> class SP,
- template <class> class CNP
- >
-struct less< Loki::SmartPtr<T, OP, CP, KP, SP, CNP > >
- : public binary_function < Loki::SmartPtr<T, OP, CP, KP, SP, CNP >,
- Loki::SmartPtr<T, OP, CP, KP, SP, CNP >, bool >
-{
- bool operator()(const Loki::SmartPtr<T, OP, CP, KP, SP, CNP >& lhs,
- const Loki::SmartPtr<T, OP, CP, KP, SP, CNP >& rhs) const
- { return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
-};
-}
-
-#endif // end file guardian
-
bgstack15