blob: a904cd0ea6f07b23e4ad17fa219af791e77882f6 [file] [log] [blame]
Todd Fialae77fce02016-09-04 00:18:56 +00001//===-- 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//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000026template <class T> class CFReleaser {
Todd Fialae77fce02016-09-04 00:18:56 +000027public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000028 // Type names for the avlue
29 typedef T element_type;
Todd Fialae77fce02016-09-04 00:18:56 +000030
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 // Constructors and destructors
32 CFReleaser(T ptr = NULL) : _ptr(ptr) {}
33 CFReleaser(const CFReleaser &copy) : _ptr(copy.get()) {
34 if (get())
35 ::CFRetain(get());
36 }
37 virtual ~CFReleaser() { reset(); }
Todd Fialae77fce02016-09-04 00:18:56 +000038
Kate Stoneb9c1b512016-09-06 20:57:50 +000039 // Assignments
40 CFReleaser &operator=(const CFReleaser<T> &copy) {
41 if (copy != *this) {
42 // Replace our owned pointer with the new one
43 reset(copy.get());
44 // Retain the current pointer that we own
45 if (get())
46 ::CFRetain(get());
47 }
48 }
49 // Get the address of the contained type
50 T *ptr_address() { return &_ptr; }
Todd Fialae77fce02016-09-04 00:18:56 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052 // Access the pointer itself
53 const T get() const { return _ptr; }
54 T get() { return _ptr; }
Todd Fialae77fce02016-09-04 00:18:56 +000055
Kate Stoneb9c1b512016-09-06 20:57:50 +000056 // Set a new value for the pointer and CFRelease our old
57 // value if we had a valid one.
58 void reset(T ptr = NULL) {
59 if (ptr != _ptr) {
60 if (_ptr != NULL)
61 ::CFRelease(_ptr);
62 _ptr = ptr;
63 }
64 }
Todd Fialae77fce02016-09-04 00:18:56 +000065
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 // Release ownership without calling CFRelease
67 T release() {
68 T tmp = _ptr;
69 _ptr = NULL;
70 return tmp;
71 }
72
Todd Fialae77fce02016-09-04 00:18:56 +000073private:
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 element_type _ptr;
Todd Fialae77fce02016-09-04 00:18:56 +000075};
76
Kate Stoneb9c1b512016-09-06 20:57:50 +000077#endif // #ifdef __cplusplus
78#endif // #ifndef __CFUtils_h__