UCommon
/usr/src/RPM/BUILD/ucommon-6.3.3/inc/ucommon/generics.h
Go to the documentation of this file.
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