ucommon

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_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