LCOV - code coverage report
Current view: top level - xpcom/ds - ArrayIterator.h (source / functions) Hit Total Coverage
Test: output.info Lines: 47 51 92.2 %
Date: 2017-07-14 16:53:18 Functions: 677 4559 14.8 %
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             : // Common iterator implementation for array classes e.g. nsTArray.
       8             : 
       9             : #ifndef mozilla_ArrayIterator_h
      10             : #define mozilla_ArrayIterator_h
      11             : 
      12             : #include <iterator>
      13             : 
      14             : #include "mozilla/TypeTraits.h"
      15             : 
      16             : namespace mozilla {
      17             : 
      18             : // We have implemented a custom iterator class for array rather than using
      19             : // raw pointers into the backing storage to improve the safety of C++11-style
      20             : // range based iteration in the presence of array mutation, or script execution
      21             : // (bug 1299489).
      22             : //
      23             : // Mutating an array which is being iterated is still wrong, and will either
      24             : // cause elements to be missed or firefox to crash, but will not trigger memory
      25             : // safety problems due to the release-mode bounds checking found in ElementAt.
      26             : //
      27             : // Dereferencing this iterator returns type Element. When Element is a reference
      28             : // type, this iterator implements the full standard random access iterator spec,
      29             : // and can be treated in many ways as though it is a pointer. Otherwise, it is
      30             : // just enough to be used in range-based for loop.
      31             : template<class Element, class ArrayType>
      32             : class ArrayIterator
      33             : {
      34             : public:
      35             :   typedef ArrayType                               array_type;
      36             :   typedef ArrayIterator<Element, ArrayType>       iterator_type;
      37             :   typedef typename array_type::index_type         index_type;
      38             :   typedef typename RemoveReference<Element>::Type value_type;
      39             :   typedef ptrdiff_t                               difference_type;
      40             :   typedef value_type*                             pointer;
      41             :   typedef value_type&                             reference;
      42             :   typedef std::random_access_iterator_tag         iterator_category;
      43             : 
      44             : private:
      45             :   const array_type* mArray;
      46             :   index_type mIndex;
      47             : 
      48             : public:
      49             :   ArrayIterator() : mArray(nullptr), mIndex(0) {}
      50       51626 :   ArrayIterator(const iterator_type& aOther)
      51       51626 :     : mArray(aOther.mArray), mIndex(aOther.mIndex) {}
      52       74902 :   ArrayIterator(const array_type& aArray, index_type aIndex)
      53       74902 :     : mArray(&aArray), mIndex(aIndex) {}
      54             : 
      55          47 :   iterator_type& operator=(const iterator_type& aOther) {
      56          47 :     mArray = aOther.mArray;
      57          47 :     mIndex = aOther.mIndex;
      58          47 :     return *this;
      59             :   }
      60             : 
      61       67290 :   bool operator==(const iterator_type& aRhs) const {
      62       67290 :     return mIndex == aRhs.mIndex;
      63             :   }
      64       65139 :   bool operator!=(const iterator_type& aRhs) const {
      65       65139 :     return !(*this == aRhs);
      66             :   }
      67          37 :   bool operator<(const iterator_type& aRhs) const {
      68          37 :     return mIndex < aRhs.mIndex;
      69             :   }
      70             :   bool operator>(const iterator_type& aRhs) const {
      71             :     return mIndex > aRhs.mIndex;
      72             :   }
      73             :   bool operator<=(const iterator_type& aRhs) const {
      74             :     return mIndex <= aRhs.mIndex;
      75             :   }
      76           3 :   bool operator>=(const iterator_type& aRhs) const {
      77           3 :     return mIndex >= aRhs.mIndex;
      78             :   }
      79             : 
      80             :   // These operators depend on the release mode bounds checks in
      81             :   // ArrayIterator::ElementAt for safety.
      82         933 :   value_type* operator->() const {
      83         933 :     return const_cast<value_type*>(&mArray->ElementAt(mIndex));
      84             :   }
      85       40407 :   Element operator*() const {
      86       40407 :     return const_cast<Element>(mArray->ElementAt(mIndex));
      87             :   }
      88             : 
      89       29680 :   iterator_type& operator++() {
      90       29680 :     ++mIndex;
      91       29680 :     return *this;
      92             :   }
      93        1853 :   iterator_type operator++(int) {
      94        1853 :     iterator_type it = *this;
      95        1853 :     ++*this;
      96        1853 :     return it;
      97             :   }
      98        4230 :   iterator_type& operator--() {
      99        4230 :     --mIndex;
     100        4230 :     return *this;
     101             :   }
     102           0 :   iterator_type operator--(int) {
     103           0 :     iterator_type it = *this;
     104           0 :     --*this;
     105           0 :     return it;
     106             :   }
     107             : 
     108        7127 :   iterator_type& operator+=(difference_type aDiff) {
     109        7127 :     mIndex += aDiff;
     110        7127 :     return *this;
     111             :   }
     112         308 :   iterator_type& operator-=(difference_type aDiff) {
     113         308 :     mIndex -= aDiff;
     114         308 :     return *this;
     115             :   }
     116             : 
     117        7127 :   iterator_type operator+(difference_type aDiff) const {
     118        7127 :     iterator_type it = *this;
     119        7127 :     it += aDiff;
     120        7127 :     return it;
     121             :   }
     122         308 :   iterator_type operator-(difference_type aDiff) const {
     123         308 :     iterator_type it = *this;
     124         308 :     it -= aDiff;
     125         308 :     return it;
     126             :   }
     127             : 
     128        4557 :   difference_type operator-(const iterator_type& aOther) const {
     129        4557 :     return static_cast<difference_type>(mIndex) -
     130        4557 :       static_cast<difference_type>(aOther.mIndex);
     131             :   }
     132             : 
     133             :   Element operator[](difference_type aIndex) const {
     134             :     return *this->operator+(aIndex);
     135             :   }
     136             : };
     137             : 
     138             : } // namespace mozilla
     139             : 
     140             : #endif // mozilla_ArrayIterator_h

Generated by: LCOV version 1.13