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_CONFIG_H_
00028 #include <ucommon/platform.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 set(ref);
00123 return *this;
00124 }
00125
00126 inline pointer& operator=(T *ptr) {
00127 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 set(ref);
00220 return *this;
00221 }
00222
00223 inline array_pointer& operator=(T *ptr) {
00224 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
00422 template<class T>
00423 inline bool is(T& object)
00424 {return object.operator bool();}
00425
00432 template<typename T>
00433 inline bool isnull(T& object)
00434 {return (bool)(object.operator*() == NULL);}
00435
00442 template<typename T>
00443 inline bool isnullp(T *object)
00444 {return (bool)(object->operator*() == NULL);}
00445
00451 template<typename T>
00452 inline T* dup(const T& object)
00453 {return new T(object);}
00454
00455 template<>
00456 inline char *dup<char>(const char& object)
00457 {return strdup(&object);}
00458
00464 template<typename T>
00465 inline void swap(T& o1, T& o2)
00466 {cpr_memswap(&o1, &o2, sizeof(T));}
00467
00474 template<typename T>
00475 inline T& (max)(T& o1, T& o2)
00476 {
00477 return o1 > o2 ? o1 : o2;
00478 }
00479
00486 template<typename T>
00487 inline T& (min)(T& o1, T& o2)
00488 {
00489 return o1 < o2 ? o1 : o2;
00490 }
00491
00492 END_NAMESPACE
00493
00494 #endif