1061da546Spatrick //===-- CFUtils.h -----------------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick // 9061da546Spatrick // Created by Greg Clayton on 3/5/07. 10061da546Spatrick // 11061da546Spatrick //===----------------------------------------------------------------------===// 12061da546Spatrick 13*dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFUTILS_H 14*dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFUTILS_H 15061da546Spatrick 16061da546Spatrick #include <CoreFoundation/CoreFoundation.h> 17061da546Spatrick 18061da546Spatrick #ifdef __cplusplus 19061da546Spatrick 20061da546Spatrick // Templatized CF helper class that can own any CF pointer and will 21061da546Spatrick // call CFRelease() on any valid pointer it owns unless that pointer is 22061da546Spatrick // explicitly released using the release() member function. 23061da546Spatrick template <class T> class CFReleaser { 24061da546Spatrick public: 25*dda28197Spatrick // Type names for the value 26061da546Spatrick typedef T element_type; 27061da546Spatrick 28061da546Spatrick // Constructors and destructors _ptr(ptr)29061da546Spatrick CFReleaser(T ptr = NULL) : _ptr(ptr) {} CFReleaser(const CFReleaser & copy)30061da546Spatrick CFReleaser(const CFReleaser ©) : _ptr(copy.get()) { 31061da546Spatrick if (get()) 32061da546Spatrick ::CFRetain(get()); 33061da546Spatrick } ~CFReleaser()34061da546Spatrick virtual ~CFReleaser() { reset(); } 35061da546Spatrick 36061da546Spatrick // Assignments 37061da546Spatrick CFReleaser &operator=(const CFReleaser<T> ©) { 38061da546Spatrick if (copy != *this) { 39061da546Spatrick // Replace our owned pointer with the new one 40061da546Spatrick reset(copy.get()); 41061da546Spatrick // Retain the current pointer that we own 42061da546Spatrick if (get()) 43061da546Spatrick ::CFRetain(get()); 44061da546Spatrick } 45061da546Spatrick } 46061da546Spatrick // Get the address of the contained type ptr_address()47061da546Spatrick T *ptr_address() { return &_ptr; } 48061da546Spatrick 49061da546Spatrick // Access the pointer itself get()50061da546Spatrick const T get() const { return _ptr; } get()51061da546Spatrick T get() { return _ptr; } 52061da546Spatrick 53061da546Spatrick // Set a new value for the pointer and CFRelease our old 54061da546Spatrick // value if we had a valid one. 55061da546Spatrick void reset(T ptr = NULL) { 56061da546Spatrick if (ptr != _ptr) { 57061da546Spatrick if (_ptr != NULL) 58061da546Spatrick ::CFRelease(_ptr); 59061da546Spatrick _ptr = ptr; 60061da546Spatrick } 61061da546Spatrick } 62061da546Spatrick 63061da546Spatrick // Release ownership without calling CFRelease release()64061da546Spatrick T release() { 65061da546Spatrick T tmp = _ptr; 66061da546Spatrick _ptr = NULL; 67061da546Spatrick return tmp; 68061da546Spatrick } 69061da546Spatrick 70061da546Spatrick private: 71061da546Spatrick element_type _ptr; 72061da546Spatrick }; 73061da546Spatrick 74061da546Spatrick #endif // #ifdef __cplusplus 75*dda28197Spatrick #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_CFUTILS_H 76