00001 #ifndef copy_ptr_H_HEADER_GUARD_
00002 #define copy_ptr_H_HEADER_GUARD_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 template < typename T, typename DT> T * copy_ptr_ConstructAndDestruct_default_allocator_(const T*, bool, DT* , void*);
00042 template < typename T, typename D, class AX_TYPE> T * copy_ptr_ConstructAndDestruct_(const T* , bool, D* , AX_TYPE*);
00043
00049 template<typename T>
00050 class copy_ptr
00051 {
00052 typedef T * ( *clone_fct_Type ) (const T *, bool, void*, void*);
00053 T* m_type;
00054 clone_fct_Type m_clone_fct;
00055 public:
00056 template<typename T_obj>
00057 static clone_fct_Type get_alloc_func(T_obj*)
00058 {
00059 T * ( *tmp ) (const T *, bool, T_obj*, void*) = copy_ptr_ConstructAndDestruct_default_allocator_<T,T_obj>;
00060 return (clone_fct_Type)tmp;
00061 }
00062
00063 template<typename T_obj>
00064 copy_ptr(T_obj* type):m_type(type), m_clone_fct(get_alloc_func(type))
00065 {
00066 #ifdef BOOST_ASSERT
00067 BOOST_ASSERT(type != NULL);
00068 BOOST_ASSERT(typeid(*type) == typeid(T_obj));
00069 #endif //BOOST_ASSERT
00070 }
00071 template<typename T_obj, class AX_TYPE>
00072 copy_ptr(T_obj* type, AX_TYPE&):m_type(type), m_clone_fct(NULL)
00073 {
00074 #ifdef BOOST_ASSERT
00075 BOOST_ASSERT(type != NULL);
00076 BOOST_ASSERT(typeid(*type) == typeid(T_obj));
00077 #endif //BOOST_ASSERT
00078 T * ( *tmp ) ( const T *, bool, T_obj*, AX_TYPE*) = copy_ptr_ConstructAndDestruct_<T,T_obj, AX_TYPE>;
00079 m_clone_fct = (clone_fct_Type)tmp;
00080 }
00081
00082 ~copy_ptr()throw(){if (m_type) m_type=m_clone_fct(m_type, false, NULL, NULL);}
00083
00084 copy_ptr(const copy_ptr& Src):m_type((Src.m_type)?Src.m_clone_fct(Src.m_type, true, NULL, NULL):NULL), m_clone_fct(Src.m_clone_fct){}
00085 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
00086
00087 template<class CompatibleDerivedT> copy_ptr(const copy_ptr<CompatibleDerivedT>& Src):m_type(NULL), m_clone_fct(NULL){assign(Src);}
00088
00089 template<class CompatibleSmartPtr> copy_ptr(const CompatibleSmartPtr& Src):m_type(NULL), m_clone_fct(NULL){Src.make_clone(m_type, m_clone_fct);}
00090 #else
00091 #ifdef cow_ptr_H_HEADER_GUARD_
00092 copy_ptr(const cow_ptr<T>& Src):m_type(NULL), m_clone_fct(NULL){Src.make_clone(m_type, m_clone_fct);}
00093 #endif //cow_ptr_H_HEADER_GUARD_
00094 #endif //_MSC_VER != 1200
00095
00096 copy_ptr& operator=(const copy_ptr& Src){return assign(Src);}
00097 enum implement_default_object{eYes, eNo};
00098
00099 copy_ptr(implement_default_object use_default_obj = eYes):m_type(NULL), m_clone_fct(NULL)
00100 {
00101 if (use_default_obj == eYes)
00102 {
00103 copy_ptr<T> &defaultObj = GetSetDefaultObject();
00104 if (defaultObj.m_type)
00105 {
00106 m_type = defaultObj.m_clone_fct(defaultObj.m_type, true, NULL, NULL);
00107 m_clone_fct = defaultObj.m_clone_fct;
00108 }
00109 }
00110 }
00111
00112
00113 static void SetDefaultObject(const copy_ptr<T>& NewValue){GetSetDefaultObject(&NewValue);}
00114 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
00115
00116 template<class CompatibleDerivedT> copy_ptr& operator=(const copy_ptr<CompatibleDerivedT>& Src){return assign(Src);}
00117 #endif //_MSC_VER != 1200
00118 typedef T* pointer;
00119 typedef T& reference;
00120 bool operator! () const{
00121 return m_type == 0;
00122 }
00123 template<typename T2>
00124 copy_ptr& equal(const T2& Src){
00125 (*m_type) = (Src);
00126 return *this;
00127 }
00128 inline T* operator->() const{return m_type;}
00129 inline T& operator*() const{return *m_type;}
00130
00131 copy_ptr& operator+=(const copy_ptr& Src){
00132 m_type->operator+=(*Src.m_type);
00133 return *this;
00134 }
00135 template<typename T2>
00136 copy_ptr& operator+=(const T2& Src){
00137 m_type->operator+=(Src);
00138 return *this;
00139 }
00140 copy_ptr& operator+(const copy_ptr& Src){
00141 m_type->operator+(*Src.m_type);
00142 return *this;
00143 }
00144 copy_ptr& operator-=(const copy_ptr& Src){
00145 m_type->operator-=(*Src.m_type);
00146 return *this;
00147 }
00148 copy_ptr& operator-(const copy_ptr& Src){
00149 m_type->operator-(*Src.m_type);
00150 return *this;
00151 }
00152 const T* c_ptr()const{return m_type;}
00153 const T& c_ref()const{return *m_type;}
00154 T* get_ptr(){return m_type;}
00155
00156 void swap(copy_ptr<T> & other)throw(){std::swap(m_type, other.m_type);std::swap(m_clone_fct, other.m_clone_fct);}
00157
00158
00159 clone_fct_Type get_function_ptr()const{return m_clone_fct;}
00160 private:
00161 template<class CompatibleSmartPtr>
00162 copy_ptr& assign(CompatibleSmartPtr& Src)
00163 {
00164 if (m_type != (T*)Src.c_ptr())
00165 {
00166 if (m_type) m_clone_fct(m_type, false, NULL, NULL);
00167 if (Src.c_ptr())
00168 m_type = Src.get_function_ptr()(Src.c_ptr(), true, NULL, NULL);
00169 else m_type = NULL;
00170 m_clone_fct = (clone_fct_Type)Src.get_function_ptr();
00171 }
00172 return *this;
00173 }
00174
00175 static copy_ptr<T>& GetSetDefaultObject(const copy_ptr<T>* NewValue = NULL)
00176 {
00177 static copy_ptr<T> DefaultObj(eNo);
00178 if (NewValue && NewValue->m_type)
00179 DefaultObj = *NewValue;
00180 return DefaultObj;
00181 }
00182 };
00183
00184 template<class T, class U> inline bool operator<(copy_ptr<T> const & a, copy_ptr<U> const & b){return (*a.c_ptr()) < (*b.c_ptr());}
00185 template<class T, class U> inline bool operator>(copy_ptr<T> const & a, copy_ptr<U> const & b){return (*a.c_ptr()) > (*b.c_ptr());}
00186 template<class T, class U> inline bool operator<=(copy_ptr<T> const & a, copy_ptr<U> const & b){return (*a.c_ptr()) <= (*b.c_ptr());}
00187 template<class T, class U> inline bool operator>=(copy_ptr<T> const & a, copy_ptr<U> const & b){return (*a.c_ptr()) >= (*b.c_ptr());}
00188 template<class T, class U> inline bool operator==(copy_ptr<T> const & a, copy_ptr<U> const & b){return (*a.c_ptr()) == (*b.c_ptr());}
00189 template<class T, class U> inline bool operator!=(copy_ptr<T> const & a, copy_ptr<U> const & b){return (*a.c_ptr()) != (*b.c_ptr());}
00190
00191 #if __GNUC__ == 2 && __GNUC_MINOR__ <= 96
00192
00193 template<class T> inline bool operator!=(copy_ptr<T> const & a, copy_ptr<T> const & b){return (*a.c_ptr()) != (*b.c_ptr());}
00194 #endif
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 template < typename T, typename DT> T * copy_ptr_ConstructAndDestruct_default_allocator_(const T * ptr, bool bConstruct, DT* , void*) {
00206 if (bConstruct)
00207 {
00208 DT* d = new DT(*static_cast<const DT*>(ptr));
00209 #ifdef BOOST_ASSERT
00210 BOOST_ASSERT(typeid(*static_cast<const DT*>(ptr)) == typeid(*d));
00211 #endif //BOOST_ASSERT
00212 return d;
00213 }
00214 #if !defined(_MSC_VER) || (_MSC_VER > 1200)
00215 delete ptr;
00216 #else
00217 delete const_cast<T*>(ptr);
00218 #endif
00219 return NULL;
00220 }
00221
00222 template < typename T, typename D, class AX_TYPE> T * copy_ptr_ConstructAndDestruct_(const T * ptr, bool bConstruct, D* , AX_TYPE*) {
00223 D * Obj = static_cast<D*>( ptr );
00224 if (bConstruct)
00225 {
00226 AX_TYPE alloc;
00227 D* tmp_ptr = alloc.allocate(1, NULL);
00228 alloc.construct(tmp_ptr, *(Obj));
00229 #ifdef BOOST_ASSERT
00230 BOOST_ASSERT(typeid(*tmp_ptr) == typeid(*Obj));
00231 #endif //BOOST_ASSERT
00232 return tmp_ptr;
00233 }
00234 AX_TYPE alloc;
00235 alloc.destroy(Obj);
00236 alloc.deallocate(Obj, 1);
00237 return NULL;
00238 }
00239
00240
00241 #endif
00242