📄 smartptr.h
字号:
template <class P>
class NoCopy
{
public:
NoCopy()
{}
template <class P1>
NoCopy(const NoCopy<P1>&)
{}
static P Clone(const P&)
{
CT_ASSERT(false, This_Policy_Disallows_Value_Copying);
}
static bool Release(const P&)
{ return true; }
static void Swap(NoCopy&)
{}
enum { destructiveCopy = false };
};
////////////////////////////////////////////////////////////////////////////////
// class template AllowConversion
// Implementation of the ConversionPolicy used by SmartPtr
// Allows implicit conversion from SmartPtr to the pointee type
////////////////////////////////////////////////////////////////////////////////
struct AllowConversion
{
enum { allow = true };
void Swap(AllowConversion&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class template DisallowConversion
// 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&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class template NoCheck
// 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&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class template AssertCheck
// 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); }
static void Swap(AssertCheck&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class template AssertCheckStrict
// 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&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class NullPointerException
// Used by some implementations of the CheckingPolicy used by SmartPtr
////////////////////////////////////////////////////////////////////////////////
struct NullPointerException : public std::runtime_error
{
NullPointerException() : std::runtime_error("")
{ }
const char* what() const
{ return "Null Pointer Exception"; }
};
////////////////////////////////////////////////////////////////////////////////
// class template RejectNullStatic
// 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&)
{
CompileTimeError<false>
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&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class template RejectNull
// 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 val)
{ if (!val) throw NullPointerException(); }
static void OnDefault(P val)
{ OnInit(val); }
void OnDereference(P val)
{ OnInit(val); }
void Swap(RejectNull&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class template RejectNullStrict
// 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 Swap(RejectNullStrict&)
{}
};
////////////////////////////////////////////////////////////////////////////////
// class template ByRef
// Transports a reference as a value
// Serves to implement the Colvin/Gibbons trick for SmartPtr
////////////////////////////////////////////////////////////////////////////////
template <class T>
class ByRef
{
public:
ByRef(T& v) : value_(v) {}
operator T&() { return value_; }
// gcc doesn't like this:
// operator const T&() const { return value_; }
private:
T& value_;
};
////////////////////////////////////////////////////////////////////////////////
// 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
>
class SmartPtr;
////////////////////////////////////////////////////////////////////////////////
// class template SmartPtr (definition)
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
template <class> class OwnershipPolicy,
class ConversionPolicy,
template <class> class CheckingPolicy,
template <class> class StoragePolicy
>
class SmartPtr
: public StoragePolicy<T>
, public OwnershipPolicy<typename StoragePolicy<T>::PointerType>
, public CheckingPolicy<typename StoragePolicy<T>::StoredType>
, public ConversionPolicy
{
typedef StoragePolicy<T> SP;
typedef OwnershipPolicy<typename StoragePolicy<T>::PointerType> OP;
typedef CheckingPolicy<typename StoragePolicy<T>::StoredType> KP;
typedef ConversionPolicy CP;
public:
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;
SmartPtr()
{ KP::OnDefault(GetImpl(*this)); }
SmartPtr(const StoredType& 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
>
SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1>& 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
>
SmartPtr(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
SmartPtr(ByRef<SmartPtr> rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{}
operator ByRef<SmartPtr>()
{ return ByRef<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
>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -