00001 #ifndef smart_ptr_HPP_HEADER_GUARD_
00002 #define smart_ptr_HPP_HEADER_GUARD_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00095 #ifndef __BORLANDC__
00096 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
00097
00098 #define SMART_PTR_SUPPORT_RETURN_TYPE_THROUGH_POLICY_
00099 #endif
00100 #endif
00101
00123 struct allocator_default_policy
00124 {
00134 template<typename T_obj> static inline T_obj* allocate(const T_obj* ptr)
00135 {
00136 if (ptr) return new T_obj(*ptr);
00137 return NULL;
00138 }
00142 template<typename T_obj> static inline void deallocate(T_obj* ptr){delete ptr;}
00143 };
00144
00165 struct clone_function_allocator_policy
00166 {
00176 template<typename T_obj> static inline T_obj* allocate(const T_obj* ptr)
00177 {
00178 if(!ptr) return NULL;
00179 return static_cast<T_obj*>(ptr->do_clone());
00180 }
00184 template<typename T_obj> static inline void deallocate(T_obj* ptr){delete ptr;}
00185 };
00186
00208 struct clone_static_function_allocator_policy
00209 {
00216 template<typename T_obj> static inline T_obj* allocate(const T_obj* ptr)
00217 {
00218 if(!ptr) return NULL;
00219 return T_obj::do_clone(*ptr);
00220 }
00224 template<typename T_obj> static inline void deallocate(T_obj* ptr){delete ptr;}
00225 };
00226
00227
00239 template<size_t size_array>
00240 struct allocator_array_policy
00241 {
00250 template<typename T_obj> static T_obj* allocate(const T_obj* ptr)
00251 {
00252 if (!ptr) return NULL;
00253 #ifdef BOOST_ASSERT
00254 BOOST_ASSERT(size_array);
00255 #endif //BOOST_ASSERT
00256 T_obj *arr = new T_obj[size_array];
00257 for(size_t i = 0;i < size_array;++i)
00258 arr[i] = ptr[i];
00259 return arr;
00260 }
00264 template<typename T_obj> static inline void deallocate(T_obj* ptr){delete[] ptr;}
00265 };
00266
00267
00283 struct value_comparsion_semantic_policy
00284 {
00285 template<class T1, class T2> static bool less_than(const T1 & a, const T2 & b){return (*a.c_ptr()) < (*b.c_ptr());}
00286 template<class T1, class T2> static bool greater_than(const T1 & a, const T2 & b){return (*a.c_ptr()) > (*b.c_ptr());}
00287 template<class T1, class T2> static bool less_than_or_equal(const T1 & a, const T2 & b){return (*a.c_ptr()) <= (*b.c_ptr());}
00288 template<class T1, class T2> static bool greater_than_or_equal(const T1 & a, const T2 & b){return (*a.c_ptr()) >= (*b.c_ptr());}
00289 template<class T1, class T2> static bool is_equal(const T1 & a, const T2 & b){return (*a.c_ptr()) == (*b.c_ptr());}
00290 };
00291
00300 struct pointer_comparsion_semantic_policy
00301 {
00302 template<class T1, class T2> static bool less_than(const T1 & a, const T2 & b){return (a.c_ptr()) < (b.c_ptr());}
00303 template<class T1, class T2> static bool greater_than(const T1 & a, const T2 & b){return (a.c_ptr()) > (b.c_ptr());}
00304 template<class T1, class T2> static bool less_than_or_equal(const T1 & a, const T2 & b){return (a.c_ptr()) <= (b.c_ptr());}
00305 template<class T1, class T2> static bool greater_than_or_equal(const T1 & a, const T2 & b){return (a.c_ptr()) >= (b.c_ptr());}
00306 template<class T1, class T2> static bool is_equal(const T1 & a, const T2 & b){return (a.c_ptr()) == (b.c_ptr());}
00307 };
00308
00315 struct no_comparsion_semantic_policy{};
00316
00326 struct value_stream_operator_semantic_policy
00327 {
00328 template<class T1, class T2> static T1& input_stream(T1 &is, T2 &smart_pointer){is >> (*smart_pointer.get_ptr());return is;}
00329 template<class T1, class T2> static T1& output_stream(T1 &io, T2 &smart_pointer){io << (*smart_pointer.c_ptr());return io;}
00330 };
00331
00339 struct no_stream_operator_semantic_policy{};
00340
00356 struct value_arithmetic_semantic_policy
00357 {
00358
00359 template<class T> struct return_type{typedef T type;};
00360
00361 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;}
00362 template<class T1, class T2> static T1& plus_equal(T1 & a, const T2 & b){a.get_ptr()->operator+=(b);return a;}
00363 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;}
00364 template<class T1, class T2> static T1& minus_equal(T1 & a, const T2 & b){a.get_ptr()->operator-=(b);return a;}
00365 template<class T1, class T2> static T1 plus(const T1 & a, const T2 & b)
00366 {
00367 T1 c(a);
00368 c.get_ptr()->operator+=(*b.c_ptr());
00369 return c;
00370 }
00371 template<class T1, class T2> static T1 minus(const T1 & a, const T2 & b)
00372 {
00373 T1 c(a);
00374 c.get_ptr()->operator-=(*b.c_ptr());
00375 return c;
00376 }
00377 };
00378
00379
00387 struct no_arithmetic_semantic_policy{template<class T>struct return_type{typedef T type;};};
00388
00389
00413 class ref_link_policy
00414 {
00415 struct ref_link
00416 {
00417 ref_link():m_back(NULL), m_front(NULL){}
00418 ref_link *m_back;
00419 ref_link *m_front;
00420 private:
00421 ref_link(const ref_link&);
00422 ref_link& operator=(const ref_link&);
00423 };
00424 ref_link m_ref_link;
00425 void pop_link()
00426 {
00427 if (m_ref_link.m_back)
00428 {
00429 m_ref_link.m_back->m_front = m_ref_link.m_front;
00430 }
00431 if (m_ref_link.m_front)
00432 {
00433 m_ref_link.m_front->m_back = m_ref_link.m_back;
00434 }
00435 m_ref_link.m_front = NULL;
00436 m_ref_link.m_back = NULL;
00437 }
00438 void insert_link(ref_link *Target)
00439 {
00440 m_ref_link.m_back = Target;
00441 m_ref_link.m_front = Target->m_front;
00442 if (m_ref_link.m_front)
00443 {
00444 m_ref_link.m_front->m_back = &m_ref_link;
00445 }
00446 if (m_ref_link.m_back)
00447 {
00448 m_ref_link.m_back->m_front = &m_ref_link;
00449 }
00450 }
00451 ref_link_policy(const ref_link_policy&);
00452 ref_link_policy& operator=(const ref_link_policy&);
00453 protected:
00454 template<class T>
00455 inline bool is_referenced(T&)const{return (m_ref_link.m_back || m_ref_link.m_front);}
00456 public:
00457 ref_link_policy(){}
00458 template<class T1>
00459 inline ref_link_policy(ref_link_policy& src, T1&)
00460 {
00461 insert_link(&src.m_ref_link);
00462 }
00463 template<class T, class F, class LCK>
00464 void release(T& type, F clone_fct, LCK &lck_policy)
00465 {
00466 if (!is_referenced(type)){
00467 if (type && clone_fct)
00468 {
00469 clone_fct(type, false, NULL, NULL, NULL);
00470 }
00471 type = NULL;
00472 }
00473 else
00474 {
00475 pop_link();
00476 lck_policy.assignment_unlock_policy(type);
00477 }
00478 }
00479 template<class T1, class F1, class T2, class F2, class LCK>
00480 void assign(T1& type1, F1& clone_fct1, T2 type2, const F2 clone_fct2, ref_link_policy& src_policy, LCK &lck_policy)
00481 {
00482 if (!type1 || type1 != type2)
00483 {
00484 lck_policy.assignment_lock_policy(type1);
00485 const bool src_policy_eq_this = (this == &src_policy);
00486 release(type1, clone_fct1, lck_policy);
00487 type1 = type2;
00488 clone_fct1 = clone_fct2;
00489 if (src_policy_eq_this)
00490 {
00491 m_ref_link.m_back = NULL;
00492 m_ref_link.m_front = NULL;
00493 }
00494 else
00495 insert_link(&src_policy.m_ref_link);
00496 }
00497 }
00498 };
00499
00523 class ref_count_policy
00524 {
00525 struct ref_count
00526 {
00527 ref_count():m_count(new size_t(1)){}
00528 ref_count(size_t *count_):m_count(count_){}
00529 size_t *m_count;
00530 private:
00531 ref_count(const ref_count&);
00532 ref_count& operator=(const ref_count&);
00533 };
00534 ref_count m_ref_count;
00535 ref_count_policy(const ref_count_policy&);
00536 ref_count_policy& operator=(const ref_count_policy&);
00537 protected:
00538 template<class T>
00539 inline bool is_referenced(T&)const{return (m_ref_count.m_count && (*m_ref_count.m_count) > 1);}
00540 public:
00541 ref_count_policy(){}
00542 template<class T1>
00543 inline ref_count_policy(ref_count_policy& src, T1&):m_ref_count(src.m_ref_count.m_count)
00544 {
00545 if (m_ref_count.m_count) ++(*m_ref_count.m_count);
00546 }
00548 template<class T, class F, class LCK>
00549 void release(T& type, F clone_fct, LCK &lck_policy)
00550 {
00551 if (!is_referenced(type)){
00552 if (type && clone_fct)
00553 {
00554 clone_fct(type, false, NULL, NULL, NULL);
00555 }
00556 type = NULL;
00557 delete m_ref_count.m_count;
00558 m_ref_count.m_count = NULL;
00559 }
00560 else
00561 {
00562 if (m_ref_count.m_count) --(*m_ref_count.m_count);
00563 lck_policy.assignment_unlock_policy(type);
00564 }
00565 }
00566 template<class T1, class F1, class T2, class F2, class LCK>
00567 void assign(T1& type1, F1& clone_fct1, T2 type2, const F2 clone_fct2, ref_count_policy& src_policy, LCK &lck_policy)
00568 {
00569 if (!type1 || type1 != type2)
00570 {
00571 lck_policy.assignment_lock_policy(type1);
00572 const bool src_policy_eq_this = (this == &src_policy);
00573 release(type1, clone_fct1, lck_policy);
00574 type1 = type2;
00575 clone_fct1 = clone_fct2;
00576 if (src_policy_eq_this)
00577 m_ref_count.m_count = new size_t(0);
00578 else
00579 m_ref_count.m_count = src_policy.m_ref_count.m_count;
00580 if (m_ref_count.m_count) ++(*m_ref_count.m_count);
00581 }
00582 }
00583 };
00584
00611 class ref_intrusive_policy
00612 {
00613 ref_intrusive_policy(const ref_intrusive_policy&);
00614 ref_intrusive_policy& operator=(const ref_intrusive_policy&);
00615 protected:
00616 template<class T>
00617 inline bool is_referenced(T& type)const{return intrusive_ptr_is_ref(type);}
00618 public:
00619 ref_intrusive_policy(){}
00620 template<class T>
00621 inline ref_intrusive_policy(ref_intrusive_policy&, T& type)
00622 {
00623 if (type) intrusive_ptr_add_ref(type);
00624 }
00625 template<class T, class F, class LCK>
00626 void release(T& type, F, LCK &)
00627 {
00628
00629 if (type) intrusive_ptr_release(type);
00630 }
00631 template<class T1, class F1, class T2, class F2, class LCK>
00632 void assign(T1& type1, F1& clone_fct1, T2 type2, const F2 clone_fct2, ref_intrusive_policy &src_policy, LCK &lck_policy)
00633 {
00634 if (!type1 || type1 != type2)
00635 {
00636 lck_policy.assignment_lock_policy(type1);
00637 const bool src_policy_eq_this = (this == &src_policy);
00638 release(type1, clone_fct1, lck_policy);
00639 type1 = type2;
00640 clone_fct1 = clone_fct2;
00641 if (type1 && !src_policy_eq_this) intrusive_ptr_add_ref(type1);
00642 }
00643 }
00644 };
00645
00653 struct no_lock_policy
00654 {
00655 no_lock_policy(){}
00656 template<class T_obj> inline void pointee_lock_policy(T_obj*){}
00657 template<class T_obj> inline void const_pointee_lock_policy(T_obj*){}
00658 template<class T_obj> inline void assignment_lock_policy(T_obj*){}
00659 template<class T_obj> inline void assignment_unlock_policy(T_obj*){}
00660 template<class T_obj> inline void destructor_lock_policy(T_obj*){}
00661 template<class T_obj> inline void destructor_unlock_policy(T_obj*){}
00662 template<class T_obj> inline T_obj* constructor_lock_policy(T_obj* p){return p;}
00663 template<class T_obj> inline void constructor_unlock_policy(T_obj*){}
00664
00665 template<class T> struct return_type{typedef T* type_pointee;typedef T& type_ref;};
00666
00667
00668 template<class T_obj> inline void lock(T_obj*){}
00669 template<class T_obj> inline void unlock(T_obj*){}
00670 private:
00671
00672 template<class T_obj> inline bool trylock(T_obj*);
00673 template<class T_obj> inline bool islock(T_obj*);
00674
00675 no_lock_policy(const no_lock_policy&);
00676 no_lock_policy& operator=(const no_lock_policy&);
00677 };
00678
00704 struct intrusive_lock_policy
00705 {
00706 intrusive_lock_policy(){}
00707 template<class T_obj> inline void pointee_lock_policy(T_obj* p){}
00708 template<class T_obj> inline void const_pointee_lock_policy(T_obj* p){}
00709 template<class T_obj> inline void assignment_lock_policy(T_obj* p){if (p) lock(p);}
00710 template<class T_obj> inline void assignment_unlock_policy(T_obj* p){if (p) unlock(p);}
00711 template<class T_obj> inline void destructor_lock_policy(T_obj* p){if (p) lock(p);}
00712 template<class T_obj> inline void destructor_unlock_policy(T_obj* p){if (p) unlock(p);}
00713 template<class T_obj> inline T_obj* constructor_lock_policy(T_obj* p){if (p) lock(p);return p;}
00714 template<class T_obj> inline void constructor_unlock_policy(T_obj* p){if (p) unlock(p);}
00715 template<class T_obj> inline void lock(T_obj* p){intrusive_ptr_lock(p);}
00716 template<class T_obj> inline void unlock(T_obj* p){intrusive_ptr_unlock(p);}
00717 template<class T_obj> inline bool trylock(T_obj* p){return intrusive_ptr_trylock(p);}
00718 template<class T_obj> inline bool islock(T_obj* p){return intrusive_ptr_islock(p);}
00719
00720 template<class T> struct return_type{typedef T* type_pointee;typedef T& type_ref;};
00721
00722 private:
00723 intrusive_lock_policy(const intrusive_lock_policy&);
00724 intrusive_lock_policy& operator=(const intrusive_lock_policy&);
00725 };
00726
00727
00728 #ifndef SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
00729 typedef no_lock_policy lock_default_policy;
00730 typedef ref_link_policy ref_default_policy;
00731 #endif // not SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
00732
00733
00734 struct weak_storage
00735 {
00736 struct ref_count
00737 {
00738 ref_count():m_count(new size_t(1)){}
00739 size_t *m_count;
00740 private:
00741 ref_count(const ref_count&);
00742 ref_count& operator=(const ref_count&);
00743 };
00744 ref_count m_ref_count;
00745 };
00746
00747 struct no_weak_support{};
00748
00774 template<class REFERENCE_POLICY = ref_default_policy, class LOCK_POLICY = lock_default_policy, class WEAK_SUPPORT_POLICY = no_weak_support>
00775 class copy_on_write_policy : public REFERENCE_POLICY, public LOCK_POLICY
00776 {
00777 public:
00778 copy_on_write_policy(){}
00779 template<class T1, class F1, class T2>
00780 inline copy_on_write_policy(REFERENCE_POLICY& src, const T1& type, const F1&, const T2&):REFERENCE_POLICY(src, type)
00781 {
00782 }
00783 template<class T, class F>
00784 T get_non_constant_ptr(T& type, F clone_fct)
00785 {
00786 if (REFERENCE_POLICY::is_referenced(type) && type && clone_fct)
00787 {
00788 assign(type, clone_fct,
00789 clone_fct(type, true, NULL, NULL, NULL),
00790 clone_fct, *this, *this);
00791 }
00792 return type;
00793 }
00794 };
00795
00826 template<class REFERENCE_POLICY = ref_default_policy, class LOCK_POLICY = lock_default_policy, class WEAK_SUPPORT_POLICY = no_weak_support>
00827 class shared_ptr_policy : public REFERENCE_POLICY, public LOCK_POLICY
00828 {
00829 public:
00830 shared_ptr_policy(){}
00831 template<class T1, class F1, class T2>
00832 inline shared_ptr_policy(REFERENCE_POLICY& src, const T1& type, const F1&, const T2&):REFERENCE_POLICY(src, type)
00833 {
00834 }
00835 template<class T, class F>
00836 inline T& get_non_constant_ptr(T& type, const F&){return type;}
00837 };
00838
00855 template<class LOCK_POLICY = lock_default_policy>
00856 class deep_copy_policy : public LOCK_POLICY
00857 {
00858 public:
00859 deep_copy_policy(){}
00860 template<class T1, class F1, class T2>
00861 inline deep_copy_policy(deep_copy_policy&, T1 type_src, F1 clone_fct, T2& type_target)
00862 {
00863 type_target = clone_fct(type_src, true, NULL, NULL, NULL);
00864 }
00865 template<class T, class F, class LCK>
00866 inline void release(T& type, F clone_fct, LCK &)
00867 {
00868 if (type && clone_fct)
00869 {
00870 clone_fct(type, false, NULL, NULL, NULL);
00871 }
00872 type = NULL;
00873 }
00874 template<class T1, class F1, class T2, class F2, class LCK>
00875 void assign(T1& type1, F1& clone_fct1, T2 type2, const F2 clone_fct2, deep_copy_policy&, LCK &lck_policy)
00876 {
00877 if (!type1 && type1 != type2)
00878 {
00879 lck_policy.assignment_lock_policy(type1);
00880 release(type1, clone_fct1, lck_policy);
00881 if (type2)
00882 type1 = clone_fct2(type2, true, NULL, NULL, NULL);
00883 clone_fct1 = clone_fct2;
00884 }
00885 }
00886 template<class T, class F>
00887 inline T& get_non_constant_ptr(T& type, const F&)
00888 {
00889 return type;
00890 }
00891 };
00892
00897 struct no_checking_policy
00898 {
00899 template<class T_obj> static void check_type_pass_to_constructor(T_obj*){}
00900 template<class T_obj> static void on_dereference(T_obj*){}
00901 template<class T_obj> static void on_const_dereference(T_obj*){}
00902 template<class T_obj> static void before_release(T_obj*){}
00903 template<class T_obj> static void after_release(T_obj*){}
00904 };
00905
00906
00907 struct boost_assert_checking_policy
00908 {
00909 #ifdef BOOST_ASSERT
00910 template<class T_obj> static void check_type_pass_to_constructor(T_obj*){}
00911 template<class T_obj> static void on_dereference(T_obj*){}
00912 template<class T_obj> static void on_const_dereference(T_obj*){}
00913 #else
00914 template<class T_obj> static void check_type_pass_to_constructor(T_obj* type)
00915 {
00916 BOOST_ASSERT(type != NULL);
00917 BOOST_ASSERT(typeid(*type) == typeid(T_obj));
00918 }
00919 template<class T_obj> static void on_dereference(T_obj* type)
00920 {
00921 BOOST_ASSERT(type != NULL);
00922 BOOST_ASSERT(typeid(*type) == typeid(T_obj));
00923 }
00924 template<class T_obj> static void on_const_dereference(T_obj* type)
00925 {
00926 BOOST_ASSERT(type != NULL);
00927 BOOST_ASSERT(typeid(*type) == typeid(T_obj));
00928 }
00929 #endif //BOOST_ASSERT
00930 template<class T_obj> static void before_release(T_obj*){}
00931 template<class T_obj> static void after_release(T_obj*){}
00932 };
00933
00934
00935
00944 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00945 template < typename TT, typename DT, typename AL> TT * constructor_and_destructor_allocator_function( TT * ptr, bool bConstruct, DT*, AL* , void*)
00946 {
00947 if (!ptr) return NULL;
00948 if (bConstruct){return AL::allocate(static_cast<const DT*>(ptr));}
00949 AL::deallocate(ptr);
00950 return NULL;
00951 }
00952 #endif //defined(_MSC_VER) && (_MSC_VER <= 1200)
00953
00954
00968 #ifndef SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
00969 typedef value_comparsion_semantic_policy comparison_default_policy;
00970 typedef no_stream_operator_semantic_policy stream_default_policy;
00971 typedef no_checking_policy checking_default_policy;
00972
00973
00974
00975 typedef copy_on_write_policy<ref_default_policy, lock_default_policy> ownership_default_policy;
00976 typedef no_arithmetic_semantic_policy arithmetic_default_policy;
00977 #endif // not SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
00978
00992 template<class T, class ALLOCATOR_POLICY>
00993 class smart_ptr_base
00994 {
00995 protected:
00996 typedef T * ( *clone_fct_Type ) (const T *, bool, void*, ALLOCATOR_POLICY*, void*);
00997 T* m_type;
00998 clone_fct_Type m_clone_fct;
00999 inline smart_ptr_base(T* type, clone_fct_Type clone_fct): m_type(type), m_clone_fct(clone_fct){}
01000 inline ~smart_ptr_base() throw()
01001 {
01002 if (m_type) m_clone_fct(m_type, false, NULL, NULL, NULL);
01003 }
01004 private:
01005 smart_ptr_base(const smart_ptr_base&);
01006 smart_ptr_base& operator=(const smart_ptr_base& Src);
01007 };
01008
01009
01140
01141
01142
01143
01144
01145
01146 template<class T,
01147
01148 class OWNERSHIP_POLICY = ownership_default_policy ,
01149
01150 class ALLOCATOR_POLICY = allocator_default_policy,
01151
01152 class CHECKING_POLICY = checking_default_policy,
01153
01154 class COMPARISON_SEMANTIC_POLICY = comparison_default_policy,
01155
01156 class STREAM_OP_SEMANTIC_POLICY = stream_default_policy,
01157
01158 class ARITHMETIC_SEMANTIC_POLICY = arithmetic_default_policy>
01159 class smart_ptr : smart_ptr_base<T, ALLOCATOR_POLICY>
01160 {
01161 enum implement_default_object{eYes, eNo};
01162 mutable OWNERSHIP_POLICY m_ownership_policy;
01163 public:
01169 template<typename T_obj>
01170 inline smart_ptr(T_obj* type):smart_ptr_base<T,ALLOCATOR_POLICY>(type, get_alloc_func(type))
01171 {
01172 CHECKING_POLICY::check_type_pass_to_constructor(type);
01173 }
01175 inline smart_ptr(const smart_ptr& Src):smart_ptr_base<T,ALLOCATOR_POLICY>(Src.m_ownership_policy.constructor_lock_policy(Src.m_type), Src.m_clone_fct), m_ownership_policy(Src.m_ownership_policy, Src.m_type, Src.m_clone_fct, m_type){Src.m_ownership_policy.constructor_unlock_policy(Src.m_type);}
01177 smart_ptr(implement_default_object use_default_obj = eYes):smart_ptr_base<T,ALLOCATOR_POLICY>(NULL, NULL)
01178 {
01179 if (use_default_obj == eYes)
01180 {
01181 smart_ptr& default_obj = get_or_set_default_object();
01182 default_obj.lock();
01183 m_ownership_policy.assign(m_type, m_clone_fct, default_obj.m_type, default_obj.m_clone_fct, default_obj.m_ownership_policy, m_ownership_policy);
01184 default_obj.unlock();
01185 }
01186 }
01188 inline ~smart_ptr() throw()
01189 {
01190 m_ownership_policy.destructor_lock_policy(m_type);
01191 CHECKING_POLICY::before_release(m_type);
01192 m_ownership_policy.release(m_type, m_clone_fct, m_ownership_policy);
01193 CHECKING_POLICY::after_release(m_type);
01194 m_type = NULL;
01195 }
01196 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
01197
01198 template<class CompatibleDerivedT, class OWNERSHIP_POLICY_T, class ALLOCATOR_POLICY_T, class CHECKING_POLICY_T, class COMPARISON_SEMANTIC_POLICY_T, class STREAM_OPERATOR_SEMANTIC_POLICY_T, class ARITHMETIC_SEMANTIC_POLICY_T>
01199 smart_ptr(const smart_ptr<CompatibleDerivedT, OWNERSHIP_POLICY_T, ALLOCATOR_POLICY_T, CHECKING_POLICY_T, COMPARISON_SEMANTIC_POLICY_T, STREAM_OPERATOR_SEMANTIC_POLICY_T, ARITHMETIC_SEMANTIC_POLICY_T>& Src):smart_ptr_base<T,ALLOCATOR_POLICY>(NULL, NULL)
01200 {
01201 Src.lock();
01202 Src.make_clone(m_type, m_clone_fct);
01203 Src.unlock();
01204 }
01206
01208 template<class CompatibleDerivedT, class OWNERSHIP_POLICY_T, class ALLOCATOR_POLICY_T, class CHECKING_POLICY_T, class COMPARISON_SEMANTIC_POLICY_T, class STREAM_OPERATOR_SEMANTIC_POLICY_T, class ARITHMETIC_SEMANTIC_POLICY_T>
01209 smart_ptr& operator=(const smart_ptr<CompatibleDerivedT, OWNERSHIP_POLICY_T, ALLOCATOR_POLICY_T, CHECKING_POLICY_T, COMPARISON_SEMANTIC_POLICY_T, STREAM_OPERATOR_SEMANTIC_POLICY_T, ARITHMETIC_SEMANTIC_POLICY_T>& Src)
01210 {
01211 if (m_type != Src.c_ptr())
01212 {
01213 m_ownership_policy.assignment_lock_policy(m_type);
01214 CHECKING_POLICY::before_release(m_type);
01215 m_ownership_policy.release(m_type, m_clone_fct, m_ownership_policy);
01216 CHECKING_POLICY::after_release(m_type);
01217 Src.lock();
01218 Src.make_clone(m_type, m_clone_fct);
01219 Src.unlock();
01220 }
01221 return *this;
01222 }
01223 #else
01224
01225 template<class CompatiblePointerTypeForVC60>
01226 smart_ptr& operator=(const CompatiblePointerTypeForVC60& Src)
01227 {
01228 m_ownership_policy.assignment_lock_policy(m_type);
01229 CHECKING_POLICY::before_release(m_type);
01230 m_ownership_policy.release(m_type, m_clone_fct, m_ownership_policy);
01231 if (m_type) m_ownership_policy.assignment_unlock_policy(m_type);
01232 CHECKING_POLICY::after_release(m_type);
01233 Src.lock();
01234 Src.make_clone(m_type, m_clone_fct);
01235 Src.unlock();
01236 return *this;
01237 }
01238 #endif //_MSC_VER noteq 1200
01239
01240 smart_ptr& operator=(smart_ptr& Src)
01241 {
01242 if (m_type != Src.m_type)
01243 {
01244 Src.lock();
01245 m_ownership_policy.assign(m_type, m_clone_fct, Src.m_type, Src.m_clone_fct, Src.m_ownership_policy, m_ownership_policy);
01246 Src.unlock();
01247 }
01248 return *this;
01249 }
01250 bool operator! () const{return c_ptr() == 0;}
01251 #ifdef SMART_PTR_SUPPORT_RETURN_TYPE_THROUGH_POLICY_
01252
01253
01254 typedef typename ARITHMETIC_SEMANTIC_POLICY::template return_type<smart_ptr>::type arith_retrn_type;
01255
01256
01257
01258 arith_retrn_type& operator+=(const smart_ptr& Src){return ARITHMETIC_SEMANTIC_POLICY::plus_equal_smart_ptr(*this, Src);}
01259 template<class T2> arith_retrn_type& operator+=(const T2& Src){return ARITHMETIC_SEMANTIC_POLICY::plus_equal(*this, Src);}
01260 arith_retrn_type& operator-=(const smart_ptr& Src){return ARITHMETIC_SEMANTIC_POLICY::minus_equal_smart_ptr(*this, Src);}
01261 template<class T2> arith_retrn_type& operator-=(const T2& Src){return ARITHMETIC_SEMANTIC_POLICY::minus_equal(*this, Src);}
01262 friend arith_retrn_type operator+(const smart_ptr& a, const smart_ptr& b){return ARITHMETIC_SEMANTIC_POLICY::plus(a, b);}
01263 friend arith_retrn_type operator-(const smart_ptr& a, const smart_ptr& b){return ARITHMETIC_SEMANTIC_POLICY::minus(a, b);}
01264
01265
01266 typedef typename OWNERSHIP_POLICY::template return_type<T>::type_pointee ownership_retrn_type_pointee;
01267 typedef typename OWNERSHIP_POLICY::template return_type<T>::type_ref ownership_retrn_type_ref;
01268
01269
01270 inline ownership_retrn_type_pointee operator->()
01271 {
01272 m_ownership_policy.pointee_lock_policy(m_type);
01273 CHECKING_POLICY::on_dereference(m_type);
01274 return m_ownership_policy.get_non_constant_ptr(m_type, m_clone_fct);
01275 }
01276 inline ownership_retrn_type_ref operator*()
01277 {
01278 m_ownership_policy.pointee_lock_policy(m_type);
01279 CHECKING_POLICY::on_dereference(m_type);
01280 return *m_ownership_policy.get_non_constant_ptr(m_type, m_clone_fct);
01281 }
01282 inline ownership_retrn_type_pointee operator->()const {
01283 m_ownership_policy.const_pointee_lock_policy(m_type);
01284 CHECKING_POLICY::on_const_dereference(m_type);
01285 return m_type;
01286 }
01287 inline ownership_retrn_type_ref operator*() const {
01288 m_ownership_policy.const_pointee_lock_policy(m_type);
01289 CHECKING_POLICY::on_const_dereference(m_type);
01290 return *m_type;
01291 }
01292 #else
01293
01294 inline T* operator->()
01295 {
01296 m_ownership_policy.pointee_lock_policy(m_type);
01297 CHECKING_POLICY::on_dereference(m_type);
01298 return m_ownership_policy.get_non_constant_ptr(m_type, m_clone_fct);
01299 }
01300 inline T& operator*()
01301 {
01302 m_ownership_policy.pointee_lock_policy(m_type);
01303 CHECKING_POLICY::on_dereference(m_type);
01304 return *m_ownership_policy.get_non_constant_ptr(m_type, m_clone_fct);
01305 }
01306 inline const T* operator->()const {
01307 m_ownership_policy.const_pointee_lock_policy(m_type);
01308 CHECKING_POLICY::on_const_dereference(m_type);
01309 return m_type;
01310 }
01311 inline const T& operator*() const {
01312 m_ownership_policy.const_pointee_lock_policy(m_type);
01313 CHECKING_POLICY::on_const_dereference(m_type);
01314 return *m_type;
01315 }
01316 #endif //SMART_PTR_SUPPORT_RETURN_TYPE_THROUGH_POLICY_
01317
01318
01324 void lock() const {if (m_type) m_ownership_policy.lock(m_type);}
01328 void unlock() const {if (m_type) m_ownership_policy.unlock(m_type);}
01333 void trylock() const {if (m_type) m_ownership_policy.trylock(m_type);}
01339 void islock() const {if (m_type) m_ownership_policy.islock(m_type);}
01341
01342
01348 static void set_default_object(const smart_ptr& NewValue){get_or_set_default_object(&NewValue);}
01353 template<class T2> smart_ptr& equal(const T2& Src){
01354 (*get_ptr()) = (Src);
01355 return *this;
01356 }
01360 clone_fct_Type get_function_ptr()const{return m_clone_fct;}
01364 void swap(smart_ptr<T> & other)throw(){std::swap(m_ownership_policy, other.m_ownership_policy);std::swap(m_type, other.m_type);std::swap(m_clone_fct, other.m_clone_fct);}
01370 template<class PT, class FPT> void make_clone(PT*& ptr, FPT& func_ptr) const
01371 {
01372 if (m_type && m_clone_fct)
01373 {
01374 ptr = m_clone_fct(m_type, true, NULL, NULL, NULL);
01375 func_ptr = (FPT)m_clone_fct;
01376 }
01377 else
01378 ptr = NULL;
01379 }
01381
01382
01385 inline T* get_ptr(){return m_ownership_policy.get_non_constant_ptr(m_type, m_clone_fct);}
01386 inline const T* c_ptr()const{return m_type;}
01387 inline const T& c_ref()const{return *m_type;}
01389
01390
01391 typedef COMPARISON_SEMANTIC_POLICY comparison_semantic_policy_type;
01392 typedef T* pointer;
01393 typedef T& reference;
01394
01395 private:
01396 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
01397
01398
01399
01400
01401
01402
01403
01404 template < typename TT, typename DT, typename AL> static TT * constructor_and_destructor_allocator_function( TT * ptr, bool bConstruct, DT*, AL* , void*)
01405 {
01406 if (!ptr) return NULL;
01407 if (bConstruct){return AL::allocate(static_cast<const DT*>(ptr));}
01408 AL::deallocate(ptr);
01409 return NULL;
01410 }
01411 template<typename T_obj>
01412 inline static clone_fct_Type get_alloc_func(T_obj*)
01413 {
01414 T * ( *tmp ) (T *, bool, T_obj*, ALLOCATOR_POLICY*, void*) = constructor_and_destructor_allocator_function<T,T_obj,ALLOCATOR_POLICY>;
01415 return (clone_fct_Type)tmp;
01416 }
01417 #else
01418 template<typename T_obj>
01419 inline static clone_fct_Type get_alloc_func(T_obj*)
01420 {
01421 T * ( *tmp ) (T *, bool, T_obj*, ALLOCATOR_POLICY*, void*) = constructor_and_destructor_allocator_function<T,T_obj,ALLOCATOR_POLICY>;
01422 if (!tmp) constructor_and_destructor_allocator_function((T*)NULL, false, (T_obj*)NULL, (ALLOCATOR_POLICY*)NULL, NULL);
01423 return (clone_fct_Type)tmp;
01424 }
01425 #endif //_MSC_VER noteq 1200
01426
01427 static smart_ptr& get_or_set_default_object(const smart_ptr* NewValue = NULL)
01428 {
01429 static smart_ptr DefaultObj(eNo);
01430 if (NewValue && NewValue->m_type)
01431 DefaultObj = *NewValue;
01432 return DefaultObj;
01433 }
01434
01435 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
01436 template<class T1> friend bool operator==(const smart_ptr & a, const T1 & b){return T1::comparison_semantic_policy_type::is_equal(a,b);}
01437 template<class T1> friend bool operator!=(const smart_ptr & a, const T1 & b){return !T1::comparison_semantic_policy_type::is_equal(a,b);}
01438 template<class T1> friend bool operator> (const smart_ptr & a, const T1 & b){return T1::comparison_semantic_policy_type::greater_than(a,b);}
01439 template<class T1> friend bool operator< (const smart_ptr & a, const T1 & b){return T1::comparison_semantic_policy_type::less_than(a,b);}
01440 template<class T1> friend bool operator>=(const smart_ptr & a, const T1 & b){return T1::comparison_semantic_policy_type::greater_than_or_equal(a,b);}
01441 template<class T1> friend bool operator<=(const smart_ptr & a, const T1 & b){return T1::comparison_semantic_policy_type::less_than_or_equal(a,b);}
01442 #else //Can not support exchangeable comparison in VC++ 6.0
01443 friend inline bool operator==(const smart_ptr & a, const smart_ptr & b){return COMPARISON_SEMANTIC_POLICY::is_equal(a,b);}
01444 friend inline bool operator!=(const smart_ptr & a, const smart_ptr & b){return !COMPARISON_SEMANTIC_POLICY::is_equal(a,b);}
01445 friend inline bool operator< (const smart_ptr & a, const smart_ptr & b){return COMPARISON_SEMANTIC_POLICY::less_than(a,b);}
01446 friend inline bool operator> (const smart_ptr & a, const smart_ptr & b){return COMPARISON_SEMANTIC_POLICY::greater_than(a,b);}
01447 friend inline bool operator<=(const smart_ptr & a, const smart_ptr & b){return COMPARISON_SEMANTIC_POLICY::less_than_or_equal(a,b);}
01448 friend inline bool operator>=(const smart_ptr & a, const smart_ptr & b){return COMPARISON_SEMANTIC_POLICY::greater_than_or_equal(a,b);}
01449 #endif //not defined(_MSC_VER) || (_MSC_VER > 1200)
01450
01451 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
01452
01453 template<class T> friend bool operator!=(const smart_ptr<T> & a, const smart_ptr<T> & b){return !COMPARISON_SEMANTIC_POLICY::is_equal(a,b);}
01454 #endif
01455
01456 template<class T1> T1& input_stream(T1 &is){return STREAM_OP_SEMANTIC_POLICY::input_stream(is, *this);}
01457 template<class T1> T1& output_stream(T1 &io) const {return STREAM_OP_SEMANTIC_POLICY::output_stream(io, *this);}
01458
01459 template<class TS> inline friend TS& operator >>(TS &is,smart_ptr &obj){return obj.input_stream(is);}
01460 template<class TS> inline friend TS& operator <<(TS &io,const smart_ptr &obj){return obj.output_stream(io);}
01461
01462 };
01463
01464
01465
01466
01467
01468
01469
01470 template<
01471
01472 class OWNERSHIP_POLICY = ownership_default_policy ,
01473
01474 class ALLOCATOR_POLICY = allocator_default_policy,
01475
01476 class CHECKING_POLICY = checking_default_policy,
01477
01478 class COMPARISON_SEMANTIC_POLICY = comparison_default_policy,
01479
01480 class STREAM_OP_SEMANTIC_POLICY = stream_default_policy,
01481
01482 class ARITHMETIC_SEMANTIC_POLICY = arithmetic_default_policy>
01483 struct smart_ptr_type
01484 {
01485 template<class T> struct to{typedef smart_ptr<T, OWNERSHIP_POLICY, ALLOCATOR_POLICY, CHECKING_POLICY, COMPARISON_SEMANTIC_POLICY, STREAM_OP_SEMANTIC_POLICY, ARITHMETIC_SEMANTIC_POLICY> type;};
01486 template<class T> struct ptr_to : public smart_ptr<T, OWNERSHIP_POLICY, ALLOCATOR_POLICY, CHECKING_POLICY, COMPARISON_SEMANTIC_POLICY, STREAM_OP_SEMANTIC_POLICY, ARITHMETIC_SEMANTIC_POLICY>{};
01487 template<class T1> inline smart_ptr_type(T1 &t1): smart_ptr(t1){}
01488 };
01489
01490
01491 struct smart_ptr_policies
01492 {
01493 typedef smart_ptr_type<copy_on_write_policy<ref_link_policy, intrusive_lock_policy> > cow_sync_ptr;
01494 typedef smart_ptr_type<deep_copy_policy<intrusive_lock_policy> > copy_sync_ptr;
01495 typedef smart_ptr_type<shared_ptr_policy<ref_link_policy, intrusive_lock_policy> > shared_sync_ptr;
01496 typedef smart_ptr_type<copy_on_write_policy<ref_link_policy> > cow_ptr;
01497 typedef smart_ptr_type<deep_copy_policy<> > copy_ptr;
01498 typedef smart_ptr_type<shared_ptr_policy<ref_link_policy> > shared_ptr;
01499 };
01500
01501
01556 #endif //not smart_ptr_HPP_HEADER_GUARD_
01557