UCommon
|
00001 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. 00002 // 00003 // This file is part of GNU uCommon C++. 00004 // 00005 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU Lesser General Public License as published 00007 // by the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // GNU uCommon C++ is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public License 00016 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 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 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 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<typename T> 00456 inline void dupfree(T object) 00457 {delete object;} 00458 00459 template<> 00460 inline char *dup<char>(const char& object) 00461 {return strdup(&object);} 00462 00463 template<> 00464 inline void dupfree<char*>(char* object) 00465 {::free(object);} 00466 00472 template<typename T> 00473 inline void swap(T& o1, T& o2) 00474 {cpr_memswap(&o1, &o2, sizeof(T));} 00475 00482 template<typename T> 00483 inline T& (max)(T& o1, T& o2) 00484 { 00485 return o1 > o2 ? o1 : o2; 00486 } 00487 00494 template<typename T> 00495 inline T& (min)(T& o1, T& o2) 00496 { 00497 return o1 < o2 ? o1 : o2; 00498 } 00499 00500 END_NAMESPACE 00501 00502 #endif