LCOV - code coverage report
Current view: top level - mfbt - EnumSet.h (source / functions) Hit Total Coverage
Test: output.info Lines: 69 101 68.3 %
Date: 2017-07-14 16:53:18 Functions: 33 73 45.2 %
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             : /* A set abstraction for enumeration values. */
       8             : 
       9             : #ifndef mozilla_EnumSet_h
      10             : #define mozilla_EnumSet_h
      11             : 
      12             : #include "mozilla/Assertions.h"
      13             : #include "mozilla/Attributes.h"
      14             : 
      15             : #include <initializer_list>
      16             : 
      17             : #include <stdint.h>
      18             : 
      19             : namespace mozilla {
      20             : 
      21             : /**
      22             :  * EnumSet<T> is a set of values defined by an enumeration. It is implemented
      23             :  * using a 32 bit mask for each value so it will only work for enums with an int
      24             :  * representation less than 32. It works both for enum and enum class types.
      25             :  */
      26             : template<typename T>
      27             : class EnumSet
      28             : {
      29             : public:
      30         843 :   EnumSet()
      31         843 :     : mBitField(0)
      32             :   {
      33         843 :     initVersion();
      34         843 :   }
      35             : 
      36           0 :   MOZ_IMPLICIT EnumSet(T aEnum)
      37           0 :     : mBitField(bitFor(aEnum))
      38           0 :   { }
      39             : 
      40           0 :   EnumSet(T aEnum1, T aEnum2)
      41           0 :     : mBitField(bitFor(aEnum1) |
      42           0 :                 bitFor(aEnum2))
      43             :   {
      44           0 :     initVersion();
      45           0 :   }
      46             : 
      47             :   EnumSet(T aEnum1, T aEnum2, T aEnum3)
      48             :     : mBitField(bitFor(aEnum1) |
      49             :                 bitFor(aEnum2) |
      50             :                 bitFor(aEnum3))
      51             :   {
      52             :     initVersion();
      53             :   }
      54             : 
      55             :   EnumSet(T aEnum1, T aEnum2, T aEnum3, T aEnum4)
      56             :     : mBitField(bitFor(aEnum1) |
      57             :                 bitFor(aEnum2) |
      58             :                 bitFor(aEnum3) |
      59             :                 bitFor(aEnum4))
      60             :   {
      61             :     initVersion();
      62             :   }
      63             : 
      64          36 :   MOZ_IMPLICIT EnumSet(std::initializer_list<T> list)
      65          36 :     : mBitField(0)
      66             :   {
      67         204 :     for (auto value : list) {
      68         168 :       (*this) += value;
      69             :     }
      70          36 :     initVersion();
      71          36 :   }
      72             : 
      73           0 :   EnumSet(const EnumSet& aEnumSet)
      74           0 :     : mBitField(aEnumSet.mBitField)
      75             :   {
      76           0 :     initVersion();
      77           0 :   }
      78             : 
      79             :   /**
      80             :    * Add an element
      81             :    */
      82         470 :   void operator+=(T aEnum)
      83             :   {
      84         470 :     incVersion();
      85         470 :     mBitField |= bitFor(aEnum);
      86         470 :   }
      87             : 
      88             :   /**
      89             :    * Add an element
      90             :    */
      91             :   EnumSet<T> operator+(T aEnum) const
      92             :   {
      93             :     EnumSet<T> result(*this);
      94             :     result += aEnum;
      95             :     return result;
      96             :   }
      97             : 
      98             :   /**
      99             :    * Union
     100             :    */
     101           0 :   void operator+=(const EnumSet<T> aEnumSet)
     102             :   {
     103           0 :     incVersion();
     104           0 :     mBitField |= aEnumSet.mBitField;
     105           0 :   }
     106             : 
     107             :   /**
     108             :    * Union
     109             :    */
     110             :   EnumSet<T> operator+(const EnumSet<T> aEnumSet) const
     111             :   {
     112             :     EnumSet<T> result(*this);
     113             :     result += aEnumSet;
     114             :     return result;
     115             :   }
     116             : 
     117             :   /**
     118             :    * Remove an element
     119             :    */
     120             :   void operator-=(T aEnum)
     121             :   {
     122             :     incVersion();
     123             :     mBitField &= ~(bitFor(aEnum));
     124             :   }
     125             : 
     126             :   /**
     127             :    * Remove an element
     128             :    */
     129             :   EnumSet<T> operator-(T aEnum) const
     130             :   {
     131             :     EnumSet<T> result(*this);
     132             :     result -= aEnum;
     133             :     return result;
     134             :   }
     135             : 
     136             :   /**
     137             :    * Remove a set of elements
     138             :    */
     139           0 :   void operator-=(const EnumSet<T> aEnumSet)
     140             :   {
     141           0 :     incVersion();
     142           0 :     mBitField &= ~(aEnumSet.mBitField);
     143           0 :   }
     144             : 
     145             :   /**
     146             :    * Remove a set of elements
     147             :    */
     148           0 :   EnumSet<T> operator-(const EnumSet<T> aEnumSet) const
     149             :   {
     150           0 :     EnumSet<T> result(*this);
     151           0 :     result -= aEnumSet;
     152           0 :     return result;
     153             :   }
     154             : 
     155             :   /**
     156             :    * Clear
     157             :    */
     158           0 :   void clear()
     159             :   {
     160           0 :     incVersion();
     161           0 :     mBitField = 0;
     162           0 :   }
     163             : 
     164             :   /**
     165             :    * Intersection
     166             :    */
     167             :   void operator&=(const EnumSet<T> aEnumSet)
     168             :   {
     169             :     incVersion();
     170             :     mBitField &= aEnumSet.mBitField;
     171             :   }
     172             : 
     173             :   /**
     174             :    * Intersection
     175             :    */
     176             :   EnumSet<T> operator&(const EnumSet<T> aEnumSet) const
     177             :   {
     178             :     EnumSet<T> result(*this);
     179             :     result &= aEnumSet;
     180             :     return result;
     181             :   }
     182             : 
     183             :   /**
     184             :    * Equality
     185             :    */
     186           0 :   bool operator==(const EnumSet<T> aEnumSet) const
     187             :   {
     188           0 :     return mBitField == aEnumSet.mBitField;
     189             :   }
     190             : 
     191             :   /**
     192             :    * Test is an element is contained in the set.
     193             :    */
     194         528 :   bool contains(T aEnum) const
     195             :   {
     196         528 :     return mBitField & bitFor(aEnum);
     197             :   }
     198             : 
     199             :   /**
     200             :    * Return the number of elements in the set.
     201             :    */
     202             :   uint8_t size() const
     203             :   {
     204             :     uint8_t count = 0;
     205             :     for (uint32_t bitField = mBitField; bitField; bitField >>= 1) {
     206             :       if (bitField & 1) {
     207             :         count++;
     208             :       }
     209             :     }
     210             :     return count;
     211             :   }
     212             : 
     213          42 :   bool isEmpty() const
     214             :   {
     215          42 :     return mBitField == 0;
     216             :   }
     217             : 
     218           0 :   uint32_t serialize() const
     219             :   {
     220           0 :     return mBitField;
     221             :   }
     222             : 
     223         204 :   void deserialize(uint32_t aValue)
     224             :   {
     225         204 :     incVersion();
     226         204 :     mBitField = aValue;
     227         204 :   }
     228             : 
     229             :   class ConstIterator
     230             :   {
     231             :     const EnumSet<T>* mSet;
     232             :     uint32_t mPos;
     233             : #ifdef DEBUG
     234             :     uint64_t mVersion;
     235             : #endif
     236             : 
     237         108 :     void checkVersion() {
     238             :       // Check that the set has not been modified while being iterated.
     239         108 :       MOZ_ASSERT_IF(mSet, mSet->mVersion == mVersion);
     240         108 :     }
     241             : 
     242             :    public:
     243          18 :     ConstIterator(const EnumSet<T>& aSet, uint32_t aPos)
     244          18 :      : mSet(&aSet), mPos(aPos)
     245             :     {
     246             : #ifdef DEBUG
     247          18 :       mVersion = mSet->mVersion;
     248             : #endif
     249          18 :       MOZ_ASSERT(aPos <= kMaxBits);
     250          18 :       if (aPos != kMaxBits && !mSet->contains(T(mPos)))
     251           9 :         ++*this;
     252          18 :     }
     253             : 
     254             :     ConstIterator(const ConstIterator& aOther)
     255             :      : mSet(aOther.mSet), mPos(aOther.mPos)
     256             :     {
     257             : #ifdef DEBUG
     258             :       mVersion = aOther.mVersion;
     259             :       checkVersion();
     260             : #endif
     261             :     }
     262             : 
     263             :     ConstIterator(ConstIterator&& aOther)
     264             :      : mSet(aOther.mSet), mPos(aOther.mPos)
     265             :     {
     266             : #ifdef DEBUG
     267             :       mVersion = aOther.mVersion;
     268             :       checkVersion();
     269             : #endif
     270             :       aOther.mSet = nullptr;
     271             :     }
     272             : 
     273          18 :     ~ConstIterator() {
     274          18 :       checkVersion();
     275          18 :     }
     276             : 
     277          33 :     bool operator==(const ConstIterator& other) {
     278          33 :       MOZ_ASSERT(mSet == other.mSet);
     279          33 :       checkVersion();
     280          33 :       return mPos == other.mPos;
     281             :     }
     282             : 
     283          33 :     bool operator!=(const ConstIterator& other) {
     284          33 :       return !(*this == other);
     285             :     }
     286             : 
     287          24 :     T operator*() {
     288          24 :       MOZ_ASSERT(mSet);
     289          24 :       MOZ_ASSERT(mPos < kMaxBits);
     290          24 :       MOZ_ASSERT(mSet->contains(T(mPos)));
     291          24 :       checkVersion();
     292          24 :       return T(mPos);
     293             :     }
     294             : 
     295          33 :     ConstIterator& operator++() {
     296          33 :       MOZ_ASSERT(mSet);
     297          33 :       MOZ_ASSERT(mPos < kMaxBits);
     298          33 :       checkVersion();
     299         288 :       do {
     300         288 :         mPos++;
     301         288 :       } while (mPos < kMaxBits && !mSet->contains(T(mPos)));
     302          33 :       return *this;
     303             :     }
     304             :   };
     305             : 
     306           9 :   ConstIterator begin() const {
     307           9 :     return ConstIterator(*this, 0);
     308             :   }
     309             : 
     310           9 :   ConstIterator end() const {
     311           9 :     return ConstIterator(*this, kMaxBits);
     312             :   }
     313             : 
     314             : private:
     315         998 :   static uint32_t bitFor(T aEnum)
     316             :   {
     317         998 :     uint32_t bitNumber = (uint32_t)aEnum;
     318         998 :     MOZ_ASSERT(bitNumber < kMaxBits);
     319         998 :     return 1U << bitNumber;
     320             :   }
     321             : 
     322         879 :   void initVersion() {
     323             : #ifdef DEBUG
     324         879 :     mVersion = 0;
     325             : #endif
     326         879 :   }
     327             : 
     328         674 :   void incVersion() {
     329             : #ifdef DEBUG
     330         674 :     mVersion++;
     331             : #endif
     332         674 :   }
     333             : 
     334             :   static const size_t kMaxBits = 32;
     335             :   uint32_t mBitField;
     336             : 
     337             : #ifdef DEBUG
     338             :   uint64_t mVersion;
     339             : #endif
     340             : };
     341             : 
     342             : } // namespace mozilla
     343             : 
     344             : #endif /* mozilla_EnumSet_h_*/

Generated by: LCOV version 1.13