From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- xpcom/base/nsAutoPtr.h | 454 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 454 insertions(+) create mode 100644 xpcom/base/nsAutoPtr.h (limited to 'xpcom/base/nsAutoPtr.h') diff --git a/xpcom/base/nsAutoPtr.h b/xpcom/base/nsAutoPtr.h new file mode 100644 index 000000000..b5a15000c --- /dev/null +++ b/xpcom/base/nsAutoPtr.h @@ -0,0 +1,454 @@ +/* -*- 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/. */ + +#ifndef nsAutoPtr_h +#define nsAutoPtr_h + +#include "nsCOMPtr.h" +#include "mozilla/RefPtr.h" +#include "mozilla/TypeTraits.h" + +#include "nsCycleCollectionNoteChild.h" +#include "mozilla/MemoryReporting.h" + +/*****************************************************************************/ + +// template class nsAutoPtrGetterTransfers; + +template +class nsAutoPtr +{ +private: + static_assert(!mozilla::IsScalar::value, "If you are using " + "nsAutoPtr to hold an array, use UniquePtr instead"); + + void** + begin_assignment() + { + assign(0); + return reinterpret_cast(&mRawPtr); + } + + void + assign(T* aNewPtr) + { + T* oldPtr = mRawPtr; + + if (aNewPtr && aNewPtr == oldPtr) { + NS_RUNTIMEABORT("Logic flaw in the caller"); + } + + mRawPtr = aNewPtr; + delete oldPtr; + } + + // |class Ptr| helps us prevent implicit "copy construction" + // through |operator T*() const| from a |const nsAutoPtr| + // because two implicit conversions in a row aren't allowed. + // It still allows assignment from T* through implicit conversion + // from |T*| to |nsAutoPtr::Ptr| + class Ptr + { + public: + MOZ_IMPLICIT Ptr(T* aPtr) + : mPtr(aPtr) + { + } + + operator T*() const + { + return mPtr; + } + + private: + T* MOZ_NON_OWNING_REF mPtr; + }; + +private: + T* MOZ_OWNING_REF mRawPtr; + +public: + typedef T element_type; + + ~nsAutoPtr() + { + delete mRawPtr; + } + + // Constructors + + nsAutoPtr() + : mRawPtr(0) + // default constructor + { + } + + MOZ_IMPLICIT nsAutoPtr(Ptr aRawPtr) + : mRawPtr(aRawPtr) + // construct from a raw pointer (of the right type) + { + } + + // This constructor shouldn't exist; we should just use the && + // constructor. + nsAutoPtr(nsAutoPtr& aSmartPtr) + : mRawPtr(aSmartPtr.forget()) + // Construct by transferring ownership from another smart pointer. + { + } + + template + MOZ_IMPLICIT nsAutoPtr(nsAutoPtr& aSmartPtr) + : mRawPtr(aSmartPtr.forget()) + // Construct by transferring ownership from another smart pointer. + { + } + + nsAutoPtr(nsAutoPtr&& aSmartPtr) + : mRawPtr(aSmartPtr.forget()) + // Construct by transferring ownership from another smart pointer. + { + } + + template + MOZ_IMPLICIT nsAutoPtr(nsAutoPtr&& aSmartPtr) + : mRawPtr(aSmartPtr.forget()) + // Construct by transferring ownership from another smart pointer. + { + } + + // Assignment operators + + nsAutoPtr& + operator=(T* aRhs) + // assign from a raw pointer (of the right type) + { + assign(aRhs); + return *this; + } + + nsAutoPtr& operator=(nsAutoPtr& aRhs) + // assign by transferring ownership from another smart pointer. + { + assign(aRhs.forget()); + return *this; + } + + template + nsAutoPtr& operator=(nsAutoPtr& aRhs) + // assign by transferring ownership from another smart pointer. + { + assign(aRhs.forget()); + return *this; + } + + nsAutoPtr& operator=(nsAutoPtr&& aRhs) + { + assign(aRhs.forget()); + return *this; + } + + template + nsAutoPtr& operator=(nsAutoPtr&& aRhs) + { + assign(aRhs.forget()); + return *this; + } + + // Other pointer operators + + T* + get() const + /* + Prefer the implicit conversion provided automatically by + |operator T*() const|. Use |get()| _only_ to resolve + ambiguity. + */ + { + return mRawPtr; + } + + operator T*() const + /* + ...makes an |nsAutoPtr| 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 |nsAutoPtr| + substitutable for a raw pointer. + + Prefer the implicit use of this operator to calling |get()|, + except where necessary to resolve ambiguity. + */ + { + return get(); + } + + T* + forget() + { + T* temp = mRawPtr; + mRawPtr = 0; + return temp; + } + + T* + operator->() const + { + NS_PRECONDITION(mRawPtr != 0, + "You can't dereference a NULL nsAutoPtr with operator->()."); + return get(); + } + + template + class Proxy + { + typedef R (T::*member_function)(Args...); + T* mRawPtr; + member_function mFunction; + public: + Proxy(T* aRawPtr, member_function aFunction) + : mRawPtr(aRawPtr), + mFunction(aFunction) + { + } + template + R operator()(ActualArgs&&... aArgs) + { + return ((*mRawPtr).*mFunction)(mozilla::Forward(aArgs)...); + } + }; + + template + Proxy operator->*(R (C::*aFptr)(Args...)) const + { + NS_PRECONDITION(mRawPtr != 0, + "You can't dereference a NULL nsAutoPtr with operator->*()."); + return Proxy(get(), aFptr); + } + + nsAutoPtr* + get_address() + // This is not intended to be used by clients. See |address_of| + // below. + { + return this; + } + + const nsAutoPtr* + get_address() const + // This is not intended to be used by clients. See |address_of| + // below. + { + return this; + } + +public: + T& + operator*() const + { + NS_PRECONDITION(mRawPtr != 0, + "You can't dereference a NULL nsAutoPtr with operator*()."); + return *get(); + } + + T** + StartAssignment() + { +#ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT + return reinterpret_cast(begin_assignment()); +#else + assign(0); + return reinterpret_cast(&mRawPtr); +#endif + } +}; + +template +inline nsAutoPtr* +address_of(nsAutoPtr& aPtr) +{ + return aPtr.get_address(); +} + +template +inline const nsAutoPtr* +address_of(const nsAutoPtr& aPtr) +{ + return aPtr.get_address(); +} + +template +class nsAutoPtrGetterTransfers +/* + ... + + This class is designed to be used for anonymous temporary objects in the + argument list of calls that return COM interface pointers, e.g., + + nsAutoPtr fooP; + ...->GetTransferedPointer(getter_Transfers(fooP)) + + DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE. Use |getter_Transfers()| instead. + + When initialized with a |nsAutoPtr|, as in the example above, it returns + a |void**|, a |T**|, or an |nsISupports**| as needed, that the + outer call (|GetTransferedPointer| in this case) can fill in. + + This type should be a nested class inside |nsAutoPtr|. +*/ +{ +public: + explicit + nsAutoPtrGetterTransfers(nsAutoPtr& aSmartPtr) + : mTargetSmartPtr(aSmartPtr) + { + // nothing else to do + } + + operator void**() + { + return reinterpret_cast(mTargetSmartPtr.StartAssignment()); + } + + operator T**() + { + return mTargetSmartPtr.StartAssignment(); + } + + T*& + operator*() + { + return *(mTargetSmartPtr.StartAssignment()); + } + +private: + nsAutoPtr& mTargetSmartPtr; +}; + +template +inline nsAutoPtrGetterTransfers +getter_Transfers(nsAutoPtr& aSmartPtr) +/* + Used around a |nsAutoPtr| when + ...makes the class |nsAutoPtrGetterTransfers| invisible. +*/ +{ + return nsAutoPtrGetterTransfers(aSmartPtr); +} + + + +// Comparing two |nsAutoPtr|s + +template +inline bool +operator==(const nsAutoPtr& aLhs, const nsAutoPtr& aRhs) +{ + return static_cast(aLhs.get()) == static_cast(aRhs.get()); +} + + +template +inline bool +operator!=(const nsAutoPtr& aLhs, const nsAutoPtr& aRhs) +{ + return static_cast(aLhs.get()) != static_cast(aRhs.get()); +} + + +// Comparing an |nsAutoPtr| to a raw pointer + +template +inline bool +operator==(const nsAutoPtr& aLhs, const U* aRhs) +{ + return static_cast(aLhs.get()) == static_cast(aRhs); +} + +template +inline bool +operator==(const U* aLhs, const nsAutoPtr& aRhs) +{ + return static_cast(aLhs) == static_cast(aRhs.get()); +} + +template +inline bool +operator!=(const nsAutoPtr& aLhs, const U* aRhs) +{ + return static_cast(aLhs.get()) != static_cast(aRhs); +} + +template +inline bool +operator!=(const U* aLhs, const nsAutoPtr& aRhs) +{ + return static_cast(aLhs) != static_cast(aRhs.get()); +} + +template +inline bool +operator==(const nsAutoPtr& aLhs, U* aRhs) +{ + return static_cast(aLhs.get()) == const_cast(aRhs); +} + +template +inline bool +operator==(U* aLhs, const nsAutoPtr& aRhs) +{ + return const_cast(aLhs) == static_cast(aRhs.get()); +} + +template +inline bool +operator!=(const nsAutoPtr& aLhs, U* aRhs) +{ + return static_cast(aLhs.get()) != const_cast(aRhs); +} + +template +inline bool +operator!=(U* aLhs, const nsAutoPtr& aRhs) +{ + return const_cast(aLhs) != static_cast(aRhs.get()); +} + + + +// Comparing an |nsAutoPtr| to |nullptr| + +template +inline bool +operator==(const nsAutoPtr& aLhs, decltype(nullptr)) +{ + return aLhs.get() == nullptr; +} + +template +inline bool +operator==(decltype(nullptr), const nsAutoPtr& aRhs) +{ + return nullptr == aRhs.get(); +} + +template +inline bool +operator!=(const nsAutoPtr& aLhs, decltype(nullptr)) +{ + return aLhs.get() != nullptr; +} + +template +inline bool +operator!=(decltype(nullptr), const nsAutoPtr& aRhs) +{ + return nullptr != aRhs.get(); +} + + +/*****************************************************************************/ + +#endif // !defined(nsAutoPtr_h) -- cgit v1.2.3