/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Host/macosx/cfcpp/CFCReleaser.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- CFCReleaser.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 | | #ifndef LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCRELEASER_H |
10 | | #define LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCRELEASER_H |
11 | | |
12 | | #include <CoreFoundation/CoreFoundation.h> |
13 | | |
14 | | #include <cassert> |
15 | | |
16 | | // Templatized CF helper class that can own any CF pointer and will |
17 | | // call CFRelease() on any valid pointer it owns unless that pointer is |
18 | | // explicitly released using the release() member function. This class |
19 | | // is designed to mimic the std::auto_ptr<T> class and has all of the |
20 | | // same functions. The one thing to watch out for is the |
21 | | // CFCReleaser<T>::release() function won't actually CFRelease any owned |
22 | | // pointer, it is designed to relinquish ownership of the pointer just |
23 | | // like std:auto_ptr<T>::release() does. |
24 | | template <class T> class CFCReleaser { |
25 | | public: |
26 | | // Constructor that takes a pointer to a CF object that is |
27 | | // to be released when this object goes out of scope |
28 | 1.27k | CFCReleaser(T ptr = NULL) : _ptr(ptr) {} CFCReleaser<__CFBundle*>::CFCReleaser(__CFBundle*) Line | Count | Source | 28 | 2 | CFCReleaser(T ptr = NULL) : _ptr(ptr) {} |
CFCReleaser<__CFData const*>::CFCReleaser(__CFData const*) Line | Count | Source | 28 | 10 | CFCReleaser(T ptr = NULL) : _ptr(ptr) {} |
Unexecuted instantiation: CFCReleaser<__CFWriteStream*>::CFCReleaser(__CFWriteStream*) CFCReleaser<__CFString const*>::CFCReleaser(__CFString const*) Line | Count | Source | 28 | 12 | CFCReleaser(T ptr = NULL) : _ptr(ptr) {} |
CFCReleaser<__CFUUID const*>::CFCReleaser(__CFUUID const*) Line | Count | Source | 28 | 412 | CFCReleaser(T ptr = NULL) : _ptr(ptr) {} |
CFCReleaser<__CFDictionary const*>::CFCReleaser(__CFDictionary const*) Line | Count | Source | 28 | 10 | CFCReleaser(T ptr = NULL) : _ptr(ptr) {} |
CFCReleaser<__CFURL const*>::CFCReleaser(__CFURL const*) Line | Count | Source | 28 | 828 | CFCReleaser(T ptr = NULL) : _ptr(ptr) {} |
Unexecuted instantiation: CFCReleaser<__CFArray const*>::CFCReleaser(__CFArray const*) |
29 | | |
30 | | // Copy constructor |
31 | | // |
32 | | // Note that copying a CFCReleaser will not transfer |
33 | | // ownership of the contained pointer, but it will bump its |
34 | | // reference count. This is where this class differs from |
35 | | // std::auto_ptr. |
36 | 0 | CFCReleaser(const CFCReleaser &rhs) : _ptr(rhs.get()) { |
37 | 0 | if (get()) |
38 | 0 | ::CFRetain(get()); |
39 | 0 | } Unexecuted instantiation: CFCReleaser<__CFData const*>::CFCReleaser(CFCReleaser<__CFData const*> const&) Unexecuted instantiation: CFCReleaser<__CFString const*>::CFCReleaser(CFCReleaser<__CFString const*> const&) |
40 | | |
41 | | // The destructor will release the pointer that it contains |
42 | | // if it has a valid pointer. |
43 | 1.27k | virtual ~CFCReleaser() { reset(); } CFCReleaser<__CFBundle*>::~CFCReleaser() Line | Count | Source | 43 | 2 | virtual ~CFCReleaser() { reset(); } |
CFCReleaser<__CFData const*>::~CFCReleaser() Line | Count | Source | 43 | 10 | virtual ~CFCReleaser() { reset(); } |
Unexecuted instantiation: CFCReleaser<__CFWriteStream*>::~CFCReleaser() CFCReleaser<__CFString const*>::~CFCReleaser() Line | Count | Source | 43 | 12 | virtual ~CFCReleaser() { reset(); } |
CFCReleaser<__CFUUID const*>::~CFCReleaser() Line | Count | Source | 43 | 412 | virtual ~CFCReleaser() { reset(); } |
CFCReleaser<__CFDictionary const*>::~CFCReleaser() Line | Count | Source | 43 | 10 | virtual ~CFCReleaser() { reset(); } |
CFCReleaser<__CFURL const*>::~CFCReleaser() Line | Count | Source | 43 | 828 | virtual ~CFCReleaser() { reset(); } |
Unexecuted instantiation: CFCReleaser<__CFArray const*>::~CFCReleaser() |
44 | | |
45 | | // Assignment operator. |
46 | | // |
47 | | // Note that assigning one CFCReleaser to another will |
48 | | // not transfer ownership of the contained pointer, but it |
49 | | // will bump its reference count. This is where this class |
50 | | // differs from std::auto_ptr. |
51 | | CFCReleaser &operator=(const CFCReleaser<T> &rhs) { |
52 | | if (this != &rhs) { |
53 | | // Replace our owned pointer with the new one |
54 | | reset(rhs.get()); |
55 | | // Retain the current pointer that we own |
56 | | if (get()) |
57 | | ::CFRetain(get()); |
58 | | } |
59 | | return *this; |
60 | | } |
61 | | |
62 | | // Get the address of the contained type in case it needs |
63 | | // to be passed to a function that will fill in a pointer |
64 | | // value. The function currently will assert if _ptr is not |
65 | | // NULL because the only time this method should be used is |
66 | | // if another function will modify the contents, and we |
67 | | // could leak a pointer if this is not NULL. If the |
68 | | // assertion fires, check the offending code, or call |
69 | | // reset() prior to using the "ptr_address()" member to make |
70 | | // sure any owned objects has CFRelease called on it. |
71 | | // I had to add the "enforce_null" bool here because some |
72 | | // API's require the pointer address even though they don't change it. |
73 | | T *ptr_address(bool enforce_null = true) { |
74 | | if (enforce_null) |
75 | | assert(_ptr == NULL); |
76 | | return &_ptr; |
77 | | } |
78 | | |
79 | | // Access the pointer itself |
80 | 1.71k | T get() { return _ptr; } CFCReleaser<__CFBundle*>::get() Line | Count | Source | 80 | 2 | T get() { return _ptr; } |
Unexecuted instantiation: CFCReleaser<__CFWriteStream*>::get() CFCReleaser<__CFUUID const*>::get() Line | Count | Source | 80 | 824 | T get() { return _ptr; } |
CFCReleaser<__CFDictionary const*>::get() Line | Count | Source | 80 | 30 | T get() { return _ptr; } |
CFCReleaser<__CFData const*>::get() Line | Count | Source | 80 | 10 | T get() { return _ptr; } |
CFCReleaser<__CFURL const*>::get() Line | Count | Source | 80 | 832 | T get() { return _ptr; } |
CFCReleaser<__CFString const*>::get() Line | Count | Source | 80 | 16 | T get() { return _ptr; } |
Unexecuted instantiation: CFCReleaser<__CFArray const*>::get() |
81 | | |
82 | 2 | const T get() const { return _ptr; } CFCReleaser<__CFBundle*>::get() const Line | Count | Source | 82 | 2 | const T get() const { return _ptr; } |
Unexecuted instantiation: CFCReleaser<__CFData const*>::get() const Unexecuted instantiation: CFCReleaser<__CFString const*>::get() const |
83 | | |
84 | | // Set a new value for the pointer and CFRelease our old |
85 | | // value if we had a valid one. |
86 | 1.70k | void reset(T ptr = NULL) { |
87 | 1.70k | if ((_ptr != NULL) && (ptr != _ptr)862 ) |
88 | 862 | ::CFRelease(_ptr); |
89 | 1.70k | _ptr = ptr; |
90 | 1.70k | } CFCReleaser<__CFBundle*>::reset(__CFBundle*) Line | Count | Source | 86 | 6 | void reset(T ptr = NULL) { | 87 | 6 | if ((_ptr != NULL) && (ptr != _ptr)2 ) | 88 | 2 | ::CFRelease(_ptr); | 89 | 6 | _ptr = ptr; | 90 | 6 | } |
CFCReleaser<__CFData const*>::reset(__CFData const*) Line | Count | Source | 86 | 10 | void reset(T ptr = NULL) { | 87 | 10 | if ((_ptr != NULL) && (ptr != _ptr)) | 88 | 10 | ::CFRelease(_ptr); | 89 | 10 | _ptr = ptr; | 90 | 10 | } |
Unexecuted instantiation: CFCReleaser<__CFWriteStream*>::reset(__CFWriteStream*) CFCReleaser<__CFString const*>::reset(__CFString const*) Line | Count | Source | 86 | 24 | void reset(T ptr = NULL) { | 87 | 24 | if ((_ptr != NULL) && (ptr != _ptr)12 ) | 88 | 12 | ::CFRelease(_ptr); | 89 | 24 | _ptr = ptr; | 90 | 24 | } |
CFCReleaser<__CFUUID const*>::reset(__CFUUID const*) Line | Count | Source | 86 | 412 | void reset(T ptr = NULL) { | 87 | 412 | if ((_ptr != NULL) && (ptr != _ptr)) | 88 | 412 | ::CFRelease(_ptr); | 89 | 412 | _ptr = ptr; | 90 | 412 | } |
CFCReleaser<__CFDictionary const*>::reset(__CFDictionary const*) Line | Count | Source | 86 | 10 | void reset(T ptr = NULL) { | 87 | 10 | if ((_ptr != NULL) && (ptr != _ptr)) | 88 | 10 | ::CFRelease(_ptr); | 89 | 10 | _ptr = ptr; | 90 | 10 | } |
CFCReleaser<__CFURL const*>::reset(__CFURL const*) Line | Count | Source | 86 | 1.24k | void reset(T ptr = NULL) { | 87 | 1.24k | if ((_ptr != NULL) && (ptr != _ptr)416 ) | 88 | 416 | ::CFRelease(_ptr); | 89 | 1.24k | _ptr = ptr; | 90 | 1.24k | } |
Unexecuted instantiation: CFCReleaser<__CFArray const*>::reset(__CFArray const*) |
91 | | |
92 | | // Release ownership without calling CFRelease. This class |
93 | | // is designed to mimic std::auto_ptr<T>, so the release |
94 | | // method releases ownership of the contained pointer |
95 | | // and does NOT call CFRelease. |
96 | | T release() { |
97 | | T tmp = _ptr; |
98 | | _ptr = NULL; |
99 | | return tmp; |
100 | | } |
101 | | |
102 | | private: |
103 | | T _ptr; |
104 | | }; |
105 | | |
106 | | #endif // LLDB_SOURCE_HOST_MACOSX_CFCPP_CFCRELEASER_H |