diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/api/scoped_refptr.h | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/api/scoped_refptr.h')
-rw-r--r-- | third_party/libwebrtc/api/scoped_refptr.h | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/scoped_refptr.h b/third_party/libwebrtc/api/scoped_refptr.h new file mode 100644 index 0000000000..e145509127 --- /dev/null +++ b/third_party/libwebrtc/api/scoped_refptr.h @@ -0,0 +1,222 @@ +/* + * Copyright 2011 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. + */ + +// Originally these classes are from Chromium. +// http://src.chromium.org/viewvc/chrome/trunk/src/base/memory/ref_counted.h?view=markup + +// +// A smart pointer class for reference counted objects. Use this class instead +// of calling AddRef and Release manually on a reference counted object to +// avoid common memory leaks caused by forgetting to Release an object +// reference. Sample usage: +// +// class MyFoo : public RefCounted<MyFoo> { +// ... +// }; +// +// void some_function() { +// scoped_refptr<MyFoo> foo = new MyFoo(); +// foo->Method(param); +// // `foo` is released when this function returns +// } +// +// void some_other_function() { +// scoped_refptr<MyFoo> foo = new MyFoo(); +// ... +// foo = nullptr; // explicitly releases `foo` +// ... +// if (foo) +// foo->Method(param); +// } +// +// The above examples show how scoped_refptr<T> acts like a pointer to T. +// Given two scoped_refptr<T> classes, it is also possible to exchange +// references between the two objects, like so: +// +// { +// scoped_refptr<MyFoo> a = new MyFoo(); +// scoped_refptr<MyFoo> b; +// +// b.swap(a); +// // now, `b` references the MyFoo object, and `a` references null. +// } +// +// To make both `a` and `b` in the above example reference the same MyFoo +// object, simply use the assignment operator: +// +// { +// scoped_refptr<MyFoo> a = new MyFoo(); +// scoped_refptr<MyFoo> b; +// +// b = a; +// // now, `a` and `b` each own a reference to the same MyFoo object. +// } +// + +#ifndef API_SCOPED_REFPTR_H_ +#define API_SCOPED_REFPTR_H_ + +#include <memory> +#include <utility> + +namespace rtc { + +template <class T> +class scoped_refptr { + public: + typedef T element_type; + + scoped_refptr() : ptr_(nullptr) {} + scoped_refptr(std::nullptr_t) : ptr_(nullptr) {} // NOLINT(runtime/explicit) + + explicit scoped_refptr(T* p) : ptr_(p) { + if (ptr_) + ptr_->AddRef(); + } + + scoped_refptr(const scoped_refptr<T>& r) : ptr_(r.ptr_) { + if (ptr_) + ptr_->AddRef(); + } + + template <typename U> + scoped_refptr(const scoped_refptr<U>& r) : ptr_(r.get()) { + if (ptr_) + ptr_->AddRef(); + } + + // Move constructors. + scoped_refptr(scoped_refptr<T>&& r) noexcept : ptr_(r.release()) {} + + template <typename U> + scoped_refptr(scoped_refptr<U>&& r) noexcept : ptr_(r.release()) {} + + ~scoped_refptr() { + if (ptr_) + ptr_->Release(); + } + + T* get() const { return ptr_; } + explicit operator bool() const { return ptr_ != nullptr; } + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + + // Returns the (possibly null) raw pointer, and makes the scoped_refptr hold a + // null pointer, all without touching the reference count of the underlying + // pointed-to object. The object is still reference counted, and the caller of + // release() is now the proud owner of one reference, so it is responsible for + // calling Release() once on the object when no longer using it. + T* release() { + T* retVal = ptr_; + ptr_ = nullptr; + return retVal; + } + + scoped_refptr<T>& operator=(T* p) { + // AddRef first so that self assignment should work + if (p) + p->AddRef(); + if (ptr_) + ptr_->Release(); + ptr_ = p; + return *this; + } + + scoped_refptr<T>& operator=(const scoped_refptr<T>& r) { + return *this = r.ptr_; + } + + template <typename U> + scoped_refptr<T>& operator=(const scoped_refptr<U>& r) { + return *this = r.get(); + } + + scoped_refptr<T>& operator=(scoped_refptr<T>&& r) noexcept { + scoped_refptr<T>(std::move(r)).swap(*this); + return *this; + } + + template <typename U> + scoped_refptr<T>& operator=(scoped_refptr<U>&& r) noexcept { + scoped_refptr<T>(std::move(r)).swap(*this); + return *this; + } + + void swap(T** pp) noexcept { + T* p = ptr_; + ptr_ = *pp; + *pp = p; + } + + void swap(scoped_refptr<T>& r) noexcept { swap(&r.ptr_); } + + protected: + T* ptr_; +}; + +template <typename T, typename U> +bool operator==(const rtc::scoped_refptr<T>& a, + const rtc::scoped_refptr<U>& b) { + return a.get() == b.get(); +} +template <typename T, typename U> +bool operator!=(const rtc::scoped_refptr<T>& a, + const rtc::scoped_refptr<U>& b) { + return !(a == b); +} + +template <typename T> +bool operator==(const rtc::scoped_refptr<T>& a, std::nullptr_t) { + return a.get() == nullptr; +} + +template <typename T> +bool operator!=(const rtc::scoped_refptr<T>& a, std::nullptr_t) { + return !(a == nullptr); +} + +template <typename T> +bool operator==(std::nullptr_t, const rtc::scoped_refptr<T>& a) { + return a.get() == nullptr; +} + +template <typename T> +bool operator!=(std::nullptr_t, const rtc::scoped_refptr<T>& a) { + return !(a == nullptr); +} + +// Comparison with raw pointer. +template <typename T, typename U> +bool operator==(const rtc::scoped_refptr<T>& a, const U* b) { + return a.get() == b; +} +template <typename T, typename U> +bool operator!=(const rtc::scoped_refptr<T>& a, const U* b) { + return !(a == b); +} + +template <typename T, typename U> +bool operator==(const T* a, const rtc::scoped_refptr<U>& b) { + return a == b.get(); +} +template <typename T, typename U> +bool operator!=(const T* a, const rtc::scoped_refptr<U>& b) { + return !(a == b); +} + +// Ordered comparison, needed for use as a std::map key. +template <typename T, typename U> +bool operator<(const rtc::scoped_refptr<T>& a, const rtc::scoped_refptr<U>& b) { + return a.get() < b.get(); +} + +} // namespace rtc + +#endif // API_SCOPED_REFPTR_H_ |