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