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
46namespace ucommon {
47
53template <typename T>
55{
56protected:
57 unsigned *counter;
58 T *object;
59
60public:
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
155template <typename T>
157{
158protected:
159 unsigned *counter;
160 T *array;
161
162public:
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
260template<typename T>
262{
263private:
264 T *original;
265 T temp;
266
267 save_restore() __DELETED;
268
269public:
274 inline save_restore(T& object) {
275 original = &object; temp = object;
276 }
277
281 inline ~save_restore() {
282 *original = temp;
283 }
284};
285
291template<typename T>
292inline bool is(T& object) {
293 return object.operator bool();
294}
295
302template<typename T>
303inline bool isnull(T& object) {
304 return (bool)(object.operator*() == nullptr);
305}
306
313template<typename T>
314inline bool isnullp(T *object) {
315 return (bool)(object->operator*() == nullptr);
316}
317
323template<typename T>
324inline T* dup(const T& object) {
325 return new T(object);
326}
327
328template<typename T>
329inline void dupfree(T object) {
330 delete object;
331}
332
333template<>
334inline char *dup<char>(const char& object) {
335 return strdup(&object);
336}
337
338template<>
339inline void dupfree<char*>(char* object) {
340 ::free(object);
341}
342
347template<typename T>
348inline void reset_unsafe(T& object) {
349 new((caddr_t)&object) T;
350}
351
356template<typename T>
357inline void zero_unsafe(T& object) {
358 memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;
359}
360
366template<typename T>
367inline void copy_unsafe(T* target, const T* source) {
368 memcpy((void *)target, (void *)source, sizeof(T));
369}
370
376template<typename T>
377inline void store_unsafe(T& target, const T* source) {
378 memcpy((void *)&target, (void *)source, sizeof(T));
379}
380
386template<typename T>
387inline void swap(T& o1, T& o2) {
388 cpr_memswap(&o1, &o2, sizeof(T));
389}
390
394template<typename T>
395inline T copy(const T& src) {
396 return T(src);
397}
398
399template<typename T>
400inline T& copy(const T& src, T& to) {
401 new((caddr_t)&to) T(src);
402 return to;
403}
404
408template<typename T>
409inline 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
415template<typename T>
416inline T& clear(T& o) {
417 o.~T();
418 new((caddr_t)&o) T();
419 return o;
420}
421
429template<typename T>
430inline 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
444template<typename T>
445inline T& (max)(T& o1, T& o2) {
446 return o1 > o2 ? o1 : o2;
447}
448
455template<typename T>
456inline T& (min)(T& o1, T& o2) {
457 return o1 < o2 ? o1 : o2;
458}
459
467template<typename T>
468inline T& (limit)(T& value, T& low, T& high) {
469 return (value < low) ? low : ((value > high) ? high : value);
470}
471
478template<typename T>
479inline T& deref_pointer(T *pointer) {
480 __THROW_DEREF(pointer);
481 return *pointer;
482}
483
484} // namespace ucommon
485
486#endif
Runtime functions.
void cpr_memswap(void *mem1, void *mem2, size_t size)
Portable swap code.
Common namespace for all ucommon objects.
Definition access.h:47
void store_unsafe(T &target, const T *source)
Convenience function to store object pointer into object.
Definition generics.h:377
T * dup(const T &object)
Convenience function to duplicate object pointer to heap.
Definition generics.h:324
bool isnullp(T *object)
Convenience function to test pointer-pointer object.
Definition generics.h:314
T & max(T &o1, T &o2)
Convenience function to return max of two objects.
Definition generics.h:445
T & limit(T &value, T &low, T &high)
Convenience macro to range restrict values.
Definition generics.h:468
bool bound(const T *pointer, const T *base, size_t count)
Convenience function to check memory arrays.
Definition generics.h:430
void reset_unsafe(T &object)
Convenience function to reset an existing object.
Definition generics.h:348
T & deref_pointer(T *pointer)
Convert a pointer to a reference with type checking.
Definition generics.h:479
void swap(T &o1, T &o2)
Convenience function to swap objects.
Definition generics.h:387
T & move(T &src, T &to)
Convenience function to move objects.
Definition generics.h:409
void zero_unsafe(T &object)
Convenience function to zero an object and restore type info.
Definition generics.h:357
T copy(const T &src)
Convenience function to copy objects.
Definition generics.h:395
T & min(T &o1, T &o2)
Convenience function to return min of two objects.
Definition generics.h:456
bool isnull(T &object)
Convenience function to test pointer object.
Definition generics.h:303
void copy_unsafe(T *target, const T *source)
Convenience function to copy class.
Definition generics.h:367
bool is(T &object)
Convenience function to validate object assuming it is castable to bool.
Definition generics.h:292
Automatic integer counting class.
Definition counter.h:44
Generic smart pointer class.
Definition generics.h:55
Generic smart array class.
Definition generics.h:157
Save and restore global objects in function call stack frames.
Definition generics.h:262
~save_restore()
Restore original when stack frame is released.
Definition generics.h:281
save_restore(T &object)
Save object into local copy and keep reference to the original object.
Definition generics.h:274