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 00033 #ifdef NEW_STDLIB 00034 #include <stdexcept> 00035 #endif 00036 00037 #if defined(NEW_STDLIB) || defined(OLD_STDLIB) 00038 #define THROW(x) throw x 00039 #define THROWS(x) throw(x) 00040 #define THROWS_ANY throw() 00041 #else 00042 #define THROW(x) ::abort() 00043 #define THROWS(x) 00044 #define THROWS_ANY 00045 #endif 00046 00047 NAMESPACE_UCOMMON 00048 00054 template <typename T> 00055 class pointer 00056 { 00057 protected: 00058 unsigned *counter; 00059 T *object; 00060 00061 public: 00062 inline void release(void) { 00063 if(counter && --(*counter)==0) { 00064 delete counter; 00065 delete object; 00066 } 00067 object = NULL; 00068 counter = NULL; 00069 } 00070 00071 inline void retain(void) { 00072 if(counter) 00073 ++*counter; 00074 } 00075 00076 inline void set(T* ptr) { 00077 if(object != ptr) { 00078 release(); 00079 counter = new unsigned; 00080 *counter = 1; 00081 object = ptr; 00082 } 00083 } 00084 00085 inline void set(const pointer<T> &ref) { 00086 if(object == ref.object) 00087 return; 00088 00089 if(counter && --(*counter)==0) { 00090 delete counter; 00091 delete object; 00092 } 00093 object = ref.object; 00094 counter = ref.counter; 00095 if(counter) 00096 ++(*counter); 00097 } 00098 00099 inline pointer() { 00100 counter = NULL; 00101 object = NULL; 00102 } 00103 00104 inline explicit pointer(T* ptr = NULL) : object(ptr) { 00105 if(object) { 00106 counter = new unsigned; 00107 *counter = 1; 00108 } 00109 else 00110 counter = NULL; 00111 } 00112 00113 inline pointer(const pointer<T> &ref) { 00114 object = ref.object; 00115 counter = ref.counter; 00116 if(counter) 00117 ++(*counter); 00118 } 00119 00120 inline pointer& operator=(const pointer<T> &ref) { 00121 set(ref); 00122 return *this; 00123 } 00124 00125 inline pointer& operator=(T *ptr) { 00126 set(ptr); 00127 return *this; 00128 } 00129 00130 inline ~pointer() 00131 {release();} 00132 00133 inline T& operator*() const 00134 {return *object;}; 00135 00136 inline T* operator->() const 00137 {return object;}; 00138 00139 inline bool operator!() const 00140 {return (counter == NULL);}; 00141 00142 inline operator bool() const 00143 {return counter != NULL;}; 00144 }; 00145 00151 template <typename T> 00152 class array_pointer 00153 { 00154 protected: 00155 unsigned *counter; 00156 T *array; 00157 00158 public: 00159 inline void release(void) { 00160 if(counter && --(*counter)==0) { 00161 delete counter; 00162 delete[] array; 00163 } 00164 array = NULL; 00165 counter = NULL; 00166 } 00167 00168 inline void retain(void) { 00169 if(counter) 00170 ++*counter; 00171 } 00172 00173 inline void set(T* ptr) { 00174 if(array != ptr) { 00175 release(); 00176 counter = new unsigned; 00177 *counter = 1; 00178 array = ptr; 00179 } 00180 } 00181 00182 inline void set(const array_pointer<T> &ref) { 00183 if(array == ref.array) 00184 return; 00185 00186 if(counter && --(*counter)==0) { 00187 delete counter; 00188 delete[] array; 00189 } 00190 array = ref.array; 00191 counter = ref.counter; 00192 if(counter) 00193 ++(*counter); 00194 } 00195 00196 inline array_pointer() { 00197 counter = NULL; 00198 array = NULL; 00199 } 00200 00201 inline explicit array_pointer(T* ptr = NULL) : array(ptr) { 00202 if(array) { 00203 counter = new unsigned; 00204 *counter = 1; 00205 } 00206 else 00207 counter = NULL; 00208 } 00209 00210 inline array_pointer(const array_pointer<T> &ref) { 00211 array = ref.array; 00212 counter = ref.counter; 00213 if(counter) 00214 ++(*counter); 00215 } 00216 00217 inline array_pointer& operator=(const array_pointer<T> &ref) { 00218 set(ref); 00219 return *this; 00220 } 00221 00222 inline array_pointer& operator=(T *ptr) { 00223 set(ptr); 00224 return *this; 00225 } 00226 00227 inline ~array_pointer() 00228 {release();} 00229 00230 inline T* operator*() const 00231 {return array;}; 00232 00233 inline T& operator[](size_t offset) const 00234 {return array[offset];}; 00235 00236 inline T* operator()(size_t offset) const 00237 {return &array[offset];}; 00238 00239 inline bool operator!() const 00240 {return (counter == NULL);}; 00241 00242 inline operator bool() const 00243 {return counter != NULL;}; 00244 }; 00245 00257 template <typename T> 00258 class temporary 00259 { 00260 protected: 00261 T *object; 00262 public: 00266 inline temporary() 00267 {object = NULL;}; 00268 00272 temporary(const temporary<T>&) 00273 {::abort();}; 00274 00278 inline temporary(T *ptr) 00279 {object = ptr;}; 00280 00287 inline T& operator=(T *temp) { 00288 if(object) 00289 delete object; 00290 object = temp; 00291 return *this; 00292 } 00293 00300 inline void set(T *temp) { 00301 if(object) 00302 delete object; 00303 object = temp; 00304 } 00305 00310 inline T& operator*() const 00311 {return *object;}; 00312 00317 inline T* operator->() const 00318 {return object;}; 00319 00320 inline operator bool() const 00321 {return object != NULL;}; 00322 00323 inline bool operator!() const 00324 {return object == NULL;}; 00325 00326 inline ~temporary() { 00327 if(object) 00328 delete object; 00329 object = NULL; 00330 } 00331 }; 00332 00344 template <typename T> 00345 class temp_array 00346 { 00347 protected: 00348 T *array; 00349 size_t size; 00350 00351 public: 00355 inline temp_array(size_t s) 00356 {array = new T[s]; size = s;}; 00357 00362 inline temp_array(const T& initial, size_t s) { 00363 array = new T[s]; 00364 size = s; 00365 for(size_t p = 0; p < s; ++p) 00366 array[p] = initial; 00367 } 00368 00369 inline void reset(size_t s) 00370 {delete[] array; array = new T[s]; size = s;}; 00371 00372 inline void reset(const T& initial, size_t s) { 00373 if(array) 00374 delete[] array; 00375 array = new T[s]; 00376 size = s; 00377 for(size_t p = 0; p < s; ++p) 00378 array[p] = initial; 00379 } 00380 00381 inline void set(const T& initial) { 00382 for(size_t p = 0; p < size; ++p) 00383 array[p] = initial; 00384 } 00385 00389 temp_array(const temp_array<T>&) 00390 {::abort();}; 00391 00392 inline operator bool() const 00393 {return array != NULL;}; 00394 00395 inline bool operator!() const 00396 {return array == NULL;}; 00397 00398 inline ~temp_array() { 00399 if(array) 00400 delete[] array; 00401 array = NULL; 00402 size = 0; 00403 } 00404 00405 inline T& operator[](size_t offset) const { 00406 crit(offset < size, "array out of bound"); 00407 return array[offset]; 00408 } 00409 00410 inline T* operator()(size_t offset) const { 00411 crit(offset < size, "array out of bound"); 00412 return &array[offset]; 00413 } 00414 }; 00415 00421 template<class T> 00422 inline bool is(T& object) 00423 {return object.operator bool();} 00424 00431 template<class T> 00432 inline bool isnull(T& object) 00433 {return (bool)(object.operator*() == NULL);} 00434 00441 template<class T> 00442 inline bool isnullp(T *object) 00443 {return (bool)(object->operator*() == NULL);} 00444 00450 template<typename T> 00451 inline void swap(T& o1, T& o2) 00452 {cpr_memswap(&o1, &o2, sizeof(T));} 00453 00460 template<typename T> 00461 inline T& (max)(T& o1, T& o2) 00462 { 00463 return o1 > o2 ? o1 : o2; 00464 } 00465 00472 template<typename T> 00473 inline T& (min)(T& o1, T& o2) 00474 { 00475 return o1 < o2 ? o1 : o2; 00476 } 00477 00478 END_NAMESPACE 00479 00480 #endif