📄 smart_ptr.hpp
字号:
Example implementation for intrusive functions:\n
void intrusive_ptr_add_ref(Shape * p){++(p->references);}\n
void intrusive_ptr_release(Shape * p){\n
if (--(p->references) == 0)\n
delete p;\n
}\n
bool intrusive_ptr_is_ref(Shape * p){return (p->references > 1);}\n
\n
<b>Example Usage</b>
@include ../examples/example_ref_intrusive_policy_usage.hxx
\n
@note
The ref_link_policy can still be used in synchronized
code, if intrusive_lock_policy is used.
@see smart_ptr, ref_count_policy, ref_link_policy
*/
class ref_intrusive_policy
{
ref_intrusive_policy(const ref_intrusive_policy&);
ref_intrusive_policy& operator=(const ref_intrusive_policy&);
protected:
template<class T>
inline bool is_referenced(T& type)const{return intrusive_ptr_is_ref(type);}
public:
ref_intrusive_policy(){}
template<class T>
inline ref_intrusive_policy(ref_intrusive_policy&, T& type)
{
if (type) intrusive_ptr_add_ref(type);
}
template<class T, class F, class LCK>
void release(T& type, F, LCK &)
{
//intrusive_ptr_release must perform assignment_unlock_policy (unlock)
if (type) intrusive_ptr_release(type);
}
template<class T1, class F1, class T2, class F2, class LCK>
void assign(T1& type1, F1& clone_fct1, T2 type2, const F2 clone_fct2, ref_intrusive_policy &src_policy, LCK &lck_policy)
{
if (!type1 || type1 != type2)
{
lck_policy.assignment_lock_policy(type1);
const bool src_policy_eq_this = (this == &src_policy);
release(type1, clone_fct1, lck_policy);
type1 = type2;
clone_fct1 = clone_fct2;
if (type1 && !src_policy_eq_this) intrusive_ptr_add_ref(type1);
}
}
};
/*!
@struct no_lock_policy
@brief The no lock policy has no lock implementation.
Use this policy when synchronization is not required.
\n
@see smart_ptr, intrusive_lock_policy
*/
struct no_lock_policy
{
no_lock_policy(){}
template<class T_obj> inline void pointee_lock_policy(T_obj*){}
template<class T_obj> inline void const_pointee_lock_policy(T_obj*){}
template<class T_obj> inline void assignment_lock_policy(T_obj*){}
template<class T_obj> inline void assignment_unlock_policy(T_obj*){}
template<class T_obj> inline void destructor_lock_policy(T_obj*){}
template<class T_obj> inline void destructor_unlock_policy(T_obj*){}
template<class T_obj> inline T_obj* constructor_lock_policy(T_obj* p){return p;}
template<class T_obj> inline void constructor_unlock_policy(T_obj*){}
// @cond INCLUDE_ALL_OBJS_
template<class T> struct return_type{typedef T* type_pointee;typedef T& type_ref;};//The struct type is here for a future optional feature
// @endcond
//A lock policy should have the following two functions implemented
template<class T_obj> inline void lock(T_obj*){}
template<class T_obj> inline void unlock(T_obj*){}
private:
//A lock policy can optionally have the following two functions implemented and public
template<class T_obj> inline bool trylock(T_obj*);
template<class T_obj> inline bool islock(T_obj*);// Should only be used with trylock
//The following should always be private with non implementation
no_lock_policy(const no_lock_policy&);
no_lock_policy& operator=(const no_lock_policy&);
};
/*!
@struct intrusive_lock_policy
@brief This implements an intrusive lock policy.
Allows synchronization of the smart pointer
and the pointee.\n
The intrusive_lock_policy requires the user
to implement two intrusive lock functions that
take the pointer type.\n
void intrusive_ptr_lock(T * p);\n
void intrusive_ptr_unlock(T * p);\n
Where T is the target type, and the functions
are in a namespace accessible to the lock policy.\n
Optionally, the following functions can also
be implemented, but are not required:\n
bool intrusive_ptr_trylock(T * p);
bool intrusive_ptr_islock(T * p);
\n
<b>Example Usage</b>
@include ../examples/example_intrusive_lock_policy_usage.hxx
\n
@see smart_ptr, no_lock_policy
\n
@note
The intrusive lock policy will work with ALL ownership policy types.
*/
struct intrusive_lock_policy
{
intrusive_lock_policy(){}
template<class T_obj> inline void pointee_lock_policy(T_obj* p){}
template<class T_obj> inline void const_pointee_lock_policy(T_obj* p){}
template<class T_obj> inline void assignment_lock_policy(T_obj* p){if (p) lock(p);}
template<class T_obj> inline void assignment_unlock_policy(T_obj* p){if (p) unlock(p);}
template<class T_obj> inline void destructor_lock_policy(T_obj* p){if (p) lock(p);}
template<class T_obj> inline void destructor_unlock_policy(T_obj* p){if (p) unlock(p);}
template<class T_obj> inline T_obj* constructor_lock_policy(T_obj* p){if (p) lock(p);return p;}
template<class T_obj> inline void constructor_unlock_policy(T_obj* p){if (p) unlock(p);}
template<class T_obj> inline void lock(T_obj* p){intrusive_ptr_lock(p);}
template<class T_obj> inline void unlock(T_obj* p){intrusive_ptr_unlock(p);}
template<class T_obj> inline bool trylock(T_obj* p){return intrusive_ptr_trylock(p);}
template<class T_obj> inline bool islock(T_obj* p){return intrusive_ptr_islock(p);}// Should only be used with trylock
// @cond INCLUDE_ALL_OBJS_
template<class T> struct return_type{typedef T* type_pointee;typedef T& type_ref;};//The struct type is here for a future optional feature
// @endcond
private: //The following should always be private with no implementation
intrusive_lock_policy(const intrusive_lock_policy&);
intrusive_lock_policy& operator=(const intrusive_lock_policy&);
};
//See Note#2 listed below
#ifndef SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
typedef no_lock_policy lock_default_policy;
typedef ref_link_policy ref_default_policy;
#endif // not SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
//weak_storage implementation is still in progress
struct weak_storage
{
struct ref_count
{
ref_count():m_count(new size_t(1)){}
size_t *m_count;
private: //Disallow copy constructor and assignment op
ref_count(const ref_count&);
ref_count& operator=(const ref_count&);
};
ref_count m_ref_count;
};
struct no_weak_support{};
/*!
@class copy_on_write_policy
@brief This is a copy on write ownership policy.
This policy is a mixture of a deep copy clone policy
and the shared pointer policy.
It shares the pointer as long as no attempt
is made to access the pointee through non-constant
operator->().\n
When access is made to the non-constant operator->(),
the smart pointer clones itself if it's being referenced.
When it clones itself, it performs a deep copy of the pointee.
\n
<b>Example Usage</b>
@include ../examples/example_copy_on_write_policy_usage.hxx
\n
@see smart_ptr, shared_ptr_policy, deep_copy_policy, ref_link_policy,
ref_count_policy, ref_intrusive_policy, intrusive_lock_policy
\n
@note
The Ownership policy classes must take the lowest common
denominator of arguments for constructor and common functions.
Although this policy doesn't need the additional arguments,
other policies do, and therefore to keep a standard interface,
it must also take the additional arguments.
*/
template<class REFERENCE_POLICY = ref_default_policy, class LOCK_POLICY = lock_default_policy, class WEAK_SUPPORT_POLICY = no_weak_support>
class copy_on_write_policy : public REFERENCE_POLICY, public LOCK_POLICY
{
public:
copy_on_write_policy(){}
template<class T1, class F1, class T2>
inline copy_on_write_policy(REFERENCE_POLICY& src, const T1& type, const F1&, const T2&):REFERENCE_POLICY(src, type)
{
}
template<class T, class F>
T get_non_constant_ptr(T& type, F clone_fct)
{
if (REFERENCE_POLICY::is_referenced(type) && type && clone_fct)
{
assign(type, clone_fct,
clone_fct(type, true, NULL, NULL, NULL),
clone_fct, *this, *this);
}
return type;
}
};
/*!
@class shared_ptr_policy
@brief This is a shared pointer ownership policy.
This policy is similar to the ownership policy
used by boost::shared_ptr. However, by default,
the shared_ptr_policy uses reference link instead of
reference counting logic that is used by boost::shared_ptr.
In general, reference link logic is faster than
reference counting, so this make shared_ptr_policy with
it's default policies faster in general than
boost::shared_ptr.
For more information on pros and cons of the different
reference logic available,
see ref_link_policy, ref_count_policy, and ref_intrusive_policy.
\n
<b>Example Usage</b>
@include ../examples/example_shared_ptr_policy_usage.hxx
\n
@see smart_ptr, copy_on_write_policy, deep_copy_policy, ref_link_policy,
ref_count_policy, ref_intrusive_policy, intrusive_lock_policy
\n
@note
The Ownership policy classes must take the lowest common
denominator of arguments for constructor and common functions.
Although this policy doesn't need the additional arguments,
other policies do, and therefore to keep a standard interface,
it must also take the additional arguments.
Since shared_ptr_policy does not clone on write, get_non_constant_ptr
always returns the input pointer.
*/
template<class REFERENCE_POLICY = ref_default_policy, class LOCK_POLICY = lock_default_policy, class WEAK_SUPPORT_POLICY = no_weak_support>
class shared_ptr_policy : public REFERENCE_POLICY, public LOCK_POLICY
{
public:
shared_ptr_policy(){}
template<class T1, class F1, class T2>
inline shared_ptr_policy(REFERENCE_POLICY& src, const T1& type, const F1&, const T2&):REFERENCE_POLICY(src, type)
{
}
template<class T, class F>
inline T& get_non_constant_ptr(T& type, const F&){return type;}
};
/*!
@class deep_copy_policy
@brief This is a deep copy (Clone) ownership policy.
This policy is similar to most clone smart pointers.
However, when use with default allocator policy,
this type of policy does NOT require that the
pointee have a clone function implementation.
\n
<b>Example Usage</b>
@include ../examples/example_deep_copy_policy_usage.hxx
\n
@see smart_ptr, copy_on_write_policy, shared_ptr_policy, allocator_default_policy,
clone_function_allocator_policy, clone_static_function_allocator_policy,
intrusive_lock_policy
\n
*/
template<class LOCK_POLICY = lock_default_policy>
class deep_copy_policy : public LOCK_POLICY
{
public:
deep_copy_policy(){}
template<class T1, class F1, class T2>
inline deep_copy_policy(deep_copy_policy&, T1 type_src, F1 clone_fct, T2& type_target)
{
type_target = clone_fct(type_src, true, NULL, NULL, NULL);
}
template<class T, class F, class LCK>
inline void release(T& type, F clone_fct, LCK &)
{
if (type && clone_fct)
{
clone_fct(type, false, NULL, NULL, NULL);
}
type = NULL;
}
template<class T1, class F1, class T2, class F2, class LCK>
void assign(T1& type1, F1& clone_fct1, T2 type2, const F2 clone_fct2, deep_copy_policy&, LCK &lck_policy)
{
if (!type1 && type1 != type2)
{
lck_policy.assignment_lock_policy(type1);
release(type1, clone_fct1, lck_policy);
if (type2)
type1 = clone_fct2(type2, true, NULL, NULL, NULL);
clone_fct1 = clone_fct2;
}
}
template<class T, class F>
inline T& get_non_constant_ptr(T& type, const F&)
{//deep copy policy always clones on the constructor, so no need to clone here, and we can just return the pointer
return type;
}
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -