brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · ae541fe Raw
257 lines · cpp
1//===- llvm/unittests/ADT/BitFieldsTest.cpp - BitFields unit tests --------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ADT/Bitfields.h"10#include "gtest/gtest.h"11 12using namespace llvm;13 14namespace {15 16TEST(BitfieldsTest, Example) {17  uint8_t Storage = 0;18 19  // Store and retrieve a single bit as bool.20  using Bool = Bitfield::Element<bool, 0, 1>;21  Bitfield::set<Bool>(Storage, true);22  EXPECT_EQ(Storage, 0b00000001);23  //                          ^24  EXPECT_EQ(Bitfield::get<Bool>(Storage), true);25 26  // Store and retrieve a 2 bit typed enum.27  // Note: enum underlying type must be unsigned.28  enum class SuitEnum : uint8_t { CLUBS, DIAMONDS, HEARTS, SPADES };29  // Note: enum maximum value needs to be passed in as last parameter.30  using Suit = Bitfield::Element<SuitEnum, 1, 2, SuitEnum::SPADES>;31  Bitfield::set<Suit>(Storage, SuitEnum::HEARTS);32  EXPECT_EQ(Storage, 0b00000101);33  //                        ^^34  EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::HEARTS);35 36  // Store and retrieve a 5 bit value as unsigned.37  using Value = Bitfield::Element<unsigned, 3, 5>;38  Bitfield::set<Value>(Storage, 10);39  EXPECT_EQ(Storage, 0b01010101);40  //                   ^^^^^41  EXPECT_EQ(Bitfield::get<Value>(Storage), 10U);42 43  // Interpret the same 5 bit value as signed.44  using SignedValue = Bitfield::Element<int, 3, 5>;45  Bitfield::set<SignedValue>(Storage, -2);46  EXPECT_EQ(Storage, 0b11110101);47  //                   ^^^^^48  EXPECT_EQ(Bitfield::get<SignedValue>(Storage), -2);49 50  // Ability to efficiently test if a field is non zero.51  EXPECT_TRUE(Bitfield::test<Value>(Storage));52 53  // Alter Storage changes value.54  Storage = 0;55  EXPECT_EQ(Bitfield::get<Bool>(Storage), false);56  EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::CLUBS);57  EXPECT_EQ(Bitfield::get<Value>(Storage), 0U);58  EXPECT_EQ(Bitfield::get<SignedValue>(Storage), 0);59 60  Storage = 255;61  EXPECT_EQ(Bitfield::get<Bool>(Storage), true);62  EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::SPADES);63  EXPECT_EQ(Bitfield::get<Value>(Storage), 31U);64  EXPECT_EQ(Bitfield::get<SignedValue>(Storage), -1);65}66 67TEST(BitfieldsTest, FirstBit) {68  uint8_t Storage = 0;69  using FirstBit = Bitfield::Element<bool, 0, 1>;70  // Set true71  Bitfield::set<FirstBit>(Storage, true);72  EXPECT_EQ(Bitfield::get<FirstBit>(Storage), true);73  EXPECT_EQ(Storage, 0x1ULL);74  // Set false75  Bitfield::set<FirstBit>(Storage, false);76  EXPECT_EQ(Bitfield::get<FirstBit>(Storage), false);77  EXPECT_EQ(Storage, 0x0ULL);78}79 80TEST(BitfieldsTest, SecondBit) {81  uint8_t Storage = 0;82  using SecondBit = Bitfield::Element<bool, 1, 1>;83  // Set true84  Bitfield::set<SecondBit>(Storage, true);85  EXPECT_EQ(Bitfield::get<SecondBit>(Storage), true);86  EXPECT_EQ(Storage, 0x2ULL);87  // Set false88  Bitfield::set<SecondBit>(Storage, false);89  EXPECT_EQ(Bitfield::get<SecondBit>(Storage), false);90  EXPECT_EQ(Storage, 0x0ULL);91}92 93TEST(BitfieldsTest, LastBit) {94  uint8_t Storage = 0;95  using LastBit = Bitfield::Element<bool, 7, 1>;96  // Set true97  Bitfield::set<LastBit>(Storage, true);98  EXPECT_EQ(Bitfield::get<LastBit>(Storage), true);99  EXPECT_EQ(Storage, 0x80ULL);100  // Set false101  Bitfield::set<LastBit>(Storage, false);102  EXPECT_EQ(Bitfield::get<LastBit>(Storage), false);103  EXPECT_EQ(Storage, 0x0ULL);104}105 106TEST(BitfieldsTest, LastBitUint64) {107  uint64_t Storage = 0;108  using LastBit = Bitfield::Element<bool, 63, 1>;109  // Set true110  Bitfield::set<LastBit>(Storage, true);111  EXPECT_EQ(Bitfield::get<LastBit>(Storage), true);112  EXPECT_EQ(Storage, 0x8000000000000000ULL);113  // Set false114  Bitfield::set<LastBit>(Storage, false);115  EXPECT_EQ(Bitfield::get<LastBit>(Storage), false);116  EXPECT_EQ(Storage, 0x0ULL);117}118 119TEST(BitfieldsTest, Enum) {120  enum Enum : unsigned { Zero = 0, Two = 2, LAST = Two };121 122  uint8_t Storage = 0;123  using OrderingField = Bitfield::Element<Enum, 1, 2, LAST>;124  EXPECT_EQ(Bitfield::get<OrderingField>(Storage), Zero);125  Bitfield::set<OrderingField>(Storage, Two);126  EXPECT_EQ(Bitfield::get<OrderingField>(Storage), Two);127  EXPECT_EQ(Storage, 0b00000100);128  // value 2 in             ^^129}130 131TEST(BitfieldsTest, EnumClass) {132  enum class Enum : unsigned { Zero = 0, Two = 2, LAST = Two };133 134  uint8_t Storage = 0;135  using OrderingField = Bitfield::Element<Enum, 1, 2, Enum::LAST>;136  EXPECT_EQ(Bitfield::get<OrderingField>(Storage), Enum::Zero);137  Bitfield::set<OrderingField>(Storage, Enum::Two);138  EXPECT_EQ(Bitfield::get<OrderingField>(Storage), Enum::Two);139  EXPECT_EQ(Storage, 0b00000100);140  // value 2 in             ^^141}142 143TEST(BitfieldsTest, OneBitSigned) {144  uint8_t Storage = 0;145  using SignedField = Bitfield::Element<int, 1, 1>;146  EXPECT_EQ(Bitfield::get<SignedField>(Storage), 0);147  EXPECT_EQ(Storage, 0b00000000);148  // value 0 in              ^149  Bitfield::set<SignedField>(Storage, -1);150  EXPECT_EQ(Bitfield::get<SignedField>(Storage), -1);151  EXPECT_EQ(Storage, 0b00000010);152  // value 1 in              ^153}154 155TEST(BitfieldsTest, TwoBitSigned) {156  uint8_t Storage = 0;157  using SignedField = Bitfield::Element<int, 1, 2>;158  EXPECT_EQ(Bitfield::get<SignedField>(Storage), 0);159  EXPECT_EQ(Storage, 0b00000000);160  // value 0 in             ^^161  Bitfield::set<SignedField>(Storage, 1);162  EXPECT_EQ(Bitfield::get<SignedField>(Storage), 1);163  EXPECT_EQ(Storage, 0b00000010);164  // value 1 in             ^^165  Bitfield::set<SignedField>(Storage, -1);166  EXPECT_EQ(Bitfield::get<SignedField>(Storage), -1);167  EXPECT_EQ(Storage, 0b00000110);168  // value -1 in            ^^169  Bitfield::set<SignedField>(Storage, -2);170  EXPECT_EQ(Bitfield::get<SignedField>(Storage), -2);171  EXPECT_EQ(Storage, 0b00000100);172  // value -2 in            ^^173}174 175TEST(BitfieldsTest, isOverlapping) {176  //    01234567177  // A: --------178  // B:    ---179  // C:  ---180  // D:     ---181  using A = Bitfield::Element<unsigned, 0, 8>;182  using B = Bitfield::Element<unsigned, 3, 3>;183  using C = Bitfield::Element<unsigned, 1, 3>;184  using D = Bitfield::Element<unsigned, 4, 3>;185  EXPECT_TRUE((Bitfield::isOverlapping<A, B>()));186  EXPECT_TRUE((Bitfield::isOverlapping<A, C>()));187  EXPECT_TRUE((Bitfield::isOverlapping<A, B>()));188  EXPECT_TRUE((Bitfield::isOverlapping<A, D>()));189 190  EXPECT_TRUE((Bitfield::isOverlapping<B, C>()));191  EXPECT_TRUE((Bitfield::isOverlapping<B, D>()));192  EXPECT_FALSE((Bitfield::isOverlapping<C, D>()));193}194 195TEST(BitfieldsTest, areContiguous) {196  using A = Bitfield::Element<unsigned, 0, 1>; // Next Bit:1197  using B = Bitfield::Element<unsigned, 1, 4>; // Next Bit:5198  using C = Bitfield::Element<unsigned, 5, 3>; // Next Bit:8199  EXPECT_TRUE((Bitfield::areContiguous<A, B>()));200  EXPECT_TRUE((Bitfield::areContiguous<A, B, C>()));201 202  EXPECT_FALSE((Bitfield::areContiguous<A, C>()));203  EXPECT_FALSE((Bitfield::areContiguous<A, A>()));204  EXPECT_FALSE((Bitfield::areContiguous<B, A>()));205}206 207TEST(BitfieldsTest, FullUint64) {208  uint64_t Storage = 0;209  using Value = Bitfield::Element<uint64_t, 0, 64>;210  Bitfield::set<Value>(Storage, -1ULL);211  EXPECT_EQ(Bitfield::get<Value>(Storage), -1ULL);212  Bitfield::set<Value>(Storage, 0ULL);213  EXPECT_EQ(Bitfield::get<Value>(Storage), 0ULL);214}215 216TEST(BitfieldsTest, FullInt64) {217  uint64_t Storage = 0;218  using Value = Bitfield::Element<int64_t, 0, 64>;219  Bitfield::set<Value>(Storage, -1);220  EXPECT_EQ(Bitfield::get<Value>(Storage), -1);221  Bitfield::set<Value>(Storage, 0);222  EXPECT_EQ(Bitfield::get<Value>(Storage), 0);223}224 225#ifdef EXPECT_DEBUG_DEATH226 227TEST(BitfieldsTest, ValueTooBigBool) {228  uint64_t Storage = 0;229  using A = Bitfield::Element<unsigned, 0, 1>;230  Bitfield::set<A>(Storage, true);231  Bitfield::set<A>(Storage, false);232  EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, 2), "value is too big");233}234 235TEST(BitfieldsTest, ValueTooBigInt) {236  uint64_t Storage = 0;237  using A = Bitfield::Element<unsigned, 0, 2>;238  Bitfield::set<A>(Storage, 3);239  EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, 4), "value is too big");240  EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, -1), "value is too big");241}242 243TEST(BitfieldsTest, ValueTooBigBounded) {244  uint8_t Storage = 0;245  using A = Bitfield::Element<int, 1, 2>;246  Bitfield::set<A>(Storage, 1);247  Bitfield::set<A>(Storage, 0);248  Bitfield::set<A>(Storage, -1);249  Bitfield::set<A>(Storage, -2);250  EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, 2), "value is out of range");251  EXPECT_DEBUG_DEATH(Bitfield::set<A>(Storage, -3), "value is out of range");252}253 254#endif255 256} // namespace257