From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- widget/cocoa/CFTypeRefPtr.h | 194 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 widget/cocoa/CFTypeRefPtr.h (limited to 'widget/cocoa/CFTypeRefPtr.h') diff --git a/widget/cocoa/CFTypeRefPtr.h b/widget/cocoa/CFTypeRefPtr.h new file mode 100644 index 0000000000..185355777e --- /dev/null +++ b/widget/cocoa/CFTypeRefPtr.h @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef CFTypeRefPtr_h +#define CFTypeRefPtr_h + +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/DbgMacro.h" +#include "mozilla/HashFunctions.h" + +// A smart pointer for CoreFoundation classes which does reference counting. +// +// Manual reference counting: +// +// UInt32 someNumber = 10; +// CFNumberRef numberObject = +// CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &someNumber); +// // do something with numberObject +// CFRelease(numberObject); +// +// Automatic reference counting using CFTypeRefPtr: +// +// UInt32 someNumber = 10; +// auto numberObject = +// CFTypeRefPtr::WrapUnderCreateRule( +// CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &someNumber)); +// // do something with numberObject +// // no CFRelease + +template +class CFTypeRefPtr { + private: + void assign_with_CFRetain(PtrT aRawPtr) { + CFRetain(aRawPtr); + assign_assuming_CFRetain(aRawPtr); + } + + void assign_assuming_CFRetain(PtrT aNewPtr) { + PtrT oldPtr = mRawPtr; + mRawPtr = aNewPtr; + if (oldPtr) { + CFRelease(oldPtr); + } + } + + private: + PtrT mRawPtr; + + public: + ~CFTypeRefPtr() { + if (mRawPtr) { + CFRelease(mRawPtr); + } + } + + // Constructors + + CFTypeRefPtr() : mRawPtr(nullptr) {} + + CFTypeRefPtr(const CFTypeRefPtr& aSmartPtr) + : mRawPtr(aSmartPtr.mRawPtr) { + if (mRawPtr) { + CFRetain(mRawPtr); + } + } + + CFTypeRefPtr(CFTypeRefPtr&& aRefPtr) : mRawPtr(aRefPtr.mRawPtr) { + aRefPtr.mRawPtr = nullptr; + } + + MOZ_IMPLICIT CFTypeRefPtr(decltype(nullptr)) : mRawPtr(nullptr) {} + + // There is no constructor from a raw pointer value. + // Use one of the static WrapUnder*Rule methods below instead. + + static CFTypeRefPtr WrapUnderCreateRule(PtrT aRawPtr) { + CFTypeRefPtr ptr; + ptr.AssignUnderCreateRule(aRawPtr); + return ptr; + } + + static CFTypeRefPtr WrapUnderGetRule(PtrT aRawPtr) { + CFTypeRefPtr ptr; + ptr.AssignUnderGetRule(aRawPtr); + return ptr; + } + + // Assignment operators + + CFTypeRefPtr& operator=(decltype(nullptr)) { + assign_assuming_CFRetain(nullptr); + return *this; + } + + CFTypeRefPtr& operator=(const CFTypeRefPtr& aRhs) { + assign_with_CFRetain(aRhs.mRawPtr); + return *this; + } + + CFTypeRefPtr& operator=(CFTypeRefPtr&& aRefPtr) { + assign_assuming_CFRetain(aRefPtr.mRawPtr); + aRefPtr.mRawPtr = nullptr; + return *this; + } + + // There is no operator= for a raw pointer value. + // Use one of the AssignUnder*Rule methods below instead. + + CFTypeRefPtr& AssignUnderCreateRule(PtrT aRawPtr) { + // Freshly-created objects come with a retain count of 1. + assign_assuming_CFRetain(aRawPtr); + return *this; + } + + CFTypeRefPtr& AssignUnderGetRule(PtrT aRawPtr) { + assign_with_CFRetain(aRawPtr); + return *this; + } + + // Other pointer operators + + // This is the only way to get the raw pointer out of the smart pointer. + // There is no implicit conversion to a raw pointer. + PtrT get() const { return mRawPtr; } + + // Don't allow implicit conversion of temporary CFTypeRefPtr to raw pointer, + // because the refcount might be one and the pointer will immediately become + // invalid. + operator PtrT() const&& = delete; + // Also don't allow implicit conversion of non-temporary CFTypeRefPtr. + operator PtrT() const& = delete; + + // These let you null-check a pointer without calling get(). + explicit operator bool() const { return !!mRawPtr; } +}; + +template +inline bool operator==(const CFTypeRefPtr& aLhs, + const CFTypeRefPtr& aRhs) { + return aLhs.get() == aRhs.get(); +} + +template +inline bool operator!=(const CFTypeRefPtr& aLhs, + const CFTypeRefPtr& aRhs) { + return !(aLhs == aRhs); +} + +// Comparing an |CFTypeRefPtr| to |nullptr| + +template +inline bool operator==(const CFTypeRefPtr& aLhs, decltype(nullptr)) { + return aLhs.get() == nullptr; +} + +template +inline bool operator==(decltype(nullptr), const CFTypeRefPtr& aRhs) { + return nullptr == aRhs.get(); +} + +template +inline bool operator!=(const CFTypeRefPtr& aLhs, decltype(nullptr)) { + return aLhs.get() != nullptr; +} + +template +inline bool operator!=(decltype(nullptr), const CFTypeRefPtr& aRhs) { + return nullptr != aRhs.get(); +} + +// MOZ_DBG support + +template +std::ostream& operator<<(std::ostream& aOut, const CFTypeRefPtr& aObj) { + return mozilla::DebugValue(aOut, aObj.get()); +} + +// std::hash support (e.g. for unordered_map) +namespace std { +template +struct hash> { + typedef CFTypeRefPtr argument_type; + typedef std::size_t result_type; + result_type operator()(argument_type const& aPtr) const { + return mozilla::HashGeneric(reinterpret_cast(aPtr.get())); + } +}; +} // namespace std + +#endif /* CFTypeRefPtr_h */ -- cgit v1.2.3