1 #ifndef cow_ptr_H_HEADER_GUARD_ 2 #define cow_ptr_H_HEADER_GUARD_ 49 template <
typename T,
typename DT> T * cow_ptr_ConstructAndDestruct_default_allocator_(T*,
bool, DT* ,
void*);
58 typedef T * ( *clone_fct_Type ) (
const T *, bool,
void*,
void*);
61 ref_link():m_back(NULL), m_front(NULL){}
65 ref_link(
const ref_link&);
66 ref_link& operator=(
const ref_link&);
68 mutable ref_link m_ref_link;
70 clone_fct_Type m_clone_fct;
73 template<
typename T_obj>
74 cow_ptr(T_obj* type): m_type(type), m_clone_fct(get_alloc_func(type))
77 BOOST_ASSERT(type != NULL);
78 BOOST_ASSERT(
typeid(*type) ==
typeid(T_obj));
84 cow_ptr(
const cow_ptr& Src):m_type(Src.m_type), m_clone_fct(Src.m_clone_fct){insert_link(&Src.m_ref_link);}
85 #if !defined(_MSC_VER) || (_MSC_VER > 1200) 87 template<
class CompatibleDerivedT>
90 Src.make_clone(m_type, m_clone_fct);
92 template<
class CompatibleDerivedT>
96 Src.make_clone(m_type, m_clone_fct);
99 #endif //_MSC_VER != 1200 102 enum implement_default_object{eYes, eNo};
104 cow_ptr(implement_default_object use_default_obj = eYes):m_type(NULL), m_clone_fct(NULL)
106 if (use_default_obj == eYes)
107 assign(GetSetDefaultObject());
111 static void SetDefaultObject(
const cow_ptr<T>& NewValue){GetSetDefaultObject(&NewValue);}
113 typedef T& reference;
114 bool operator! ()
const{
return c_ptr() == 0;}
117 (*get_ptr()) = (Src);
121 inline T* operator->() {
return get_ptr();}
122 inline T& operator*() {
return *get_ptr();}
123 inline const T* operator->()
const {
return m_type;}
124 inline const T& operator*()
const {
return *m_type;}
126 get_ptr()->operator+=(*Src.c_ptr());
130 cow_ptr& operator+=(
const T2& Src){
131 get_ptr()->operator+=(Src);
135 get_ptr()->operator+(*Src.c_ptr());
139 get_ptr()->operator-=(*Src.c_ptr());
143 get_ptr()->operator-(*Src.c_ptr());
146 clone_fct_Type get_function_ptr()
const{
return m_clone_fct;}
151 T* tmp = m_clone_fct(m_type,
true, NULL, NULL);
157 inline const T* c_ptr()
const{
return m_type;}
158 inline const T& c_ref()
const{
return *m_type;}
160 void swap(
cow_ptr<T> & other)
throw(){std::swap(m_ref_link, other.m_ref_link);std::swap(m_type, other.m_type);std::swap(m_clone_fct, other.m_clone_fct);}
162 bool is_ref_linked()
const{
return (m_ref_link.m_back || m_ref_link.m_front);}
164 template<
class PT,
class FPT>
void make_clone(PT*& ptr, FPT& func_ptr)
const 168 ptr = m_clone_fct(m_type,
true, NULL, NULL);
169 func_ptr = (FPT)m_clone_fct;
175 template<
typename T_obj>
176 static clone_fct_Type get_alloc_func(T_obj*)
178 T * ( *tmp ) (T *, bool, T_obj*,
void*) = cow_ptr_ConstructAndDestruct_default_allocator_<T,T_obj>;
179 return (clone_fct_Type)tmp;
181 void release()
throw()
183 if (!is_ref_linked())
187 m_clone_fct(m_type,
false, NULL, NULL);
198 if (m_ref_link.m_back)
200 m_ref_link.m_back->m_front = m_ref_link.m_front;
202 if (m_ref_link.m_front)
204 m_ref_link.m_front->m_back = m_ref_link.m_back;
206 m_ref_link.m_front = NULL;
207 m_ref_link.m_back = NULL;
209 void insert_link(ref_link *Target)
211 m_ref_link.m_back = Target;
212 m_ref_link.m_front = Target->m_front;
213 if (m_ref_link.m_front)
215 m_ref_link.m_front->m_back = &m_ref_link;
217 if (m_ref_link.m_back)
219 m_ref_link.m_back->m_front = &m_ref_link;
222 template<
class CompatibleSmartPtr>
223 cow_ptr& assign(CompatibleSmartPtr& Src)
225 if (!m_type || Src.is_ref_linked() || m_type != Src.c_ptr())
229 m_clone_fct = Src.m_clone_fct;
230 insert_link(&Src.m_ref_link);
237 if (NewValue && NewValue->m_type)
238 DefaultObj = *NewValue;
244 template<
class T,
class U>
bool operator<(cow_ptr<T>
const & a,
cow_ptr<U> const & b){
return (*a.c_ptr()) < (*b.c_ptr());}
245 template<
class T,
class U>
bool operator>(
cow_ptr<T> const & a,
cow_ptr<U> const & b){
return (*a.c_ptr()) > (*b.c_ptr());}
246 template<
class T,
class U>
bool operator<=(cow_ptr<T>
const & a,
cow_ptr<U> const & b){
return (*a.c_ptr()) <= (*b.c_ptr());}
247 template<
class T,
class U>
bool operator>=(
cow_ptr<T> const & a,
cow_ptr<U> const & b){
return (*a.c_ptr()) >= (*b.c_ptr());}
248 template<
class T,
class U>
bool operator==(
cow_ptr<T> const & a,
cow_ptr<U> const & b){
return (*a.c_ptr()) == (*b.c_ptr());}
249 template<
class T,
class U>
bool operator!=(
cow_ptr<T> const & a,
cow_ptr<U> const & b){
return (*a.c_ptr()) != (*b.c_ptr());}
251 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 253 template<
class T>
bool operator!=(
cow_ptr<T> const & a,
cow_ptr<T> const & b){
return (*a.c_ptr()) != (*b.c_ptr());}
266 template <
typename T,
typename DT> T * cow_ptr_ConstructAndDestruct_default_allocator_(T * ptr,
bool bConstruct, DT* ,
void*) {
267 if (bConstruct){
return new DT(*static_cast<const DT*>(ptr));}
268 delete const_cast<T*
>(ptr);
cow_ptr is a Copy On Write smart pointer. It does not require the pointee to have clone function logi...
Definition: cow_ptr.hpp:56