/* -*- 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/. */
class nsQueryReferent; class nsCOMPtr_helper; class nsISupports;
namespace mozilla { template <class T> class MovingNotNull; template <class T> class NotNull; template <class T> class OwningNonNull; template <class T> class StaticLocalRefPtr; template <class T> class StaticRefPtr;
// Traditionally, RefPtr supports automatic refcounting of any pointer type // with AddRef() and Release() methods that follow the traditional semantics. // // This traits class can be specialized to operate on other pointer types. For // example, we specialize this trait for opaque FFI types that represent // refcounted objects in Rust. // // Given the use of ConstRemovingRefPtrTraits below, U should not be a const- // qualified type. template <class U> struct RefPtrTraits { staticvoid AddRef(U* aPtr) { aPtr->AddRef(); } staticvoid Release(U* aPtr) { aPtr->Release(); }
};
} // namespace mozilla
template <class T> class MOZ_IS_REFPTR RefPtr { private: void assign_with_AddRef(T* aRawPtr) { if (aRawPtr) {
ConstRemovingRefPtrTraits<T>::AddRef(aRawPtr);
}
assign_assuming_AddRef(aRawPtr);
}
template <typename I, typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
MOZ_IMPLICIT RefPtr(already_AddRefed<I>& aSmartPtr)
: mRawPtr(aSmartPtr.take()) // construct from |already_AddRefed|
{}
template <typename I, typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
MOZ_IMPLICIT RefPtr(already_AddRefed<I>&& aSmartPtr)
: mRawPtr(aSmartPtr.take()) // construct from |otherRefPtr.forget()|
{}
template <typename I, typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
MOZ_IMPLICIT RefPtr(const RefPtr<I>& aSmartPtr)
: mRawPtr(aSmartPtr.get()) // copy-construct from a smart pointer with a related pointer type
{ if (mRawPtr) {
ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
}
}
template <typename I, typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
MOZ_IMPLICIT RefPtr(RefPtr<I>&& aSmartPtr)
: mRawPtr(aSmartPtr.forget().take()) // construct from |Move(RefPtr<SomeSubclassOfT>)|.
{}
template <typename I>
RefPtr<T>& operator=(const RefPtr<I>& aRhs) // assign from an RefPtr of a related pointer type
{
assign_with_AddRef(aRhs.get()); return *this;
}
RefPtr<T>& operator=(T* aRhs) // assign from a raw pointer (of the right type)
{
assign_with_AddRef(aRhs); return *this;
}
template <typename I, typename = std::enable_if_t<std::is_convertible_v<I, RefPtr<T>>>>
RefPtr<T>& operator=(const mozilla::NotNull<I>& aSmartPtr) // assign from |mozilla::NotNull|.
{
assign_assuming_AddRef(RefPtr<T>(aSmartPtr.get()).forget().take()); return *this;
}
template <typename I, typename = std::enable_if_t<std::is_convertible_v<I, RefPtr<T>>>>
RefPtr<T>& operator=(mozilla::MovingNotNull<I>&& aSmartPtr) // assign from |mozilla::MovingNotNull|.
{
assign_assuming_AddRef(
RefPtr<T>(std::move(aSmartPtr).unwrapBasePtr()).forget().take()); return *this;
}
// Defined in OwningNonNull.h template <class U>
RefPtr<T>& operator=(const mozilla::OwningNonNull<U>& aOther);
// Defined in StaticLocalPtr.h template <class U>
RefPtr<T>& operator=(const mozilla::StaticLocalRefPtr<U>& aOther);
// Defined in StaticPtr.h template <class U>
RefPtr<T>& operator=(const mozilla::StaticRefPtr<U>& aOther);
// Other pointer operators
void swap(RefPtr<T>& aRhs) // ...exchange ownership with |aRhs|; can save a pair of refcount operations
{
T* temp = aRhs.mRawPtr;
aRhs.mRawPtr = mRawPtr;
mRawPtr = temp;
}
void swap(T*& aRhs) // ...exchange ownership with |aRhs|; can save a pair of refcount operations
{
T* temp = aRhs;
aRhs = mRawPtr;
mRawPtr = temp;
}
already_AddRefed<T> MOZ_MAY_CALL_AFTER_MUST_RETURN forget() // return the value of mRawPtr and null out mRawPtr. Useful for // already_AddRefed return values.
{
T* temp = nullptr;
swap(temp); return already_AddRefed<T>(temp);
}
template <typename I> void forget(I** aRhs) // Set the target of aRhs to the value of mRawPtr and null out mRawPtr. // Useful to avoid unnecessary AddRef/Release pairs with "out" // parameters where aRhs bay be a T** or an I** where I is a base class // of T.
{
MOZ_ASSERT(aRhs, "Null pointer passed to forget!");
*aRhs = mRawPtr;
mRawPtr = nullptr;
}
T* get() const /* Prefer the implicit conversion provided automatically by |operator T*() const|. Use |get()| to resolve ambiguity or to get a castable pointer.
*/
{ returnconst_cast<T*>(mRawPtr);
}
operator T*() const& /* ...makes an |RefPtr| act like its underlying raw pointer type whenever it is used in a context where a raw pointer is expected. It is this operator that makes an |RefPtr| substitutable for a raw pointer.
Prefer the implicit use of this operator to calling |get()|, except where necessary to resolve ambiguity.
*/
{ return get();
}
// Don't allow implicit conversion of temporary RefPtr to raw pointer, // because the refcount might be one and the pointer will immediately become // invalid. operator T*() const&& = delete;
// These are needed to avoid the deleted operator above. XXX Why is operator! // needed separately? Shouldn't the compiler prefer using the non-deleted // operator bool instead of the deleted operator T*? explicitoperatorbool() const { return !!mRawPtr; } booloperator!() const { return !mRawPtr; }
T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
MOZ_ASSERT(mRawPtr != nullptr, "You can't dereference a NULL RefPtr with operator->()."); return get();
}
template <typename R, typename... Args> class Proxy { typedef R (T::*member_function)(Args...);
T* mRawPtr;
member_function mFunction;
private: // This helper class makes |RefPtr<const T>| possible by casting away // the constness from the pointer when calling AddRef() and Release(). // // This is necessary because AddRef() and Release() implementations can't // generally expected to be const themselves (without heavy use of |mutable| // and |const_cast| in their own implementations). // // This should be sound because while |RefPtr<const T>| provides a // const view of an object, the object itself should not be const (it // would have to be allocated as |new const T| or similar to be const). template <class U> struct ConstRemovingRefPtrTraits { staticvoid AddRef(U* aPtr) { mozilla::RefPtrTraits<U>::AddRef(aPtr); } staticvoid Release(U* aPtr) { mozilla::RefPtrTraits<U>::Release(aPtr); }
}; template <class U> struct ConstRemovingRefPtrTraits<const U> { staticvoid AddRef(const U* aPtr) {
mozilla::RefPtrTraits<U>::AddRef(const_cast<U*>(aPtr));
} staticvoid Release(const U* aPtr) {
mozilla::RefPtrTraits<U>::Release(const_cast<U*>(aPtr));
}
};
};
DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_AddRefs()| instead.
When initialized with a |RefPtr|, as in the example above, it returns a |void**|, a |T**|, or an |nsISupports**| as needed, that the outer call (|GetAddRefedPointer| in this case) can fill in.
This type should be a nested class inside |RefPtr<T>|.
*/
{ public: explicit RefPtrGetterAddRefs(RefPtr<T>& aSmartPtr)
: mTargetSmartPtr(aSmartPtr) { // nothing else to do
}
template <class T> inline RefPtrGetterAddRefs<T> getter_AddRefs(RefPtr<T>& aSmartPtr) /* Used around a |RefPtr| when ...makes the class |RefPtrGetterAddRefs<T>| invisible.
*/
{ return RefPtrGetterAddRefs<T>(aSmartPtr);
}
// Provide a specialization of AlignmentFinder to allow MOZ_ALIGNOF(RefPtr<T>) // with an incomplete T. template <typename T> class AlignmentFinder<RefPtr<T>> { public: staticconst size_t alignment = alignof(T*);
};
/** * Helper function to be able to conveniently write things like: * * already_AddRefed<T> * f(...) * { * return MakeAndAddRef<T>(...); * }
*/ template <typename T, typename... Args>
already_AddRefed<T> MakeAndAddRef(Args&&... aArgs) {
RefPtr<T> p(new T(std::forward<Args>(aArgs)...)); return p.forget();
}
/** * Helper function to be able to conveniently write things like: * * auto runnable = * MakeRefPtr<ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>>( * mOnSuccess, mOnFailure, *error, mWindowID);
*/ template <typename T, typename... Args>
RefPtr<T> MakeRefPtr(Args&&... aArgs) {
RefPtr<T> p(new T(std::forward<Args>(aArgs)...)); return p;
}
} // namespace mozilla
/** * Deduction guide to allow simple `RefPtr` definitions from an * already_AddRefed<T> without repeating the type, e.g.: * * RefPtr ptr = MakeAndAddRef<SomeType>(...);
*/ template <typename T>
RefPtr(already_AddRefed<T>) -> RefPtr<T>;
#endif/* mozilla_RefPtr_h */
¤ Dauer der Verarbeitung: 0.37 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.