tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestEnumSet.cpp (9370B)


      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/BitSet.h"
      8 #include "mozilla/EnumSet.h"
      9 #include "mozilla/Vector.h"
     10 
     11 #include <type_traits>
     12 
     13 using namespace mozilla;
     14 
     15 enum SeaBird {
     16  PENGUIN,
     17  ALBATROSS,
     18  FULMAR,
     19  PRION,
     20  SHEARWATER,
     21  GADFLY_PETREL,
     22  TRUE_PETREL,
     23  DIVING_PETREL,
     24  STORM_PETREL,
     25  PELICAN,
     26  GANNET,
     27  BOOBY,
     28  CORMORANT,
     29  FRIGATEBIRD,
     30  TROPICBIRD,
     31  SKUA,
     32  GULL,
     33  TERN,
     34  SKIMMER,
     35  AUK,
     36 
     37  SEA_BIRD_COUNT
     38 };
     39 
     40 enum class SmallEnum : uint8_t {
     41  Foo,
     42  Bar,
     43 };
     44 
     45 enum class BigEnum : uint64_t {
     46  Foo,
     47  Bar = 35,
     48 };
     49 
     50 template <typename Storage = typename std::make_unsigned<
     51              typename std::underlying_type<SeaBird>::type>::type>
     52 class EnumSetSuite {
     53 public:
     54  using EnumSetSeaBird = EnumSet<SeaBird, Storage>;
     55 
     56  EnumSetSuite()
     57      : mAlcidae(),
     58        mDiomedeidae(ALBATROSS),
     59        mPetrelProcellariidae(GADFLY_PETREL, TRUE_PETREL),
     60        mNonPetrelProcellariidae(FULMAR, PRION, SHEARWATER),
     61        mPetrels(GADFLY_PETREL, TRUE_PETREL, DIVING_PETREL, STORM_PETREL) {}
     62 
     63  void runTests() {
     64    testSize();
     65    testContains();
     66    testAddTo();
     67    testAdd();
     68    testAddAll();
     69    testUnion();
     70    testRemoveFrom();
     71    testRemove();
     72    testRemoveAllFrom();
     73    testRemoveAll();
     74    testIntersect();
     75    testInsersection();
     76    testEquality();
     77    testDuplicates();
     78    testIteration();
     79    testInitializerListConstuctor();
     80    testBigEnum();
     81  }
     82 
     83 private:
     84  void testEnumSetLayout() {
     85 #ifndef DEBUG
     86    static_assert(sizeof(EnumSet<SmallEnum>) == sizeof(SmallEnum),
     87                  "EnumSet should be no bigger than the enum by default");
     88    static_assert(sizeof(EnumSet<SmallEnum, uint32_t>) == sizeof(uint32_t),
     89                  "EnumSet should be able to have its size overriden.");
     90    static_assert(std::is_trivially_copyable_v<EnumSet<SmallEnum>>,
     91                  "EnumSet should be lightweight outside of debug.");
     92 #endif
     93  }
     94 
     95  void testSize() {
     96    MOZ_RELEASE_ASSERT(mAlcidae.size() == 0);
     97    MOZ_RELEASE_ASSERT(mDiomedeidae.size() == 1);
     98    MOZ_RELEASE_ASSERT(mPetrelProcellariidae.size() == 2);
     99    MOZ_RELEASE_ASSERT(mNonPetrelProcellariidae.size() == 3);
    100    MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
    101  }
    102 
    103  void testContains() {
    104    MOZ_RELEASE_ASSERT(!mPetrels.contains(PENGUIN));
    105    MOZ_RELEASE_ASSERT(!mPetrels.contains(ALBATROSS));
    106    MOZ_RELEASE_ASSERT(!mPetrels.contains(FULMAR));
    107    MOZ_RELEASE_ASSERT(!mPetrels.contains(PRION));
    108    MOZ_RELEASE_ASSERT(!mPetrels.contains(SHEARWATER));
    109    MOZ_RELEASE_ASSERT(mPetrels.contains(GADFLY_PETREL));
    110    MOZ_RELEASE_ASSERT(mPetrels.contains(TRUE_PETREL));
    111    MOZ_RELEASE_ASSERT(mPetrels.contains(DIVING_PETREL));
    112    MOZ_RELEASE_ASSERT(mPetrels.contains(STORM_PETREL));
    113    MOZ_RELEASE_ASSERT(!mPetrels.contains(PELICAN));
    114    MOZ_RELEASE_ASSERT(!mPetrels.contains(GANNET));
    115    MOZ_RELEASE_ASSERT(!mPetrels.contains(BOOBY));
    116    MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
    117    MOZ_RELEASE_ASSERT(!mPetrels.contains(FRIGATEBIRD));
    118    MOZ_RELEASE_ASSERT(!mPetrels.contains(TROPICBIRD));
    119    MOZ_RELEASE_ASSERT(!mPetrels.contains(SKUA));
    120    MOZ_RELEASE_ASSERT(!mPetrels.contains(GULL));
    121    MOZ_RELEASE_ASSERT(!mPetrels.contains(TERN));
    122    MOZ_RELEASE_ASSERT(!mPetrels.contains(SKIMMER));
    123    MOZ_RELEASE_ASSERT(!mPetrels.contains(AUK));
    124  }
    125 
    126  void testCopy() {
    127    EnumSetSeaBird likes = mPetrels;
    128    likes -= TRUE_PETREL;
    129    MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
    130    MOZ_RELEASE_ASSERT(mPetrels.contains(TRUE_PETREL));
    131 
    132    MOZ_RELEASE_ASSERT(likes.size() == 3);
    133    MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
    134    MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
    135    MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
    136  }
    137 
    138  void testAddTo() {
    139    EnumSetSeaBird seen = mPetrels;
    140    seen += CORMORANT;
    141    seen += TRUE_PETREL;
    142    MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
    143    MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
    144    MOZ_RELEASE_ASSERT(seen.size() == 5);
    145    MOZ_RELEASE_ASSERT(seen.contains(GADFLY_PETREL));
    146    MOZ_RELEASE_ASSERT(seen.contains(TRUE_PETREL));
    147    MOZ_RELEASE_ASSERT(seen.contains(DIVING_PETREL));
    148    MOZ_RELEASE_ASSERT(seen.contains(STORM_PETREL));
    149    MOZ_RELEASE_ASSERT(seen.contains(CORMORANT));
    150  }
    151 
    152  void testAdd() {
    153    EnumSetSeaBird seen = mPetrels + CORMORANT + STORM_PETREL;
    154    MOZ_RELEASE_ASSERT(mPetrels.size() == 4);
    155    MOZ_RELEASE_ASSERT(!mPetrels.contains(CORMORANT));
    156    MOZ_RELEASE_ASSERT(seen.size() == 5);
    157    MOZ_RELEASE_ASSERT(seen.contains(GADFLY_PETREL));
    158    MOZ_RELEASE_ASSERT(seen.contains(TRUE_PETREL));
    159    MOZ_RELEASE_ASSERT(seen.contains(DIVING_PETREL));
    160    MOZ_RELEASE_ASSERT(seen.contains(STORM_PETREL));
    161    MOZ_RELEASE_ASSERT(seen.contains(CORMORANT));
    162  }
    163 
    164  void testAddAll() {
    165    EnumSetSeaBird procellariidae;
    166    procellariidae += mPetrelProcellariidae;
    167    procellariidae += mNonPetrelProcellariidae;
    168    MOZ_RELEASE_ASSERT(procellariidae.size() == 5);
    169 
    170    // Both procellariidae and mPetrels include GADFLY_PERTEL and TRUE_PETREL
    171    EnumSetSeaBird procellariiformes;
    172    procellariiformes += mDiomedeidae;
    173    procellariiformes += procellariidae;
    174    procellariiformes += mPetrels;
    175    MOZ_RELEASE_ASSERT(procellariiformes.size() == 8);
    176  }
    177 
    178  void testUnion() {
    179    EnumSetSeaBird procellariidae =
    180        mPetrelProcellariidae + mNonPetrelProcellariidae;
    181    MOZ_RELEASE_ASSERT(procellariidae.size() == 5);
    182 
    183    // Both procellariidae and mPetrels include GADFLY_PETREL and TRUE_PETREL
    184    EnumSetSeaBird procellariiformes = mDiomedeidae + procellariidae + mPetrels;
    185    MOZ_RELEASE_ASSERT(procellariiformes.size() == 8);
    186  }
    187 
    188  void testRemoveFrom() {
    189    EnumSetSeaBird likes = mPetrels;
    190    likes -= TRUE_PETREL;
    191    likes -= DIVING_PETREL;
    192    MOZ_RELEASE_ASSERT(likes.size() == 2);
    193    MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
    194    MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
    195  }
    196 
    197  void testRemove() {
    198    EnumSetSeaBird likes = mPetrels - TRUE_PETREL - DIVING_PETREL;
    199    MOZ_RELEASE_ASSERT(likes.size() == 2);
    200    MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
    201    MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
    202  }
    203 
    204  void testRemoveAllFrom() {
    205    EnumSetSeaBird likes = mPetrels;
    206    likes -= mPetrelProcellariidae;
    207    MOZ_RELEASE_ASSERT(likes.size() == 2);
    208    MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
    209    MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
    210  }
    211 
    212  void testRemoveAll() {
    213    EnumSetSeaBird likes = mPetrels - mPetrelProcellariidae;
    214    MOZ_RELEASE_ASSERT(likes.size() == 2);
    215    MOZ_RELEASE_ASSERT(likes.contains(DIVING_PETREL));
    216    MOZ_RELEASE_ASSERT(likes.contains(STORM_PETREL));
    217  }
    218 
    219  void testIntersect() {
    220    EnumSetSeaBird likes = mPetrels;
    221    likes &= mPetrelProcellariidae;
    222    MOZ_RELEASE_ASSERT(likes.size() == 2);
    223    MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
    224    MOZ_RELEASE_ASSERT(likes.contains(TRUE_PETREL));
    225  }
    226 
    227  void testInsersection() {
    228    EnumSetSeaBird likes = mPetrels & mPetrelProcellariidae;
    229    MOZ_RELEASE_ASSERT(likes.size() == 2);
    230    MOZ_RELEASE_ASSERT(likes.contains(GADFLY_PETREL));
    231    MOZ_RELEASE_ASSERT(likes.contains(TRUE_PETREL));
    232  }
    233 
    234  void testEquality() {
    235    EnumSetSeaBird likes = mPetrels & mPetrelProcellariidae;
    236    MOZ_RELEASE_ASSERT(likes == EnumSetSeaBird(GADFLY_PETREL, TRUE_PETREL));
    237  }
    238 
    239  void testDuplicates() {
    240    EnumSetSeaBird likes = mPetrels;
    241    likes += GADFLY_PETREL;
    242    likes += TRUE_PETREL;
    243    likes += DIVING_PETREL;
    244    likes += STORM_PETREL;
    245    MOZ_RELEASE_ASSERT(likes.size() == 4);
    246    MOZ_RELEASE_ASSERT(likes == mPetrels);
    247  }
    248 
    249  void testIteration() {
    250    EnumSetSeaBird birds;
    251    Vector<SeaBird> vec;
    252 
    253    for (auto bird : birds) {
    254      MOZ_RELEASE_ASSERT(vec.append(bird));
    255    }
    256    MOZ_RELEASE_ASSERT(vec.length() == 0);
    257 
    258    birds += DIVING_PETREL;
    259    birds += GADFLY_PETREL;
    260    birds += STORM_PETREL;
    261    birds += TRUE_PETREL;
    262    for (auto bird : birds) {
    263      MOZ_RELEASE_ASSERT(vec.append(bird));
    264    }
    265 
    266    MOZ_RELEASE_ASSERT(vec.length() == 4);
    267    MOZ_RELEASE_ASSERT(vec[0] == GADFLY_PETREL);
    268    MOZ_RELEASE_ASSERT(vec[1] == TRUE_PETREL);
    269    MOZ_RELEASE_ASSERT(vec[2] == DIVING_PETREL);
    270    MOZ_RELEASE_ASSERT(vec[3] == STORM_PETREL);
    271  }
    272 
    273  void testInitializerListConstuctor() {
    274    EnumSetSeaBird empty{};
    275    MOZ_RELEASE_ASSERT(empty.size() == 0);
    276    MOZ_RELEASE_ASSERT(empty.isEmpty());
    277 
    278    EnumSetSeaBird someBirds{SKIMMER, GULL, BOOBY};
    279    MOZ_RELEASE_ASSERT(someBirds.size() == 3);
    280    MOZ_RELEASE_ASSERT(someBirds.contains(SKIMMER));
    281    MOZ_RELEASE_ASSERT(someBirds.contains(GULL));
    282    MOZ_RELEASE_ASSERT(someBirds.contains(BOOBY));
    283  }
    284 
    285  void testBigEnum() {
    286    EnumSet<BigEnum> set;
    287    set += BigEnum::Bar;
    288    MOZ_RELEASE_ASSERT(set.serialize() ==
    289                       (uint64_t(1) << uint64_t(BigEnum::Bar)));
    290  }
    291 
    292  EnumSetSeaBird mAlcidae;
    293  EnumSetSeaBird mDiomedeidae;
    294  EnumSetSeaBird mPetrelProcellariidae;
    295  EnumSetSeaBird mNonPetrelProcellariidae;
    296  EnumSetSeaBird mPetrels;
    297 };
    298 
    299 int main() {
    300  EnumSetSuite<uint32_t> suite1;
    301  suite1.runTests();
    302 
    303  EnumSetSuite<BitSet<SEA_BIRD_COUNT>> suite2;
    304  suite2.runTests();
    305  return 0;
    306 }