LCOV - code coverage report
Current view: top level - xpcom/base - nsISupportsUtils.h (source / functions) Hit Total Coverage
Test: output.info Lines: 8 10 80.0 %
Date: 2017-07-14 16:53:18 Functions: 180 1005 17.9 %
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 nsISupportsUtils_h__
       8             : #define nsISupportsUtils_h__
       9             : 
      10             : #include "nscore.h"
      11             : #include "nsISupportsBase.h"
      12             : #include "nsError.h"
      13             : #include "nsDebug.h"
      14             : #include "nsISupportsImpl.h"
      15             : #include "mozilla/RefPtr.h"
      16             : #include "mozilla/TypeTraits.h"
      17             : 
      18             : /**
      19             :  * Macro for adding a reference to an interface.
      20             :  * @param _ptr The interface pointer.
      21             :  */
      22             : #define NS_ADDREF(_ptr) \
      23             :   (_ptr)->AddRef()
      24             : 
      25             : /**
      26             :  * Macro for adding a reference to this. This macro should be used
      27             :  * because NS_ADDREF (when tracing) may require an ambiguous cast
      28             :  * from the pointers primary type to nsISupports. This macro sidesteps
      29             :  * that entire problem.
      30             :  */
      31             : #define NS_ADDREF_THIS() \
      32             :   AddRef()
      33             : 
      34             : 
      35             : // Making this a |inline| |template| allows |aExpr| to be evaluated only once,
      36             : // yet still denies you the ability to |AddRef()| an |nsCOMPtr|.
      37             : template<class T>
      38             : inline void
      39       21468 : ns_if_addref(T aExpr)
      40             : {
      41       21468 :   if (aExpr) {
      42       18975 :     aExpr->AddRef();
      43             :   }
      44       21468 : }
      45             : 
      46             : /**
      47             :  * Macro for adding a reference to an interface that checks for nullptr.
      48             :  * @param _expr The interface pointer.
      49             :  */
      50             : #define NS_IF_ADDREF(_expr) ns_if_addref(_expr)
      51             : 
      52             : /*
      53             :  * Given these declarations, it explicitly OK and efficient to end a `getter' with:
      54             :  *
      55             :  *    NS_IF_ADDREF(*result = mThing);
      56             :  *
      57             :  * even if |mThing| is an |nsCOMPtr|.  If |mThing| is an |nsCOMPtr|, however, it is still
      58             :  * _illegal_ to say |NS_IF_ADDREF(mThing)|.
      59             :  */
      60             : 
      61             : /**
      62             :  * Macro for releasing a reference to an interface.
      63             :  * @param _ptr The interface pointer.
      64             :  */
      65             : #define NS_RELEASE(_ptr)                                                      \
      66             :   do {                                                                        \
      67             :     (_ptr)->Release();                                                        \
      68             :     (_ptr) = 0;                                                               \
      69             :   } while (0)
      70             : 
      71             : /**
      72             :  * Macro for releasing a reference to this interface.
      73             :  */
      74             : #define NS_RELEASE_THIS() \
      75             :     Release()
      76             : 
      77             : /**
      78             :  * Macro for releasing a reference to an interface, except that this
      79             :  * macro preserves the return value from the underlying Release call.
      80             :  * The interface pointer argument will only be NULLed if the reference count
      81             :  * goes to zero.
      82             :  *
      83             :  * @param _ptr The interface pointer.
      84             :  * @param _rc  The reference count.
      85             :  */
      86             : #define NS_RELEASE2(_ptr, _rc)                                                \
      87             :   do {                                                                        \
      88             :     _rc = (_ptr)->Release();                                                  \
      89             :     if (0 == (_rc)) (_ptr) = 0;                                               \
      90             :   } while (0)
      91             : 
      92             : /**
      93             :  * Macro for releasing a reference to an interface that checks for nullptr;
      94             :  * @param _ptr The interface pointer.
      95             :  */
      96             : #define NS_IF_RELEASE(_ptr)                                                   \
      97             :   do {                                                                        \
      98             :     if (_ptr) {                                                               \
      99             :       (_ptr)->Release();                                                      \
     100             :       (_ptr) = 0;                                                             \
     101             :     }                                                                         \
     102             :   } while (0)
     103             : 
     104             : /*
     105             :  * Often you have to cast an implementation pointer, e.g., |this|, to an
     106             :  * |nsISupports*|, but because you have multiple inheritance, a simple cast
     107             :  * is ambiguous.  One could simply say, e.g., (given a base |nsIBase|),
     108             :  * |static_cast<nsIBase*>(this)|; but that disguises the fact that what
     109             :  * you are really doing is disambiguating the |nsISupports|.  You could make
     110             :  * that more obvious with a double cast, e.g., |static_cast<nsISupports*>
     111             :                                                            (* static_cast<nsIBase*>(this))|, but that is bulky and harder to read...
     112             :  *
     113             :  * The following macro is clean, short, and obvious.  In the example above,
     114             :  * you would use it like this: |NS_ISUPPORTS_CAST(nsIBase*, this)|.
     115             :  */
     116             : 
     117             : #define NS_ISUPPORTS_CAST(__unambiguousBase, __expr) \
     118             :   static_cast<nsISupports*>(static_cast<__unambiguousBase>(__expr))
     119             : 
     120             : // a type-safe shortcut for calling the |QueryInterface()| member function
     121             : template<class T, class DestinationType>
     122             : inline nsresult
     123       59357 : CallQueryInterface(T* aSource, DestinationType** aDestination)
     124             : {
     125             :   // We permit nsISupports-to-nsISupports here so that one can still obtain
     126             :   // the canonical nsISupports pointer with CallQueryInterface.
     127             :   static_assert(!mozilla::IsSame<T, DestinationType>::value ||
     128             :                 mozilla::IsSame<DestinationType, nsISupports>::value,
     129             :                 "don't use CallQueryInterface for compile-time-determinable casts");
     130             : 
     131       59357 :   NS_PRECONDITION(aSource, "null parameter");
     132       59357 :   NS_PRECONDITION(aDestination, "null parameter");
     133             : 
     134             :   return aSource->QueryInterface(NS_GET_TEMPLATE_IID(DestinationType),
     135       59357 :                                  reinterpret_cast<void**>(aDestination));
     136             : }
     137             : 
     138             : template <class SourceType, class DestinationType>
     139             : inline nsresult
     140           0 : CallQueryInterface(RefPtr<SourceType>& aSourcePtr, DestinationType** aDestPtr)
     141             : {
     142           0 :   return CallQueryInterface(aSourcePtr.get(), aDestPtr);
     143             : }
     144             : 
     145             : #endif /* __nsISupportsUtils_h */

Generated by: LCOV version 1.13