00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00024 #ifndef _UCOMMON_GENERICS_H_
00025 #define _UCOMMON_GENERICS_H_
00026
00027 #ifndef _UCOMMON_CPR_H_
00028 #include <ucommon/cpr.h>
00029 #endif
00030
00031 #include <stdlib.h>
00032 #include <string.h>
00033
00034 #ifdef NEW_STDLIB
00035 #include <stdexcept>
00036 #endif
00037
00038 #if defined(NEW_STDLIB) || defined(OLD_STDLIB)
00039 #define THROW(x) throw x
00040 #define THROWS(x) throw(x)
00041 #define THROWS_ANY throw()
00042 #else
00043 #define THROW(x) ::abort()
00044 #define THROWS(x)
00045 #define THROWS_ANY
00046 #endif
00047
00048 NAMESPACE_UCOMMON
00049
00055 template <typename T>
00056 class pointer
00057 {
00058 protected:
00059 unsigned *counter;
00060 T *object;
00061
00062 public:
00063 inline void release(void) {
00064 if(counter && --(*counter)==0) {
00065 delete counter;
00066 delete object;
00067 }
00068 object = NULL;
00069 counter = NULL;
00070 }
00071
00072 inline void retain(void) {
00073 if(counter)
00074 ++*counter;
00075 }
00076
00077 inline void set(T* ptr) {
00078 if(object != ptr) {
00079 release();
00080 counter = new unsigned;
00081 *counter = 1;
00082 object = ptr;
00083 }
00084 }
00085
00086 inline void set(const pointer<T> &ref) {
00087 if(object == ref.object)
00088 return;
00089
00090 if(counter && --(*counter)==0) {
00091 delete counter;
00092 delete object;
00093 }
00094 object = ref.object;
00095 counter = ref.counter;
00096 if(counter)
00097 ++(*counter);
00098 }
00099
00100 inline pointer() {
00101 counter = NULL;
00102 object = NULL;
00103 }
00104
00105 inline explicit pointer(T* ptr = NULL) : object(ptr) {
00106 if(object) {
00107 counter = new unsigned;
00108 *counter = 1;
00109 }
00110 else
00111 counter = NULL;
00112 }
00113
00114 inline pointer(const pointer<T> &ref) {
00115 object = ref.object;
00116 counter = ref.counter;
00117 if(counter)
00118 ++(*counter);
00119 }
00120
00121 inline pointer& operator=(const pointer<T> &ref) {
00122 this->set(ref);
00123 return *this;
00124 }
00125
00126 inline pointer& operator=(T *ptr) {
00127 this->set(ptr);
00128 return *this;
00129 }
00130
00131 inline ~pointer()
00132 {release();}
00133
00134 inline T& operator*() const
00135 {return *object;};
00136
00137 inline T* operator->() const
00138 {return object;};
00139
00140 inline bool operator!() const
00141 {return (counter == NULL);};
00142
00143 inline operator bool() const
00144 {return counter != NULL;};
00145 };
00146
00152 template <typename T>
00153 class array_pointer
00154 {
00155 protected:
00156 unsigned *counter;
00157 T *array;
00158
00159 public:
00160 inline void release(void) {
00161 if(counter && --(*counter)==0) {
00162 delete counter;
00163 delete[] array;
00164 }
00165 array = NULL;
00166 counter = NULL;
00167 }
00168
00169 inline void retain(void) {
00170 if(counter)
00171 ++*counter;
00172 }
00173
00174 inline void set(T* ptr) {
00175 if(array != ptr) {
00176 release();
00177 counter = new unsigned;
00178 *counter = 1;
00179 array = ptr;
00180 }
00181 }
00182
00183 inline void set(const array_pointer<T> &ref) {
00184 if(array == ref.array)
00185 return;
00186
00187 if(counter && --(*counter)==0) {
00188 delete counter;
00189 delete[] array;
00190 }
00191 array = ref.array;
00192 counter = ref.counter;
00193 if(counter)
00194 ++(*counter);
00195 }
00196
00197 inline array_pointer() {
00198 counter = NULL;
00199 array = NULL;
00200 }
00201
00202 inline explicit array_pointer(T* ptr = NULL) : array(ptr) {
00203 if(array) {
00204 counter = new unsigned;
00205 *counter = 1;
00206 }
00207 else
00208 counter = NULL;
00209 }
00210
00211 inline array_pointer(const array_pointer<T> &ref) {
00212 array = ref.array;
00213 counter = ref.counter;
00214 if(counter)
00215 ++(*counter);
00216 }
00217
00218 inline array_pointer& operator=(const array_pointer<T> &ref) {
00219 this->set(ref);
00220 return *this;
00221 }
00222
00223 inline array_pointer& operator=(T *ptr) {
00224 this->set(ptr);
00225 return *this;
00226 }
00227
00228 inline ~array_pointer()
00229 {release();}
00230
00231 inline T* operator*() const
00232 {return array;};
00233
00234 inline T& operator[](size_t offset) const
00235 {return array[offset];};
00236
00237 inline T* operator()(size_t offset) const
00238 {return &array[offset];};
00239
00240 inline bool operator!() const
00241 {return (counter == NULL);};
00242
00243 inline operator bool() const
00244 {return counter != NULL;};
00245 };
00246
00258 template <typename T>
00259 class temporary
00260 {
00261 protected:
00262 T *object;
00263 public:
00267 inline temporary()
00268 {object = NULL;};
00269
00273 temporary(const temporary<T>&)
00274 {::abort();};
00275
00279 inline temporary(T *ptr)
00280 {object = ptr;};
00281
00288 inline T& operator=(T *temp) {
00289 if(object)
00290 delete object;
00291 object = temp;
00292 return *this;
00293 }
00294
00301 inline void set(T *temp) {
00302 if(object)
00303 delete object;
00304 object = temp;
00305 }
00306
00311 inline T& operator*() const
00312 {return *object;};
00313
00318 inline T* operator->() const
00319 {return object;};
00320
00321 inline operator bool() const
00322 {return object != NULL;};
00323
00324 inline bool operator!() const
00325 {return object == NULL;};
00326
00327 inline ~temporary() {
00328 if(object)
00329 delete object;
00330 object = NULL;
00331 }
00332 };
00333
00345 template <typename T>
00346 class temp_array
00347 {
00348 protected:
00349 T *array;
00350 size_t size;
00351
00352 public:
00356 inline temp_array(size_t s)
00357 {array = new T[s]; size = s;};
00358
00363 inline temp_array(const T& initial, size_t s) {
00364 array = new T[s];
00365 size = s;
00366 for(size_t p = 0; p < s; ++p)
00367 array[p] = initial;
00368 }
00369
00370 inline void reset(size_t s)
00371 {delete[] array; array = new T[s]; size = s;};
00372
00373 inline void reset(const T& initial, size_t s) {
00374 if(array)
00375 delete[] array;
00376 array = new T[s];
00377 size = s;
00378 for(size_t p = 0; p < s; ++p)
00379 array[p] = initial;
00380 }
00381
00382 inline void set(const T& initial) {
00383 for(size_t p = 0; p < size; ++p)
00384 array[p] = initial;
00385 }
00386
00390 temp_array(const temp_array<T>&)
00391 {::abort();};
00392
00393 inline operator bool() const
00394 {return array != NULL;};
00395
00396 inline bool operator!() const
00397 {return array == NULL;};
00398
00399 inline ~temp_array() {
00400 if(array)
00401 delete[] array;
00402 array = NULL;
00403 size = 0;
00404 }
00405
00406 inline T& operator[](size_t offset) const {
00407 crit(offset < size, "array out of bound");
00408 return array[offset];
00409 }
00410
00411 inline T* operator()(size_t offset) const {
00412 crit(offset < size, "array out of bound");
00413 return &array[offset];
00414 }
00415 };
00416
00421 template<typename T>
00422 class save_restore
00423 {
00424 private:
00425 T *original;
00426 T temp;
00427
00428 public:
00433 inline save_restore(T& object)
00434 {original = &object; temp = object;};
00435
00439 inline ~save_restore()
00440 {*original = temp;};
00441 };
00442
00448 template<class T>
00449 inline bool is(T& object)
00450 {return object.operator bool();}
00451
00458 template<typename T>
00459 inline bool isnull(T& object)
00460 {return (bool)(object.operator*() == NULL);}
00461
00468 template<typename T>
00469 inline bool isnullp(T *object)
00470 {return (bool)(object->operator*() == NULL);}
00471
00477 template<typename T>
00478 inline T* dup(const T& object)
00479 {return new T(object);}
00480
00481 template<typename T>
00482 inline void dupfree(T object)
00483 {delete object;}
00484
00485 template<>
00486 inline char *dup<char>(const char& object)
00487 {return strdup(&object);}
00488
00489 template<>
00490 inline void dupfree<char*>(char* object)
00491 {::free(object);}
00492
00497 template<typename T>
00498 inline void reset_unsafe(T& object)
00499 {new((caddr_t)&object) T;}
00500
00505 template<typename T>
00506 inline void zero_unsafe(T& object)
00507 {memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;}
00508
00514 template<typename T>
00515 inline void copy_unsafe(T* target, const T* source)
00516 {memcpy((void *)target, (void *)source, sizeof(T));}
00517
00523 template<typename T>
00524 inline void store_unsafe(T& target, const T* source)
00525 {memcpy((void *)&target, (void *)source, sizeof(T));}
00526
00532 template<typename T>
00533 inline void swap(T& o1, T& o2)
00534 {cpr_memswap(&o1, &o2, sizeof(T));}
00535
00542 template<typename T>
00543 inline T& (max)(T& o1, T& o2)
00544 {
00545 return o1 > o2 ? o1 : o2;
00546 }
00547
00554 template<typename T>
00555 inline T& (min)(T& o1, T& o2)
00556 {
00557 return o1 < o2 ? o1 : o2;
00558 }
00559
00567 template<typename T>
00568 inline T& (limit)(T& value, T& low, T& high)
00569 {
00570 return (value < low) ? low : ((value > high) ? high : value);
00571 }
00572
00573 END_NAMESPACE
00574
00575 #endif