Browse Source

Math: follow Vector changes in BoolVector.

Added constexpr "filling" constructor, updated tests, added constexpr
test.
pull/7/head
Vladimír Vondruš 13 years ago
parent
commit
f517a000ed
  1. 50
      src/Math/BoolVector.h
  2. 41
      src/Math/Test/BoolVectorTest.cpp
  3. 16
      src/Math/Vector.h

50
src/Math/BoolVector.h

@ -24,6 +24,22 @@
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<std::size_t ...> struct Sequence {};
/* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */
template<std::size_t N, std::size_t ...sequence> struct GenerateSequence:
GenerateSequence<N-1, N-1, sequence...> {};
template<std::size_t ...sequence> struct GenerateSequence<0, sequence...> {
typedef Sequence<sequence...> Type;
};
template<class T> inline constexpr T repeat(T value, std::size_t) { return value; }
}
#endif
/**
@brief %Vector storing boolean values
@tparam size Bit count
@ -40,23 +56,26 @@ template<std::size_t size> class BoolVector {
static const std::size_t Size = size; /**< @brief %Vector size */
static const std::size_t DataSize = (size-1)/8+1; /**< @brief %Vector storage size */
/** @brief Construct boolean with one value for all elements */
inline static BoolVector<size> from(bool value) {
BoolVector<size> out;
for(std::size_t i = 0; i != size; ++i)
out._data[i] = (value ? FullSegmentMask : 0);
return out;
}
/** @brief Construct zero-filled boolean vector */
inline constexpr BoolVector(): _data() {}
/** @brief Construct boolean vector from given values */
template<class ...U> inline constexpr BoolVector(std::uint8_t first, U... next): _data{first, std::uint8_t(next)...} {
static_assert(sizeof...(next)+1 == DataSize, "Improper number of arguments passed to BoolVector constructor");
}
/**
* @brief Construct boolean vector from segment values
* @param first Value for first 8bit segment
* @param next Values for next Bbit segments
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<class ...T> inline constexpr /*implicit*/ BoolVector(std::uint8_t first, T... next);
#else
template<class ...T, class U = typename std::enable_if<sizeof...(T)+1 == DataSize, bool>::type> inline constexpr /*implicit*/ BoolVector(std::uint8_t first, T... next): _data{first, std::uint8_t(next)...} {}
#endif
/** @brief Construct boolean vector with one value for all fields */
#ifdef DOXYGEN_GENERATING_OUTPUT
inline explicit BoolVector(T value);
#else
template<class T, class U = typename std::enable_if<std::is_same<bool, T>::value && size != 1, bool>::type> inline constexpr explicit BoolVector(T value): BoolVector(typename Implementation::GenerateSequence<DataSize>::Type(), value ? FullSegmentMask : 0) {}
#endif
/** @brief Copy constructor */
inline constexpr BoolVector(const BoolVector<size>&) = default;
@ -211,6 +230,9 @@ template<std::size_t size> class BoolVector {
LastSegmentMask = (1 << size%8) - 1
};
/* Implementation for Vector<size, T>::Vector(U) */
template<std::size_t ...sequence> inline constexpr explicit BoolVector(Implementation::Sequence<sequence...>, std::uint8_t value): _data{Implementation::repeat(value, sequence)...} {}
std::uint8_t _data[(size-1)/8+1];
};

41
src/Math/Test/BoolVectorTest.cpp

@ -26,8 +26,11 @@ class BoolVectorTest: public Corrade::TestSuite::Tester {
void constructDefault();
void constructOneValue();
void constructOneElement();
void data();
void constExpressions();
void compare();
void compareUndefined();
void all();
@ -49,8 +52,11 @@ typedef Math::BoolVector<19> BoolVector19;
BoolVectorTest::BoolVectorTest() {
addTests(&BoolVectorTest::constructDefault,
&BoolVectorTest::constructOneValue,
&BoolVectorTest::constructOneElement,
&BoolVectorTest::data,
&BoolVectorTest::constExpressions,
&BoolVectorTest::compare,
&BoolVectorTest::compareUndefined,
&BoolVectorTest::all,
@ -68,8 +74,15 @@ void BoolVectorTest::constructDefault() {
}
void BoolVectorTest::constructOneValue() {
CORRADE_COMPARE(BoolVector19::from(false), BoolVector19(0x00, 0x00, 0x00));
CORRADE_COMPARE(BoolVector19::from(true), BoolVector19(0xff, 0xff, 0x07));
CORRADE_COMPARE(BoolVector19(false), BoolVector19(0x00, 0x00, 0x00));
CORRADE_COMPARE(BoolVector19(true), BoolVector19(0xff, 0xff, 0x07));
}
void BoolVectorTest::constructOneElement() {
typedef BoolVector<1> BoolVector1;
BoolVector1 a = 0x01;
CORRADE_COMPARE(a, BoolVector1(0x01));
}
void BoolVectorTest::data() {
@ -89,6 +102,30 @@ void BoolVectorTest::data() {
CORRADE_COMPARE(a, BoolVector19(0x08, 0x83, 0x04));
}
void BoolVectorTest::constExpressions() {
/* Default constructor */
constexpr BoolVector19 a;
CORRADE_COMPARE(a, BoolVector19(0x00, 0x00, 0x00));
/* Value constructor */
constexpr BoolVector19 b(0xa5, 0x5f, 0x07);
CORRADE_COMPARE(b, BoolVector19(0xa5, 0x5f, 0x07));
/* One-value constructor */
constexpr BoolVector19 c(true);
CORRADE_COMPARE(c, BoolVector19(0xff, 0xff, 0x07));
/* Copy constructor */
constexpr BoolVector19 d(b);
CORRADE_COMPARE(d, BoolVector19(0xa5, 0x5f, 0x07));
/* Data access, pointer chasings, i.e. *(b.data()[3]), are not possible */
constexpr bool e = b[2];
constexpr std::uint8_t f = *b.data();
CORRADE_COMPARE(e, true);
CORRADE_COMPARE(f, 0xa5);
}
void BoolVectorTest::compare() {
BoolVector19 a(0xa5, 0x5f, 0x07);
CORRADE_VERIFY(a == a);

16
src/Math/Vector.h

@ -32,22 +32,6 @@
namespace Magnum { namespace Math {
#ifndef DOXYGEN_GENERATING_OUTPUT
namespace Implementation {
template<std::size_t ...> struct Sequence {};
/* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */
template<std::size_t N, std::size_t ...sequence> struct GenerateSequence:
GenerateSequence<N-1, N-1, sequence...> {};
template<std::size_t ...sequence> struct GenerateSequence<0, sequence...> {
typedef Sequence<sequence...> Type;
};
template<class T> inline constexpr T repeat(T value, std::size_t) { return value; }
}
#endif
/**
@brief %Vector
@tparam size %Vector size

Loading…
Cancel
Save