diff options
Diffstat (limited to 'third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h')
-rw-r--r-- | third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h b/third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h new file mode 100644 index 0000000000..092f02b3af --- /dev/null +++ b/third_party/libwebrtc/sdk/objc/helpers/scoped_cftyperef.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + * + */ + +#ifndef SDK_OBJC_HELPERS_SCOPED_CFTYPEREF_H_ +#define SDK_OBJC_HELPERS_SCOPED_CFTYPEREF_H_ + +#include <CoreFoundation/CoreFoundation.h> +namespace rtc { + +// RETAIN: ScopedTypeRef should retain the object when it takes +// ownership. +// ASSUME: Assume the object already has already been retained. +// ScopedTypeRef takes over ownership. +enum class RetainPolicy { RETAIN, ASSUME }; + +namespace internal { +template <typename T> +struct CFTypeRefTraits { + static T InvalidValue() { return nullptr; } + static void Release(T ref) { CFRelease(ref); } + static T Retain(T ref) { + CFRetain(ref); + return ref; + } +}; + +template <typename T, typename Traits> +class ScopedTypeRef { + public: + ScopedTypeRef() : ptr_(Traits::InvalidValue()) {} + explicit ScopedTypeRef(T ptr) : ptr_(ptr) {} + ScopedTypeRef(T ptr, RetainPolicy policy) : ScopedTypeRef(ptr) { + if (ptr_ && policy == RetainPolicy::RETAIN) + Traits::Retain(ptr_); + } + + ScopedTypeRef(const ScopedTypeRef<T, Traits>& rhs) : ptr_(rhs.ptr_) { + if (ptr_) + ptr_ = Traits::Retain(ptr_); + } + + ~ScopedTypeRef() { + if (ptr_) { + Traits::Release(ptr_); + } + } + + T get() const { return ptr_; } + T operator->() const { return ptr_; } + explicit operator bool() const { return ptr_; } + + bool operator!() const { return !ptr_; } + + ScopedTypeRef& operator=(const T& rhs) { + if (ptr_) + Traits::Release(ptr_); + ptr_ = rhs; + return *this; + } + + ScopedTypeRef& operator=(const ScopedTypeRef<T, Traits>& rhs) { + reset(rhs.get(), RetainPolicy::RETAIN); + return *this; + } + + // This is intended to take ownership of objects that are + // created by pass-by-pointer initializers. + T* InitializeInto() { + RTC_DCHECK(!ptr_); + return &ptr_; + } + + void reset(T ptr, RetainPolicy policy = RetainPolicy::ASSUME) { + if (ptr && policy == RetainPolicy::RETAIN) + Traits::Retain(ptr); + if (ptr_) + Traits::Release(ptr_); + ptr_ = ptr; + } + + T release() { + T temp = ptr_; + ptr_ = Traits::InvalidValue(); + return temp; + } + + private: + T ptr_; +}; +} // namespace internal + +template <typename T> +using ScopedCFTypeRef = + internal::ScopedTypeRef<T, internal::CFTypeRefTraits<T>>; + +template <typename T> +static ScopedCFTypeRef<T> AdoptCF(T cftype) { + return ScopedCFTypeRef<T>(cftype, RetainPolicy::RETAIN); +} + +template <typename T> +static ScopedCFTypeRef<T> ScopedCF(T cftype) { + return ScopedCFTypeRef<T>(cftype); +} + +} // namespace rtc + +#endif // SDK_OBJC_HELPERS_SCOPED_CFTYPEREF_H_ |