diff options
Diffstat (limited to 'onlineupdate/source/update/inc/nsAutoRef.h')
-rw-r--r-- | onlineupdate/source/update/inc/nsAutoRef.h | 670 |
1 files changed, 0 insertions, 670 deletions
diff --git a/onlineupdate/source/update/inc/nsAutoRef.h b/onlineupdate/source/update/inc/nsAutoRef.h deleted file mode 100644 index a159f5954e96..000000000000 --- a/onlineupdate/source/update/inc/nsAutoRef.h +++ /dev/null @@ -1,670 +0,0 @@ -/* -*- 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 nsAutoRef_h_ -#define nsAutoRef_h_ - -#include "mozilla/Attributes.h" - -template <class T> class nsSimpleRef; -template <class T> class nsAutoRefBase; -template <class T> class nsReturnRef; -template <class T> class nsReturningRef; - -/** - * template <class T> class nsAutoRef - * - * A class that holds a handle to a resource that must be released. - * No reference is added on construction. - * - * No copy constructor nor copy assignment operators are available, so the - * resource will be held until released on destruction or explicitly - * |reset()| or transferred through provided methods. - * - * The publicly available methods are the public methods on this class and its - * public base classes |nsAutoRefBase<T>| and |nsSimpleRef<T>|. - * - * For ref-counted resources see also |nsCountedRef<T>|. - * For function return values see |nsReturnRef<T>|. - * - * For each class |T|, |nsAutoRefTraits<T>| or |nsSimpleRef<T>| must be - * specialized to use |nsAutoRef<T>| and |nsCountedRef<T>|. - * - * @param T A class identifying the type of reference held by the - * |nsAutoRef<T>| and the unique set methods for managing references - * to the resource (defined by |nsAutoRefTraits<T>| or - * |nsSimpleRef<T>|). - * - * Often this is the class representing the resource. Sometimes a - * new possibly-incomplete class may need to be declared. - * - * - * Example: An Automatically closing file descriptor - * - * // References that are simple integral types (as file-descriptors are) - * // usually need a new class to represent the resource and how to handle its - * // references. - * class nsRawFD; - * - * // Specializing nsAutoRefTraits<nsRawFD> describes how to manage file - * // descriptors, so that nsAutoRef<nsRawFD> provides automatic closing of - * // its file descriptor on destruction. - * template <> - * class nsAutoRefTraits<nsRawFD> { - * public: - * // The file descriptor is held in an int. - * typedef int RawRef; - * // -1 means that there is no file associated with the handle. - * static int Void() { return -1; } - * // The file associated with a file descriptor is released with close(). - * static void Release(RawRef aFD) { close(aFD); } - * }; - * - * // A function returning a file descriptor that must be closed. - * nsReturnRef<nsRawFD> get_file(const char *filename) { - * // Constructing from a raw file descriptor assumes ownership. - * nsAutoRef<nsRawFD> fd(open(filename, O_RDONLY)); - * fcntl(fd, F_SETFD, FD_CLOEXEC); - * return fd.out(); - * } - * - * void f() { - * unsigned char buf[1024]; - * - * // Hold a file descriptor for /etc/hosts in fd1. - * nsAutoRef<nsRawFD> fd1(get_file("/etc/hosts")); - * - * nsAutoRef<nsRawFD> fd2; - * fd2.steal(fd1); // fd2 takes the file descriptor from fd1 - * ssize_t count = read(fd1, buf, 1024); // error fd1 has no file - * count = read(fd2, buf, 1024); // reads from /etc/hosts - * - * // If the file descriptor is not stored then it is closed. - * get_file("/etc/login.defs"); // login.defs is closed - * - * // Now use fd1 to hold a file descriptor for /etc/passwd. - * fd1 = get_file("/etc/passwd"); - * - * // The nsAutoRef<nsRawFD> can give up the file descriptor if explicitly - * // instructed, but the caller must then ensure that the file is closed. - * int rawfd = fd1.disown(); - * - * // Assume ownership of another file descriptor. - * fd1.own(open("/proc/1/maps"); - * - * // On destruction, fd1 closes /proc/1/maps and fd2 closes /etc/hosts, - * // but /etc/passwd is not closed. - * } - * - */ - - -template <class T> -class nsAutoRef : public nsAutoRefBase<T> -{ -protected: - typedef nsAutoRef<T> ThisClass; - typedef nsAutoRefBase<T> BaseClass; - typedef nsSimpleRef<T> SimpleRef; - typedef typename BaseClass::RawRefOnly RawRefOnly; - typedef typename BaseClass::LocalSimpleRef LocalSimpleRef; - -public: - nsAutoRef() - { - } - - // Explicit construction is required so as not to risk unintentionally - // releasing the resource associated with a raw ref. - explicit nsAutoRef(RawRefOnly aRefToRelease) - : BaseClass(aRefToRelease) - { - } - - // Construction from a nsReturnRef<T> function return value, which expects - // to give up ownership, transfers ownership. - // (nsReturnRef<T> is converted to const nsReturningRef<T>.) - explicit nsAutoRef(const nsReturningRef<T>& aReturning) - : BaseClass(aReturning) - { - } - - // The only assignment operator provided is for transferring from an - // nsReturnRef smart reference, which expects to pass its ownership to - // another object. - // - // With raw references and other smart references, the type of the lhs and - // its taking and releasing nature is often not obvious from an assignment - // statement. Assignment from a raw ptr especially is not normally - // expected to release the reference. - // - // Use |steal| for taking ownership from other smart refs. - // - // For raw references, use |own| to indicate intention to have the - // resource released. - // - // Or, to create another owner of the same reference, use an nsCountedRef. - - ThisClass& operator=(const nsReturningRef<T>& aReturning) - { - BaseClass::steal(aReturning.mReturnRef); - return *this; - } - - // Conversion to a raw reference allow the nsAutoRef<T> to often be used - // like a raw reference. - operator typename SimpleRef::RawRef() const - { - return this->get(); - } - - // Transfer ownership from another smart reference. - void steal(ThisClass& aOtherRef) - { - BaseClass::steal(aOtherRef); - } - - // Assume ownership of a raw ref. - // - // |own| has similar function to |steal|, and is useful for receiving - // ownership from a return value of a function. It is named differently - // because |own| requires more care to ensure that the function intends to - // give away ownership, and so that |steal| can be safely used, knowing - // that it won't steal ownership from any methods returning raw ptrs to - // data owned by a foreign object. - void own(RawRefOnly aRefToRelease) - { - BaseClass::own(aRefToRelease); - } - - // Exchange ownership with |aOther| - void swap(ThisClass& aOther) - { - LocalSimpleRef temp; - temp.SimpleRef::operator=(*this); - SimpleRef::operator=(aOther); - aOther.SimpleRef::operator=(temp); - } - - // Release the reference now. - void reset() - { - this->SafeRelease(); - LocalSimpleRef empty; - SimpleRef::operator=(empty); - } - - // Pass out the reference for a function return values. - nsReturnRef<T> out() - { - return nsReturnRef<T>(this->disown()); - } - - // operator->() and disown() are provided by nsAutoRefBase<T>. - // The default nsSimpleRef<T> provides get(). - -private: - // No copy constructor - explicit nsAutoRef(ThisClass& aRefToSteal); -}; - -/** - * template <class T> class nsCountedRef - * - * A class that creates (adds) a new reference to a resource on construction - * or assignment and releases on destruction. - * - * This class is similar to nsAutoRef<T> and inherits its methods, but also - * provides copy construction and assignment operators that enable more than - * one concurrent reference to the same resource. - * - * Specialize |nsAutoRefTraits<T>| or |nsSimpleRef<T>| to use this. This - * class assumes that the resource itself counts references and so can only be - * used when |T| represents a reference-counting resource. - */ - -template <class T> -class nsCountedRef : public nsAutoRef<T> -{ -protected: - typedef nsCountedRef<T> ThisClass; - typedef nsAutoRef<T> BaseClass; - typedef nsSimpleRef<T> SimpleRef; - typedef typename BaseClass::RawRef RawRef; - -public: - nsCountedRef() - { - } - - // Construction and assignment from a another nsCountedRef - // or a raw ref copies and increments the ref count. - nsCountedRef(const ThisClass& aRefToCopy) - { - SimpleRef::operator=(aRefToCopy); - SafeAddRef(); - } - ThisClass& operator=(const ThisClass& aRefToCopy) - { - if (this == &aRefToCopy) { - return *this; - } - - this->SafeRelease(); - SimpleRef::operator=(aRefToCopy); - SafeAddRef(); - return *this; - } - - // Implicit conversion from another smart ref argument (to a raw ref) is - // accepted here because construction and assignment safely creates a new - // reference without interfering with the reference to copy. - explicit nsCountedRef(RawRef aRefToCopy) - : BaseClass(aRefToCopy) - { - SafeAddRef(); - } - ThisClass& operator=(RawRef aRefToCopy) - { - this->own(aRefToCopy); - SafeAddRef(); - return *this; - } - - // Construction and assignment from an nsReturnRef function return value, - // which expects to give up ownership, transfers ownership. - explicit nsCountedRef(const nsReturningRef<T>& aReturning) - : BaseClass(aReturning) - { - } - ThisClass& operator=(const nsReturningRef<T>& aReturning) - { - BaseClass::operator=(aReturning); - return *this; - } - -protected: - // Increase the reference count if there is a resource. - void SafeAddRef() - { - if (this->HaveResource()) { - this->AddRef(this->get()); - } - } -}; - -/** - * template <class T> class nsReturnRef - * - * A type for function return values that hold a reference to a resource that - * must be released. See also |nsAutoRef<T>::out()|. - */ - -template <class T> -class nsReturnRef : public nsAutoRefBase<T> -{ -protected: - typedef nsAutoRefBase<T> BaseClass; - typedef typename BaseClass::RawRefOnly RawRefOnly; - -public: - // For constructing a return value with no resource - nsReturnRef() - { - } - - // For returning a smart reference from a raw reference that must be - // released. Explicit construction is required so as not to risk - // unintentionally releasing the resource associated with a raw ref. - MOZ_IMPLICIT nsReturnRef(RawRefOnly aRefToRelease) - : BaseClass(aRefToRelease) - { - } - - // Copy construction transfers ownership - nsReturnRef(nsReturnRef<T>& aRefToSteal) - : BaseClass(aRefToSteal) - { - } - - MOZ_IMPLICIT nsReturnRef(const nsReturningRef<T>& aReturning) - : BaseClass(aReturning) - { - } - - // Conversion to a temporary (const) object referring to this object so - // that the reference may be passed from a function return value - // (temporary) to another smart reference. There is no need to use this - // explicitly. Simply assign a nsReturnRef<T> function return value to a - // smart reference. - operator nsReturningRef<T>() - { - return nsReturningRef<T>(*this); - } - - // No conversion to RawRef operator is provided on nsReturnRef, to ensure - // that the return value is not carelessly assigned to a raw ptr (and the - // resource then released). If passing to a function that takes a raw - // ptr, use get or disown as appropriate. -}; - -/** - * template <class T> class nsReturningRef - * - * A class to allow ownership to be transferred from nsReturnRef function - * return values. - * - * It should not be necessary for clients to reference this - * class directly. Simply pass an nsReturnRef<T> to a parameter taking an - * |nsReturningRef<T>|. - * - * The conversion operator on nsReturnRef constructs a temporary wrapper of - * class nsReturningRef<T> around a non-const reference to the nsReturnRef. - * The wrapper can then be passed as an rvalue parameter. - */ - -template <class T> -class nsReturningRef -{ -private: - friend class nsReturnRef<T>; - - explicit nsReturningRef(nsReturnRef<T>& aReturnRef) - : mReturnRef(aReturnRef) - { - } -public: - nsReturnRef<T>& mReturnRef; -}; - -/** - * template <class T> class nsAutoRefTraits - * - * A class describing traits of references managed by the default - * |nsSimpleRef<T>| implementation and thus |nsAutoRef<T>| and |nsCountedRef|. - * The default |nsSimpleRef<T> is suitable for resources with handles that - * have a void value. (If there is no such void value for a handle, - * specialize |nsSimpleRef<T>|.) - * - * Specializations must be provided for each class |T| according to the - * following pattern: - * - * // The template parameter |T| should be a class such that the set of fields - * // in class nsAutoRefTraits<T> is unique for class |T|. Usually the - * // resource object class is sufficient. For handles that are simple - * // integral typedefs, a new unique possibly-incomplete class may need to be - * // declared. - * - * template <> - * class nsAutoRefTraits<T> - * { - * // Specializations must provide a typedef for RawRef, describing the - * // type of the handle to the resource. - * typedef <handle-type> RawRef; - * - * // Specializations should define Void(), a function returning a value - * // suitable for a handle that does not have an associated resource. - * // - * // The return type must be a suitable as the parameter to a RawRef - * // constructor and operator==. - * // - * // If this method is not accessible then some limited nsAutoRef - * // functionality will still be available, but the default constructor, - * // |reset|, and most transfer of ownership methods will not be available. - * static <return-type> Void(); - * - * // Specializations must define Release() to properly finalize the - * // handle to a non-void custom-deleted or reference-counted resource. - * static void Release(RawRef aRawRef); - * - * // For reference-counted resources, if |nsCountedRef<T>| is to be used, - * // specializations must define AddRef to increment the reference count - * // held by a non-void handle. - * // (AddRef() is not necessary for |nsAutoRef<T>|.) - * static void AddRef(RawRef aRawRef); - * }; - * - * See nsPointerRefTraits for example specializations for simple pointer - * references. See nsAutoRef for an example specialization for a non-pointer - * reference. - */ - -template <class T> class nsAutoRefTraits; - -/** - * template <class T> class nsPointerRefTraits - * - * A convenience class useful as a base class for specializations of - * |nsAutoRefTraits<T>| where the handle to the resource is a pointer to |T|. - * By inheriting from this class, definitions of only Release(RawRef) and - * possibly AddRef(RawRef) need to be added. - * - * Examples of use: - * - * template <> - * class nsAutoRefTraits<PRFileDesc> : public nsPointerRefTraits<PRFileDesc> - * { - * public: - * static void Release(PRFileDesc *ptr) { PR_Close(ptr); } - * }; - * - * template <> - * class nsAutoRefTraits<FcPattern> : public nsPointerRefTraits<FcPattern> - * { - * public: - * static void Release(FcPattern *ptr) { FcPatternDestroy(ptr); } - * static void AddRef(FcPattern *ptr) { FcPatternReference(ptr); } - * }; - */ - -template <class T> -class nsPointerRefTraits -{ -public: - // The handle is a pointer to T. - typedef T* RawRef; - // A nullptr does not have a resource. - static RawRef Void() - { - return nullptr; - } -}; - -/** - * template <class T> class nsSimpleRef - * - * Constructs a non-smart reference, and provides methods to test whether - * there is an associated resource and (if so) get its raw handle. - * - * A default implementation is suitable for resources with handles that have a - * void value. This is not intended for direct use but used by |nsAutoRef<T>| - * and thus |nsCountedRef<T>|. - * - * Specialize this class if there is no particular void value for the resource - * handle. A specialized implementation must also provide Release(RawRef), - * and, if |nsCountedRef<T>| is required, AddRef(RawRef), as described in - * nsAutoRefTraits<T>. - */ - -template <class T> -class nsSimpleRef : protected nsAutoRefTraits<T> -{ -protected: - // The default implementation uses nsAutoRefTrait<T>. - // Specializations need not define this typedef. - typedef nsAutoRefTraits<T> Traits; - // The type of the handle to the resource. - // A specialization must provide a typedef for RawRef. - typedef typename Traits::RawRef RawRef; - - // Construct with no resource. - // - // If this constructor is not accessible then some limited nsAutoRef - // functionality will still be available, but the default constructor, - // |reset|, and most transfer of ownership methods will not be available. - nsSimpleRef() - : mRawRef(Traits::Void()) - { - } - // Construct with a handle to a resource. - // A specialization must provide this. - explicit nsSimpleRef(RawRef aRawRef) - : mRawRef(aRawRef) - { - } - - // Test whether there is an associated resource. A specialization must - // provide this. The function is permitted to always return true if the - // default constructor is not accessible, or if Release (and AddRef) can - // deal with void handles. - bool HaveResource() const - { - return mRawRef != Traits::Void(); - } - -public: - // A specialization must provide get() or loose some functionality. This - // is inherited by derived classes and the specialization may choose - // whether it is public or protected. - RawRef get() const - { - return mRawRef; - } - -private: - RawRef mRawRef; -}; - - -/** - * template <class T> class nsAutoRefBase - * - * Internal base class for |nsAutoRef<T>| and |nsReturnRef<T>|. - * Adds release on destruction to a |nsSimpleRef<T>|. - */ - -template <class T> -class nsAutoRefBase : public nsSimpleRef<T> -{ -protected: - typedef nsAutoRefBase<T> ThisClass; - typedef nsSimpleRef<T> SimpleRef; - typedef typename SimpleRef::RawRef RawRef; - - nsAutoRefBase() - { - } - - // A type for parameters that should be passed a raw ref but should not - // accept implicit conversions (from another smart ref). (The only - // conversion to this type is from a raw ref so only raw refs will be - // accepted.) - class RawRefOnly - { - public: - MOZ_IMPLICIT RawRefOnly(RawRef aRawRef) - : mRawRef(aRawRef) - { - } - operator RawRef() const - { - return mRawRef; - } - private: - RawRef mRawRef; - }; - - // Construction from a raw ref assumes ownership - explicit nsAutoRefBase(RawRefOnly aRefToRelease) - : SimpleRef(aRefToRelease) - { - } - - // Constructors that steal ownership - explicit nsAutoRefBase(ThisClass& aRefToSteal) - : SimpleRef(aRefToSteal.disown()) - { - } - explicit nsAutoRefBase(const nsReturningRef<T>& aReturning) - : SimpleRef(aReturning.mReturnRef.disown()) - { - } - - ~nsAutoRefBase() - { - SafeRelease(); - } - - // An internal class providing access to protected nsSimpleRef<T> - // constructors for construction of temporary simple references (that are - // not ThisClass). - class LocalSimpleRef : public SimpleRef - { - public: - LocalSimpleRef() - { - } - explicit LocalSimpleRef(RawRef aRawRef) - : SimpleRef(aRawRef) - { - } - }; - -private: - ThisClass& operator=(const ThisClass& aSmartRef) = delete; - -public: - RawRef operator->() const - { - return this->get(); - } - - // Transfer ownership to a raw reference. - // - // THE CALLER MUST ENSURE THAT THE REFERENCE IS EXPLICITLY RELEASED. - // - // Is this really what you want to use? Using this removes any guarantee - // of release. Use nsAutoRef<T>::out() for return values, or an - // nsAutoRef<T> modifiable lvalue for an out parameter. Use disown() when - // the reference must be stored in a POD type object, such as may be - // preferred for a namespace-scope object with static storage duration, - // for example. - RawRef disown() - { - RawRef temp = this->get(); - LocalSimpleRef empty; - SimpleRef::operator=(empty); - return temp; - } - -protected: - // steal and own are protected because they make no sense on nsReturnRef, - // but steal is implemented on this class for access to aOtherRef.disown() - // when aOtherRef is an nsReturnRef; - - // Transfer ownership from another smart reference. - void steal(ThisClass& aOtherRef) - { - own(aOtherRef.disown()); - } - // Assume ownership of a raw ref. - void own(RawRefOnly aRefToRelease) - { - SafeRelease(); - LocalSimpleRef ref(aRefToRelease); - SimpleRef::operator=(ref); - } - - // Release a resource if there is one. - void SafeRelease() - { - if (this->HaveResource()) { - this->Release(this->get()); - } - } -}; - -#endif // !defined(nsAutoRef_h_) |