LCOV - code coverage report
Current view: top level - mfbt - EnumeratedRange.h (source / functions) Hit Total Coverage
Test: output.info Lines: 17 17 100.0 %
Date: 2017-07-14 16:53:18 Functions: 33 60 55.0 %
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             : /* Iterator over contiguous enum values */
       8             : 
       9             : /*
      10             :  * Implements generator functions that create a range to iterate over the values
      11             :  * of a scoped or unscoped enum. Unlike IntegerRange, which can only function on
      12             :  * the underlying integral type, the elements of the generated sequence will
      13             :  * have the type of the enum in question.
      14             :  *
      15             :  * Note that the enum values should be contiguous in the iterated range;
      16             :  * unfortunately there exists no way for EnumeratedRange to enforce this
      17             :  * either dynamically or at compile time.
      18             :  */
      19             : 
      20             : #ifndef mozilla_EnumeratedRange_h
      21             : #define mozilla_EnumeratedRange_h
      22             : 
      23             : #include <type_traits>
      24             : 
      25             : #include "mozilla/ReverseIterator.h"
      26             : 
      27             : namespace mozilla {
      28             : 
      29             : namespace detail {
      30             : 
      31             : template<typename EnumTypeT>
      32             : class EnumeratedIterator
      33             : {
      34             : public:
      35             :   typedef typename std::underlying_type<EnumTypeT>::type IntTypeT;
      36             : 
      37             :   template<typename EnumType>
      38        1874 :   explicit EnumeratedIterator(EnumType aCurrent)
      39        1874 :     : mCurrent(aCurrent) { }
      40             : 
      41             :   template<typename EnumType>
      42             :   explicit EnumeratedIterator(const EnumeratedIterator<EnumType>& aOther)
      43             :     : mCurrent(aOther.mCurrent) { }
      44             : 
      45       33941 :   EnumTypeT operator*() const { return mCurrent; }
      46             : 
      47             :   /* Increment and decrement operators */
      48             : 
      49       33941 :   EnumeratedIterator& operator++()
      50             :   {
      51       33941 :     mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
      52       33941 :     return *this;
      53             :   }
      54             :   EnumeratedIterator& operator--()
      55             :   {
      56             :     mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
      57             :     return *this;
      58             :   }
      59             :   EnumeratedIterator operator++(int)
      60             :   {
      61             :     auto ret = *this;
      62             :     mCurrent = EnumTypeT(IntTypeT(mCurrent) + IntTypeT(1));
      63             :     return ret;
      64             :   }
      65             :   EnumeratedIterator operator--(int)
      66             :   {
      67             :     auto ret = *this;
      68             :     mCurrent = EnumTypeT(IntTypeT(mCurrent) - IntTypeT(1));
      69             :     return ret;
      70             :   }
      71             : 
      72             :   /* Comparison operators */
      73             : 
      74             :   template<typename EnumType>
      75             :   friend bool operator==(const EnumeratedIterator<EnumType>& aIter1,
      76             :                          const EnumeratedIterator<EnumType>& aIter2);
      77             :   template<typename EnumType>
      78             :   friend bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
      79             :                          const EnumeratedIterator<EnumType>& aIter2);
      80             :   template<typename EnumType>
      81             :   friend bool operator<(const EnumeratedIterator<EnumType>& aIter1,
      82             :                         const EnumeratedIterator<EnumType>& aIter2);
      83             :   template<typename EnumType>
      84             :   friend bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
      85             :                          const EnumeratedIterator<EnumType>& aIter2);
      86             :   template<typename EnumType>
      87             :   friend bool operator>(const EnumeratedIterator<EnumType>& aIter1,
      88             :                         const EnumeratedIterator<EnumType>& aIter2);
      89             :   template<typename EnumType>
      90             :   friend bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
      91             :                          const EnumeratedIterator<EnumType>& aIter2);
      92             : 
      93             : private:
      94             :   EnumTypeT mCurrent;
      95             : };
      96             : 
      97             : template<typename EnumType>
      98             : bool operator==(const EnumeratedIterator<EnumType>& aIter1,
      99             :                 const EnumeratedIterator<EnumType>& aIter2)
     100             : {
     101             :   return aIter1.mCurrent == aIter2.mCurrent;
     102             : }
     103             : 
     104             : template<typename EnumType>
     105       34878 : bool operator!=(const EnumeratedIterator<EnumType>& aIter1,
     106             :                 const EnumeratedIterator<EnumType>& aIter2)
     107             : {
     108       34878 :   return aIter1.mCurrent != aIter2.mCurrent;
     109             : }
     110             : 
     111             : template<typename EnumType>
     112             : bool operator<(const EnumeratedIterator<EnumType>& aIter1,
     113             :                const EnumeratedIterator<EnumType>& aIter2)
     114             : {
     115             :   return aIter1.mCurrent < aIter2.mCurrent;
     116             : }
     117             : 
     118             : template<typename EnumType>
     119             : bool operator<=(const EnumeratedIterator<EnumType>& aIter1,
     120             :                 const EnumeratedIterator<EnumType>& aIter2)
     121             : {
     122             :   return aIter1.mCurrent <= aIter2.mCurrent;
     123             : }
     124             : 
     125             : template<typename EnumType>
     126             : bool operator>(const EnumeratedIterator<EnumType>& aIter1,
     127             :                const EnumeratedIterator<EnumType>& aIter2)
     128             : {
     129             :   return aIter1.mCurrent > aIter2.mCurrent;
     130             : }
     131             : 
     132             : template<typename EnumType>
     133             : bool operator>=(const EnumeratedIterator<EnumType>& aIter1,
     134             :                 const EnumeratedIterator<EnumType>& aIter2)
     135             : {
     136             :   return aIter1.mCurrent >= aIter2.mCurrent;
     137             : }
     138             : 
     139             : template<typename EnumTypeT>
     140             : class EnumeratedRange
     141             : {
     142             : public:
     143             :   typedef EnumeratedIterator<EnumTypeT> iterator;
     144             :   typedef EnumeratedIterator<EnumTypeT> const_iterator;
     145             :   typedef ReverseIterator<iterator> reverse_iterator;
     146             :   typedef ReverseIterator<const_iterator> const_reverse_iterator;
     147             : 
     148             :   template<typename EnumType>
     149         937 :   EnumeratedRange(EnumType aBegin, EnumType aEnd)
     150         937 :     : mBegin(aBegin), mEnd(aEnd) { }
     151             : 
     152         937 :   iterator begin() const { return iterator(mBegin); }
     153             :   const_iterator cbegin() const { return begin(); }
     154         937 :   iterator end() const { return iterator(mEnd); }
     155             :   const_iterator cend() const { return end(); }
     156             :   reverse_iterator rbegin() const { return reverse_iterator(mEnd); }
     157             :   const_reverse_iterator crbegin() const { return rbegin(); }
     158             :   reverse_iterator rend() const { return reverse_iterator(mBegin); }
     159             :   const_reverse_iterator crend() const { return rend(); }
     160             : 
     161             : private:
     162             :   EnumTypeT mBegin;
     163             :   EnumTypeT mEnd;
     164             : };
     165             : 
     166             : } // namespace detail
     167             : 
     168             : #ifdef __GNUC__
     169             : // Enums can have an unsigned underlying type, which makes some of the
     170             : // comparisons below always true or always false. Temporarily disable
     171             : // -Wtype-limits to avoid breaking -Werror builds.
     172             : #  pragma GCC diagnostic push
     173             : #  pragma GCC diagnostic ignored "-Wtype-limits"
     174             : #endif
     175             : 
     176             : // Create a range to iterate from aBegin to aEnd, exclusive.
     177             : template<typename EnumType>
     178             : inline detail::EnumeratedRange<EnumType>
     179         937 : MakeEnumeratedRange(EnumType aBegin, EnumType aEnd)
     180             : {
     181         937 :   MOZ_ASSERT(aBegin <= aEnd, "Cannot generate invalid, unbounded range!");
     182         937 :   return detail::EnumeratedRange<EnumType>(aBegin, aEnd);
     183             : }
     184             : 
     185             : // Create a range to iterate from EnumType(0) to aEnd, exclusive. EnumType(0)
     186             : // should exist, but note that there is no way for us to ensure that it does!
     187             : template<typename EnumType>
     188             : inline detail::EnumeratedRange<EnumType>
     189          99 : MakeEnumeratedRange(EnumType aEnd)
     190             : {
     191          99 :   return MakeEnumeratedRange(EnumType(0), aEnd);
     192             : }
     193             : 
     194             : #ifdef __GNUC__
     195             : #  pragma GCC diagnostic pop
     196             : #endif
     197             : 
     198             : } // namespace mozilla
     199             : 
     200             : #endif // mozilla_EnumeratedRange_h
     201             : 

Generated by: LCOV version 1.13