ucommon
generics.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 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 <cstdlib>
32 #include <cstring>
33 #include <stdexcept>
34 
35 #ifndef UCOMMON_SYSRUNTIME
36 #define THROW(x) throw x
37 #define THROWS(x) throw(x)
38 #define THROWS_ANY throw()
39 #else
40 #define THROW(x) ::abort()
41 #define THROWS(x)
42 #define THROWS_ANY
43 #endif
44 
45 namespace ucommon {
46 
52 template <typename T>
53 class pointer
54 {
55 protected:
56  unsigned *counter;
57  T *object;
58 
59 public:
60  inline void release(void) {
61  if(counter && --(*counter)==0) {
62  delete counter;
63  delete object;
64  }
65  object = NULL;
66  counter = NULL;
67  }
68 
69  inline void retain(void) {
70  if(counter)
71  ++*counter;
72  }
73 
74  inline void set(T* ptr) {
75  if(object != ptr) {
76  release();
77  counter = new unsigned;
78  *counter = 1;
79  object = ptr;
80  }
81  }
82 
83  inline void set(const pointer<T> &ref) {
84  if(object == ref.object)
85  return;
86 
87  if(counter && --(*counter)==0) {
88  delete counter;
89  delete object;
90  }
91  object = ref.object;
92  counter = ref.counter;
93  if(counter)
94  ++(*counter);
95  }
96 
97  inline pointer() {
98  counter = NULL;
99  object = NULL;
100  }
101 
102  inline explicit pointer(T* ptr = NULL) : object(ptr) {
103  if(object) {
104  counter = new unsigned;
105  *counter = 1;
106  }
107  else
108  counter = NULL;
109  }
110 
111  inline pointer(const pointer<T> &ref) {
112  object = ref.object;
113  counter = ref.counter;
114  if(counter)
115  ++(*counter);
116  }
117 
118  inline pointer& operator=(const pointer<T> &ref) {
119  this->set(ref);
120  return *this;
121  }
122 
123  inline pointer& operator=(T *ptr) {
124  this->set(ptr);
125  return *this;
126  }
127 
128  inline ~pointer()
129  {release();}
130 
131  inline T& operator*() const
132  {return *object;}
133 
134  inline T* operator->() const
135  {return object;}
136 
137  inline bool operator!() const
138  {return (counter == NULL);}
139 
140  inline operator bool() const
141  {return counter != NULL;}
142 };
143 
149 template <typename T>
151 {
152 protected:
153  unsigned *counter;
154  T *array;
155 
156 public:
157  inline void release(void) {
158  if(counter && --(*counter)==0) {
159  delete counter;
160  delete[] array;
161  }
162  array = NULL;
163  counter = NULL;
164  }
165 
166  inline void retain(void) {
167  if(counter)
168  ++*counter;
169  }
170 
171  inline void set(T* ptr) {
172  if(array != ptr) {
173  release();
174  counter = new unsigned;
175  *counter = 1;
176  array = ptr;
177  }
178  }
179 
180  inline void set(const array_pointer<T> &ref) {
181  if(array == ref.array)
182  return;
183 
184  if(counter && --(*counter)==0) {
185  delete counter;
186  delete[] array;
187  }
188  array = ref.array;
189  counter = ref.counter;
190  if(counter)
191  ++(*counter);
192  }
193 
194  inline array_pointer() {
195  counter = NULL;
196  array = NULL;
197  }
198 
199  inline explicit array_pointer(T* ptr = NULL) : array(ptr) {
200  if(array) {
201  counter = new unsigned;
202  *counter = 1;
203  }
204  else
205  counter = NULL;
206  }
207 
208  inline array_pointer(const array_pointer<T> &ref) {
209  array = ref.array;
210  counter = ref.counter;
211  if(counter)
212  ++(*counter);
213  }
214 
215  inline array_pointer& operator=(const array_pointer<T> &ref) {
216  this->set(ref);
217  return *this;
218  }
219 
220  inline array_pointer& operator=(T *ptr) {
221  this->set(ptr);
222  return *this;
223  }
224 
225  inline ~array_pointer()
226  {release();}
227 
228  inline T* operator*() const
229  {return array;}
230 
231  inline T& operator[](size_t offset) const
232  {return array[offset];}
233 
234  inline T* operator()(size_t offset) const
235  {return &array[offset];}
236 
237  inline bool operator!() const
238  {return (counter == NULL);}
239 
240  inline operator bool() const
241  {return counter != NULL;}
242 };
243 
255 template <typename T>
257 {
258 protected:
259  T *object;
260 public:
264  inline temporary()
265  {object = NULL;}
266 
271  {::abort();}
272 
276  inline temporary(T *ptr)
277  {object = ptr;}
278 
285  inline T& operator=(T *temp) {
286  if(object)
287  delete object;
288  object = temp;
289  return *this;
290  }
291 
298  inline void set(T *temp) {
299  if(object)
300  delete object;
301  object = temp;
302  }
303 
308  inline T& operator*() const
309  {return *object;}
310 
315  inline T* operator->() const
316  {return object;}
317 
318  inline operator bool() const
319  {return object != NULL;}
320 
321  inline bool operator!() const
322  {return object == NULL;}
323 
324  inline ~temporary() {
325  if(object)
326  delete object;
327  object = NULL;
328  }
329 };
330 
342 template <typename T>
344 {
345 protected:
346  T *array;
347  size_t size;
348 
349 public:
353  inline temp_array(size_t s)
354  {array = new T[s]; size = s;}
355 
360  inline temp_array(const T& initial, size_t s) {
361  array = new T[s];
362  size = s;
363  for(size_t p = 0; p < s; ++p)
364  array[p] = initial;
365  }
366 
367  inline void reset(size_t s)
368  {delete[] array; array = new T[s]; size = s;}
369 
370  inline void reset(const T& initial, size_t s) {
371  if(array)
372  delete[] array;
373  array = new T[s];
374  size = s;
375  for(size_t p = 0; p < s; ++p)
376  array[p] = initial;
377  }
378 
379  inline void set(const T& initial) {
380  for(size_t p = 0; p < size; ++p)
381  array[p] = initial;
382  }
383 
388  {::abort();}
389 
390  inline operator bool() const
391  {return array != NULL;}
392 
393  inline bool operator!() const
394  {return array == NULL;}
395 
396  inline ~temp_array() {
397  if(array)
398  delete[] array;
399  array = NULL;
400  size = 0;
401  }
402 
403  inline T& operator[](size_t offset) const {
404  crit(offset < size, "array out of bound");
405  return array[offset];
406  }
407 
408  inline T* operator()(size_t offset) const {
409  crit(offset < size, "array out of bound");
410  return &array[offset];
411  }
412 };
413 
418 template<typename T>
420 {
421 private:
422  T *original;
423  T temp;
424 
425 public:
430  inline save_restore(T& object)
431  {original = &object; temp = object;}
432 
436  inline ~save_restore()
437  {*original = temp;}
438 };
439 
445 template<class T>
446 inline bool is(T& object)
447  {return object.operator bool();}
448 
455 template<typename T>
456 inline bool isnull(T& object)
457  {return (bool)(object.operator*() == NULL);}
458 
465 template<typename T>
466 inline bool isnullp(T *object)
467  {return (bool)(object->operator*() == NULL);}
468 
474 template<typename T>
475 inline T* dup(const T& object)
476  {return new T(object);}
477 
478 template<typename T>
479 inline void dupfree(T object)
480  {delete object;}
481 
482 template<>
483 inline char *dup<char>(const char& object)
484  {return strdup(&object);}
485 
486 template<>
487 inline void dupfree<char*>(char* object)
488  {::free(object);}
489 
494 template<typename T>
495 inline void reset_unsafe(T& object)
496  {new((caddr_t)&object) T;}
497 
502 template<typename T>
503 inline void zero_unsafe(T& object)
504  {memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;}
505 
511 template<typename T>
512 inline void copy_unsafe(T* target, const T* source)
513  {memcpy((void *)target, (void *)source, sizeof(T));}
514 
520 template<typename T>
521 inline void store_unsafe(T& target, const T* source)
522  {memcpy((void *)&target, (void *)source, sizeof(T));}
523 
529 template<typename T>
530 inline void swap(T& o1, T& o2)
531  {cpr_memswap(&o1, &o2, sizeof(T));}
532 
539 template<typename T>
540 inline T& (max)(T& o1, T& o2)
541 {
542  return o1 > o2 ? o1 : o2;
543 }
544 
551 template<typename T>
552 inline T& (min)(T& o1, T& o2)
553 {
554  return o1 < o2 ? o1 : o2;
555 }
556 
564 template<typename T>
565 inline T& (limit)(T& value, T& low, T& high)
566 {
567  return (value < low) ? low : ((value > high) ? high : value);
568 }
569 
570 } // namespace ucommon
571 
572 #endif
~save_restore()
Restore original when stack frame is released.
Definition: generics.h:436
T &() limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition: generics.h:565
temporary(T *ptr)
Construct an assigned pointer.
Definition: generics.h:276
Save and restore global objects in function call stack frames.
Definition: generics.h:419
Manage temporary array stored on the heap.
Definition: generics.h:343
Generic smart array class.
Definition: generics.h:150
void cpr_memswap(void *mem1, void *mem2, size_t size)
Portable swap code.
temporary()
Construct a temporary object, create our stack frame reference.
Definition: generics.h:264
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition: generics.h:530
void copy_unsafe(T *target, const T *source)
Convenience function to copy class.
Definition: generics.h:512
Common namespace for all ucommon objects.
Definition: access.h:46
temp_array(const T &initial, size_t s)
Construct a temporary object with a copy of some initial value.
Definition: generics.h:360
Manage temporary object stored on the heap.
Definition: generics.h:256
void store_unsafe(T &target, const T *source)
Convenience function to store object pointer into object.
Definition: generics.h:521
Generic smart pointer class.
Definition: generics.h:53
T * operator->() const
Access members of our heap object through our temporary.
Definition: generics.h:315
Runtime functions.
T &() min(T &o1, T &o2)
Convenience function to return min of two objects.
Definition: generics.h:552
temp_array(size_t s)
Construct a temporary object, create our stack frame reference.
Definition: generics.h:353
T & operator*() const
Access heap object through our temporary directly.
Definition: generics.h:308
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:540
void zero_unsafe(T &object)
Convenience function to zero an object and restore type info.
Definition: generics.h:503
save_restore(T &object)
Save object into local copy and keep reference to the original object.
Definition: generics.h:430
void set(T *temp)
Assign a temporary object.
Definition: generics.h:298
T & operator=(T *temp)
Assign a temporary object.
Definition: generics.h:285
temp_array(const temp_array< T > &)
Disable copy constructor.
Definition: generics.h:387
bool isnull(T &object)
Convenience function to test pointer object.
Definition: generics.h:456
void reset_unsafe(T &object)
Convenience function to reset an existing object.
Definition: generics.h:495
Automatic integer counting class.
Definition: counter.h:42
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition: generics.h:475
bool is(T &object)
Convenience function to validate object assuming it is castable to bool.
Definition: generics.h:446
bool isnullp(T *object)
Convenience function to test pointer-pointer object.
Definition: generics.h:466
temporary(const temporary< T > &)
Disable copy constructor.
Definition: generics.h:270