blob: 9dae40670f3426afda40bcf847997ba733a32259 [file] [log] [blame]
Todd Fialae77fce02016-09-04 00:18:56 +00001//===-- CFUtils.h -----------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Todd Fialae77fce02016-09-04 00:18:56 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Created by Greg Clayton on 3/5/07.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef __CFUtils_h__
14#define __CFUtils_h__
15
16#include <CoreFoundation/CoreFoundation.h>
17
18#ifdef __cplusplus
19
20//----------------------------------------------------------------------
21// Templatized CF helper class that can own any CF pointer and will
22// call CFRelease() on any valid pointer it owns unless that pointer is
23// explicitly released using the release() member function.
24//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000025template <class T> class CFReleaser {
Todd Fialae77fce02016-09-04 00:18:56 +000026public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000027 // Type names for the avlue
28 typedef T element_type;
Todd Fialae77fce02016-09-04 00:18:56 +000029
Kate Stoneb9c1b512016-09-06 20:57:50 +000030 // Constructors and destructors
31 CFReleaser(T ptr = NULL) : _ptr(ptr) {}
32 CFReleaser(const CFReleaser &copy) : _ptr(copy.get()) {
33 if (get())
34 ::CFRetain(get());
35 }
36 virtual ~CFReleaser() { reset(); }
Todd Fialae77fce02016-09-04 00:18:56 +000037
Kate Stoneb9c1b512016-09-06 20:57:50 +000038 // Assignments
39 CFReleaser &operator=(const CFReleaser<T> &copy) {
40 if (copy != *this) {
41 // Replace our owned pointer with the new one
42 reset(copy.get());
43 // Retain the current pointer that we own
44 if (get())
45 ::CFRetain(get());
46 }
47 }
48 // Get the address of the contained type
49 T *ptr_address() { return &_ptr; }
Todd Fialae77fce02016-09-04 00:18:56 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051 // Access the pointer itself
52 const T get() const { return _ptr; }
53 T get() { return _ptr; }
Todd Fialae77fce02016-09-04 00:18:56 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 // Set a new value for the pointer and CFRelease our old
56 // value if we had a valid one.
57 void reset(T ptr = NULL) {
58 if (ptr != _ptr) {
59 if (_ptr != NULL)
60 ::CFRelease(_ptr);
61 _ptr = ptr;
62 }
63 }
Todd Fialae77fce02016-09-04 00:18:56 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 // Release ownership without calling CFRelease
66 T release() {
67 T tmp = _ptr;
68 _ptr = NULL;
69 return tmp;
70 }
71
Todd Fialae77fce02016-09-04 00:18:56 +000072private:
Kate Stoneb9c1b512016-09-06 20:57:50 +000073 element_type _ptr;
Todd Fialae77fce02016-09-04 00:18:56 +000074};
75
Kate Stoneb9c1b512016-09-06 20:57:50 +000076#endif // #ifdef __cplusplus
77#endif // #ifndef __CFUtils_h__