Blame mfbt/RefPtr.h

Packit f0b94e
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
Packit f0b94e
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
Packit f0b94e
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit f0b94e
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit f0b94e
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit f0b94e
Packit f0b94e
#ifndef mozilla_RefPtr_h
Packit f0b94e
#define mozilla_RefPtr_h
Packit f0b94e
Packit f0b94e
#include "mozilla/AlreadyAddRefed.h"
Packit f0b94e
#include "mozilla/Assertions.h"
Packit f0b94e
#include "mozilla/Attributes.h"
Packit f0b94e
Packit f0b94e
/*****************************************************************************/
Packit f0b94e
Packit f0b94e
// template <class T> class RefPtrGetterAddRefs;
Packit f0b94e
Packit f0b94e
class nsQueryReferent;
Packit f0b94e
class nsCOMPtr_helper;
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
template <class T>
Packit f0b94e
class OwningNonNull;
Packit f0b94e
template <class T>
Packit f0b94e
class StaticRefPtr;
Packit f0b94e
Packit f0b94e
// Traditionally, RefPtr supports automatic refcounting of any pointer type
Packit f0b94e
// with AddRef() and Release() methods that follow the traditional semantics.
Packit f0b94e
//
Packit f0b94e
// This traits class can be specialized to operate on other pointer types. For
Packit f0b94e
// example, we specialize this trait for opaque FFI types that represent
Packit f0b94e
// refcounted objects in Rust.
Packit f0b94e
//
Packit f0b94e
// Given the use of ConstRemovingRefPtrTraits below, U should not be a const-
Packit f0b94e
// qualified type.
Packit f0b94e
template <class U>
Packit f0b94e
struct RefPtrTraits {
Packit f0b94e
  static void AddRef(U* aPtr) { aPtr->AddRef(); }
Packit f0b94e
  static void Release(U* aPtr) { aPtr->Release(); }
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
class MOZ_IS_REFPTR RefPtr {
Packit f0b94e
 private:
Packit f0b94e
  void assign_with_AddRef(T* aRawPtr) {
Packit f0b94e
    if (aRawPtr) {
Packit f0b94e
      ConstRemovingRefPtrTraits<T>::AddRef(aRawPtr);
Packit f0b94e
    }
Packit f0b94e
    assign_assuming_AddRef(aRawPtr);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  void assign_assuming_AddRef(T* aNewPtr) {
Packit f0b94e
    T* oldPtr = mRawPtr;
Packit f0b94e
    mRawPtr = aNewPtr;
Packit f0b94e
    if (oldPtr) {
Packit f0b94e
      ConstRemovingRefPtrTraits<T>::Release(oldPtr);
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  T* MOZ_OWNING_REF mRawPtr;
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  typedef T element_type;
Packit f0b94e
Packit f0b94e
  ~RefPtr() {
Packit f0b94e
    if (mRawPtr) {
Packit f0b94e
      ConstRemovingRefPtrTraits<T>::Release(mRawPtr);
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Constructors
Packit f0b94e
Packit f0b94e
  RefPtr()
Packit f0b94e
      : mRawPtr(nullptr)
Packit f0b94e
  // default constructor
Packit f0b94e
  {}
Packit f0b94e
Packit f0b94e
  RefPtr(const RefPtr<T>& aSmartPtr)
Packit f0b94e
      : mRawPtr(aSmartPtr.mRawPtr)
Packit f0b94e
  // copy-constructor
Packit f0b94e
  {
Packit f0b94e
    if (mRawPtr) {
Packit f0b94e
      ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  RefPtr(RefPtr<T>&& aRefPtr) : mRawPtr(aRefPtr.mRawPtr) {
Packit f0b94e
    aRefPtr.mRawPtr = nullptr;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // construct from a raw pointer (of the right type)
Packit f0b94e
Packit f0b94e
  MOZ_IMPLICIT RefPtr(T* aRawPtr) : mRawPtr(aRawPtr) {
Packit f0b94e
    if (mRawPtr) {
Packit f0b94e
      ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  MOZ_IMPLICIT RefPtr(decltype(nullptr)) : mRawPtr(nullptr) {}
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  MOZ_IMPLICIT RefPtr(already_AddRefed& aSmartPtr)
Packit f0b94e
      : mRawPtr(aSmartPtr.take())
Packit f0b94e
  // construct from |already_AddRefed|
Packit f0b94e
  {}
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  MOZ_IMPLICIT RefPtr(already_AddRefed&& aSmartPtr)
Packit f0b94e
      : mRawPtr(aSmartPtr.take())
Packit f0b94e
  // construct from |otherRefPtr.forget()|
Packit f0b94e
  {}
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  MOZ_IMPLICIT RefPtr(const RefPtr& aSmartPtr)
Packit f0b94e
      : mRawPtr(aSmartPtr.get())
Packit f0b94e
  // copy-construct from a smart pointer with a related pointer type
Packit f0b94e
  {
Packit f0b94e
    if (mRawPtr) {
Packit f0b94e
      ConstRemovingRefPtrTraits<T>::AddRef(mRawPtr);
Packit f0b94e
    }
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  MOZ_IMPLICIT RefPtr(RefPtr&& aSmartPtr)
Packit f0b94e
      : mRawPtr(aSmartPtr.forget().take())
Packit f0b94e
  // construct from |Move(RefPtr<SomeSubclassOfT>)|.
Packit f0b94e
  {}
Packit f0b94e
Packit f0b94e
  MOZ_IMPLICIT RefPtr(const nsQueryReferent& aHelper);
Packit f0b94e
  MOZ_IMPLICIT RefPtr(const nsCOMPtr_helper& aHelper);
Packit f0b94e
Packit f0b94e
  // Defined in OwningNonNull.h
Packit f0b94e
  template <class U>
Packit f0b94e
  MOZ_IMPLICIT RefPtr(const mozilla::OwningNonNull<U>& aOther);
Packit f0b94e
Packit f0b94e
  // Defined in StaticPtr.h
Packit f0b94e
  template <class U>
Packit f0b94e
  MOZ_IMPLICIT RefPtr(const mozilla::StaticRefPtr<U>& aOther);
Packit f0b94e
Packit f0b94e
  // Assignment operators
Packit f0b94e
Packit f0b94e
  RefPtr<T>& operator=(decltype(nullptr)) {
Packit f0b94e
    assign_assuming_AddRef(nullptr);
Packit f0b94e
    return *this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  RefPtr<T>& operator=(const RefPtr<T>& aRhs)
Packit f0b94e
  // copy assignment operator
Packit f0b94e
  {
Packit f0b94e
    assign_with_AddRef(aRhs.mRawPtr);
Packit f0b94e
    return *this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  RefPtr<T>& operator=(const RefPtr& aRhs)
Packit f0b94e
  // assign from an RefPtr of a related pointer type
Packit f0b94e
  {
Packit f0b94e
    assign_with_AddRef(aRhs.get());
Packit f0b94e
    return *this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  RefPtr<T>& operator=(T* aRhs)
Packit f0b94e
  // assign from a raw pointer (of the right type)
Packit f0b94e
  {
Packit f0b94e
    assign_with_AddRef(aRhs);
Packit f0b94e
    return *this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  RefPtr<T>& operator=(already_AddRefed& aRhs)
Packit f0b94e
  // assign from |already_AddRefed|
Packit f0b94e
  {
Packit f0b94e
    assign_assuming_AddRef(aRhs.take());
Packit f0b94e
    return *this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  RefPtr<T>& operator=(already_AddRefed&& aRhs)
Packit f0b94e
  // assign from |otherRefPtr.forget()|
Packit f0b94e
  {
Packit f0b94e
    assign_assuming_AddRef(aRhs.take());
Packit f0b94e
    return *this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  RefPtr<T>& operator=(const nsQueryReferent& aQueryReferent);
Packit f0b94e
  RefPtr<T>& operator=(const nsCOMPtr_helper& aHelper);
Packit f0b94e
Packit f0b94e
  RefPtr<T>& operator=(RefPtr<T>&& aRefPtr) {
Packit f0b94e
    assign_assuming_AddRef(aRefPtr.mRawPtr);
Packit f0b94e
    aRefPtr.mRawPtr = nullptr;
Packit f0b94e
    return *this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Defined in OwningNonNull.h
Packit f0b94e
  template <class U>
Packit f0b94e
  RefPtr<T>& operator=(const mozilla::OwningNonNull<U>& aOther);
Packit f0b94e
Packit f0b94e
  // Defined in StaticPtr.h
Packit f0b94e
  template <class U>
Packit f0b94e
  RefPtr<T>& operator=(const mozilla::StaticRefPtr<U>& aOther);
Packit f0b94e
Packit f0b94e
  // Other pointer operators
Packit f0b94e
Packit f0b94e
  void swap(RefPtr<T>& aRhs)
Packit f0b94e
  // ...exchange ownership with |aRhs|; can save a pair of refcount operations
Packit f0b94e
  {
Packit f0b94e
    T* temp = aRhs.mRawPtr;
Packit f0b94e
    aRhs.mRawPtr = mRawPtr;
Packit f0b94e
    mRawPtr = temp;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  void swap(T*& aRhs)
Packit f0b94e
  // ...exchange ownership with |aRhs|; can save a pair of refcount operations
Packit f0b94e
  {
Packit f0b94e
    T* temp = aRhs;
Packit f0b94e
    aRhs = mRawPtr;
Packit f0b94e
    mRawPtr = temp;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  already_AddRefed<T> MOZ_MAY_CALL_AFTER_MUST_RETURN forget()
Packit f0b94e
  // return the value of mRawPtr and null out mRawPtr. Useful for
Packit f0b94e
  // already_AddRefed return values.
Packit f0b94e
  {
Packit f0b94e
    T* temp = nullptr;
Packit f0b94e
    swap(temp);
Packit f0b94e
    return already_AddRefed<T>(temp);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  template <typename I>
Packit f0b94e
  void forget(I** aRhs)
Packit f0b94e
  // Set the target of aRhs to the value of mRawPtr and null out mRawPtr.
Packit f0b94e
  // Useful to avoid unnecessary AddRef/Release pairs with "out"
Packit f0b94e
  // parameters where aRhs bay be a T** or an I** where I is a base class
Packit f0b94e
  // of T.
Packit f0b94e
  {
Packit f0b94e
    MOZ_ASSERT(aRhs, "Null pointer passed to forget!");
Packit f0b94e
    *aRhs = mRawPtr;
Packit f0b94e
    mRawPtr = nullptr;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  T* get() const
Packit f0b94e
  /*
Packit f0b94e
    Prefer the implicit conversion provided automatically by |operator T*()
Packit f0b94e
    const|. Use |get()| to resolve ambiguity or to get a castable pointer.
Packit f0b94e
  */
Packit f0b94e
  {
Packit f0b94e
    return const_cast<T*>(mRawPtr);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  operator T*() const &
Packit f0b94e
  /*
Packit f0b94e
    ...makes an |RefPtr| act like its underlying raw pointer type whenever it
Packit f0b94e
    is used in a context where a raw pointer is expected.  It is this operator
Packit f0b94e
    that makes an |RefPtr| substitutable for a raw pointer.
Packit f0b94e
Packit f0b94e
    Prefer the implicit use of this operator to calling |get()|, except where
Packit f0b94e
    necessary to resolve ambiguity.
Packit f0b94e
  */
Packit f0b94e
  {
Packit f0b94e
    return get();
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  // Don't allow implicit conversion of temporary RefPtr to raw pointer,
Packit f0b94e
  // because the refcount might be one and the pointer will immediately become
Packit f0b94e
  // invalid.
Packit f0b94e
  operator T*() const && = delete;
Packit f0b94e
Packit f0b94e
  // These are needed to avoid the deleted operator above.  XXX Why is operator!
Packit f0b94e
  // needed separately?  Shouldn't the compiler prefer using the non-deleted
Packit f0b94e
  // operator bool instead of the deleted operator T*?
Packit f0b94e
  explicit operator bool() const { return !!mRawPtr; }
Packit f0b94e
  bool operator!() const { return !mRawPtr; }
Packit f0b94e
Packit f0b94e
  T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
Packit f0b94e
    MOZ_ASSERT(mRawPtr != nullptr,
Packit f0b94e
               "You can't dereference a NULL RefPtr with operator->().");
Packit f0b94e
    return get();
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  template <typename R, typename... Args>
Packit f0b94e
  class Proxy {
Packit f0b94e
    typedef R (T::*member_function)(Args...);
Packit f0b94e
    T* mRawPtr;
Packit f0b94e
    member_function mFunction;
Packit f0b94e
Packit f0b94e
   public:
Packit f0b94e
    Proxy(T* aRawPtr, member_function aFunction)
Packit f0b94e
        : mRawPtr(aRawPtr), mFunction(aFunction) {}
Packit f0b94e
    template <typename... ActualArgs>
Packit f0b94e
    R operator()(ActualArgs&&... aArgs) {
Packit f0b94e
      return ((*mRawPtr).*mFunction)(mozilla::Forward<ActualArgs>(aArgs)...);
Packit f0b94e
    }
Packit f0b94e
  };
Packit f0b94e
Packit f0b94e
  template <typename R, typename... Args>
Packit f0b94e
  Proxy<R, Args...> operator->*(R (T::*aFptr)(Args...)) const {
Packit f0b94e
    MOZ_ASSERT(mRawPtr != nullptr,
Packit f0b94e
               "You can't dereference a NULL RefPtr with operator->*().");
Packit f0b94e
    return Proxy<R, Args...>(get(), aFptr);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  RefPtr<T>* get_address()
Packit f0b94e
  // This is not intended to be used by clients.  See |address_of|
Packit f0b94e
  // below.
Packit f0b94e
  {
Packit f0b94e
    return this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  const RefPtr<T>* get_address() const
Packit f0b94e
  // This is not intended to be used by clients.  See |address_of|
Packit f0b94e
  // below.
Packit f0b94e
  {
Packit f0b94e
    return this;
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
 public:
Packit f0b94e
  T& operator*() const {
Packit f0b94e
    MOZ_ASSERT(mRawPtr != nullptr,
Packit f0b94e
               "You can't dereference a NULL RefPtr with operator*().");
Packit f0b94e
    return *get();
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  T** StartAssignment() {
Packit f0b94e
    assign_assuming_AddRef(nullptr);
Packit f0b94e
    return reinterpret_cast<T**>(&mRawPtr);
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  // This helper class makes |RefPtr<const T>| possible by casting away
Packit f0b94e
  // the constness from the pointer when calling AddRef() and Release().
Packit f0b94e
  //
Packit f0b94e
  // This is necessary because AddRef() and Release() implementations can't
Packit f0b94e
  // generally expected to be const themselves (without heavy use of |mutable|
Packit f0b94e
  // and |const_cast| in their own implementations).
Packit f0b94e
  //
Packit f0b94e
  // This should be sound because while |RefPtr<const T>| provides a
Packit f0b94e
  // const view of an object, the object itself should not be const (it
Packit f0b94e
  // would have to be allocated as |new const T| or similar to be const).
Packit f0b94e
  template <class U>
Packit f0b94e
  struct ConstRemovingRefPtrTraits {
Packit f0b94e
    static void AddRef(U* aPtr) { mozilla::RefPtrTraits<U>::AddRef(aPtr); }
Packit f0b94e
    static void Release(U* aPtr) { mozilla::RefPtrTraits<U>::Release(aPtr); }
Packit f0b94e
  };
Packit f0b94e
  template <class U>
Packit f0b94e
  struct ConstRemovingRefPtrTraits<const U> {
Packit f0b94e
    static void AddRef(const U* aPtr) {
Packit f0b94e
      mozilla::RefPtrTraits<U>::AddRef(const_cast<U*>(aPtr));
Packit f0b94e
    }
Packit f0b94e
    static void Release(const U* aPtr) {
Packit f0b94e
      mozilla::RefPtrTraits<U>::Release(const_cast<U*>(aPtr));
Packit f0b94e
    }
Packit f0b94e
  };
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
class nsCycleCollectionTraversalCallback;
Packit f0b94e
template <typename T>
Packit f0b94e
void CycleCollectionNoteChild(nsCycleCollectionTraversalCallback& aCallback,
Packit f0b94e
                              T* aChild, const char* aName, uint32_t aFlags);
Packit f0b94e
Packit f0b94e
template <typename T>
Packit f0b94e
inline void ImplCycleCollectionUnlink(RefPtr<T>& aField) {
Packit f0b94e
  aField = nullptr;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <typename T>
Packit f0b94e
inline void ImplCycleCollectionTraverse(
Packit f0b94e
    nsCycleCollectionTraversalCallback& aCallback, RefPtr<T>& aField,
Packit f0b94e
    const char* aName, uint32_t aFlags = 0) {
Packit f0b94e
  CycleCollectionNoteChild(aCallback, aField.get(), aName, aFlags);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline RefPtr<T>* address_of(RefPtr<T>& aPtr) {
Packit f0b94e
  return aPtr.get_address();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline const RefPtr<T>* address_of(const RefPtr<T>& aPtr) {
Packit f0b94e
  return aPtr.get_address();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
class RefPtrGetterAddRefs
Packit f0b94e
/*
Packit f0b94e
  ...
Packit f0b94e
Packit f0b94e
  This class is designed to be used for anonymous temporary objects in the
Packit f0b94e
  argument list of calls that return COM interface pointers, e.g.,
Packit f0b94e
Packit f0b94e
    RefPtr<IFoo> fooP;
Packit f0b94e
    ...->GetAddRefedPointer(getter_AddRefs(fooP))
Packit f0b94e
Packit f0b94e
  DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_AddRefs()| instead.
Packit f0b94e
Packit f0b94e
  When initialized with a |RefPtr|, as in the example above, it returns
Packit f0b94e
  a |void**|, a |T**|, or an |nsISupports**| as needed, that the
Packit f0b94e
  outer call (|GetAddRefedPointer| in this case) can fill in.
Packit f0b94e
Packit f0b94e
  This type should be a nested class inside |RefPtr<T>|.
Packit f0b94e
*/
Packit f0b94e
{
Packit f0b94e
 public:
Packit f0b94e
  explicit RefPtrGetterAddRefs(RefPtr<T>& aSmartPtr)
Packit f0b94e
      : mTargetSmartPtr(aSmartPtr) {
Packit f0b94e
    // nothing else to do
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  operator void**() {
Packit f0b94e
    return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
Packit f0b94e
  }
Packit f0b94e
Packit f0b94e
  operator T**() { return mTargetSmartPtr.StartAssignment(); }
Packit f0b94e
Packit f0b94e
  T*& operator*() { return *(mTargetSmartPtr.StartAssignment()); }
Packit f0b94e
Packit f0b94e
 private:
Packit f0b94e
  RefPtr<T>& mTargetSmartPtr;
Packit f0b94e
};
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline RefPtrGetterAddRefs<T> getter_AddRefs(RefPtr<T>& aSmartPtr)
Packit f0b94e
/*
Packit f0b94e
  Used around a |RefPtr| when
Packit f0b94e
  ...makes the class |RefPtrGetterAddRefs<T>| invisible.
Packit f0b94e
*/
Packit f0b94e
{
Packit f0b94e
  return RefPtrGetterAddRefs<T>(aSmartPtr);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
// Comparing two |RefPtr|s
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator==(const RefPtr<T>& aLhs, const RefPtr<U>& aRhs) {
Packit f0b94e
  return static_cast<const T*>(aLhs.get()) == static_cast<const U*>(aRhs.get());
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator!=(const RefPtr<T>& aLhs, const RefPtr<U>& aRhs) {
Packit f0b94e
  return static_cast<const T*>(aLhs.get()) != static_cast<const U*>(aRhs.get());
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
// Comparing an |RefPtr| to a raw pointer
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator==(const RefPtr<T>& aLhs, const U* aRhs) {
Packit f0b94e
  return static_cast<const T*>(aLhs.get()) == static_cast<const U*>(aRhs);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator==(const U* aLhs, const RefPtr<T>& aRhs) {
Packit f0b94e
  return static_cast<const U*>(aLhs) == static_cast<const T*>(aRhs.get());
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator!=(const RefPtr<T>& aLhs, const U* aRhs) {
Packit f0b94e
  return static_cast<const T*>(aLhs.get()) != static_cast<const U*>(aRhs);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator!=(const U* aLhs, const RefPtr<T>& aRhs) {
Packit f0b94e
  return static_cast<const U*>(aLhs) != static_cast<const T*>(aRhs.get());
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator==(const RefPtr<T>& aLhs, U* aRhs) {
Packit f0b94e
  return static_cast<const T*>(aLhs.get()) == const_cast<const U*>(aRhs);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator==(U* aLhs, const RefPtr<T>& aRhs) {
Packit f0b94e
  return const_cast<const U*>(aLhs) == static_cast<const T*>(aRhs.get());
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator!=(const RefPtr<T>& aLhs, U* aRhs) {
Packit f0b94e
  return static_cast<const T*>(aLhs.get()) != const_cast<const U*>(aRhs);
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T, class U>
Packit f0b94e
inline bool operator!=(U* aLhs, const RefPtr<T>& aRhs) {
Packit f0b94e
  return const_cast<const U*>(aLhs) != static_cast<const T*>(aRhs.get());
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
// Comparing an |RefPtr| to |nullptr|
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline bool operator==(const RefPtr<T>& aLhs, decltype(nullptr)) {
Packit f0b94e
  return aLhs.get() == nullptr;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline bool operator==(decltype(nullptr), const RefPtr<T>& aRhs) {
Packit f0b94e
  return nullptr == aRhs.get();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline bool operator!=(const RefPtr<T>& aLhs, decltype(nullptr)) {
Packit f0b94e
  return aLhs.get() != nullptr;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline bool operator!=(decltype(nullptr), const RefPtr<T>& aRhs) {
Packit f0b94e
  return nullptr != aRhs.get();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
/*****************************************************************************/
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline already_AddRefed<T> do_AddRef(T* aObj) {
Packit f0b94e
  RefPtr<T> ref(aObj);
Packit f0b94e
  return ref.forget();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
template <class T>
Packit f0b94e
inline already_AddRefed<T> do_AddRef(const RefPtr<T>& aObj) {
Packit f0b94e
  RefPtr<T> ref(aObj);
Packit f0b94e
  return ref.forget();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
namespace mozilla {
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * Helper function to be able to conveniently write things like:
Packit f0b94e
 *
Packit f0b94e
 *   already_AddRefed<T>
Packit f0b94e
 *   f(...)
Packit f0b94e
 *   {
Packit f0b94e
 *     return MakeAndAddRef<T>(...);
Packit f0b94e
 *   }
Packit f0b94e
 */
Packit f0b94e
template <typename T, typename... Args>
Packit f0b94e
already_AddRefed<T> MakeAndAddRef(Args&&... aArgs) {
Packit f0b94e
  RefPtr<T> p(new T(Forward<Args>(aArgs)...));
Packit f0b94e
  return p.forget();
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
/**
Packit f0b94e
 * Helper function to be able to conveniently write things like:
Packit f0b94e
 *
Packit f0b94e
 *   auto runnable =
Packit f0b94e
 * MakeRefPtr<ErrorCallbackRunnable<nsIDOMGetUserMediaSuccessCallback>>(
Packit f0b94e
 *       mOnSuccess, mOnFailure, *error, mWindowID);
Packit f0b94e
 */
Packit f0b94e
template <typename T, typename... Args>
Packit f0b94e
RefPtr<T> MakeRefPtr(Args&&... aArgs) {
Packit f0b94e
  RefPtr<T> p(new T(Forward<Args>(aArgs)...));
Packit f0b94e
  return p;
Packit f0b94e
}
Packit f0b94e
Packit f0b94e
}  // namespace mozilla
Packit f0b94e
Packit f0b94e
#endif /* mozilla_RefPtr_h */