UCommon
|
00001 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks. 00002 // Copyright (C) 2015 Cherokees of Idaho. 00003 // 00004 // This file is part of GNU uCommon C++. 00005 // 00006 // GNU uCommon C++ is free software: you can redistribute it and/or modify 00007 // it under the terms of the GNU Lesser General Public License as published 00008 // by the Free Software Foundation, either version 3 of the License, or 00009 // (at your option) any later version. 00010 // 00011 // GNU uCommon C++ is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU Lesser General Public License for more details. 00015 // 00016 // You should have received a copy of the GNU Lesser General Public License 00017 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>. 00018 00025 #ifndef _UCOMMON_GENERICS_H_ 00026 #define _UCOMMON_GENERICS_H_ 00027 00028 #ifndef _UCOMMON_CPR_H_ 00029 #include <ucommon/cpr.h> 00030 #endif 00031 00032 #include <cstdlib> 00033 #include <cstring> 00034 #include <stdexcept> 00035 00036 #ifndef UCOMMON_SYSRUNTIME 00037 #define THROW(x) throw x 00038 #define THROWS(x) throw(x) 00039 #define THROWS_ANY throw() 00040 #else 00041 #define THROW(x) ::abort() 00042 #define THROWS(x) 00043 #define THROWS_ANY 00044 #endif 00045 00046 namespace ucommon { 00047 00053 template <typename T> 00054 class pointer 00055 { 00056 protected: 00057 unsigned *counter; 00058 T *object; 00059 00060 public: 00061 inline void release(void) { 00062 if(counter && --(*counter)==0) { 00063 delete counter; 00064 delete object; 00065 } 00066 object = NULL; 00067 counter = NULL; 00068 } 00069 00070 inline void retain(void) { 00071 if(counter) 00072 ++*counter; 00073 } 00074 00075 inline void set(T* ptr) { 00076 if(object != ptr) { 00077 release(); 00078 counter = new unsigned; 00079 *counter = 1; 00080 object = ptr; 00081 } 00082 } 00083 00084 inline void set(const pointer<T> &ref) { 00085 if(object == ref.object) 00086 return; 00087 00088 if(counter && --(*counter)==0) { 00089 delete counter; 00090 delete object; 00091 } 00092 object = ref.object; 00093 counter = ref.counter; 00094 if(counter) 00095 ++(*counter); 00096 } 00097 00098 inline pointer() { 00099 counter = NULL; 00100 object = NULL; 00101 } 00102 00103 inline explicit pointer(T* ptr = NULL) : object(ptr) { 00104 if(object) { 00105 counter = new unsigned; 00106 *counter = 1; 00107 } 00108 else 00109 counter = NULL; 00110 } 00111 00112 inline pointer(const pointer<T> &ref) { 00113 object = ref.object; 00114 counter = ref.counter; 00115 if(counter) 00116 ++(*counter); 00117 } 00118 00119 inline pointer& operator=(const pointer<T> &ref) { 00120 this->set(ref); 00121 return *this; 00122 } 00123 00124 inline pointer& operator=(T *ptr) { 00125 this->set(ptr); 00126 return *this; 00127 } 00128 00129 inline ~pointer() { 00130 release(); 00131 } 00132 00133 inline T& operator*() const { 00134 return *object; 00135 } 00136 00137 inline T* operator->() const { 00138 return object; 00139 } 00140 00141 inline bool operator!() const { 00142 return (counter == NULL); 00143 } 00144 00145 inline operator bool() const { 00146 return counter != NULL; 00147 } 00148 }; 00149 00155 template <typename T> 00156 class array_pointer 00157 { 00158 protected: 00159 unsigned *counter; 00160 T *array; 00161 00162 public: 00163 inline void release(void) { 00164 if(counter && --(*counter)==0) { 00165 delete counter; 00166 delete[] array; 00167 } 00168 array = NULL; 00169 counter = NULL; 00170 } 00171 00172 inline void retain(void) { 00173 if(counter) 00174 ++*counter; 00175 } 00176 00177 inline void set(T* ptr) { 00178 if(array != ptr) { 00179 release(); 00180 counter = new unsigned; 00181 *counter = 1; 00182 array = ptr; 00183 } 00184 } 00185 00186 inline void set(const array_pointer<T> &ref) { 00187 if(array == ref.array) 00188 return; 00189 00190 if(counter && --(*counter)==0) { 00191 delete counter; 00192 delete[] array; 00193 } 00194 array = ref.array; 00195 counter = ref.counter; 00196 if(counter) 00197 ++(*counter); 00198 } 00199 00200 inline array_pointer() { 00201 counter = NULL; 00202 array = NULL; 00203 } 00204 00205 inline explicit array_pointer(T* ptr = NULL) : array(ptr) { 00206 if(array) { 00207 counter = new unsigned; 00208 *counter = 1; 00209 } 00210 else 00211 counter = NULL; 00212 } 00213 00214 inline array_pointer(const array_pointer<T> &ref) { 00215 array = ref.array; 00216 counter = ref.counter; 00217 if(counter) 00218 ++(*counter); 00219 } 00220 00221 inline array_pointer& operator=(const array_pointer<T> &ref) { 00222 this->set(ref); 00223 return *this; 00224 } 00225 00226 inline array_pointer& operator=(T *ptr) { 00227 this->set(ptr); 00228 return *this; 00229 } 00230 00231 inline ~array_pointer() { 00232 release(); 00233 } 00234 00235 inline T* operator*() const { 00236 return array; 00237 } 00238 00239 inline T& operator[](size_t offset) const { 00240 return array[offset]; 00241 } 00242 00243 inline T* operator()(size_t offset) const { 00244 return &array[offset]; 00245 } 00246 00247 inline bool operator!() const { 00248 return (counter == NULL); 00249 } 00250 00251 inline operator bool() const { 00252 return counter != NULL; 00253 } 00254 }; 00255 00267 template <typename T> 00268 class temporary 00269 { 00270 protected: 00271 T *object; 00272 public: 00276 inline temporary() { 00277 object = NULL; 00278 } 00279 00283 temporary(const temporary<T>&) { 00284 ::abort(); 00285 } 00286 00290 inline temporary(T *ptr) { 00291 object = ptr; 00292 } 00293 00300 inline T& operator=(T *temp) { 00301 if(object) 00302 delete object; 00303 object = temp; 00304 return *this; 00305 } 00306 00313 inline void set(T *temp) { 00314 if(object) 00315 delete object; 00316 object = temp; 00317 } 00318 00323 inline T& operator*() const { 00324 return *object; 00325 } 00326 00331 inline T* operator->() const { 00332 return object; 00333 } 00334 00335 inline operator bool() const { 00336 return object != NULL; 00337 } 00338 00339 inline bool operator!() const { 00340 return object == NULL; 00341 } 00342 00343 inline ~temporary() { 00344 if(object) 00345 delete object; 00346 object = NULL; 00347 } 00348 }; 00349 00361 template <typename T> 00362 class temp_array 00363 { 00364 protected: 00365 T *array; 00366 size_t size; 00367 00368 public: 00372 inline temp_array(size_t s) { 00373 array = new T[s]; size = s; 00374 } 00375 00380 inline temp_array(const T& initial, size_t s) { 00381 array = new T[s]; 00382 size = s; 00383 for(size_t p = 0; p < s; ++p) 00384 array[p] = initial; 00385 } 00386 00387 inline void reset(size_t s) { 00388 delete[] array; array = new T[s]; size = s; 00389 } 00390 00391 inline void reset(const T& initial, size_t s) { 00392 if(array) 00393 delete[] array; 00394 array = new T[s]; 00395 size = s; 00396 for(size_t p = 0; p < s; ++p) 00397 array[p] = initial; 00398 } 00399 00400 inline void set(const T& initial) { 00401 for(size_t p = 0; p < size; ++p) 00402 array[p] = initial; 00403 } 00404 00408 temp_array(const temp_array<T>&) { 00409 ::abort(); 00410 } 00411 00412 inline operator bool() const { 00413 return array != NULL; 00414 } 00415 00416 inline bool operator!() const { 00417 return array == NULL; 00418 } 00419 00420 inline ~temp_array() { 00421 if(array) 00422 delete[] array; 00423 array = NULL; 00424 size = 0; 00425 } 00426 00427 inline T& operator[](size_t offset) const { 00428 crit(offset < size, "array out of bound"); 00429 return array[offset]; 00430 } 00431 00432 inline T* operator()(size_t offset) const { 00433 crit(offset < size, "array out of bound"); 00434 return &array[offset]; 00435 } 00436 }; 00437 00442 template<typename T> 00443 class save_restore 00444 { 00445 private: 00446 T *original; 00447 T temp; 00448 00449 public: 00454 inline save_restore(T& object) { 00455 original = &object; temp = object; 00456 } 00457 00461 inline ~save_restore() { 00462 *original = temp; 00463 } 00464 }; 00465 00471 template<class T> 00472 inline bool is(T& object) { 00473 return object.operator bool(); 00474 } 00475 00482 template<typename T> 00483 inline bool isnull(T& object) { 00484 return (bool)(object.operator*() == NULL); 00485 } 00486 00493 template<typename T> 00494 inline bool isnullp(T *object) { 00495 return (bool)(object->operator*() == NULL); 00496 } 00497 00503 template<typename T> 00504 inline T* dup(const T& object) { 00505 return new T(object); 00506 } 00507 00508 template<typename T> 00509 inline void dupfree(T object) { 00510 delete object; 00511 } 00512 00513 template<> 00514 inline char *dup<char>(const char& object) { 00515 return strdup(&object); 00516 } 00517 00518 template<> 00519 inline void dupfree<char*>(char* object) { 00520 ::free(object); 00521 } 00522 00527 template<typename T> 00528 inline void reset_unsafe(T& object) { 00529 new((caddr_t)&object) T; 00530 } 00531 00536 template<typename T> 00537 inline void zero_unsafe(T& object) { 00538 memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T; 00539 } 00540 00546 template<typename T> 00547 inline void copy_unsafe(T* target, const T* source) { 00548 memcpy((void *)target, (void *)source, sizeof(T)); 00549 } 00550 00556 template<typename T> 00557 inline void store_unsafe(T& target, const T* source) { 00558 memcpy((void *)&target, (void *)source, sizeof(T)); 00559 } 00560 00566 template<typename T> 00567 inline void swap(T& o1, T& o2) { 00568 cpr_memswap(&o1, &o2, sizeof(T)); 00569 } 00570 00578 template<typename T> 00579 inline bool bound(const T* pointer, const T* base, size_t count) { 00580 if(pointer < base || pointer >= &base[count]) 00581 return false; 00582 if(((size_t)pointer) % sizeof(T)) 00583 return false; 00584 return true; 00585 } 00586 00593 template<typename T> 00594 inline T& (max)(T& o1, T& o2) { 00595 return o1 > o2 ? o1 : o2; 00596 } 00597 00604 template<typename T> 00605 inline T& (min)(T& o1, T& o2) { 00606 return o1 < o2 ? o1 : o2; 00607 } 00608 00616 template<typename T> 00617 inline T& (limit)(T& value, T& low, T& high) { 00618 return (value < low) ? low : ((value > high) ? high : value); 00619 } 00620 00627 template<typename T> 00628 inline T& deref_pointer(T *pointer) { 00629 return *pointer; 00630 } 00631 00632 } // namespace ucommon 00633 00634 #endif