Browse Source

Math: implement component-wise bool operations on BoolVector.

gpu-preference
Vladimír Vondruš 7 years ago
parent
commit
5a010269bd
  1. 3
      doc/changelog.dox
  2. 11
      doc/snippets/MagnumMath.cpp
  3. 42
      src/Magnum/Math/BoolVector.h
  4. 28
      src/Magnum/Math/Test/BoolVectorTest.cpp

3
doc/changelog.dox

@ -64,6 +64,9 @@ See also:
@ref Animation::Extrapolation::Extrapolated to
@ref Animation::Extrapolation::Constant to be consistent with
@ref Animation::Track
- @ref Math::BoolVector now implements component-wise @cpp && @ce,
@cpp || @ce and @cpp ! @ce for better consistency with boolean operations
done on scalar types
@subsubsection changelog-latest-changes-audio Audio library

11
doc/snippets/MagnumMath.cpp

@ -690,6 +690,17 @@ static_cast<void>(tan1);
static_cast<void>(tan2);
}
{
Vector3 epsilon;
/* [BoolVector-boolean] */
Vector3 a, b;
if(!(b < a - epsilon || a + epsilon < b)) {
// b is around a
}
/* [BoolVector-boolean] */
}
{
/* [Color3-pack] */
Color3 a{1.0f, 0.5f, 0.75f};

42
src/Magnum/Math/BoolVector.h

@ -66,6 +66,20 @@ stored as bits in array of unsigned bytes, unused bits have undefined value
which doesn't affect comparison or @ref all() / @ref none() / @ref any()
functions. See also @ref matrix-vector for brief introduction.
@section Math-BoolVector-boolean Boolean operations
The class implements @cpp && @ce, @cpp || @ce and @cpp ! @ce operators
component-wise, in other words equivalently to @cpp & @ce, @cpp | @ce and
@cpp ~ @ce. This is done in order to have consistent behavior with boolean
operations on scalar types --- in the following example, it causes the final
conversion to @cpp bool @ce done at the end (instead of it happening already in
the boolean subexpressions). Combined with @ref operator bool() returning
@cpp true @ce only if all bits are set, this means the condition will be passed
only if @cpp b @ce is around @cpp a @ce in *all dimensions*, and work the same
way as if the variables were just scalars:
@snippet MagnumMath.cpp BoolVector-boolean
@m_keyword{bvec2,GLSL bvec2,}
@m_keyword{bvec3,GLSL bvec3,}
@m_keyword{bvec4,GLSL bvec4,}
@ -175,6 +189,14 @@ template<std::size_t size> class BoolVector {
/** @brief Bitwise inversion */
BoolVector<size> operator~() const;
/**
* @brief Component-wise boolean negation
*
* Equivalent to @ref operator~(). See @ref Math-BoolVector-boolean for
* more information.
*/
BoolVector<size> operator!() const { return operator~(); }
/**
* @brief Bitwise AND and assign
*
@ -196,6 +218,16 @@ template<std::size_t size> class BoolVector {
return BoolVector<size>(*this) &= other;
}
/**
* @brief Component-wise boolean AND
*
* Equivalent to @ref operator&(). See @ref Math-BoolVector-boolean for
* more information.
*/
BoolVector<size> operator&&(const BoolVector<size>& other) const {
return BoolVector<size>(*this) &= other;
}
/**
* @brief Bitwise OR and assign
*
@ -217,6 +249,16 @@ template<std::size_t size> class BoolVector {
return BoolVector<size>(*this) |= other;
}
/**
* @brief Component-wise boolean OR
*
* Equivalent to @ref operator&(). See @ref Math-BoolVector-boolean for
* more information.
*/
BoolVector<size> operator||(const BoolVector<size>& other) const {
return BoolVector<size>(*this) |= other;
}
/**
* @brief Bitwise XOR and assign
*

28
src/Magnum/Math/Test/BoolVectorTest.cpp

@ -73,6 +73,7 @@ struct BoolVectorTest: Corrade::TestSuite::Tester {
void bitInverse();
void bitAndOrXor();
void booleanOperationEquivalents();
void strictWeakOrdering();
@ -105,6 +106,7 @@ BoolVectorTest::BoolVectorTest() {
&BoolVectorTest::bitInverse,
&BoolVectorTest::bitAndOrXor,
&BoolVectorTest::booleanOperationEquivalents,
&BoolVectorTest::strictWeakOrdering,
@ -248,11 +250,15 @@ void BoolVectorTest::compareUndefined() {
}
void BoolVectorTest::convertBool() {
/* The ! operation should *just work* using the bool conversion operator */
CORRADE_VERIFY(BoolVector19(0xff, 0xff, 0x07));
CORRADE_VERIFY(!BoolVector19(0xff, 0xff, 0x04));
CORRADE_VERIFY(!BoolVector19(0x00, 0x00, 0x00));
CORRADE_VERIFY(!!BoolVector19(0xff, 0xff, 0xff));
CORRADE_VERIFY(!bool(BoolVector19(0xff, 0xff, 0x04)));
CORRADE_VERIFY(!bool(BoolVector19(0x00, 0x00, 0x00)));
CORRADE_VERIFY(BoolVector19(0xff, 0xff, 0xff));
/* Using ! before and after bool conversion will produce a different
result -- first is equivalent to !a.all(), while second is (~a).all() */
CORRADE_COMPARE(!bool(BoolVector19(0xff, 0xff, 0x04)), true);
CORRADE_COMPARE(bool(!BoolVector19(0xff, 0xff, 0x04)), false);
/* Implicit conversion is not allowed */
CORRADE_VERIFY(!(std::is_convertible<BoolVector19, bool>::value));
@ -284,6 +290,7 @@ void BoolVectorTest::any() {
void BoolVectorTest::bitInverse() {
CORRADE_COMPARE(~BoolVector19(0xa5, 0x5f, 0x03), BoolVector19(0x5a, 0xa0, 0x04));
CORRADE_COMPARE(!BoolVector19(0xa5, 0x5f, 0x03), BoolVector19(0x5a, 0xa0, 0x04));
}
void BoolVectorTest::bitAndOrXor() {
@ -291,10 +298,23 @@ void BoolVectorTest::bitAndOrXor() {
BoolVector19 b(0x37, 0xf3, 0x06);
CORRADE_COMPARE(a & b, BoolVector19(0x25, 0x53, 0x02));
CORRADE_COMPARE(a && b, BoolVector19(0x25, 0x53, 0x02));
CORRADE_COMPARE(a | b, BoolVector19(0xb7, 0xff, 0x07));
CORRADE_COMPARE(a || b, BoolVector19(0xb7, 0xff, 0x07));
CORRADE_COMPARE(a ^ b, BoolVector19(0x92, 0xac, 0x05));
}
void BoolVectorTest::booleanOperationEquivalents() {
Math::BoolVector<2> a{0x3};
Math::BoolVector<2> b{0x2};
CORRADE_COMPARE(!(a || b), !a && !b);
CORRADE_COMPARE(!(a || b), ~(a | b));
CORRADE_COMPARE(!a && !b, ~a & ~b);
}
void BoolVectorTest::strictWeakOrdering() {
BoolVector<11> a, b, c;

Loading…
Cancel
Save