ucommon/generics.h

Go to the documentation of this file.
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_CPR_H_
00028 #include <ucommon/cpr.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 
00421 template<typename T>
00422 class save_restore
00423 {
00424 private:
00425     T *original;
00426     T temp;
00427 
00428 public:
00433     inline save_restore(T& object)
00434         {original = &object; temp = object;};
00435 
00439     inline ~save_restore()
00440         {*original = temp;};
00441 };
00442 
00448 template<class T>
00449 inline bool is(T& object)
00450     {return object.operator bool();}
00451 
00458 template<typename T>
00459 inline bool isnull(T& object)
00460     {return (bool)(object.operator*() == NULL);}
00461 
00468 template<typename T>
00469 inline bool isnullp(T *object)
00470     {return (bool)(object->operator*() == NULL);}
00471 
00477 template<typename T>
00478 inline T* dup(const T& object)
00479     {return new T(object);}
00480 
00481 template<typename T>
00482 inline void dupfree(T object)
00483     {delete object;}
00484 
00485 template<>
00486 inline char *dup<char>(const char& object)
00487     {return strdup(&object);}
00488 
00489 template<>
00490 inline void dupfree<char*>(char* object)
00491     {::free(object);}
00492 
00497 template<typename T>
00498 inline void reset_unsafe(T& object)
00499     {new((caddr_t)&object) T;}
00500 
00505 template<typename T>
00506 inline void zero_unsafe(T& object)
00507     {memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;}
00508 
00514 template<typename T>
00515 inline void copy_unsafe(T* target, const T* source)
00516     {memcpy((void *)target, (void *)source, sizeof(T));}
00517 
00523 template<typename T>
00524 inline void store_unsafe(T& target, const T* source)
00525     {memcpy((void *)&target, (void *)source, sizeof(T));}
00526 
00532 template<typename T>
00533 inline void swap(T& o1, T& o2)
00534     {cpr_memswap(&o1, &o2, sizeof(T));}
00535 
00542 template<typename T>
00543 inline T& (max)(T& o1, T& o2)
00544 {
00545     return o1 > o2 ? o1 : o2;
00546 }
00547 
00554 template<typename T>
00555 inline T& (min)(T& o1, T& o2)
00556 {
00557     return o1 < o2 ? o1 : o2;
00558 }
00559 
00567 template<typename T>
00568 inline T& (limit)(T& value, T& low, T& high)
00569 {
00570     return (value < low) ? low : ((value > high) ? high : value);
00571 }
00572 
00573 END_NAMESPACE
00574 
00575 #endif

Generated on 14 Aug 2013 for UCommon by  doxygen 1.4.7