UCommon
generics.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
25 #ifndef _UCOMMON_GENERICS_H_
26 #define _UCOMMON_GENERICS_H_
27 
28 #ifndef _UCOMMON_CPR_H_
29 #include <ucommon/cpr.h>
30 #endif
31 
32 #include <cstdlib>
33 #include <cstring>
34 #include <stdexcept>
35 
36 #ifndef UCOMMON_SYSRUNTIME
37 #define THROW(x) throw x
38 #define THROWS(x) throw(x)
39 #define THROWS_ANY throw()
40 #else
41 #define THROW(x) ::abort()
42 #define THROWS(x)
43 #define THROWS_ANY
44 #endif
45 
46 namespace ucommon {
47 
53 template <typename T>
54 class pointer
55 {
56 protected:
57  unsigned *counter;
58  T *object;
59 
60 public:
61  inline void release(void) {
62  if(counter && --(*counter)==0) {
63  delete counter;
64  delete object;
65  }
66  object = NULL;
67  counter = NULL;
68  }
69 
70  inline void retain(void) {
71  if(counter)
72  ++*counter;
73  }
74 
75  inline void set(T* ptr) {
76  if(object != ptr) {
77  release();
78  counter = new unsigned;
79  *counter = 1;
80  object = ptr;
81  }
82  }
83 
84  inline void set(const pointer<T> &ref) {
85  if(object == ref.object)
86  return;
87 
88  if(counter && --(*counter)==0) {
89  delete counter;
90  delete object;
91  }
92  object = ref.object;
93  counter = ref.counter;
94  if(counter)
95  ++(*counter);
96  }
97 
98  inline pointer() {
99  counter = NULL;
100  object = NULL;
101  }
102 
103  inline explicit pointer(T* ptr = NULL) : object(ptr) {
104  if(object) {
105  counter = new unsigned;
106  *counter = 1;
107  }
108  else
109  counter = NULL;
110  }
111 
112  inline pointer(const pointer<T> &ref) {
113  object = ref.object;
114  counter = ref.counter;
115  if(counter)
116  ++(*counter);
117  }
118 
119  inline pointer& operator=(const pointer<T> &ref) {
120  this->set(ref);
121  return *this;
122  }
123 
124  inline pointer& operator=(T *ptr) {
125  this->set(ptr);
126  return *this;
127  }
128 
129  inline ~pointer() {
130  release();
131  }
132 
133  inline T& operator*() const {
134  return *object;
135  }
136 
137  inline T* operator->() const {
138  return object;
139  }
140 
141  inline bool operator!() const {
142  return (counter == NULL);
143  }
144 
145  inline operator bool() const {
146  return counter != NULL;
147  }
148 };
149 
155 template <typename T>
157 {
158 protected:
159  unsigned *counter;
160  T *array;
161 
162 public:
163  inline void release(void) {
164  if(counter && --(*counter)==0) {
165  delete counter;
166  delete[] array;
167  }
168  array = NULL;
169  counter = NULL;
170  }
171 
172  inline void retain(void) {
173  if(counter)
174  ++*counter;
175  }
176 
177  inline void set(T* ptr) {
178  if(array != ptr) {
179  release();
180  counter = new unsigned;
181  *counter = 1;
182  array = ptr;
183  }
184  }
185 
186  inline void set(const array_pointer<T> &ref) {
187  if(array == ref.array)
188  return;
189 
190  if(counter && --(*counter)==0) {
191  delete counter;
192  delete[] array;
193  }
194  array = ref.array;
195  counter = ref.counter;
196  if(counter)
197  ++(*counter);
198  }
199 
200  inline array_pointer() {
201  counter = NULL;
202  array = NULL;
203  }
204 
205  inline explicit array_pointer(T* ptr = NULL) : array(ptr) {
206  if(array) {
207  counter = new unsigned;
208  *counter = 1;
209  }
210  else
211  counter = NULL;
212  }
213 
214  inline array_pointer(const array_pointer<T> &ref) {
215  array = ref.array;
216  counter = ref.counter;
217  if(counter)
218  ++(*counter);
219  }
220 
221  inline array_pointer& operator=(const array_pointer<T> &ref) {
222  this->set(ref);
223  return *this;
224  }
225 
226  inline array_pointer& operator=(T *ptr) {
227  this->set(ptr);
228  return *this;
229  }
230 
231  inline ~array_pointer() {
232  release();
233  }
234 
235  inline T* operator*() const {
236  return array;
237  }
238 
239  inline T& operator[](size_t offset) const {
240  return array[offset];
241  }
242 
243  inline T* operator()(size_t offset) const {
244  return &array[offset];
245  }
246 
247  inline bool operator!() const {
248  return (counter == NULL);
249  }
250 
251  inline operator bool() const {
252  return counter != NULL;
253  }
254 };
255 
260 template<typename T>
262 {
263 private:
264  T *original;
265  T temp;
266 
267  save_restore() __DELETED;
268 
269 public:
274  inline save_restore(T& object) {
275  original = &object; temp = object;
276  }
277 
281  inline ~save_restore() {
282  *original = temp;
283  }
284 };
285 
291 template<typename T>
292 inline bool is(T& object) {
293  return object.operator bool();
294 }
295 
302 template<typename T>
303 inline bool isnull(T& object) {
304  return (bool)(object.operator*() == nullptr);
305 }
306 
313 template<typename T>
314 inline bool isnullp(T *object) {
315  return (bool)(object->operator*() == nullptr);
316 }
317 
323 template<typename T>
324 inline T* dup(const T& object) {
325  return new T(object);
326 }
327 
328 template<typename T>
329 inline void dupfree(T object) {
330  delete object;
331 }
332 
333 template<>
334 inline char *dup<char>(const char& object) {
335  return strdup(&object);
336 }
337 
338 template<>
339 inline void dupfree<char*>(char* object) {
340  ::free(object);
341 }
342 
347 template<typename T>
348 inline void reset_unsafe(T& object) {
349  new((caddr_t)&object) T;
350 }
351 
356 template<typename T>
357 inline void zero_unsafe(T& object) {
358  memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;
359 }
360 
366 template<typename T>
367 inline void copy_unsafe(T* target, const T* source) {
368  memcpy((void *)target, (void *)source, sizeof(T));
369 }
370 
376 template<typename T>
377 inline void store_unsafe(T& target, const T* source) {
378  memcpy((void *)&target, (void *)source, sizeof(T));
379 }
380 
386 template<typename T>
387 inline void swap(T& o1, T& o2) {
388  cpr_memswap(&o1, &o2, sizeof(T));
389 }
390 
394 template<typename T>
395 inline T copy(const T& src) {
396  return T(src);
397 }
398 
399 template<typename T>
400 inline T& copy(const T& src, T& to) {
401  new((caddr_t)&to) T(src);
402  return to;
403 }
404 
408 template<typename T>
409 inline T& move(T& src, T& to) {
410  memcpy((void *)&to, (void *)&src, sizeof(T));
411  new((caddr_t)&src) T();
412  return to;
413 }
414 
415 template<typename T>
416 inline T& clear(T& o) {
417  o.~T();
418  new((caddr_t)&o) T();
419  return o;
420 }
421 
429 template<typename T>
430 inline bool bound(const T* pointer, const T* base, size_t count) {
431  if(pointer < base || pointer >= &base[count])
432  return false;
433  if(((size_t)pointer) % sizeof(T))
434  return false;
435  return true;
436 }
437 
444 template<typename T>
445 inline T& (max)(T& o1, T& o2) {
446  return o1 > o2 ? o1 : o2;
447 }
448 
455 template<typename T>
456 inline T& (min)(T& o1, T& o2) {
457  return o1 < o2 ? o1 : o2;
458 }
459 
467 template<typename T>
468 inline T& (limit)(T& value, T& low, T& high) {
469  return (value < low) ? low : ((value > high) ? high : value);
470 }
471 
478 template<typename T>
479 inline T& deref_pointer(T *pointer) {
480  __THROW_DEREF(pointer);
481  return *pointer;
482 }
483 
484 } // namespace ucommon
485 
486 #endif
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:445
void copy_unsafe(T *target, const T *source)
Convenience function to copy class.
Definition: generics.h:367
T & move(T &src, T &to)
Convenience function to move objects.
Definition: generics.h:409
void cpr_memswap(void *mem1, void *mem2, size_t size)
Portable swap code.
~save_restore()
Restore original when stack frame is released.
Definition: generics.h:281
bool isnull(T &object)
Convenience function to test pointer object.
Definition: generics.h:303
void zero_unsafe(T &object)
Convenience function to zero an object and restore type info.
Definition: generics.h:357
void reset_unsafe(T &object)
Convenience function to reset an existing object.
Definition: generics.h:348
bool is(T &object)
Convenience function to validate object assuming it is castable to bool.
Definition: generics.h:292
T &() limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition: generics.h:468
Save and restore global objects in function call stack frames.
Definition: generics.h:261
T &() min(T &o1, T &o2)
Convenience function to return min of two objects.
Definition: generics.h:456
bool bound(const T *pointer, const T *base, size_t count)
Convenience function to check memory arrays.
Definition: generics.h:430
void store_unsafe(T &target, const T *source)
Convenience function to store object pointer into object.
Definition: generics.h:377
Common namespace for all ucommon objects.
Definition: access.h:47
save_restore(T &object)
Save object into local copy and keep reference to the original object.
Definition: generics.h:274
Automatic integer counting class.
Definition: counter.h:43
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition: generics.h:324
T copy(const T &src)
Convenience function to copy objects.
Definition: generics.h:395
bool isnullp(T *object)
Convenience function to test pointer-pointer object.
Definition: generics.h:314
Generic smart array class.
Definition: generics.h:156
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition: generics.h:387
Runtime functions.
Generic smart pointer class.
Definition: generics.h:54
T & deref_pointer(T *pointer)
Convert a pointer to a reference with type checking.
Definition: generics.h:479