Jamoma API  0.6.0.a19
CAAutoDisposer.h
1 /* Copyright © 2007 Apple Inc. All Rights Reserved.
2 
3  Disclaimer: IMPORTANT: This Apple software is supplied to you by
4  Apple Inc. ("Apple") in consideration of your agreement to the
5  following terms, and your use, installation, modification or
6  redistribution of this Apple software constitutes acceptance of these
7  terms. If you do not agree with these terms, please do not use,
8  install, modify or redistribute this Apple software.
9 
10  In consideration of your agreement to abide by the following terms, and
11  subject to these terms, Apple grants you a personal, non-exclusive
12  license, under Apple's copyrights in this original Apple software (the
13  "Apple Software"), to use, reproduce, modify and redistribute the Apple
14  Software, with or without modifications, in source and/or binary forms;
15  provided that if you redistribute the Apple Software in its entirety and
16  without modifications, you must retain this notice and the following
17  text and disclaimers in all such redistributions of the Apple Software.
18  Neither the name, trademarks, service marks or logos of Apple Inc.
19  may be used to endorse or promote products derived from the Apple
20  Software without specific prior written permission from Apple. Except
21  as expressly stated in this notice, no other rights or licenses, express
22  or implied, are granted by Apple herein, including but not limited to
23  any patent rights that may be infringed by your derivative works or by
24  other works in which the Apple Software may be incorporated.
25 
26  The Apple Software is provided by Apple on an "AS IS" basis. APPLE
27  MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
28  THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
29  FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
30  OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
31 
32  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
33  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
36  MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
37  AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
38  STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
39  POSSIBILITY OF SUCH DAMAGE.
40 */
41 #if !defined(__CAPtr_h__)
42 #define __CAPtr_h__
43 
44 #include <stdlib.h> // for malloc
45 #include <new> // for bad_alloc
46 #include <string.h> // for memset
47 
48 inline void* CA_malloc(size_t size)
49 {
50  void* p = malloc(size);
51  if (!p && size) throw std::bad_alloc();
52  return p;
53 }
54 
55 inline void* CA_realloc(void* old, size_t size)
56 {
57 #if TARGET_OS_WIN32
58  void* p = realloc(old, size);
59 #else
60  void* p = reallocf(old, size); // reallocf ensures the old pointer is freed if memory is full (p is NULL).
61 #endif
62  if (!p && size) throw std::bad_alloc();
63  return p;
64 }
65 
66 #ifndef UINTPTR_MAX
67 #if __LP64__
68 #define UINTPTR_MAX 18446744073709551615ULL
69 #else
70 #define UINTPTR_MAX 4294967295U
71 #endif
72 #endif
73 
74 inline void* CA_calloc(size_t n, size_t size)
75 {
76  // ensure that multiplication will not overflow
77  if (n && UINTPTR_MAX / n < size) throw std::bad_alloc();
78 
79  size_t nsize = n*size;
80  void* p = malloc(nsize);
81  if (!p && nsize) throw std::bad_alloc();
82 
83  memset(p, 0, nsize);
84  return p;
85 }
86 
87 
88 // helper class for automatic conversions
89 template <typename T>
90 struct CAPtrRef
91 {
92  T* ptr_;
93 
94  explicit CAPtrRef(T* ptr) : ptr_(ptr) {}
95 };
96 
97 template <typename T>
98 class CAAutoFree
99 {
100 private:
101  T* ptr_;
102 
103 public:
104 
105  CAAutoFree() : ptr_(0) {}
106 
107  explicit CAAutoFree(T* ptr) : ptr_(ptr) {}
108 
109  template<typename U>
110  CAAutoFree(CAAutoFree<U>& that) : ptr_(that.release()) {} // take ownership
111 
112  // C++ std says: a template constructor is never a copy constructor
113  CAAutoFree(CAAutoFree<T>& that) : ptr_(that.release()) {} // take ownership
114 
115  CAAutoFree(size_t n, bool clear = false)
116  // this becomes an ambiguous call if n == 0
117  : ptr_(0)
118  {
119  size_t maxItems = ~size_t(0) / sizeof(T);
120  if (n > maxItems)
121  throw std::bad_alloc();
122 
123  ptr_ = static_cast<T*>(clear ? CA_calloc(n, sizeof(T)) : CA_malloc(n * sizeof(T)));
124  }
125 
126  ~CAAutoFree() { free(); }
127 
128  void alloc(size_t numItems, bool clear = false)
129  {
130  size_t maxItems = ~size_t(0) / sizeof(T);
131  if (numItems > maxItems) throw std::bad_alloc();
132 
133  free();
134  ptr_ = static_cast<T*>(clear ? CA_calloc(numItems, sizeof(T)) : CA_malloc(numItems * sizeof(T)));
135  }
136 
137  void allocBytes(size_t numBytes, bool clear = false)
138  {
139  free();
140  ptr_ = static_cast<T*>(clear ? CA_calloc(1, numBytes) : CA_malloc(numBytes));
141  }
142 
143  void reallocBytes(size_t numBytes)
144  {
145  ptr_ = static_cast<T*>(CA_realloc(ptr_, numBytes));
146  }
147 
148  void reallocItems(size_t numItems)
149  {
150  size_t maxItems = ~size_t(0) / sizeof(T);
151  if (numItems > maxItems) throw std::bad_alloc();
152 
153  ptr_ = static_cast<T*>(CA_realloc(ptr_, numItems * sizeof(T)));
154  }
155 
156  template <typename U>
157  CAAutoFree& operator=(CAAutoFree<U>& that)
158  {
159  set(that.release()); // take ownership
160  return *this;
161  }
162 
163  CAAutoFree& operator=(CAAutoFree& that)
164  {
165  set(that.release()); // take ownership
166  return *this;
167  }
168 
169  CAAutoFree& operator=(T* ptr)
170  {
171  set(ptr);
172  return *this;
173  }
174 
175  template <typename U>
176  CAAutoFree& operator=(U* ptr)
177  {
178  set(ptr);
179  return *this;
180  }
181 
182  T& operator*() const { return *ptr_; }
183  T* operator->() const { return ptr_; }
184 
185  T* operator()() const { return ptr_; }
186  T* get() const { return ptr_; }
187  operator T*() const { return ptr_; }
188 
189  bool operator==(CAAutoFree const& that) const { return ptr_ == that.ptr_; }
190  bool operator!=(CAAutoFree const& that) const { return ptr_ != that.ptr_; }
191  bool operator==(T* ptr) const { return ptr_ == ptr; }
192  bool operator!=(T* ptr) const { return ptr_ != ptr; }
193 
194  T* release()
195  {
196  // release ownership
197  T* result = ptr_;
198  ptr_ = 0;
199  return result;
200  }
201 
202  void set(T* ptr)
203  {
204  if (ptr != ptr_)
205  {
206  ::free(ptr_);
207  ptr_ = ptr;
208  }
209  }
210 
211  void free()
212  {
213  set(0);
214  }
215 
216 
217  // automatic conversions to allow assignment from results of functions.
218  // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
219  CAAutoFree(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
220 
221  CAAutoFree& operator=(CAPtrRef<T> ref)
222  {
223  set(ref.ptr_);
224  return *this;
225  }
226 
227  template<typename U>
228  operator CAPtrRef<U>()
229  { return CAPtrRef<U>(release()); }
230 
231  template<typename U>
232  operator CAAutoFree<U>()
233  { return CAAutoFree<U>(release()); }
234 
235 };
236 
237 
238 template <typename T>
239 class CAAutoDelete
240 {
241 private:
242  T* ptr_;
243 
244 public:
245  CAAutoDelete() : ptr_(0) {}
246 
247  explicit CAAutoDelete(T* ptr) : ptr_(ptr) {}
248 
249  template<typename U>
250  CAAutoDelete(CAAutoDelete<U>& that) : ptr_(that.release()) {} // take ownership
251 
252  // C++ std says: a template constructor is never a copy constructor
253  CAAutoDelete(CAAutoDelete<T>& that) : ptr_(that.release()) {} // take ownership
254 
255  ~CAAutoDelete() { free(); }
256 
257  template <typename U>
258  CAAutoDelete& operator=(CAAutoDelete<U>& that)
259  {
260  set(that.release()); // take ownership
261  return *this;
262  }
263 
264  CAAutoDelete& operator=(CAAutoDelete& that)
265  {
266  set(that.release()); // take ownership
267  return *this;
268  }
269 
270  CAAutoDelete& operator=(T* ptr)
271  {
272  set(ptr);
273  return *this;
274  }
275 
276  template <typename U>
277  CAAutoDelete& operator=(U* ptr)
278  {
279  set(ptr);
280  return *this;
281  }
282 
283  T& operator*() const { return *ptr_; }
284  T* operator->() const { return ptr_; }
285 
286  T* operator()() const { return ptr_; }
287  T* get() const { return ptr_; }
288  operator T*() const { return ptr_; }
289 
290  bool operator==(CAAutoDelete const& that) const { return ptr_ == that.ptr_; }
291  bool operator!=(CAAutoDelete const& that) const { return ptr_ != that.ptr_; }
292  bool operator==(T* ptr) const { return ptr_ == ptr; }
293  bool operator!=(T* ptr) const { return ptr_ != ptr; }
294 
295  T* release()
296  {
297  // release ownership
298  T* result = ptr_;
299  ptr_ = 0;
300  return result;
301  }
302 
303  void set(T* ptr)
304  {
305  if (ptr != ptr_)
306  {
307  delete ptr_;
308  ptr_ = ptr;
309  }
310  }
311 
312  void free()
313  {
314  set(0);
315  }
316 
317 
318  // automatic conversions to allow assignment from results of functions.
319  // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
320  CAAutoDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
321 
322  CAAutoDelete& operator=(CAPtrRef<T> ref)
323  {
324  set(ref.ptr_);
325  return *this;
326  }
327 
328  template<typename U>
329  operator CAPtrRef<U>()
330  { return CAPtrRef<U>(release()); }
331 
332  template<typename U>
333  operator CAAutoFree<U>()
334  { return CAAutoFree<U>(release()); }
335 
336 };
337 
338 
339 template <typename T>
340 class CAAutoArrayDelete
341 {
342 private:
343  T* ptr_;
344 
345 public:
346  CAAutoArrayDelete() : ptr_(0) {}
347 
348  explicit CAAutoArrayDelete(T* ptr) : ptr_(ptr) {}
349 
350  template<typename U>
351  CAAutoArrayDelete(CAAutoArrayDelete<U>& that) : ptr_(that.release()) {} // take ownership
352 
353  // C++ std says: a template constructor is never a copy constructor
354  CAAutoArrayDelete(CAAutoArrayDelete<T>& that) : ptr_(that.release()) {} // take ownership
355 
356  // this becomes an ambiguous call if n == 0
357  CAAutoArrayDelete(size_t n) : ptr_(new T[n]) {}
358 
359  ~CAAutoArrayDelete() { free(); }
360 
361  void alloc(size_t numItems)
362  {
363  free();
364  ptr_ = new T [numItems];
365  }
366 
367  template <typename U>
368  CAAutoArrayDelete& operator=(CAAutoArrayDelete<U>& that)
369  {
370  set(that.release()); // take ownership
371  return *this;
372  }
373 
374  CAAutoArrayDelete& operator=(CAAutoArrayDelete& that)
375  {
376  set(that.release()); // take ownership
377  return *this;
378  }
379 
380  CAAutoArrayDelete& operator=(T* ptr)
381  {
382  set(ptr);
383  return *this;
384  }
385 
386  template <typename U>
387  CAAutoArrayDelete& operator=(U* ptr)
388  {
389  set(ptr);
390  return *this;
391  }
392 
393  T& operator*() const { return *ptr_; }
394  T* operator->() const { return ptr_; }
395 
396  T* operator()() const { return ptr_; }
397  T* get() const { return ptr_; }
398  operator T*() const { return ptr_; }
399 
400  bool operator==(CAAutoArrayDelete const& that) const { return ptr_ == that.ptr_; }
401  bool operator!=(CAAutoArrayDelete const& that) const { return ptr_ != that.ptr_; }
402  bool operator==(T* ptr) const { return ptr_ == ptr; }
403  bool operator!=(T* ptr) const { return ptr_ != ptr; }
404 
405  T* release()
406  {
407  // release ownership
408  T* result = ptr_;
409  ptr_ = 0;
410  return result;
411  }
412 
413  void set(T* ptr)
414  {
415  if (ptr != ptr_)
416  {
417  delete [] ptr_;
418  ptr_ = ptr;
419  }
420  }
421 
422  void free()
423  {
424  set(0);
425  }
426 
427 
428  // automatic conversions to allow assignment from results of functions.
429  // hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
430  CAAutoArrayDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
431 
432  CAAutoArrayDelete& operator=(CAPtrRef<T> ref)
433  {
434  set(ref.ptr_);
435  return *this;
436  }
437 
438  template<typename U>
439  operator CAPtrRef<U>()
440  { return CAPtrRef<U>(release()); }
441 
442  template<typename U>
443  operator CAAutoArrayDelete<U>()
444  { return CAAutoFree<U>(release()); }
445 
446 };
447 
448 
449 
450 
451 
452 // convenience function
453 template <typename T>
454 void free(CAAutoFree<T>& p)
455 {
456  p.free();
457 }
458 
459 ////////////////////////////////////////////////////////////////////////////////////////////////////////
460 ////////////////////////////////////////////////////////////////////////////////////////////////////////
461 ////////////////////////////////////////////////////////////////////////////////////////////////////////
462 
463 #if 0
464 // example program showing ownership transfer
465 
466 CAAutoFree<char> source()
467 {
468  // source allocates and returns ownership to the caller.
469  const char* str = "this is a test";
470  size_t size = strlen(str) + 1;
471  CAAutoFree<char> captr(size, false);
472  strlcpy(captr(), str, size);
473  printf("source %08X %08X '%s'\n", &captr, captr(), captr());
474  return captr;
475 }
476 
477 void user(CAAutoFree<char> const& captr)
478 {
479  // passed by const reference. user can access the pointer but does not take ownership.
480  printf("user: %08X %08X '%s'\n", &captr, captr(), captr());
481 }
482 
483 void sink(CAAutoFree<char> captr)
484 {
485  // passed by value. sink takes ownership and frees the pointer on return.
486  printf("sink: %08X %08X '%s'\n", &captr, captr(), captr());
487 }
488 
489 
490 int main (int argc, char * const argv[])
491 {
492 
493  CAAutoFree<char> captr(source());
494  printf("main captr A %08X %08X\n", &captr, captr());
495  user(captr);
496  sink(captr);
497  printf("main captr B %08X %08X\n", &captr, captr());
498  return 0;
499 }
500 #endif
501 
502 #endif
bool TTFOUNDATION_EXPORT operator!=(const TTObject &anObject, const TTObject &anotherObject)
Compare two objects for inequality.
Definition: TTObject.cpp:173
bool TTFOUNDATION_EXPORT operator==(const TTObject &anObject, const TTObject &anotherObject)
Compare two objects for equality.
Definition: TTObject.cpp:167