LCOV - code coverage report
Current view: directory - xpcom/glue - nsVoidArray.h (source / functions) Found Hit Coverage
Test: app.info Lines: 52 31 59.6 %
Date: 2012-06-02 Functions: 20 13 65.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; c-file-offsets: ((substatement-open . 0))  -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : #ifndef nsVoidArray_h___
      38                 : #define nsVoidArray_h___
      39                 : 
      40                 : //#define DEBUG_VOIDARRAY 1
      41                 : 
      42                 : #include "nsDebug.h"
      43                 : 
      44                 : // Comparator callback function for sorting array values.
      45                 : typedef int (* nsVoidArrayComparatorFunc)
      46                 :             (const void* aElement1, const void* aElement2, void* aData);
      47                 : 
      48                 : // Enumerator callback function. Return false to stop
      49                 : typedef bool (* nsVoidArrayEnumFunc)(void* aElement, void *aData);
      50                 : typedef bool (* nsVoidArrayEnumFuncConst)(const void* aElement, void *aData);
      51                 : 
      52                 : // SizeOfExcludingThis callback function.
      53                 : typedef size_t (* nsVoidArraySizeOfElementIncludingThisFunc)(const void* aElement,
      54                 :                                                              nsMallocSizeOfFun aMallocSizeOf,
      55                 :                                                              void *aData);
      56                 : 
      57                 : /// A basic zero-based array of void*'s that manages its own memory
      58                 : class NS_COM_GLUE nsVoidArray {
      59                 : public:
      60                 :   nsVoidArray();
      61                 :   nsVoidArray(PRInt32 aCount);  // initial count of aCount elements set to nsnull
      62                 :   ~nsVoidArray();
      63                 : 
      64                 :   nsVoidArray& operator=(const nsVoidArray& other);
      65                 : 
      66               0 :   inline PRInt32 Count() const {
      67               0 :     return mImpl ? mImpl->mCount : 0;
      68                 :   }
      69                 :   // If the array grows, the newly created entries will all be null
      70                 :   bool SetCount(PRInt32 aNewCount);
      71                 :   // returns the max number that can be held without allocating
      72         1590914 :   inline PRInt32 GetArraySize() const {
      73         1590914 :     return mImpl ? (PRInt32(mImpl->mBits) & kArraySizeMask) : 0;
      74                 :   }
      75                 : 
      76            1390 :   void* FastElementAt(PRInt32 aIndex) const
      77                 :   {
      78            1390 :     NS_ASSERTION(0 <= aIndex && aIndex < Count(), "nsVoidArray::FastElementAt: index out of range");
      79            1390 :     return mImpl->mArray[aIndex];
      80                 :   }
      81                 : 
      82                 :   // This both asserts and bounds-checks, because (1) we don't want
      83                 :   // people to write bad code, but (2) we don't want to change it to
      84                 :   // crashing for backwards compatibility.  See bug 96108.
      85               0 :   void* ElementAt(PRInt32 aIndex) const
      86                 :   {
      87               0 :     NS_ASSERTION(0 <= aIndex && aIndex < Count(), "nsVoidArray::ElementAt: index out of range");
      88               0 :     return SafeElementAt(aIndex);
      89                 :   }
      90                 : 
      91                 :   // bounds-checked version
      92               0 :   void* SafeElementAt(PRInt32 aIndex) const
      93                 :   {
      94               0 :     if (PRUint32(aIndex) >= PRUint32(Count())) // handles aIndex < 0 too
      95                 :     {
      96               0 :       return nsnull;
      97                 :     }
      98                 :     // The bounds check ensures mImpl is non-null.
      99               0 :     return mImpl->mArray[aIndex];
     100                 :   }
     101                 : 
     102                 :   void* operator[](PRInt32 aIndex) const { return ElementAt(aIndex); }
     103                 : 
     104                 :   PRInt32 IndexOf(void* aPossibleElement) const;
     105                 : 
     106                 :   bool InsertElementAt(void* aElement, PRInt32 aIndex);
     107                 :   bool InsertElementsAt(const nsVoidArray &other, PRInt32 aIndex);
     108                 : 
     109                 :   bool ReplaceElementAt(void* aElement, PRInt32 aIndex);
     110                 : 
     111                 :   // useful for doing LRU arrays, sorting, etc
     112                 :   bool MoveElement(PRInt32 aFrom, PRInt32 aTo);
     113                 : 
     114               0 :   bool AppendElement(void* aElement) {
     115               0 :     return InsertElementAt(aElement, Count());
     116                 :   }
     117                 : 
     118                 :   bool AppendElements(nsVoidArray& aElements) {
     119                 :     return InsertElementsAt(aElements, Count());
     120                 :   }
     121                 : 
     122                 :   bool RemoveElement(void* aElement);
     123                 :   bool RemoveElementsAt(PRInt32 aIndex, PRInt32 aCount);
     124               2 :   bool RemoveElementAt(PRInt32 aIndex) { return RemoveElementsAt(aIndex,1); }
     125                 : 
     126                 :   void   Clear();
     127                 : 
     128                 :   bool SizeTo(PRInt32 aMin);
     129                 :   // Subtly different - Compact() tries to be smart about whether we
     130                 :   // should reallocate the array; SizeTo() always reallocates.
     131                 :   void Compact();
     132                 : 
     133                 :   void Sort(nsVoidArrayComparatorFunc aFunc, void* aData);
     134                 : 
     135                 :   bool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData);
     136                 :   bool EnumerateForwards(nsVoidArrayEnumFuncConst aFunc, void* aData) const;
     137                 :   bool EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData);
     138                 : 
     139                 :   // Measures the size of the array's element storage, and if
     140                 :   // |aSizeOfElementIncludingThis| is non-NULL, measures the size of things
     141                 :   // pointed to by elements.
     142                 :   size_t SizeOfExcludingThis(
     143                 :            nsVoidArraySizeOfElementIncludingThisFunc aSizeOfElementIncludingThis,
     144                 :            nsMallocSizeOfFun aMallocSizeOf, void* aData = NULL) const;
     145                 : 
     146                 : protected:
     147                 :   bool GrowArrayBy(PRInt32 aGrowBy);
     148                 : 
     149                 :   struct Impl {
     150                 :     /**
     151                 :      * Packed bits. The low 30 bits are the array's size.
     152                 :      * The two highest bits indicate whether or not we "own" mImpl and
     153                 :      * must free() it when destroyed, and whether we have a preallocated
     154                 :      * nsAutoVoidArray buffer.
     155                 :      */
     156                 :     PRUint32 mBits;
     157                 : 
     158                 :     /**
     159                 :      * The number of elements in the array
     160                 :      */
     161                 :     PRInt32 mCount;
     162                 : 
     163                 :     /**
     164                 :      * Array data, padded out to the actual size of the array.
     165                 :      */
     166                 :     void*   mArray[1];
     167                 :   };
     168                 : 
     169                 :   Impl* mImpl;
     170                 : #if DEBUG_VOIDARRAY
     171                 :   PRInt32 mMaxCount;
     172                 :   PRInt32 mMaxSize;
     173                 :   bool    mIsAuto;
     174                 : #endif
     175                 : 
     176                 :   enum {
     177                 :     kArrayOwnerMask = 1 << 31,
     178                 :     kArrayHasAutoBufferMask = 1 << 30,
     179                 :     kArraySizeMask = ~(kArrayOwnerMask | kArrayHasAutoBufferMask)
     180                 :   };
     181                 :   enum { kAutoBufSize = 8 };
     182                 : 
     183                 : 
     184                 :   // bit twiddlers
     185                 :   void SetArray(Impl *newImpl, PRInt32 aSize, PRInt32 aCount, bool aOwner,
     186                 :                 bool aHasAuto);
     187          979979 :   inline bool IsArrayOwner() const {
     188          979979 :     return mImpl && (mImpl->mBits & kArrayOwnerMask);
     189                 :   }
     190          705001 :   inline bool HasAutoBuffer() const {
     191          705001 :     return mImpl && (mImpl->mBits & kArrayHasAutoBufferMask);
     192                 :   }
     193                 : 
     194                 : private:
     195                 :   /// Copy constructors are not allowed
     196                 :   nsVoidArray(const nsVoidArray& other);
     197                 : };
     198                 : 
     199                 : 
     200                 : // A zero-based array with a bit of automatic internal storage
     201          293785 : class NS_COM_GLUE nsAutoVoidArray : public nsVoidArray {
     202                 : public:
     203                 :   nsAutoVoidArray();
     204                 : 
     205          293786 :   void ResetToAutoBuffer()
     206                 :   {
     207                 :     SetArray(reinterpret_cast<Impl*>(mAutoBuf), kAutoBufSize, 0, false,
     208          293786 :              true);
     209          293786 :   }
     210                 : 
     211          293783 :   nsAutoVoidArray& operator=(const nsVoidArray& other)
     212                 :   {
     213          293783 :     nsVoidArray::operator=(other);
     214          293781 :     return *this;
     215                 :   }
     216                 :   
     217                 : protected:
     218                 :   // The internal storage
     219                 :   char mAutoBuf[sizeof(Impl) + (kAutoBufSize - 1) * sizeof(void*)];
     220                 : };
     221                 : 
     222                 : 
     223                 : //===================================================================
     224                 : //  nsSmallVoidArray is not a general-purpose replacement for
     225                 : //  ns(Auto)VoidArray because there is (some) extra CPU overhead for arrays
     226                 : //  larger than 1 element, though not a lot.  It is appropriate for
     227                 : //  space-sensitive uses where sizes of 0 or 1 are moderately common or
     228                 : //  more, and where we're NOT storing arbitrary integers or arbitrary
     229                 : //  pointers.
     230                 : 
     231                 : // NOTE: nsSmallVoidArray can ONLY be used for holding items that always
     232                 : // have the low bit as a 0 - i.e. element & 1 == 0.  This happens to be
     233                 : // true for allocated and object pointers for all the architectures we run
     234                 : // on, but conceivably there might be some architectures/compilers for
     235                 : // which it is NOT true.  We know this works for all existing architectures
     236                 : // because if it didn't then nsCheapVoidArray would have failed.  Also note
     237                 : // that we will ASSERT if this assumption is violated in DEBUG builds.
     238                 : 
     239                 : // XXX we're really re-implementing the whole nsVoidArray interface here -
     240                 : // some form of abstract class would be useful
     241                 : 
     242                 : // I disagree on the abstraction here.  If the point of this class is to be
     243                 : // as small as possible, and no one will ever derive from it, as I found
     244                 : // today, there should not be any virtualness to it to avoid the vtable
     245                 : // ptr overhead.
     246                 : 
     247                 : class NS_COM_GLUE nsSmallVoidArray : private nsVoidArray
     248                 : {
     249                 : public:
     250                 :   ~nsSmallVoidArray();
     251                 : 
     252                 :   nsSmallVoidArray& operator=(nsSmallVoidArray& other);
     253                 :   void* operator[](PRInt32 aIndex) const { return ElementAt(aIndex); }
     254                 : 
     255                 :   PRInt32 GetArraySize() const;
     256                 : 
     257                 :   PRInt32 Count() const;
     258                 :   void* FastElementAt(PRInt32 aIndex) const;
     259                 :   // This both asserts and bounds-checks, because (1) we don't want
     260                 :   // people to write bad code, but (2) we don't want to change it to
     261                 :   // crashing for backwards compatibility.  See bug 96108.
     262               0 :   void* ElementAt(PRInt32 aIndex) const
     263                 :   {
     264               0 :     NS_ASSERTION(0 <= aIndex && aIndex < Count(), "nsSmallVoidArray::ElementAt: index out of range");
     265               0 :     return SafeElementAt(aIndex);
     266                 :   }
     267               0 :   void* SafeElementAt(PRInt32 aIndex) const {
     268                 :     // let compiler inline; it may be able to remove these checks
     269               0 :     if (PRUint32(aIndex) >= PRUint32(Count())) // handles aIndex < 0 too
     270                 :     {
     271               0 :       return nsnull;
     272                 :     }
     273               0 :     return FastElementAt(aIndex);
     274                 :   }
     275                 :   PRInt32 IndexOf(void* aPossibleElement) const;
     276                 :   bool InsertElementAt(void* aElement, PRInt32 aIndex);
     277                 :   bool InsertElementsAt(const nsVoidArray &other, PRInt32 aIndex);
     278                 :   bool ReplaceElementAt(void* aElement, PRInt32 aIndex);
     279                 :   bool MoveElement(PRInt32 aFrom, PRInt32 aTo);
     280                 :   bool AppendElement(void* aElement);
     281                 :   bool AppendElements(nsVoidArray& aElements) {
     282                 :     return InsertElementsAt(aElements, Count());
     283                 :   }
     284                 :   bool RemoveElement(void* aElement);
     285                 :   bool RemoveElementsAt(PRInt32 aIndex, PRInt32 aCount);
     286                 :   bool RemoveElementAt(PRInt32 aIndex);
     287                 : 
     288                 :   void Clear();
     289                 :   bool SizeTo(PRInt32 aMin);
     290                 :   void Compact();
     291                 :   void Sort(nsVoidArrayComparatorFunc aFunc, void* aData);
     292                 : 
     293                 :   bool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData);
     294                 :   bool EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData);
     295                 : 
     296                 : private:
     297                 : 
     298            2508 :   bool HasSingle() const
     299                 :   {
     300            2508 :     return !!(reinterpret_cast<PRWord>(mImpl) & 0x1);
     301                 :   }
     302             322 :   void* GetSingle() const
     303                 :   {
     304             322 :     NS_ASSERTION(HasSingle(), "wrong type");
     305                 :     return reinterpret_cast<void*>
     306             322 :                            (reinterpret_cast<PRWord>(mImpl) & ~0x1);
     307                 :   }
     308             122 :   void SetSingle(void *aChild)
     309                 :   {
     310             122 :     NS_ASSERTION(HasSingle() || !mImpl, "overwriting array");
     311                 :     mImpl = reinterpret_cast<Impl*>
     312             122 :                             (reinterpret_cast<PRWord>(aChild) | 0x1);
     313             122 :   }
     314             122 :   bool IsEmpty() const
     315                 :   {
     316                 :     // Note that this isn't the same as Count()==0
     317             122 :     return !mImpl;
     318                 :   }
     319             610 :   const nsVoidArray* AsArray() const
     320                 :   {
     321             610 :     NS_ASSERTION(!HasSingle(), "This is a single");
     322             610 :     return this;
     323                 :   }
     324               0 :   nsVoidArray* AsArray()
     325                 :   {
     326               0 :     NS_ASSERTION(!HasSingle(), "This is a single");
     327               0 :     return this;
     328                 :   }
     329                 :   bool EnsureArray();
     330                 : };
     331                 : 
     332                 : #endif /* nsVoidArray_h___ */

Generated by: LCOV version 1.7