OA_ptr.hpp
Go to the documentation of this file.00001
00012 #ifndef OAPTR_H
00013 #define OAPTR_H
00014
00015 #include <iostream>
00016 #include <cassert>
00017 #include <set>
00018 #include "Util.hpp"
00019
00020 static bool OA_ptr_debug = false;
00021
00022 namespace OA {
00023
00024 template <class T>
00025 class OA_ptr {
00026 public:
00027 OA_ptr() : mPtr(NULL), mRefCountPtr(NULL) { }
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 public:
00039 OA_ptr(const OA_ptr<T> &other)
00040 : mPtr(other.mPtr), mRefCountPtr(other.mRefCountPtr)
00041 {
00042 if (OA_ptr_debug) { std::cout << "OA_ptr copy constructor: other = ";
00043 other.dump(std::cout); std::cout << std::endl; }
00044 if (mRefCountPtr!=NULL)
00045 { (*mRefCountPtr)++; }
00046 }
00047
00049 OA_ptr<T>& operator= (T* ptr)
00050 {
00051
00052 if (mPtr != ptr) {
00053 decrementCurrPtr();
00054 mPtr = ptr;
00055
00056
00057
00058 if (mPtr != NULL) {
00059 mRefCountPtr = new int;
00060 *mRefCountPtr = 1;
00061 } else {
00062 mRefCountPtr = NULL;
00063 }
00064 }
00065 return *this;
00066 }
00067
00069 OA_ptr<T>& operator= (const OA_ptr<T> &other)
00070 {
00071
00072 if (mPtr != other.mPtr) {
00073 decrementCurrPtr();
00074 mPtr = other.mPtr;
00075
00076
00077
00078 mRefCountPtr = other.mRefCountPtr;
00079 if (mPtr != NULL) {
00080 (*mRefCountPtr)++;
00081 }
00082 }
00083 return *this;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 virtual ~OA_ptr()
00102 {
00103 decrementCurrPtr();
00104 }
00105
00106 T* operator->() const
00107 {
00108 assert(mPtr != NULL);
00109 return mPtr;
00110 }
00111
00112 T& operator*() const
00113 {
00114 assert(mPtr != NULL);
00115 return *mPtr;
00116 }
00117
00118
00119
00120 OA_ptr(T* ptr, int* countPtr)
00121 : mPtr(ptr), mRefCountPtr(countPtr)
00122 {
00123 assert((ptr==0&&countPtr==0) || (ptr!=0&&countPtr!=0));
00124 if (OA_ptr_debug) { std::cout << "OA_ptr constructor ptr,cnt: ptr = ";
00125
00126 }
00127 if (mRefCountPtr!=NULL) { (*mRefCountPtr)++; }
00128 if (OA_ptr_debug) { std::cout << "OA_ptr constructor ptr,cnt: *this = ";
00129 dump(std::cout); std::cout << std::endl; }
00130 }
00131
00132
00133 template <class T2>
00134 OA_ptr<T2> convert() const
00135 {
00136 assert(mPtr != NULL);
00137 T2* retval = dynamic_cast<T2*>(mPtr);
00138 assert(retval != NULL);
00139 return OA_ptr<T2>(retval,mRefCountPtr);
00140 }
00141
00142
00143 template <class T2>
00144 bool isa() const
00145 {
00146 assert(mPtr != NULL);
00147 T2* retval = dynamic_cast<T2*>(mPtr);
00148 if (retval==NULL) {
00149 return false;
00150 } else {
00151 return true;
00152 }
00153 }
00154
00155
00156
00157
00158 template <class T2> operator OA_ptr<T2> () const
00159 { return OA_ptr<T2>(mPtr,mRefCountPtr); }
00160
00161 bool ptrEqual(const T* rhs) const
00162 {
00163 return mPtr == rhs;
00164 }
00165 bool ptrEqual(const OA_ptr& other) const
00166 {
00167 return mPtr == other.mPtr;
00168 }
00169
00170
00171 bool operator==(const OA_ptr<T>& other) const
00172 {
00173 bool retval;
00174
00175 if (OA_ptr_debug) {
00176 std::cout << "In OA_ptr::operator==" << std::endl;
00177 std::cout << "\t*this=";
00178 dump(std::cout);
00179 std::cout << ", other=";
00180 other.dump(std::cout);
00181 dump(std::cout);
00182 }
00183
00184 if (mPtr==other.mPtr) {
00185 retval = true;
00186 } else if (mPtr==0 || other.mPtr==0) {
00187 retval = false;
00188 } else {
00189 retval = *mPtr==*(other.mPtr);
00190 }
00191 if (OA_ptr_debug) {
00192 std::cout << "\nOA_ptr::operator== returning " << retval
00193 << std::endl;
00194 }
00195 return retval;
00196 }
00197
00198 template <class T2>
00199 bool operator==(const OA_ptr<T2>& other) const
00200 {
00201 bool retval;
00202
00203 if (OA_ptr_debug) {
00204 std::cout << "In OA_ptr::operator==(T2)" << std::endl;
00205 std::cout << "\t*this=";
00206 dump(std::cout);
00207 std::cout << ", other=";
00208 other.dump(std::cout);
00209 dump(std::cout);
00210 }
00211
00212 if (ptrEqual(0) && other.ptrEqual(0)) {
00213 retval = true;
00214 } else if (ptrEqual(0) || other.ptrEqual(0)) {
00215 retval = false;
00216 } else {
00217 retval = *mPtr==*other;
00218 }
00219 if (OA_ptr_debug) {
00220 std::cout << "\tOA_ptr::operator== returning " << retval
00221 << std::endl;
00222 }
00223 return retval;
00224 }
00225
00226
00227 bool operator!=(const OA_ptr<T>& other) const
00228 {
00229 return ! (*this==other);
00230 }
00231
00232 template <class T2>
00233 bool operator!=(const OA_ptr<T2>& other) const
00234 {
00235 return ! (*this==other);
00236 }
00237
00238
00244 bool operator<(const OA_ptr<T>& other) const
00245 {
00246 bool retval;
00247
00248 if (OA_ptr_debug) {
00249 std::cout << "In OA_ptr::operator<" << std::endl;
00250 std::cout << "\t*this=";
00251 dump(std::cout);
00252 std::cout << ", other=";
00253 other.dump(std::cout);
00254 std::cout << std::endl;
00255 }
00256
00257
00258 if ( mPtr==other.mPtr
00259 || other.mPtr == 0
00260 || *mPtr==*(other.mPtr) )
00261 {
00262 retval = false;
00263
00264
00265 } else if ( mPtr==0 ) {
00266 retval = true;
00267
00268
00269 } else if ( mPtr==0 ) {
00270 retval = false;
00271
00272
00273 } else {
00274 retval = *mPtr<*(other.mPtr);
00275 }
00276 if (OA_ptr_debug) {
00277 std::cout << "\tOA_ptr::operator< returning " << retval
00278 << std::endl;
00279 }
00280 return retval;
00281 }
00282
00283 template <class T2>
00284 bool operator<(const OA_ptr<T2>& other) const
00285 {
00286 bool retval;
00287 if (ptrEqual(0) && other.ptrEqual(0)) {
00288 retval = false;
00289
00290 } else if (ptrEqual(0) ) {
00291 retval = true;
00292
00293 } else if (other.ptrEqual(0) ) {
00294 retval = false;
00295
00296 } else { retval = *mPtr<*(other); }
00297 return retval;
00298 }
00299
00300
00301 void dump(std::ostream& os) const
00302 {
00303 os << "OA_ptr(mPtr = " << ", *mRefCountPtr=";
00304 os.flush();
00305 if (mRefCountPtr!=NULL) { os << *mRefCountPtr; }
00306 else { os << 0; }
00307 os << ")";
00308 }
00309
00310 inline friend std::ostream& operator <<(std::ostream & out,
00311 const OA_ptr<T>& oaptr)
00312 {
00313 oaptr.dump(out);
00314 return out;
00315 }
00316
00317 private:
00318 T* mPtr;
00319 int* mRefCountPtr;
00320
00321 private:
00323 void decrementCurrPtr()
00324 {
00325 if (mPtr!=NULL) {
00326
00327
00328
00329 if (mRefCountPtr!=NULL) {
00330 (*mRefCountPtr)--;
00331 if (*mRefCountPtr == 0) {
00332 delete mPtr;
00333 delete mRefCountPtr;
00334 }
00335 }
00336 }
00337
00338 mPtr = NULL;
00339 mRefCountPtr = NULL;
00340 }
00341
00342 };
00343
00344 }
00345
00346 #endif