1 //===-- CFUtils.h -----------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  Created by Greg Clayton on 3/5/07.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef __CFUtils_h__
15 #define __CFUtils_h__
16 
17 #include <CoreFoundation/CoreFoundation.h>
18 
19 #ifdef __cplusplus
20 
21 //----------------------------------------------------------------------
22 // Templatized CF helper class that can own any CF pointer and will
23 // call CFRelease() on any valid pointer it owns unless that pointer is
24 // explicitly released using the release() member function.
25 //----------------------------------------------------------------------
26 template <class T>
27 class CFReleaser
28 {
29 public:
30             // Type names for the avlue
31             typedef T element_type;
32 
33             // Constructors and destructors
_ptr(ptr)34             CFReleaser(T ptr = NULL) : _ptr(ptr) { }
CFReleaser(const CFReleaser & copy)35             CFReleaser(const CFReleaser& copy) : _ptr(copy.get())
36             {
37                 if (get())
38                     ::CFRetain(get());
39             }
~CFReleaser()40             virtual ~CFReleaser() { reset(); }
41 
42             // Assignments
43             CFReleaser& operator= (const CFReleaser<T>& copy)
44             {
45                 if (copy != *this)
46                 {
47                     // Replace our owned pointer with the new one
48                     reset(copy.get());
49                     // Retain the current pointer that we own
50                     if (get())
51                         ::CFRetain(get());
52                 }
53             }
54             // Get the address of the contained type
ptr_address()55             T *     ptr_address()   { return &_ptr; }
56 
57             // Access the pointer itself
get()58     const   T       get() const     { return _ptr;  }
get()59             T       get()           { return _ptr;  }
60 
61             // Set a new value for the pointer and CFRelease our old
62             // value if we had a valid one.
63             void    reset(T ptr = NULL)
64                     {
65                         if (ptr != _ptr)
66                         {
67                             if (_ptr != NULL)
68                                 ::CFRelease(_ptr);
69                             _ptr = ptr;
70                         }
71                     }
72 
73             // Release ownership without calling CFRelease
release()74             T    release() { T tmp = _ptr; _ptr = NULL; return tmp; }
75 private:
76     element_type _ptr;
77 };
78 
79 #endif    // #ifdef __cplusplus
80 #endif    // #ifndef __CFUtils_h__
81 
82