Browse Source

Math: add branch-less BitVector::set() and reset().

Not sure why these weren't there since ever -- I was pretty sure I added
them.
pull/617/head
Vladimír Vondruš 3 years ago
parent
commit
3e1ce9f35c
  1. 2
      doc/changelog.dox
  2. 25
      src/Magnum/Math/BitVector.h
  3. 37
      src/Magnum/Math/Test/BitVectorTest.cpp

2
doc/changelog.dox

@ -523,6 +523,8 @@ See also:
@subsubsection changelog-latest-changes-math Math library
- Added @ref Math::BitVector::set(std::size_t) and
@ref Math::BitVector::reset(std::size_t) for branchless bit setting
- Added @ref Math::castInto() overloads for casting between @ref UnsignedByte
and @ref UnsignedShort or @ref Byte and @ref Short, from and to
@ref UnsignedLong / @ref Long, between integral types and @ref Double and

25
src/Magnum/Math/BitVector.h

@ -153,7 +153,30 @@ template<std::size_t size> class BitVector {
return (_data[i/8] >> i%8) & 0x01;
}
/** @brief Set a bit at given position */
/**
* @brief Set a bit at given position
* @m_since_latest
*/
BitVector<size>& set(std::size_t i) {
_data[i/8] |= 1 << i%8;
return *this;
}
/**
* @brief Reset a bit at given position
* @m_since_latest
*/
BitVector<size>& reset(std::size_t i) {
_data[i/8] &= ~(1 << i%8);
return *this;
}
/**
* @brief Set or reset a bit at given position
*
* Prefer to use @ref set(std::size_t) and @ref reset(std::size_t)
* where possible as that's a simpler operation.
*/
BitVector<size>& set(std::size_t i, bool value) {
value ? _data[i/8] |= (1 << i%8) :
_data[i/8] &= ~(1 << i%8);

37
src/Magnum/Math/Test/BitVectorTest.cpp

@ -220,23 +220,30 @@ void BitVectorTest::data() {
constexpr bool b = ca[9];
CORRADE_COMPARE(b, true);
BitVector19 a(0x08, 0x03, 0x04);
a.set(15, true);
CORRADE_VERIFY(a[15]);
CORRADE_COMPARE(a, BitVector19(0x08, 0x83, 0x04));
a.set(15, false);
CORRADE_VERIFY(!a[15]);
CORRADE_COMPARE(a, BitVector19(0x08, 0x03, 0x04));
BitVector19 a1(0x08, 0x03, 0x04);
BitVector19 a2(0x08, 0x03, 0x04);
a1.set(15);
a2.set(15, true);
CORRADE_VERIFY(a1[15]);
CORRADE_VERIFY(a2[15]);
CORRADE_COMPARE(a1, BitVector19(0x08, 0x83, 0x04));
CORRADE_COMPARE(a2, BitVector19(0x08, 0x83, 0x04));
a1.reset(15);
a2.set(15, false);
CORRADE_VERIFY(!a1[15]);
CORRADE_VERIFY(!a2[15]);
CORRADE_COMPARE(a1, BitVector19(0x08, 0x03, 0x04));
CORRADE_COMPARE(a2, BitVector19(0x08, 0x03, 0x04));
#ifndef CORRADE_MSVC2015_COMPATIBILITY /* Apparently dereferencing pointer is verboten */
constexpr
#endif
UnsignedByte c = *ca.data();
CORRADE_COMPARE(a.data()[1], 0x03);
CORRADE_COMPARE(a1.data()[1], 0x03);
CORRADE_COMPARE(c, 0x08);
/* It actually returns an array */
CORRADE_COMPARE(Corrade::Containers::arraySize(a.data()), 3);
CORRADE_COMPARE(Corrade::Containers::arraySize(a1.data()), 3);
CORRADE_COMPARE(Corrade::Containers::arraySize(ca.data()), 3);
}
@ -336,12 +343,12 @@ void BitVectorTest::booleanOperationEquivalents() {
void BitVectorTest::strictWeakOrdering() {
BitVector<11> a, b, c;
a.set(0, true);
a.set(1, true);
a.set(0);
a.set(1);
c.set(7, true);
c.set(7);
b.set(8, true);
b.set(8);
StrictWeakOrdering o;
CORRADE_VERIFY( o(b, a));
@ -353,8 +360,8 @@ void BitVectorTest::strictWeakOrdering() {
CORRADE_VERIFY(!o(a, a));
/* Check uninitialized padding reads */
a.set(8, true);
a.set(10, true);
a.set(8);
a.set(10);
b = a;
a.data()[1] |= 0x08;
b.data()[1] |= 0x20;

Loading…
Cancel
Save