📄 smartptr.h
字号:
SmartPtr(ByRef<SmartPtr> rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{}
// do not alter the order of the following three constructors
// otherwise the MSVC 6.0 will fail to compile the class.
template
<
typename T1,
class OP1,
class CP1,
class KP1,
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,
class OP1,
class CP1,
class KP1,
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(CopyArg& rhs)
: SP(rhs), OP(rhs), KP(rhs), CP(rhs)
{ GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); }
operator ByRef<SmartPtr>()
{ return ByRef<SmartPtr>(*this); }
// do not alter the order of the following three copy-assignment operators
// otherwise the MSVC 6.0 will fail to compile the class.
template
<
typename T1,
class OP1,
class CP1,
class KP1,
class SP1
>
SmartPtr& operator=(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
template
<
typename T1,
class OP1,
class CP1,
class KP1,
class SP1
>
SmartPtr& operator=(SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
SmartPtr& operator=(CopyArg& rhs)
{
SmartPtr temp(rhs);
temp.Swap(*this);
return *this;
}
SmartPtr& operator=(const WorkaroundType& arg)
{
SmartPtr temp(arg);
//return *this = const_cast<const SmartPtr&>(temp);
return *this = temp;
}
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();
}
}
friend inline void Release(SmartPtr& sp, StoredType& p)
{
p = GetImplRef(sp);
GetImplRef(sp) = SP::Default();
}
friend inline void Reset(SmartPtr& sp, StoredType p)
{ SmartPtr(p).Swap(sp); }
PointerType operator->()
{
KP::OnDereference(GetImplRef(*this));
return SP::operator->();
}
PointerType operator->() const
{
KP::OnDereference(GetImplRef(*this));
return SP::operator->();
}
ReferenceType operator*()
{
KP::OnDereference(GetImplRef(*this));
return SP::operator*();
}
ReferenceType operator*() const
{
KP::OnDereference(GetImplRef(*this));
return SP::operator*();
}
bool operator!() const // Enables "if (!sp) ..."
{ return GetImpl(*this) == 0; }
inline friend bool operator==(const SmartPtr& lhs,
const T* rhs)
{ return GetImpl(lhs) == rhs; }
inline friend bool operator==(const T* lhs,
const SmartPtr& rhs)
{ return rhs == lhs; }
inline friend bool operator!=(const SmartPtr& lhs,
const T* rhs)
{ return !(lhs == rhs); }
inline friend bool operator!=(const T* lhs,
const SmartPtr& rhs)
{ return rhs != lhs; }
// Ambiguity buster
template
<
typename T1,
class OP1,
class CP1,
class KP1,
class SP1
>
bool operator==(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs) const
{ return *this == GetImpl(rhs); }
// Ambiguity buster
template
<
typename T1,
class OP1,
class CP1,
class KP1,
class SP1
>
bool operator!=(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs) const
{ return !(*this == rhs); }
// Ambiguity buster
template
<
typename T1,
class OP1,
class CP1,
class KP1,
class SP1
>
bool operator<(const SmartPtr<T1, OP1, CP1, KP1, SP1>& rhs) const
{ return *this < GetImpl(rhs); }
private:
// Helper for enabling 'if (sp)'
struct Tester
{
Tester() {}
private:
void operator delete(void*);
};
public:
// enable 'if (sp)'
operator Tester*() const
{
if (!*this) return 0;
static Tester t;
return &t;
}
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); }
};
////////////////////////////////////////////////////////////////////////////////
// free comparison operators for class template SmartPtr
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// operator== for lhs = SmartPtr, rhs = raw pointer
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator==(const SmartPtr<T, OP, CP, KP, SP>& lhs,
const U* rhs)
{ return GetImpl(lhs) == rhs; }
////////////////////////////////////////////////////////////////////////////////
// operator== for lhs = raw pointer, rhs = SmartPtr
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator==(const U* lhs,
const SmartPtr<T, OP, CP, KP, SP>& rhs)
{ return rhs == lhs; }
////////////////////////////////////////////////////////////////////////////////
// operator!= for lhs = SmartPtr, rhs = raw pointer
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator!=(const SmartPtr<T, OP, CP, KP, SP>& lhs,
const U* rhs)
{ return !(lhs == rhs); }
////////////////////////////////////////////////////////////////////////////////
// operator!= for lhs = raw pointer, rhs = SmartPtr
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator!=(const U* lhs,
const SmartPtr<T, OP, CP, KP, SP>& rhs)
{ return rhs != lhs; }
////////////////////////////////////////////////////////////////////////////////
// operator< for lhs = SmartPtr, rhs = raw pointer -- NOT DEFINED
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator<(const SmartPtr<T, OP, CP, KP, SP>& lhs,
const U* rhs);
////////////////////////////////////////////////////////////////////////////////
// operator< for lhs = raw pointer, rhs = SmartPtr -- NOT DEFINED
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator<(const U* lhs,
const SmartPtr<T, OP, CP, KP, SP>& rhs);
////////////////////////////////////////////////////////////////////////////////
// operator> for lhs = SmartPtr, rhs = raw pointer -- NOT DEFINED
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator>(const SmartPtr<T, OP, CP, KP, SP>& lhs,
const U* rhs)
{ return rhs < lhs; }
////////////////////////////////////////////////////////////////////////////////
// operator> for lhs = raw pointer, rhs = SmartPtr
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator>(const U* lhs,
const SmartPtr<T, OP, CP, KP, SP>& rhs)
{ return rhs < lhs; }
////////////////////////////////////////////////////////////////////////////////
// operator<= for lhs = SmartPtr, rhs = raw pointer
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator<=(const SmartPtr<T, OP, CP, KP, SP>& lhs,
const U* rhs)
{ return !(rhs < lhs); }
////////////////////////////////////////////////////////////////////////////////
// operator<= for lhs = raw pointer, rhs = SmartPtr
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator<=(const U* lhs,
const SmartPtr<T, OP, CP, KP, SP>& rhs)
{ return !(rhs < lhs); }
////////////////////////////////////////////////////////////////////////////////
// operator>= for lhs = SmartPtr, rhs = raw pointer
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator>=(const SmartPtr<T, OP, CP, KP, SP>& lhs,
const U* rhs)
{ return !(lhs < rhs); }
////////////////////////////////////////////////////////////////////////////////
// operator>= for lhs = raw pointer, rhs = SmartPtr
////////////////////////////////////////////////////////////////////////////////
template
<
typename T,
class OP,
class CP,
class KP,
class SP,
typename U
>
inline bool operator>=(const U* lhs,
const SmartPtr<T, OP, CP, KP, SP>& rhs)
{ return !(lhs < rhs); }
} // namespace Loki
////////////////////////////////////////////////////////////////////////////////
// specialization of std::less for SmartPtr
////////////////////////////////////////////////////////////////////////////////
// MSVC 6.0 does not support partial template specialization :-(
#if !defined(_MSC_VER)
namespace std
{
template
<
typename T,
class OP,
class CP,
class KP,
class SP
>
struct less< Loki::SmartPtr<T, OP, CP, KP, SP> >
: public binary_function<Loki::SmartPtr<T, OP, CP, KP, SP>,
Loki::SmartPtr<T, OP, CP, KP, SP>, bool>
{
bool operator()(const Loki::SmartPtr<T, OP, CP, KP, SP>& lhs,
const Loki::SmartPtr<T, OP, CP, KP, SP>& rhs) const
{ return less<T*>()(GetImpl(lhs), GetImpl(rhs)); }
};
}
#else
// macros that help to specialize std::less for smarptrs.
#define SMARTPTR_SPECIALIZE_LESS_5(T, OP, CP, KP, SP) \
namespace std \
{ \
struct less< Loki::SmartPtr<T, OP, CP, KP, SP> > \
: public binary_function<Loki::SmartPtr<T, OP, CP, KP, SP>, \
Loki::SmartPtr<T, OP, CP, KP, SP>, bool> \
{ \
bool operator()(const Loki::SmartPtr<T, OP, CP, KP, SP>& lhs, \
const Loki::SmartPtr<T, OP, CP, KP, SP>& rhs) const \
{ \
typedef ApplyInnerType<SP, T>::type TempType; \
const TempType& rlhs = lhs; \
const TempType& rrhs = rhs; \
return less<T*>()(GetImpl(rlhs), GetImpl(rrhs)); \
} \
}; \
}
#define SMARTPTR_SPECIALIZE_LESS_4(T, OP, CP, KP) \
SMARTPTR_SPECIALIZE_LESS_5(T, OP, CP, KP, DefaultSPStorageWrapper)
#define SMARTPTR_SPECIALIZE_LESS_3(T, OP, CP) \
SMARTPTR_SPECIALIZE_LESS_5(T, OP, CP, AssertCheckWrapper, DefaultSPStorageWrapper)
#define SMARTPTR_SPECIALIZE_LESS_2(T, OP) \
SMARTPTR_SPECIALIZE_LESS_5(T, OP, DisallowConversion, AssertCheckWrapper, DefaultSPStorageWrapper)
#define SMARTPTR_SPECIALIZE_LESS(T) \
SMARTPTR_SPECIALIZE_LESS_5(T, RefCountedWrapper, DisallowConversion, AssertCheckWrapper, DefaultSPStorageWrapper)
#endif
////////////////////////////////////////////////////////////////////////////////
// Change log:
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
// December 09, 2001: Included <cassert>
// Oct 26, 2002: ported by Benjamin Kaufmann to MSVC 6.0
// Feb 24, 2003: ported RefCountedMT. In NoCopy replaced CT_ASSERT with
// STATIC_CHECK. B.K.
// Mar 06, 2003: added helper-macros for specializing std::less for
// Smart-Pointers.
////////////////////////////////////////////////////////////////////////////////
#endif // SMARTPTR_INC_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -