Repository navigation
Expand file tree
/
Copy pathbit_ops.cpp
More file actions
70 lines (57 loc) · 1.47 KB
/
Copy pathbit_ops.cpp
File metadata and controls
70 lines (57 loc) · 1.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include "bit_ops.hpp"
#include <stdexcept>
namespace bitops
{
namespace
{
// Single validation point for the three indexed operations. Throwing (rather
// than clamping or wrapping) is deliberate: silently "fixing" a bad index
// would hide a caller bug, and a bit index has no sensible fallback value.
void requireValidBitIndex(int bit)
{
if (bit < kMinBitIndex || bit > kMaxBitIndex)
{
throw std::out_of_range("bit index out of range");
}
}
} // namespace
std::uint32_t turnOn(std::uint32_t value, int bit)
{
requireValidBitIndex(bit);
return value | (std::uint32_t{1} << bit);
}
std::uint32_t turnOff(std::uint32_t value, int bit)
{
requireValidBitIndex(bit);
return value & ~(std::uint32_t{1} << bit);
}
std::uint32_t toggle(std::uint32_t value, int bit)
{
requireValidBitIndex(bit);
return value ^ (std::uint32_t{1} << bit);
}
std::uint32_t negateBits(std::uint32_t value)
{
return ~value;
}
std::uint32_t leftShift(std::uint32_t value)
{
// Unsigned shift: well-defined modulo 2^32, so no cast games are needed
// beyond the type itself.
return value << 1;
}
std::uint32_t rightShift(std::uint32_t value)
{
return value >> 1;
}
std::string toBitString(std::uint32_t value)
{
std::string bits;
bits.reserve(static_cast<std::string::size_type>(kBitWidth));
for (int i = kBitWidth - 1; i >= 0; --i)
{
bits.push_back(((value >> i) & 1u) != 0 ? '1' : '0');
}
return bits;
}
} // namespace bitops