LCOV - code coverage report
Current view: top level - xpcom/base - nsAutoPtr.h (source / functions) Hit Total Coverage
Test: output.info Lines: 69 84 82.1 %
Date: 2017-07-14 16:53:18 Functions: 945 3736 25.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef nsAutoPtr_h
       8             : #define nsAutoPtr_h
       9             : 
      10             : #include "nsCOMPtr.h"
      11             : #include "mozilla/RefPtr.h"
      12             : #include "mozilla/TypeTraits.h"
      13             : 
      14             : #include "nsCycleCollectionNoteChild.h"
      15             : #include "mozilla/MemoryReporting.h"
      16             : 
      17             : /*****************************************************************************/
      18             : 
      19             : // template <class T> class nsAutoPtrGetterTransfers;
      20             : 
      21             : template <class T>
      22             : class nsAutoPtr
      23             : {
      24             : private:
      25             :   static_assert(!mozilla::IsScalar<T>::value, "If you are using "
      26             :                 "nsAutoPtr to hold an array, use UniquePtr<T[]> instead");
      27             : 
      28             :   void**
      29        9219 :   begin_assignment()
      30             :   {
      31        9219 :     assign(0);
      32        9219 :     return reinterpret_cast<void**>(&mRawPtr);
      33             :   }
      34             : 
      35             :   void
      36       25614 :   assign(T* aNewPtr)
      37             :   {
      38       25614 :     T* oldPtr = mRawPtr;
      39             : 
      40       25614 :     if (aNewPtr && aNewPtr == oldPtr) {
      41           0 :       MOZ_CRASH("Logic flaw in the caller");
      42             :     }
      43             : 
      44       25614 :     mRawPtr = aNewPtr;
      45       24359 :     delete oldPtr;
      46       25614 :   }
      47             : 
      48             :   // |class Ptr| helps us prevent implicit "copy construction"
      49             :   // through |operator T*() const| from a |const nsAutoPtr<T>|
      50             :   // because two implicit conversions in a row aren't allowed.
      51             :   // It still allows assignment from T* through implicit conversion
      52             :   // from |T*| to |nsAutoPtr<T>::Ptr|
      53             :   class Ptr
      54             :   {
      55             :   public:
      56      104953 :     MOZ_IMPLICIT Ptr(T* aPtr)
      57      104953 :       : mPtr(aPtr)
      58             :     {
      59      104953 :     }
      60             : 
      61      104955 :     operator T*() const
      62             :     {
      63      104955 :       return mPtr;
      64             :     }
      65             : 
      66             :   private:
      67             :     T* MOZ_NON_OWNING_REF mPtr;
      68             :   };
      69             : 
      70             : private:
      71             :   T* MOZ_OWNING_REF mRawPtr;
      72             : 
      73             : public:
      74             :   typedef T element_type;
      75             : 
      76      141652 :   ~nsAutoPtr()
      77             :   {
      78      141652 :     delete mRawPtr;
      79      141652 :   }
      80             : 
      81             :   // Constructors
      82             : 
      83       59009 :   nsAutoPtr()
      84       59009 :     : mRawPtr(0)
      85             :     // default constructor
      86             :   {
      87       59009 :   }
      88             : 
      89      104955 :   MOZ_IMPLICIT nsAutoPtr(Ptr aRawPtr)
      90      104955 :     : mRawPtr(aRawPtr)
      91             :     // construct from a raw pointer (of the right type)
      92             :   {
      93      104956 :   }
      94             : 
      95             :   // This constructor shouldn't exist; we should just use the &&
      96             :   // constructor.
      97        1237 :   nsAutoPtr(nsAutoPtr<T>& aSmartPtr)
      98        1237 :     : mRawPtr(aSmartPtr.forget())
      99             :     // Construct by transferring ownership from another smart pointer.
     100             :   {
     101        1237 :   }
     102             : 
     103             :   template <typename I>
     104             :   MOZ_IMPLICIT nsAutoPtr(nsAutoPtr<I>& aSmartPtr)
     105             :     : mRawPtr(aSmartPtr.forget())
     106             :     // Construct by transferring ownership from another smart pointer.
     107             :   {
     108             :   }
     109             : 
     110         273 :   nsAutoPtr(nsAutoPtr<T>&& aSmartPtr)
     111         273 :     : mRawPtr(aSmartPtr.forget())
     112             :     // Construct by transferring ownership from another smart pointer.
     113             :   {
     114         273 :   }
     115             : 
     116             :   template <typename I>
     117             :   MOZ_IMPLICIT nsAutoPtr(nsAutoPtr<I>&& aSmartPtr)
     118             :     : mRawPtr(aSmartPtr.forget())
     119             :     // Construct by transferring ownership from another smart pointer.
     120             :   {
     121             :   }
     122             : 
     123             :   // Assignment operators
     124             : 
     125             :   nsAutoPtr<T>&
     126       15620 :   operator=(T* aRhs)
     127             :   // assign from a raw pointer (of the right type)
     128             :   {
     129       15620 :     assign(aRhs);
     130       15620 :     return *this;
     131             :   }
     132             : 
     133         301 :   nsAutoPtr<T>& operator=(nsAutoPtr<T>& aRhs)
     134             :   // assign by transferring ownership from another smart pointer.
     135             :   {
     136         301 :     assign(aRhs.forget());
     137         301 :     return *this;
     138             :   }
     139             : 
     140             :   template <typename I>
     141             :   nsAutoPtr<T>& operator=(nsAutoPtr<I>& aRhs)
     142             :   // assign by transferring ownership from another smart pointer.
     143             :   {
     144             :     assign(aRhs.forget());
     145             :     return *this;
     146             :   }
     147             : 
     148         474 :   nsAutoPtr<T>& operator=(nsAutoPtr<T>&& aRhs)
     149             :   {
     150         474 :     assign(aRhs.forget());
     151         474 :     return *this;
     152             :   }
     153             : 
     154             :   template <typename I>
     155             :   nsAutoPtr<T>& operator=(nsAutoPtr<I>&& aRhs)
     156             :   {
     157             :     assign(aRhs.forget());
     158             :     return *this;
     159             :   }
     160             : 
     161             :   // Other pointer operators
     162             : 
     163             :   T*
     164     1368048 :   get() const
     165             :   /*
     166             :     Prefer the implicit conversion provided automatically by
     167             :     |operator T*() const|.  Use |get()| _only_ to resolve
     168             :     ambiguity.
     169             :   */
     170             :   {
     171     1368048 :     return mRawPtr;
     172             :   }
     173             : 
     174      541291 :   operator T*() const
     175             :   /*
     176             :     ...makes an |nsAutoPtr| act like its underlying raw pointer
     177             :     type  whenever it is used in a context where a raw pointer
     178             :     is expected.  It is this operator that makes an |nsAutoPtr|
     179             :     substitutable for a raw pointer.
     180             : 
     181             :     Prefer the implicit use of this operator to calling |get()|,
     182             :     except where necessary to resolve ambiguity.
     183             :   */
     184             :   {
     185      541291 :     return get();
     186             :   }
     187             : 
     188             :   T*
     189       17579 :   forget()
     190             :   {
     191       17579 :     T* temp = mRawPtr;
     192       17579 :     mRawPtr = 0;
     193       17579 :     return temp;
     194             :   }
     195             : 
     196             :   T*
     197      824432 :   operator->() const
     198             :   {
     199      824432 :     NS_PRECONDITION(mRawPtr != 0,
     200             :                     "You can't dereference a NULL nsAutoPtr with operator->().");
     201      824432 :     return get();
     202             :   }
     203             : 
     204             :   template <typename R, typename... Args>
     205             :   class Proxy
     206             :   {
     207             :     typedef R (T::*member_function)(Args...);
     208             :     T* mRawPtr;
     209             :     member_function mFunction;
     210             :   public:
     211             :     Proxy(T* aRawPtr, member_function aFunction)
     212             :       : mRawPtr(aRawPtr),
     213             :         mFunction(aFunction)
     214             :     {
     215             :     }
     216             :     template<typename... ActualArgs>
     217             :     R operator()(ActualArgs&&... aArgs)
     218             :     {
     219             :       return ((*mRawPtr).*mFunction)(mozilla::Forward<ActualArgs>(aArgs)...);
     220             :     }
     221             :   };
     222             : 
     223             :   template <typename R, typename C, typename... Args>
     224             :   Proxy<R, Args...> operator->*(R (C::*aFptr)(Args...)) const
     225             :   {
     226             :     NS_PRECONDITION(mRawPtr != 0,
     227             :                     "You can't dereference a NULL nsAutoPtr with operator->*().");
     228             :     return Proxy<R, Args...>(get(), aFptr);
     229             :   }
     230             : 
     231             :   nsAutoPtr<T>*
     232             :   get_address()
     233             :   // This is not intended to be used by clients.  See |address_of|
     234             :   // below.
     235             :   {
     236             :     return this;
     237             :   }
     238             : 
     239             :   const nsAutoPtr<T>*
     240             :   get_address() const
     241             :   // This is not intended to be used by clients.  See |address_of|
     242             :   // below.
     243             :   {
     244             :     return this;
     245             :   }
     246             : 
     247             : public:
     248             :   T&
     249          59 :   operator*() const
     250             :   {
     251          59 :     NS_PRECONDITION(mRawPtr != 0,
     252             :                     "You can't dereference a NULL nsAutoPtr with operator*().");
     253          59 :     return *get();
     254             :   }
     255             : 
     256             :   T**
     257        9219 :   StartAssignment()
     258             :   {
     259             : #ifndef NSCAP_FEATURE_INLINE_STARTASSIGNMENT
     260        9219 :     return reinterpret_cast<T**>(begin_assignment());
     261             : #else
     262             :     assign(0);
     263             :     return reinterpret_cast<T**>(&mRawPtr);
     264             : #endif
     265             :   }
     266             : };
     267             : 
     268             : template <class T>
     269             : inline nsAutoPtr<T>*
     270             : address_of(nsAutoPtr<T>& aPtr)
     271             : {
     272             :   return aPtr.get_address();
     273             : }
     274             : 
     275             : template <class T>
     276             : inline const nsAutoPtr<T>*
     277             : address_of(const nsAutoPtr<T>& aPtr)
     278             : {
     279             :   return aPtr.get_address();
     280             : }
     281             : 
     282             : template <class T>
     283             : class nsAutoPtrGetterTransfers
     284             : /*
     285             :   ...
     286             : 
     287             :   This class is designed to be used for anonymous temporary objects in the
     288             :   argument list of calls that return COM interface pointers, e.g.,
     289             : 
     290             :     nsAutoPtr<IFoo> fooP;
     291             :     ...->GetTransferedPointer(getter_Transfers(fooP))
     292             : 
     293             :   DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.  Use |getter_Transfers()| instead.
     294             : 
     295             :   When initialized with a |nsAutoPtr|, as in the example above, it returns
     296             :   a |void**|, a |T**|, or an |nsISupports**| as needed, that the
     297             :   outer call (|GetTransferedPointer| in this case) can fill in.
     298             : 
     299             :   This type should be a nested class inside |nsAutoPtr<T>|.
     300             : */
     301             : {
     302             : public:
     303             :   explicit
     304        9219 :   nsAutoPtrGetterTransfers(nsAutoPtr<T>& aSmartPtr)
     305        9219 :     : mTargetSmartPtr(aSmartPtr)
     306             :   {
     307             :     // nothing else to do
     308        9219 :   }
     309             : 
     310           0 :   operator void**()
     311             :   {
     312           0 :     return reinterpret_cast<void**>(mTargetSmartPtr.StartAssignment());
     313             :   }
     314             : 
     315        9054 :   operator T**()
     316             :   {
     317        9054 :     return mTargetSmartPtr.StartAssignment();
     318             :   }
     319             : 
     320             :   T*&
     321         165 :   operator*()
     322             :   {
     323         165 :     return *(mTargetSmartPtr.StartAssignment());
     324             :   }
     325             : 
     326             : private:
     327             :   nsAutoPtr<T>& mTargetSmartPtr;
     328             : };
     329             : 
     330             : template <class T>
     331             : inline nsAutoPtrGetterTransfers<T>
     332        9219 : getter_Transfers(nsAutoPtr<T>& aSmartPtr)
     333             : /*
     334             :   Used around a |nsAutoPtr| when
     335             :   ...makes the class |nsAutoPtrGetterTransfers<T>| invisible.
     336             : */
     337             : {
     338        9219 :   return nsAutoPtrGetterTransfers<T>(aSmartPtr);
     339             : }
     340             : 
     341             : 
     342             : 
     343             : // Comparing two |nsAutoPtr|s
     344             : 
     345             : template <class T, class U>
     346             : inline bool
     347           0 : operator==(const nsAutoPtr<T>& aLhs, const nsAutoPtr<U>& aRhs)
     348             : {
     349           0 :   return static_cast<const T*>(aLhs.get()) == static_cast<const U*>(aRhs.get());
     350             : }
     351             : 
     352             : 
     353             : template <class T, class U>
     354             : inline bool
     355             : operator!=(const nsAutoPtr<T>& aLhs, const nsAutoPtr<U>& aRhs)
     356             : {
     357             :   return static_cast<const T*>(aLhs.get()) != static_cast<const U*>(aRhs.get());
     358             : }
     359             : 
     360             : 
     361             : // Comparing an |nsAutoPtr| to a raw pointer
     362             : 
     363             : template <class T, class U>
     364             : inline bool
     365           0 : operator==(const nsAutoPtr<T>& aLhs, const U* aRhs)
     366             : {
     367           0 :   return static_cast<const T*>(aLhs.get()) == static_cast<const U*>(aRhs);
     368             : }
     369             : 
     370             : template <class T, class U>
     371             : inline bool
     372           0 : operator==(const U* aLhs, const nsAutoPtr<T>& aRhs)
     373             : {
     374           0 :   return static_cast<const U*>(aLhs) == static_cast<const T*>(aRhs.get());
     375             : }
     376             : 
     377             : template <class T, class U>
     378             : inline bool
     379             : operator!=(const nsAutoPtr<T>& aLhs, const U* aRhs)
     380             : {
     381             :   return static_cast<const T*>(aLhs.get()) != static_cast<const U*>(aRhs);
     382             : }
     383             : 
     384             : template <class T, class U>
     385             : inline bool
     386           0 : operator!=(const U* aLhs, const nsAutoPtr<T>& aRhs)
     387             : {
     388           0 :   return static_cast<const U*>(aLhs) != static_cast<const T*>(aRhs.get());
     389             : }
     390             : 
     391             : template <class T, class U>
     392             : inline bool
     393          15 : operator==(const nsAutoPtr<T>& aLhs, U* aRhs)
     394             : {
     395          15 :   return static_cast<const T*>(aLhs.get()) == const_cast<const U*>(aRhs);
     396             : }
     397             : 
     398             : template <class T, class U>
     399             : inline bool
     400           0 : operator==(U* aLhs, const nsAutoPtr<T>& aRhs)
     401             : {
     402           0 :   return const_cast<const U*>(aLhs) == static_cast<const T*>(aRhs.get());
     403             : }
     404             : 
     405             : template <class T, class U>
     406             : inline bool
     407          22 : operator!=(const nsAutoPtr<T>& aLhs, U* aRhs)
     408             : {
     409          22 :   return static_cast<const T*>(aLhs.get()) != const_cast<const U*>(aRhs);
     410             : }
     411             : 
     412             : template <class T, class U>
     413             : inline bool
     414             : operator!=(U* aLhs, const nsAutoPtr<T>& aRhs)
     415             : {
     416             :   return const_cast<const U*>(aLhs) != static_cast<const T*>(aRhs.get());
     417             : }
     418             : 
     419             : 
     420             : 
     421             : // Comparing an |nsAutoPtr| to |nullptr|
     422             : 
     423             : template <class T>
     424             : inline bool
     425           0 : operator==(const nsAutoPtr<T>& aLhs, decltype(nullptr))
     426             : {
     427           0 :   return aLhs.get() == nullptr;
     428             : }
     429             : 
     430             : template <class T>
     431             : inline bool
     432             : operator==(decltype(nullptr), const nsAutoPtr<T>& aRhs)
     433             : {
     434             :   return nullptr == aRhs.get();
     435             : }
     436             : 
     437             : template <class T>
     438             : inline bool
     439           1 : operator!=(const nsAutoPtr<T>& aLhs, decltype(nullptr))
     440             : {
     441           1 :   return aLhs.get() != nullptr;
     442             : }
     443             : 
     444             : template <class T>
     445             : inline bool
     446             : operator!=(decltype(nullptr), const nsAutoPtr<T>& aRhs)
     447             : {
     448             :   return nullptr != aRhs.get();
     449             : }
     450             : 
     451             : 
     452             : /*****************************************************************************/
     453             : 
     454             : #endif // !defined(nsAutoPtr_h)

Generated by: LCOV version 1.13