⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smart_ptr.hpp

📁 比STL和BOOST更强大的智能指针库!!! 私藏很久的老底与大家一起分享了.
💻 HPP
📖 第 1 页 / 共 5 页
字号:
@see smart_ptr, value_comparsion_semantic_policy, no_comparsion_semantic_policy
*/
struct pointer_comparsion_semantic_policy
{
	template<class T1, class T2> static bool less_than(const T1 & a, const T2 & b){return (a.c_ptr()) < (b.c_ptr());}
	template<class T1, class T2> static bool greater_than(const T1 & a, const T2 & b){return (a.c_ptr()) > (b.c_ptr());}
	template<class T1, class T2> static bool less_than_or_equal(const T1 & a, const T2 & b){return (a.c_ptr()) <= (b.c_ptr());}
	template<class T1, class T2> static bool greater_than_or_equal(const T1 & a, const T2 & b){return (a.c_ptr()) >= (b.c_ptr());}
	template<class T1, class T2> static bool is_equal(const T1 & a, const T2 & b){return (a.c_ptr()) == (b.c_ptr());}
};

/*!	@struct no_comparsion_semantic_policy
@brief This prevents comparison operators from being used with the smart_ptr.
Use this policy to disallow the use of comparison operators
@see smart_ptr, pointer_comparsion_semantic_policy, 
value_comparsion_semantic_policy
*/
struct no_comparsion_semantic_policy{};

/*!	@struct value_stream_operator_semantic_policy
@brief This is a pointee stream operator semantic policy.
Use this policy so as to allow stream operators to operate on the pointee
\n
<b>Example Usage</b>
@include ../examples/example_value_stream_operator_semantic_policy_usage.hxx
\n
@see smart_ptr, no_stream_operator_semantic_policy
*/
struct value_stream_operator_semantic_policy
{
	template<class T1, class T2> static T1& input_stream(T1 &is, T2 &smart_pointer){is >> (*smart_pointer.get_ptr());return is;}
	template<class T1, class T2> static T1& output_stream(T1 &io, T2 &smart_pointer){io << (*smart_pointer.c_ptr());return io;}
};

/*!	@struct no_stream_operator_semantic_policy
@brief This is a policy that prevents usage of stream operator.
Use this policy so as to disallow stream operator usage with the smart pointer
\n
\n
@see smart_ptr, value_stream_operator_semantic_policy
*/
struct no_stream_operator_semantic_policy{};

/*!	@struct value_arithmetic_semantic_policy
@brief This is a policy to allow arithmetic operators to target the pointee.
Use this policy to allow arithmetic operators to target the pointee 
instead of the pointer.  Normally, smart pointers try to emulate 
raw pointers, and when arithmetic operations are performed using 
the pointer, instead of what the pointer is pointing to.  This policy 
allows arithmetic operators to perform operations on the pointee, instead 
of the pointer.
\n
<b>Example Usage</b>
@include ../examples/example_no_arithmetic_semantic_policy_usage.hxx
\n
@see smart_ptr, no_arithmetic_semantic_policy
*/

struct value_arithmetic_semantic_policy
{
	// @cond INCLUDE_ALL_OBJS_
	template<class T> struct return_type{typedef T type;};
	// @endcond
	template<class T1, class T2> static T1& plus_equal_smart_ptr(T1 & a, const T2 & b){a.get_ptr()->operator+=(*b.c_ptr());return a;}
	template<class T1, class T2> static T1& plus_equal(T1 & a, const T2 & b){a.get_ptr()->operator+=(b);return a;}
	template<class T1, class T2> static T1& minus_equal_smart_ptr(T1 & a, const T2 & b){a.get_ptr()->operator-=(*b.c_ptr());return a;}
	template<class T1, class T2> static T1& minus_equal(T1 & a, const T2 & b){a.get_ptr()->operator-=(b);return a;}
	template<class T1, class T2> static T1 plus(const T1 & a, const T2 & b)
	{
		T1 c(a);
		c.get_ptr()->operator+=(*b.c_ptr());
		return c;
	}
	template<class T1, class T2> static T1 minus(const T1 & a, const T2 & b)
	{
		T1 c(a);
		c.get_ptr()->operator-=(*b.c_ptr());
		return c;
	}
};

// @cond INCLUDE_ALL_OBJS_
/*!	@struct no_arithmetic_semantic_policy
@brief A policy to prevents usage of arithmetic operators.
Use this policy to disallow the use of arithmetic operators
\n
@see smart_ptr, value_stream_operator_semantic_policy
\n
*/
struct no_arithmetic_semantic_policy{template<class T>struct return_type{typedef T type;};};
// @endcond

/*!
@struct ref_link_policy
@brief Use this policy to create a reference linking smart pointer.
In general, this policy is faster than the ref_count_policy,
but takes a little more memory.
It's not as easy to implement in synchronized code
compare to ref_count_policy.
It is more generic than ref_intrusive_policy, since it 
does not require that the target type have intrusive
functions.
Use ref_link_policy, when speed is the primary factor,
there is no synchronized referencing requirements, 
and there's no desire to implement intrusive functions
on the target type.
\n
<b>Example Usage</b>
@include ../examples/example_ref_link_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_intrusive_policy
*/
class ref_link_policy
{
	struct ref_link
	{
		ref_link():m_back(NULL), m_front(NULL){}
		ref_link *m_back;
		ref_link *m_front;
	private:  //Disallow copy constructor and assignment op
		ref_link(const ref_link&);
		ref_link& operator=(const ref_link&);
	};
	ref_link m_ref_link;
	void pop_link()
	{
		if (m_ref_link.m_back)
		{
			m_ref_link.m_back->m_front = m_ref_link.m_front;
		}
		if (m_ref_link.m_front)
		{
			m_ref_link.m_front->m_back = m_ref_link.m_back;
		}
		m_ref_link.m_front = NULL;
		m_ref_link.m_back = NULL;
	}
	void insert_link(ref_link *Target)
	{
		m_ref_link.m_back = Target;
		m_ref_link.m_front = Target->m_front;
		if (m_ref_link.m_front)
		{
			m_ref_link.m_front->m_back = &m_ref_link;
		}
		if (m_ref_link.m_back)
		{
			m_ref_link.m_back->m_front = &m_ref_link;
		}
	}
	ref_link_policy(const ref_link_policy&);
	ref_link_policy& operator=(const ref_link_policy&);
protected:
	template<class T>
		inline bool is_referenced(T&)const{return (m_ref_link.m_back || m_ref_link.m_front);}
public:
	ref_link_policy(){}
	template<class T1>
	inline ref_link_policy(ref_link_policy& src, T1&)
	{
		insert_link(&src.m_ref_link);
	}
	template<class T, class F, class LCK>
		void release(T& type, F clone_fct, LCK &lck_policy)
	{
		if (!is_referenced(type)){
			if (type && clone_fct)
			{
				clone_fct(type, false, NULL, NULL, NULL);
			}
			type = NULL;
		}
		else
		{
			pop_link();
			lck_policy.assignment_unlock_policy(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_link_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 (src_policy_eq_this)
			{
				m_ref_link.m_back = NULL;
				m_ref_link.m_front = NULL;
			}
			else
				insert_link(&src_policy.m_ref_link);
		}
	}
};

/*!
@struct ref_count_policy
@brief Use this policy to create a reference counting smart pointer.
This policy is similar to reference counting logic used by 
boost::shared_ptr.
In general, it is slower than the other two reference 
policies (ref_link_policy and ref_intrusive_policy).
It is more generic than ref_intrusive_policy, since it 
does not require that the target type have intrusive
functions.
It takes less space than ref_link_policy, and it's 
easier to implement in synchronized code, than
ref_link_policy.
Use this policy when space is the primary factor, or
when referencing the same object in multiple threads 
and you don't wish to use an intrusive_lock_policy.
\n
<b>Example Usage</b>
@include ../examples/example_ref_count_policy_usage.hxx
\n
@see smart_ptr, ref_link_policy, ref_intrusive_policy
*/

class ref_count_policy
{
	struct ref_count
	{
		ref_count():m_count(new size_t(1)){}
		ref_count(size_t *count_):m_count(count_){}
		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;
	ref_count_policy(const ref_count_policy&);
	ref_count_policy& operator=(const ref_count_policy&);
protected:
	template<class T>
		inline bool is_referenced(T&)const{return (m_ref_count.m_count && (*m_ref_count.m_count) > 1);}
public:
	ref_count_policy(){}
	template<class T1>
		inline ref_count_policy(ref_count_policy& src, T1&):m_ref_count(src.m_ref_count.m_count)
	{
		if (m_ref_count.m_count) ++(*m_ref_count.m_count);
	}
	/// @todo Add assertion argument so function can call assertion policy
	template<class T, class F, class LCK>
		void release(T& type, F clone_fct, LCK &lck_policy)
	{
		if (!is_referenced(type)){
			if (type && clone_fct)
			{
				clone_fct(type, false, NULL, NULL, NULL);
			}
			type = NULL;
			delete m_ref_count.m_count;
			m_ref_count.m_count = NULL;
		}
		else
		{
			if (m_ref_count.m_count) --(*m_ref_count.m_count);
			lck_policy.assignment_unlock_policy(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_count_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 (src_policy_eq_this)
				m_ref_count.m_count = new size_t(0); //Set to zero, because of increment below
			else
				m_ref_count.m_count = src_policy.m_ref_count.m_count;
			if (m_ref_count.m_count) ++(*m_ref_count.m_count);
		}
	}
};

/*!
@struct ref_intrusive_policy
@brief Use this policy to create an intrusive reference smart pointer.
In general, this policy is faster than both ref_count_policy 
and ref_link_policy.
However, it requires three intrusive functions that take
the target type pointer as a parameter.\n
void intrusive_ptr_add_ref(T *);\n
void intrusive_ptr_release(T *);\n
bool intrusive_ptr_is_ref(T *);\n

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -