UCommon
generics.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
2 //
3 // This file is part of GNU uCommon C++.
4 //
5 // GNU uCommon C++ is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // GNU uCommon C++ is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
17 
24 #ifndef _UCOMMON_GENERICS_H_
25 #define _UCOMMON_GENERICS_H_
26 
27 #ifndef _UCOMMON_CPR_H_
28 #include <ucommon/cpr.h>
29 #endif
30 
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #ifdef NEW_STDLIB
35 #include <stdexcept>
36 #endif
37 
38 #if defined(NEW_STDLIB) || defined(OLD_STDLIB)
39 #define THROW(x) throw x
40 #define THROWS(x) throw(x)
41 #define THROWS_ANY throw()
42 #else
43 #define THROW(x) ::abort()
44 #define THROWS(x)
45 #define THROWS_ANY
46 #endif
47 
48 NAMESPACE_UCOMMON
49 
55 template <typename T>
56 class pointer
57 {
58 protected:
59  unsigned *counter;
60  T *object;
61 
62 public:
63  inline void release(void) {
64  if(counter && --(*counter)==0) {
65  delete counter;
66  delete object;
67  }
68  object = NULL;
69  counter = NULL;
70  }
71 
72  inline void retain(void) {
73  if(counter)
74  ++*counter;
75  }
76 
77  inline void set(T* ptr) {
78  if(object != ptr) {
79  release();
80  counter = new unsigned;
81  *counter = 1;
82  object = ptr;
83  }
84  }
85 
86  inline void set(const pointer<T> &ref) {
87  if(object == ref.object)
88  return;
89 
90  if(counter && --(*counter)==0) {
91  delete counter;
92  delete object;
93  }
94  object = ref.object;
95  counter = ref.counter;
96  if(counter)
97  ++(*counter);
98  }
99 
100  inline pointer() {
101  counter = NULL;
102  object = NULL;
103  }
104 
105  inline explicit pointer(T* ptr = NULL) : object(ptr) {
106  if(object) {
107  counter = new unsigned;
108  *counter = 1;
109  }
110  else
111  counter = NULL;
112  }
113 
114  inline pointer(const pointer<T> &ref) {
115  object = ref.object;
116  counter = ref.counter;
117  if(counter)
118  ++(*counter);
119  }
120 
121  inline pointer& operator=(const pointer<T> &ref) {
122  this->set(ref);
123  return *this;
124  }
125 
126  inline pointer& operator=(T *ptr) {
127  this->set(ptr);
128  return *this;
129  }
130 
131  inline ~pointer()
132  {release();}
133 
134  inline T& operator*() const
135  {return *object;};
136 
137  inline T* operator->() const
138  {return object;};
139 
140  inline bool operator!() const
141  {return (counter == NULL);};
142 
143  inline operator bool() const
144  {return counter != NULL;};
145 };
146 
152 template <typename T>
154 {
155 protected:
156  unsigned *counter;
157  T *array;
158 
159 public:
160  inline void release(void) {
161  if(counter && --(*counter)==0) {
162  delete counter;
163  delete[] array;
164  }
165  array = NULL;
166  counter = NULL;
167  }
168 
169  inline void retain(void) {
170  if(counter)
171  ++*counter;
172  }
173 
174  inline void set(T* ptr) {
175  if(array != ptr) {
176  release();
177  counter = new unsigned;
178  *counter = 1;
179  array = ptr;
180  }
181  }
182 
183  inline void set(const array_pointer<T> &ref) {
184  if(array == ref.array)
185  return;
186 
187  if(counter && --(*counter)==0) {
188  delete counter;
189  delete[] array;
190  }
191  array = ref.array;
192  counter = ref.counter;
193  if(counter)
194  ++(*counter);
195  }
196 
197  inline array_pointer() {
198  counter = NULL;
199  array = NULL;
200  }
201 
202  inline explicit array_pointer(T* ptr = NULL) : array(ptr) {
203  if(array) {
204  counter = new unsigned;
205  *counter = 1;
206  }
207  else
208  counter = NULL;
209  }
210 
211  inline array_pointer(const array_pointer<T> &ref) {
212  array = ref.array;
213  counter = ref.counter;
214  if(counter)
215  ++(*counter);
216  }
217 
218  inline array_pointer& operator=(const array_pointer<T> &ref) {
219  this->set(ref);
220  return *this;
221  }
222 
223  inline array_pointer& operator=(T *ptr) {
224  this->set(ptr);
225  return *this;
226  }
227 
228  inline ~array_pointer()
229  {release();}
230 
231  inline T* operator*() const
232  {return array;};
233 
234  inline T& operator[](size_t offset) const
235  {return array[offset];};
236 
237  inline T* operator()(size_t offset) const
238  {return &array[offset];};
239 
240  inline bool operator!() const
241  {return (counter == NULL);};
242 
243  inline operator bool() const
244  {return counter != NULL;};
245 };
246 
258 template <typename T>
260 {
261 protected:
262  T *object;
263 public:
267  inline temporary()
268  {object = NULL;};
269 
274  {::abort();};
275 
279  inline temporary(T *ptr)
280  {object = ptr;};
281 
288  inline T& operator=(T *temp) {
289  if(object)
290  delete object;
291  object = temp;
292  return *this;
293  }
294 
301  inline void set(T *temp) {
302  if(object)
303  delete object;
304  object = temp;
305  }
306 
311  inline T& operator*() const
312  {return *object;};
313 
318  inline T* operator->() const
319  {return object;};
320 
321  inline operator bool() const
322  {return object != NULL;};
323 
324  inline bool operator!() const
325  {return object == NULL;};
326 
327  inline ~temporary() {
328  if(object)
329  delete object;
330  object = NULL;
331  }
332 };
333 
345 template <typename T>
347 {
348 protected:
349  T *array;
350  size_t size;
351 
352 public:
356  inline temp_array(size_t s)
357  {array = new T[s]; size = s;};
358 
363  inline temp_array(const T& initial, size_t s) {
364  array = new T[s];
365  size = s;
366  for(size_t p = 0; p < s; ++p)
367  array[p] = initial;
368  }
369 
370  inline void reset(size_t s)
371  {delete[] array; array = new T[s]; size = s;};
372 
373  inline void reset(const T& initial, size_t s) {
374  if(array)
375  delete[] array;
376  array = new T[s];
377  size = s;
378  for(size_t p = 0; p < s; ++p)
379  array[p] = initial;
380  }
381 
382  inline void set(const T& initial) {
383  for(size_t p = 0; p < size; ++p)
384  array[p] = initial;
385  }
386 
391  {::abort();};
392 
393  inline operator bool() const
394  {return array != NULL;};
395 
396  inline bool operator!() const
397  {return array == NULL;};
398 
399  inline ~temp_array() {
400  if(array)
401  delete[] array;
402  array = NULL;
403  size = 0;
404  }
405 
406  inline T& operator[](size_t offset) const {
407  crit(offset < size, "array out of bound");
408  return array[offset];
409  }
410 
411  inline T* operator()(size_t offset) const {
412  crit(offset < size, "array out of bound");
413  return &array[offset];
414  }
415 };
416 
421 template<typename T>
423 {
424 private:
425  T *original;
426  T temp;
427 
428 public:
433  inline save_restore(T& object)
434  {original = &object; temp = object;};
435 
439  inline ~save_restore()
440  {*original = temp;};
441 };
442 
448 template<class T>
449 inline bool is(T& object)
450  {return object.operator bool();}
451 
458 template<typename T>
459 inline bool isnull(T& object)
460  {return (bool)(object.operator*() == NULL);}
461 
468 template<typename T>
469 inline bool isnullp(T *object)
470  {return (bool)(object->operator*() == NULL);}
471 
477 template<typename T>
478 inline T* dup(const T& object)
479  {return new T(object);}
480 
481 template<typename T>
482 inline void dupfree(T object)
483  {delete object;}
484 
485 template<>
486 inline char *dup<char>(const char& object)
487  {return strdup(&object);}
488 
489 template<>
490 inline void dupfree<char*>(char* object)
491  {::free(object);}
492 
497 template<typename T>
498 inline void reset_unsafe(T& object)
499  {new((caddr_t)&object) T;}
500 
505 template<typename T>
506 inline void zero_unsafe(T& object)
507  {memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;}
508 
514 template<typename T>
515 inline void copy_unsafe(T* target, const T* source)
516  {memcpy((void *)target, (void *)source, sizeof(T));}
517 
523 template<typename T>
524 inline void store_unsafe(T& target, const T* source)
525  {memcpy((void *)&target, (void *)source, sizeof(T));}
526 
532 template<typename T>
533 inline void swap(T& o1, T& o2)
534  {cpr_memswap(&o1, &o2, sizeof(T));}
535 
542 template<typename T>
543 inline T& (max)(T& o1, T& o2)
544 {
545  return o1 > o2 ? o1 : o2;
546 }
547 
554 template<typename T>
555 inline T& (min)(T& o1, T& o2)
556 {
557  return o1 < o2 ? o1 : o2;
558 }
559 
567 template<typename T>
568 inline T& (limit)(T& value, T& low, T& high)
569 {
570  return (value < low) ? low : ((value > high) ? high : value);
571 }
572 
573 END_NAMESPACE
574 
575 #endif
T * operator->() const
Access members of our heap object through our temporary.
Definition: generics.h:318
Save and restore global objects in function call stack frames.
Definition: generics.h:422
void retain(ObjectProtocol *object)
Convenience function to access object retention.
Definition: object.h:465
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition: generics.h:478
bool is(T &object)
Convenience function to validate object assuming it is castable to bool.
Definition: generics.h:449
bool isnullp(T *object)
Convenience function to test pointer-pointer object.
Definition: generics.h:469
Generic smart pointer class.
Definition: generics.h:56
T &() min(T &o1, T &o2)
Convenience function to return min of two objects.
Definition: generics.h:555
T &() limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition: generics.h:568
save_restore(T &object)
Save object into local copy and keep reference to the original object.
Definition: generics.h:433
Runtime functions.
Manage temporary object stored on the heap.
Definition: generics.h:259
temporary()
Construct a temporary object, create our stack frame reference.
Definition: generics.h:267
void release(SharedAccess &object)
Convenience function to unlock shared object through it&#39;s protocol.
Definition: access.h:260
~save_restore()
Restore original when stack frame is released.
Definition: generics.h:439
temp_array(size_t s)
Construct a temporary object, create our stack frame reference.
Definition: generics.h:356
void reset_unsafe(T &object)
Convenience function to reset an existing object.
Definition: generics.h:498
void store_unsafe(T &target, const T *source)
Convenience function to store object pointer into object.
Definition: generics.h:524
Manage temporary array stored on the heap.
Definition: generics.h:346
temporary(const temporary< T > &)
Disable copy constructor.
Definition: generics.h:273
void cpr_memswap(void *mem1, void *mem2, size_t size)
Portable swap code.
void set(T *temp)
Assign a temporary object.
Definition: generics.h:301
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:543
temp_array(const T &initial, size_t s)
Construct a temporary object with a copy of some initial value.
Definition: generics.h:363
void zero_unsafe(T &object)
Convenience function to zero an object and restore type info.
Definition: generics.h:506
temp_array(const temp_array< T > &)
Disable copy constructor.
Definition: generics.h:390
T & operator*() const
Access heap object through our temporary directly.
Definition: generics.h:311
Automatic integer counting class.
Definition: counter.h:42
Generic smart array class.
Definition: generics.h:153
A common string class and character string support functions.
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition: generics.h:533
temporary(T *ptr)
Construct an assigned pointer.
Definition: generics.h:279
bool isnull(T &object)
Convenience function to test pointer object.
Definition: generics.h:459
void copy_unsafe(T *target, const T *source)
Convenience function to copy class.
Definition: generics.h:515
T & operator=(T *temp)
Assign a temporary object.
Definition: generics.h:288