UCommon
generics.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015-2020 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 #if __cplusplus > 199711L
39 #define THROWS(x)
40 #define THROWS_ANY
41 #else
42 #define THROWS(x) throw(x)
43 #define THROWS_ANY throw()
44 #endif
45 #else
46 #define THROW(x) ::abort()
47 #define THROWS(x)
48 #define THROWS_ANY
49 #endif
50 
51 namespace ucommon {
52 
58 template <typename T>
59 class pointer
60 {
61 protected:
62  unsigned *counter;
63  T *object;
64 
65 public:
66  inline void release(void) {
67  if(counter && --(*counter)==0) {
68  delete counter;
69  delete object;
70  }
71  object = NULL;
72  counter = NULL;
73  }
74 
75  inline void retain(void) {
76  if(counter)
77  ++*counter;
78  }
79 
80  inline void set(T* ptr) {
81  if(object != ptr) {
82  release();
83  counter = new unsigned;
84  *counter = 1;
85  object = ptr;
86  }
87  }
88 
89  inline void set(const pointer<T> &ref) {
90  if(object == ref.object)
91  return;
92 
93  if(counter && --(*counter)==0) {
94  delete counter;
95  delete object;
96  }
97  object = ref.object;
98  counter = ref.counter;
99  if(counter)
100  ++(*counter);
101  }
102 
103  inline pointer() {
104  counter = NULL;
105  object = NULL;
106  }
107 
108  inline explicit pointer(T* ptr = NULL) : object(ptr) {
109  if(object) {
110  counter = new unsigned;
111  *counter = 1;
112  }
113  else
114  counter = NULL;
115  }
116 
117  inline pointer(const pointer<T> &ref) {
118  object = ref.object;
119  counter = ref.counter;
120  if(counter)
121  ++(*counter);
122  }
123 
124  inline pointer& operator=(const pointer<T> &ref) {
125  this->set(ref);
126  return *this;
127  }
128 
129  inline pointer& operator=(T *ptr) {
130  this->set(ptr);
131  return *this;
132  }
133 
134  inline ~pointer() {
135  release();
136  }
137 
138  inline T& operator*() const {
139  return *object;
140  }
141 
142  inline T* operator->() const {
143  return object;
144  }
145 
146  inline bool operator!() const {
147  return (counter == NULL);
148  }
149 
150  inline operator bool() const {
151  return counter != NULL;
152  }
153 };
154 
160 template <typename T>
162 {
163 protected:
164  unsigned *counter;
165  T *array;
166 
167 public:
168  inline void release(void) {
169  if(counter && --(*counter)==0) {
170  delete counter;
171  delete[] array;
172  }
173  array = NULL;
174  counter = NULL;
175  }
176 
177  inline void retain(void) {
178  if(counter)
179  ++*counter;
180  }
181 
182  inline void set(T* ptr) {
183  if(array != ptr) {
184  release();
185  counter = new unsigned;
186  *counter = 1;
187  array = ptr;
188  }
189  }
190 
191  inline void set(const array_pointer<T> &ref) {
192  if(array == ref.array)
193  return;
194 
195  if(counter && --(*counter)==0) {
196  delete counter;
197  delete[] array;
198  }
199  array = ref.array;
200  counter = ref.counter;
201  if(counter)
202  ++(*counter);
203  }
204 
205  inline array_pointer() {
206  counter = NULL;
207  array = NULL;
208  }
209 
210  inline explicit array_pointer(T* ptr = NULL) : array(ptr) {
211  if(array) {
212  counter = new unsigned;
213  *counter = 1;
214  }
215  else
216  counter = NULL;
217  }
218 
219  inline array_pointer(const array_pointer<T> &ref) {
220  array = ref.array;
221  counter = ref.counter;
222  if(counter)
223  ++(*counter);
224  }
225 
226  inline array_pointer& operator=(const array_pointer<T> &ref) {
227  this->set(ref);
228  return *this;
229  }
230 
231  inline array_pointer& operator=(T *ptr) {
232  this->set(ptr);
233  return *this;
234  }
235 
236  inline ~array_pointer() {
237  release();
238  }
239 
240  inline T* operator*() const {
241  return array;
242  }
243 
244  inline T& operator[](size_t offset) const {
245  return array[offset];
246  }
247 
248  inline T* operator()(size_t offset) const {
249  return &array[offset];
250  }
251 
252  inline bool operator!() const {
253  return (counter == NULL);
254  }
255 
256  inline operator bool() const {
257  return counter != NULL;
258  }
259 };
260 
265 template<typename T>
267 {
268 private:
269  T *original;
270  T temp;
271 
272  save_restore() __DELETED;
273 
274 public:
279  inline save_restore(T& object) {
280  original = &object; temp = object;
281  }
282 
286  inline ~save_restore() {
287  *original = temp;
288  }
289 };
290 
296 template<typename T>
297 inline bool is(T& object) {
298  return object.operator bool();
299 }
300 
307 template<typename T>
308 inline bool isnull(T& object) {
309  return (bool)(object.operator*() == nullptr);
310 }
311 
318 template<typename T>
319 inline bool isnullp(T *object) {
320  return (bool)(object->operator*() == nullptr);
321 }
322 
328 template<typename T>
329 inline T* dup(const T& object) {
330  return new T(object);
331 }
332 
333 template<typename T>
334 inline void dupfree(T object) {
335  delete object;
336 }
337 
338 template<>
339 inline char *dup<char>(const char& object) {
340  return strdup(&object);
341 }
342 
343 template<>
344 inline void dupfree<char*>(char* object) {
345  ::free(object);
346 }
347 
352 template<typename T>
353 inline void reset_unsafe(T& object) {
354  new((caddr_t)&object) T;
355 }
356 
361 template<typename T>
362 inline void zero_unsafe(T& object) {
363  memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;
364 }
365 
371 template<typename T>
372 inline void copy_unsafe(T* target, const T* source) {
373  memcpy((void *)target, (void *)source, sizeof(T));
374 }
375 
381 template<typename T>
382 inline void store_unsafe(T& target, const T* source) {
383  memcpy((void *)&target, (void *)source, sizeof(T));
384 }
385 
391 template<typename T>
392 inline void swap(T& o1, T& o2) {
393  cpr_memswap(&o1, &o2, sizeof(T));
394 }
395 
399 template<typename T>
400 inline T copy(const T& src) {
401  return T(src);
402 }
403 
404 template<typename T>
405 inline T& copy(const T& src, T& to) {
406  new((caddr_t)&to) T(src);
407  return to;
408 }
409 
413 template<typename T>
414 inline T& move(T& src, T& to) {
415  memcpy((void *)&to, (void *)&src, sizeof(T));
416  new((caddr_t)&src) T();
417  return to;
418 }
419 
420 template<typename T>
421 inline T& clear(T& o) {
422  o.~T();
423  new((caddr_t)&o) T();
424  return o;
425 }
426 
434 template<typename T>
435 inline bool bound(const T* pointer, const T* base, size_t count) {
436  if(pointer < base || pointer >= &base[count])
437  return false;
438  if(((size_t)pointer) % sizeof(T))
439  return false;
440  return true;
441 }
442 
449 template<typename T>
450 inline T& (max)(T& o1, T& o2) {
451  return o1 > o2 ? o1 : o2;
452 }
453 
460 template<typename T>
461 inline T& (min)(T& o1, T& o2) {
462  return o1 < o2 ? o1 : o2;
463 }
464 
472 template<typename T>
473 inline T& (limit)(T& value, T& low, T& high) {
474  return (value < low) ? low : ((value > high) ? high : value);
475 }
476 
483 template<typename T>
484 inline T& deref_pointer(T *pointer) {
485  __THROW_DEREF(pointer);
486  return *pointer;
487 }
488 
489 } // namespace ucommon
490 
491 #endif
Runtime functions.
Common namespace for all ucommon objects.
Definition: access.h:47
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition: generics.h:329
void store_unsafe(T &target, const T *source)
Convenience function to store object pointer into object.
Definition: generics.h:382
bool isnullp(T *object)
Convenience function to test pointer-pointer object.
Definition: generics.h:319
T &() min(T &o1, T &o2)
Convenience function to return min of two objects.
Definition: generics.h:461
bool bound(const T *pointer, const T *base, size_t count)
Convenience function to check memory arrays.
Definition: generics.h:435
void reset_unsafe(T &object)
Convenience function to reset an existing object.
Definition: generics.h:353
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition: generics.h:392
void zero_unsafe(T &object)
Convenience function to zero an object and restore type info.
Definition: generics.h:362
T & deref_pointer(T *pointer)
Convert a pointer to a reference with type checking.
Definition: generics.h:484
T copy(const T &src)
Convenience function to copy objects.
Definition: generics.h:400
T &() max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition: generics.h:450
T &() limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition: generics.h:473
bool isnull(T &object)
Convenience function to test pointer object.
Definition: generics.h:308
void copy_unsafe(T *target, const T *source)
Convenience function to copy class.
Definition: generics.h:372
T & move(T &src, T &to)
Convenience function to move objects.
Definition: generics.h:414
bool is(T &object)
Convenience function to validate object assuming it is castable to bool.
Definition: generics.h:297
Generic smart pointer class.
Definition: generics.h:60
Generic smart array class.
Definition: generics.h:162
Save and restore global objects in function call stack frames.
Definition: generics.h:267
~save_restore()
Restore original when stack frame is released.
Definition: generics.h:286
save_restore(T &object)
Save object into local copy and keep reference to the original object.
Definition: generics.h:279