зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1835119 - Remove nsCOMPtr_base. r=xpcom-reviewers,kmag
It's not clear to me why specializing nsCOMPtr<nsISupports> is particularly useful, and this removes a lot of code, bringing us closer to unifying nsCOMPtr and RefPtr. The changes in other places are needed because we used to allow nsCOMPtr<nsISupports> to implicitly coerce to nsISupports even for rvalue references. 0:47.88 /home/emilio/src/moz/gecko-4/netwerk/protocol/http/nsHttpActivityDistributor.cpp:121:11: error: conversion function from 'nsCOMPtr<nsISupports>' to 'nsISupports *' invokes a deleted function 0:47.88 nsCOMPtr<nsISupports>(do_QueryObject(channel)), aActivityType, 0:47.88 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0:47.88 /home/emilio/src/moz/gecko-4/obj-debug/dist/include/nsCOMPtr.h:764:3: note: 'operator nsISupports *' has been explicitly marked deleted here 0:47.88 operator T*() const&& = delete; 0:47.88 ^ 0:47.88 /home/emilio/src/moz/gecko-4/netwerk/protocol/http/nsHttpActivityDistributor.cpp:29:57: note: passing argument to parameter 'aHttpChannel' here 0:47.88 nsHttpActivityDistributor::ObserveActivity(nsISupports* aHttpChannel, 0:47.88 ^ Which is not allowed for a good reason, generally. Differential Revision: https://phabricator.services.mozilla.com/D179124
This commit is contained in:
Родитель
49e8a263e4
Коммит
c2f5a4ac7a
|
@ -27,7 +27,7 @@ class CanvasPath final : public nsWrapperCache {
|
|||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(CanvasPath)
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(CanvasPath)
|
||||
|
||||
nsCOMPtr<nsISupports> GetParentObject() { return mParent; }
|
||||
nsISupports* GetParentObject() { return mParent; }
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
|
|
@ -118,8 +118,8 @@ nsHttpActivityDistributor::ObserveActivityWithArgs(
|
|||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
Unused << self->ObserveActivity(
|
||||
nsCOMPtr<nsISupports>(do_QueryObject(channel)), aActivityType,
|
||||
aActivitySubtype, aTimestamp, aExtraSizeData, extraStringData);
|
||||
static_cast<nsIChannel*>(channel), aActivityType, aActivitySubtype,
|
||||
aTimestamp, aExtraSizeData, extraStringData);
|
||||
} else if (args.type() == HttpActivityArgs::THttpConnectionActivity) {
|
||||
const HttpConnectionActivity& activity =
|
||||
args.get_HttpConnectionActivity();
|
||||
|
|
|
@ -86,14 +86,9 @@ nsClipboardHelper::CopyStringToClipboard(const nsAString& aString,
|
|||
rv = data->SetData(aString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// qi the data object an |nsISupports| so that when the transferable holds
|
||||
// Pass the data object as |nsISupports| so that when the transferable holds
|
||||
// onto it, it will addref the correct interface.
|
||||
nsCOMPtr<nsISupports> genericData(do_QueryInterface(data, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(genericData, NS_ERROR_FAILURE);
|
||||
|
||||
// set the transfer data
|
||||
rv = trans->SetTransferData(kTextMime, genericData);
|
||||
rv = trans->SetTransferData(kTextMime, ToSupports(data));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// put the transferable on the clipboard
|
||||
|
|
|
@ -32,82 +32,3 @@ nsresult nsQueryInterfaceISupportsWithError::operator()(const nsIID& aIID,
|
|||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_with_AddRef(nsISupports* aRawPtr) {
|
||||
if (aRawPtr) {
|
||||
NSCAP_ADDREF(this, aRawPtr);
|
||||
}
|
||||
assign_assuming_AddRef(aRawPtr);
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_qi(const nsQueryInterfaceISupports aQI,
|
||||
const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQI(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_qi_with_error(
|
||||
const nsQueryInterfaceISupportsWithError& aQI, const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQI(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_gs_cid(const nsGetServiceByCID aGS,
|
||||
const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aGS(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_gs_cid_with_error(
|
||||
const nsGetServiceByCIDWithError& aGS, const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aGS(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_gs_contractid(
|
||||
const nsGetServiceByContractID aGS, const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aGS(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_gs_contractid_with_error(
|
||||
const nsGetServiceByContractIDWithError& aGS, const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aGS(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_query_referent(
|
||||
const nsQueryReferent& aQueryReferent, const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQueryReferent(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
||||
void nsCOMPtr_base::assign_from_helper(const nsCOMPtr_helper& aHelper,
|
||||
const nsIID& aIID) {
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aHelper(aIID, &newRawPtr))) {
|
||||
newRawPtr = nullptr;
|
||||
}
|
||||
assign_assuming_AddRef(static_cast<nsISupports*>(newRawPtr));
|
||||
}
|
||||
|
|
|
@ -282,76 +282,6 @@ class MOZ_STACK_CLASS nsQueryReferent final {
|
|||
nsresult* mErrorPtr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Factors implementation for all template versions of nsCOMPtr.
|
||||
*
|
||||
* Here's the way people normally do things like this:
|
||||
*
|
||||
* template<class T> class Foo { ... };
|
||||
* template<> class Foo<void*> { ... };
|
||||
* template<class T> class Foo<T*> : private Foo<void*> { ... };
|
||||
*/
|
||||
class nsCOMPtr_base {
|
||||
public:
|
||||
explicit nsCOMPtr_base(nsISupports* aRawPtr = nullptr) : mRawPtr(aRawPtr) {}
|
||||
|
||||
NS_CONSTRUCTOR_FASTCALL ~nsCOMPtr_base() {
|
||||
NSCAP_LOG_RELEASE(this, mRawPtr);
|
||||
if (mRawPtr) {
|
||||
NSCAP_RELEASE(this, mRawPtr);
|
||||
}
|
||||
}
|
||||
|
||||
void NS_FASTCALL assign_with_AddRef(nsISupports*);
|
||||
void NS_FASTCALL assign_from_qi(const nsQueryInterfaceISupports,
|
||||
const nsIID&);
|
||||
void NS_FASTCALL assign_from_qi_with_error(
|
||||
const nsQueryInterfaceISupportsWithError&, const nsIID&);
|
||||
void NS_FASTCALL assign_from_gs_cid(const nsGetServiceByCID, const nsIID&);
|
||||
void NS_FASTCALL assign_from_gs_cid_with_error(
|
||||
const nsGetServiceByCIDWithError&, const nsIID&);
|
||||
void NS_FASTCALL assign_from_gs_contractid(const nsGetServiceByContractID,
|
||||
const nsIID&);
|
||||
void NS_FASTCALL assign_from_gs_contractid_with_error(
|
||||
const nsGetServiceByContractIDWithError&, const nsIID&);
|
||||
void NS_FASTCALL assign_from_query_referent(const nsQueryReferent&,
|
||||
const nsIID&);
|
||||
void NS_FASTCALL assign_from_helper(const nsCOMPtr_helper&, const nsIID&);
|
||||
// Since in most cases, begin_assignment is called on a default-constructed
|
||||
// nsCOMPtr, the call to assign_assuming_AddRef becomes a no-op in release
|
||||
// builds. However, the compiler does not always optimize this away and emits a
|
||||
// call to begin_assignment without MOZ_ALWAYS_INLINE. When logging is enabled,
|
||||
// this might cause code bloat, so we MOZ_NEVER_INLINE in that case.
|
||||
#ifdef NSCAP_LOG_EXTERNAL_ASSIGNMENT
|
||||
MOZ_NEVER_INLINE
|
||||
#else
|
||||
MOZ_ALWAYS_INLINE
|
||||
#endif
|
||||
void** NS_FASTCALL begin_assignment() {
|
||||
assign_assuming_AddRef(nullptr);
|
||||
return reinterpret_cast<void**>(&mRawPtr);
|
||||
}
|
||||
|
||||
protected:
|
||||
NS_MAY_ALIAS_PTR(nsISupports) MOZ_OWNING_REF mRawPtr;
|
||||
|
||||
void assign_assuming_AddRef(nsISupports* aNewPtr) {
|
||||
// |AddRef()|ing the new value (before entering this function) before
|
||||
// |Release()|ing the old lets us safely ignore the self-assignment case.
|
||||
// We must, however, be careful only to |Release()| _after_ doing the
|
||||
// assignment, in case the |Release()| leads to our _own_ destruction,
|
||||
// which would, in turn, cause an incorrect second |Release()| of our old
|
||||
// pointer. Thank <waterson@netscape.com> for discovering this.
|
||||
nsISupports* oldPtr = mRawPtr;
|
||||
mRawPtr = aNewPtr;
|
||||
NSCAP_LOG_ASSIGNMENT(this, aNewPtr);
|
||||
NSCAP_LOG_RELEASE(this, oldPtr);
|
||||
if (oldPtr) {
|
||||
NSCAP_RELEASE(this, oldPtr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// template<class T> class nsGetterAddRefs;
|
||||
|
||||
// Helper for assert_validity method
|
||||
|
@ -413,15 +343,21 @@ class MOZ_IS_REFPTR nsCOMPtr final {
|
|||
|
||||
#ifdef NSCAP_FEATURE_TEST_DONTQUERY_CASES
|
||||
void Assert_NoQueryNeeded() {
|
||||
if (mRawPtr) {
|
||||
// This can't be defined in terms of do_QueryInterface because
|
||||
// that bans casts from a class to itself.
|
||||
void* out = nullptr;
|
||||
mRawPtr->QueryInterface(NS_GET_TEMPLATE_IID(T), &out);
|
||||
T* query_result = static_cast<T*>(out);
|
||||
MOZ_ASSERT(query_result == mRawPtr, "QueryInterface needed");
|
||||
NS_RELEASE(query_result);
|
||||
if (!mRawPtr) {
|
||||
return;
|
||||
}
|
||||
if constexpr (std::is_same_v<T, nsISupports>) {
|
||||
// FIXME: nsCOMPtr<nsISupports> never asserted this, and it currently
|
||||
// fails...
|
||||
return;
|
||||
}
|
||||
// This can't be defined in terms of do_QueryInterface because
|
||||
// that bans casts from a class to itself.
|
||||
void* out = nullptr;
|
||||
mRawPtr->QueryInterface(NS_GET_TEMPLATE_IID(T), &out);
|
||||
T* query_result = static_cast<T*>(out);
|
||||
MOZ_ASSERT(query_result == mRawPtr, "QueryInterface needed");
|
||||
NS_RELEASE(query_result);
|
||||
}
|
||||
|
||||
# define NSCAP_ASSERT_NO_QUERY_NEEDED() Assert_NoQueryNeeded();
|
||||
|
@ -853,271 +789,6 @@ class MOZ_IS_REFPTR nsCOMPtr final {
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Specializing nsCOMPtr for nsISupports allows us to use nsCOMPtr<nsISupports>
|
||||
* the same way people use nsISupports* and void*, i.e., as a `catch-all'
|
||||
* pointing to any valid [XP]COM interface. Otherwise, an nsCOMPtr<nsISupports>
|
||||
* would only be able to point to the single [XP]COM-correct nsISupports
|
||||
* instance within an object; extra querying ensues. Clients need to be able to
|
||||
* pass around arbitrary interface pointers, without hassles, through
|
||||
* intermediary code that doesn't know the exact type.
|
||||
*/
|
||||
template <>
|
||||
class MOZ_IS_REFPTR nsCOMPtr<nsISupports> : private nsCOMPtr_base {
|
||||
public:
|
||||
typedef nsISupports element_type;
|
||||
|
||||
// Constructors
|
||||
|
||||
nsCOMPtr() : nsCOMPtr_base(nullptr) { NSCAP_LOG_ASSIGNMENT(this, nullptr); }
|
||||
|
||||
MOZ_IMPLICIT nsCOMPtr(decltype(nullptr)) : nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
}
|
||||
|
||||
nsCOMPtr(const nsCOMPtr<nsISupports>& aSmartPtr)
|
||||
: nsCOMPtr_base(aSmartPtr.mRawPtr) {
|
||||
if (mRawPtr) {
|
||||
NSCAP_ADDREF(this, mRawPtr);
|
||||
}
|
||||
NSCAP_LOG_ASSIGNMENT(this, aSmartPtr.mRawPtr);
|
||||
}
|
||||
|
||||
MOZ_IMPLICIT nsCOMPtr(nsISupports* aRawPtr) : nsCOMPtr_base(aRawPtr) {
|
||||
if (mRawPtr) {
|
||||
NSCAP_ADDREF(this, mRawPtr);
|
||||
}
|
||||
NSCAP_LOG_ASSIGNMENT(this, aRawPtr);
|
||||
}
|
||||
|
||||
// Construct from |already_AddRefed|.
|
||||
MOZ_IMPLICIT nsCOMPtr(already_AddRefed<nsISupports>& aSmartPtr)
|
||||
: nsCOMPtr_base(aSmartPtr.take()) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
|
||||
}
|
||||
|
||||
// Construct from |otherComPtr.forget()|.
|
||||
MOZ_IMPLICIT nsCOMPtr(already_AddRefed<nsISupports>&& aSmartPtr)
|
||||
: nsCOMPtr_base(aSmartPtr.take()) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, mRawPtr);
|
||||
}
|
||||
|
||||
// Construct from |do_QueryInterface(expr)|.
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceISupports aQI)
|
||||
: nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_qi(aQI, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Construct from |do_QueryInterface(expr, &rv)|.
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsQueryInterfaceISupportsWithError& aQI)
|
||||
: nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_qi_with_error(aQI, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Construct from |do_GetService(cid_expr)|.
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCID aGS) : nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_gs_cid(aGS, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Construct from |do_GetService(cid_expr, &rv)|.
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByCIDWithError& aGS)
|
||||
: nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_gs_cid_with_error(aGS, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Construct from |do_GetService(contractid_expr)|.
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractID aGS)
|
||||
: nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_gs_contractid(aGS, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Construct from |do_GetService(contractid_expr, &rv)|.
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsGetServiceByContractIDWithError& aGS)
|
||||
: nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_gs_contractid_with_error(aGS, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Construct from |do_QueryReferent(ptr)|
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsQueryReferent& aQueryReferent)
|
||||
: nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_query_referent(aQueryReferent,
|
||||
NS_GET_TEMPLATE_IID(nsISupports));
|
||||
}
|
||||
|
||||
// And finally, anything else we might need to construct from can exploit
|
||||
// the |nsCOMPtr_helper| facility
|
||||
MOZ_IMPLICIT nsCOMPtr(const nsCOMPtr_helper& aHelper)
|
||||
: nsCOMPtr_base(nullptr) {
|
||||
NSCAP_LOG_ASSIGNMENT(this, nullptr);
|
||||
assign_from_helper(aHelper, NS_GET_IID(nsISupports));
|
||||
}
|
||||
|
||||
// Assignment operators
|
||||
|
||||
nsCOMPtr<nsISupports>& operator=(const nsCOMPtr<nsISupports>& aRhs) {
|
||||
assign_with_AddRef(aRhs.mRawPtr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports>& operator=(nsISupports* aRhs) {
|
||||
assign_with_AddRef(aRhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports>& operator=(decltype(nullptr)) {
|
||||
assign_assuming_AddRef(nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |already_AddRefed|.
|
||||
nsCOMPtr<nsISupports>& operator=(already_AddRefed<nsISupports>& aRhs) {
|
||||
assign_assuming_AddRef(aRhs.take());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |otherComPtr.forget()|.
|
||||
nsCOMPtr<nsISupports>& operator=(already_AddRefed<nsISupports>&& aRhs) {
|
||||
assign_assuming_AddRef(aRhs.take());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_QueryInterface(expr)|.
|
||||
nsCOMPtr<nsISupports>& operator=(const nsQueryInterfaceISupports aRhs) {
|
||||
assign_from_qi(aRhs, NS_GET_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_QueryInterface(expr, &rv)|.
|
||||
nsCOMPtr<nsISupports>& operator=(
|
||||
const nsQueryInterfaceISupportsWithError& aRhs) {
|
||||
assign_from_qi_with_error(aRhs, NS_GET_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_GetService(cid_expr)|.
|
||||
nsCOMPtr<nsISupports>& operator=(const nsGetServiceByCID aRhs) {
|
||||
assign_from_gs_cid(aRhs, NS_GET_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_GetService(cid_expr, &rv)|.
|
||||
nsCOMPtr<nsISupports>& operator=(const nsGetServiceByCIDWithError& aRhs) {
|
||||
assign_from_gs_cid_with_error(aRhs, NS_GET_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_GetService(contractid_expr)|.
|
||||
nsCOMPtr<nsISupports>& operator=(const nsGetServiceByContractID aRhs) {
|
||||
assign_from_gs_contractid(aRhs, NS_GET_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_GetService(contractid_expr, &rv)|.
|
||||
nsCOMPtr<nsISupports>& operator=(
|
||||
const nsGetServiceByContractIDWithError& aRhs) {
|
||||
assign_from_gs_contractid_with_error(aRhs, NS_GET_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign from |do_QueryReferent(ptr)|.
|
||||
nsCOMPtr<nsISupports>& operator=(const nsQueryReferent& aRhs) {
|
||||
assign_from_query_referent(aRhs, NS_GET_TEMPLATE_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// And finally, anything else we might need to assign from can exploit the
|
||||
// nsCOMPtr_helper facility
|
||||
nsCOMPtr<nsISupports>& operator=(const nsCOMPtr_helper& aRhs) {
|
||||
assign_from_helper(aRhs, NS_GET_IID(nsISupports));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Exchange ownership with |aRhs|; can save a pair of refcount operations.
|
||||
void swap(nsCOMPtr<nsISupports>& aRhs) {
|
||||
nsISupports* temp = aRhs.mRawPtr;
|
||||
NSCAP_LOG_ASSIGNMENT(&aRhs, mRawPtr);
|
||||
NSCAP_LOG_ASSIGNMENT(this, temp);
|
||||
NSCAP_LOG_RELEASE(this, mRawPtr);
|
||||
NSCAP_LOG_RELEASE(&aRhs, temp);
|
||||
aRhs.mRawPtr = mRawPtr;
|
||||
mRawPtr = temp;
|
||||
}
|
||||
|
||||
// Exchange ownership with |aRhs|; can save a pair of refcount operations.
|
||||
void swap(nsISupports*& aRhs) {
|
||||
nsISupports* temp = aRhs;
|
||||
NSCAP_LOG_ASSIGNMENT(this, temp);
|
||||
NSCAP_LOG_RELEASE(this, mRawPtr);
|
||||
aRhs = mRawPtr;
|
||||
mRawPtr = temp;
|
||||
}
|
||||
|
||||
// Return the value of mRawPtr and null out mRawPtr. Useful for
|
||||
// already_AddRefed return values.
|
||||
already_AddRefed<nsISupports> forget() {
|
||||
nsISupports* temp = nullptr;
|
||||
swap(temp);
|
||||
return already_AddRefed<nsISupports>(temp);
|
||||
}
|
||||
|
||||
// Set the target of aRhs to the value of mRawPtr and null out mRawPtr.
|
||||
// Useful to avoid unnecessary AddRef/Release pairs with "out"
|
||||
// parameters.
|
||||
void forget(nsISupports** aRhs) {
|
||||
NS_ASSERTION(aRhs, "Null pointer passed to forget!");
|
||||
*aRhs = nullptr;
|
||||
swap(*aRhs);
|
||||
}
|
||||
|
||||
// Other pointer operators
|
||||
|
||||
// Prefer the implicit conversion provided automatically by
|
||||
// |operator nsISupports*() const|. Use |get()| to resolve ambiguity or to
|
||||
// get a castable pointer.
|
||||
nsISupports* get() const { return reinterpret_cast<nsISupports*>(mRawPtr); }
|
||||
|
||||
// Makes an nsCOMPtr 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 nsCOMPtr substitutable for a raw pointer.
|
||||
//
|
||||
// Prefer the implicit use of this operator to calling |get()|, except where
|
||||
// necessary to resolve ambiguity/
|
||||
operator nsISupports*() const { return get(); }
|
||||
|
||||
nsISupports* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN {
|
||||
MOZ_ASSERT(mRawPtr != nullptr,
|
||||
"You can't dereference a NULL nsCOMPtr with operator->().");
|
||||
return get();
|
||||
}
|
||||
|
||||
// These are not intended to be used by clients. See |address_of| below.
|
||||
nsCOMPtr<nsISupports>* get_address() { return this; }
|
||||
const nsCOMPtr<nsISupports>* get_address() const { return this; }
|
||||
|
||||
public:
|
||||
nsISupports& operator*() const {
|
||||
MOZ_ASSERT(mRawPtr != nullptr,
|
||||
"You can't dereference a NULL nsCOMPtr with operator*().");
|
||||
return *get();
|
||||
}
|
||||
|
||||
nsISupports** StartAssignment() {
|
||||
#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
|
||||
return reinterpret_cast<nsISupports**>(begin_assignment());
|
||||
#else
|
||||
assign_assuming_AddRef(nullptr);
|
||||
return reinterpret_cast<nsISupports**>(&mRawPtr);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline void ImplCycleCollectionUnlink(nsCOMPtr<T>& aField) {
|
||||
aField = nullptr;
|
||||
|
@ -1142,8 +813,11 @@ template <class T>
|
|||
template <typename U>
|
||||
void nsCOMPtr<T>::assign_from_qi(const nsQueryInterface<U> aQI,
|
||||
const nsIID& aIID) {
|
||||
// Allow QIing to nsISupports from nsISupports as a special-case, since
|
||||
// SameCOMIdentity uses it.
|
||||
static_assert(
|
||||
!(std::is_same_v<T, U> || std::is_base_of<T, U>::value),
|
||||
std::is_same_v<T, nsISupports> ||
|
||||
!(std::is_same_v<T, U> || std::is_base_of<T, U>::value),
|
||||
"don't use do_QueryInterface for compile-time-determinable casts");
|
||||
void* newRawPtr;
|
||||
if (NS_FAILED(aQI(aIID, &newRawPtr))) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче