00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef _SWORD_BASE_SMARTPTR_
00020 #define _SWORD_BASE_SMARTPTR_
00021
00022 namespace sword {
00023
00025
00080 template<class MX>
00081 struct SWORDDECL SmartPtrData {
00082 SmartPtrData() : mutex_(), counter_(1) {}
00083 MX mutex_;
00084 int counter_;
00085 };
00086
00087 template<class X, class MX>
00088 struct SmartPtrDataAllocator_Dynamic {
00089 typedef SmartPtrData<MX> DataType;
00090 typedef MX MutexType;
00091
00092 static inline DataType* allocate(X* ) { return new DataType(); }
00093 static inline void deallocate(DataType* ptr) { delete ptr; }
00094 };
00095
00096 template<class X, class MX>
00097 struct SmartPtrDataAllocator_Embedded {
00098 typedef SmartPtrData<MX> DataType;
00099 typedef MX MutexType;
00100
00101 static inline DataType* allocate(X* ptr) { return ptr->smartPtrData(); }
00102 static inline void deallocate(DataType* ptr) {}
00103 };
00104
00105 template<class X, class AX=SmartPtrDataAllocator_Dynamic<X, ACE_Thread_Mutex> >
00106 class SWORDDECL SmartPtr {
00107 typedef typename AX::MutexType MX;
00108 typedef SmartPtrData<typename AX::MutexType> DataType;
00109 class Tester {
00110 void operator delete(void*);
00111 public:
00112 Tester() {}
00113 };
00114
00115 public:
00116
00117
00118 SmartPtr() throw();
00119 SmartPtr(const SmartPtr &sp);
00120 SmartPtr(int value) throw();
00121 ~SmartPtr();
00122
00123 explicit SmartPtr(X *p);
00124
00125
00126
00127 template<class Y, class AY>
00128 inline SmartPtr &operator=(const SmartPtr<Y,AY> &sp)
00129 {
00130 if ((void*)ptr_ != (void*)sp.getPtr())
00131 {
00132 detach_();
00133 attach_(sp.getControl(), dynamic_cast<X*>(sp.getPtr()));
00134 }
00135 return *this;
00136 }
00137
00138 inline SmartPtr &operator=(const SmartPtr &sp)
00139 {
00140 if (ptr_ != sp.ptr_)
00141 {
00142 detach_();
00143 attach_(sp.control_, sp.ptr_);
00144 }
00145 return *this;
00146 }
00147
00148
00149
00150 template<class Y, class AY>
00151 inline bool operator==(const SmartPtr<Y,AY> &sp) const throw()
00152 {
00153 return (void*)getPtr() == (void*)sp.getPtr();
00154 }
00155 template<class Y, class AY>
00156 inline bool operator!=(const SmartPtr<Y,AY> &sp) const throw()
00157 {
00158 return (void*)getPtr() != (void*)sp.getPtr();
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 operator Tester*() const throw();
00170
00171 template<class Y, class AY>
00172 inline bool operator<(const SmartPtr<Y,AY> &rhs) const throw()
00173 {
00174 return (void*)lhs.getPtr() < (void*)rhs.getPtr();
00175 }
00176
00177
00178
00179 SmartPtr &operator=(X *p);
00180 SmartPtr &operator=(int value);
00181
00182
00183
00184 X *getPtr() const throw();
00185 SmartPtrData<MX>* getControl() const throw();
00186
00187 X &operator*() const throw();
00188 X *operator->() const throw();
00189
00190 private:
00191 mutable SmartPtrData<MX> *control_;
00192 X *ptr_;
00193
00194 void init_(X *p);
00195 void detach_();
00196 void attach_(SmartPtrData<MX>* sp_control, X *sp_ptr);
00197 };
00198
00199 }
00200
00201 #include "sword.private/base.SmartPtr.inl"
00202
00203 #endif // _SWORD_BASE_SMARTPTR_