diff --git a/src/Math/BoolVector.h b/src/Math/BoolVector.h index eb472a64f..a5ac589d4 100644 --- a/src/Math/BoolVector.h +++ b/src/Math/BoolVector.h @@ -24,6 +24,22 @@ namespace Magnum { namespace Math { +#ifndef DOXYGEN_GENERATING_OUTPUT +namespace Implementation { + template struct Sequence {}; + + /* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */ + template struct GenerateSequence: + GenerateSequence {}; + + template struct GenerateSequence<0, sequence...> { + typedef Sequence Type; + }; + + template 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 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 from(bool value) { - BoolVector 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 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 inline constexpr /*implicit*/ BoolVector(std::uint8_t first, T... next); + #else + template::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::value && size != 1, bool>::type> inline constexpr explicit BoolVector(T value): BoolVector(typename Implementation::GenerateSequence::Type(), value ? FullSegmentMask : 0) {} + #endif /** @brief Copy constructor */ inline constexpr BoolVector(const BoolVector&) = default; @@ -211,6 +230,9 @@ template class BoolVector { LastSegmentMask = (1 << size%8) - 1 }; + /* Implementation for Vector::Vector(U) */ + template inline constexpr explicit BoolVector(Implementation::Sequence, std::uint8_t value): _data{Implementation::repeat(value, sequence)...} {} + std::uint8_t _data[(size-1)/8+1]; }; diff --git a/src/Math/Test/BoolVectorTest.cpp b/src/Math/Test/BoolVectorTest.cpp index f2b1c4e75..5729c9415 100644 --- a/src/Math/Test/BoolVectorTest.cpp +++ b/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); diff --git a/src/Math/Vector.h b/src/Math/Vector.h index 11f2a0b54..6bf8eadb4 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -32,22 +32,6 @@ namespace Magnum { namespace Math { -#ifndef DOXYGEN_GENERATING_OUTPUT -namespace Implementation { - template struct Sequence {}; - - /* E.g. GenerateSequence<3>::Type is Sequence<0, 1, 2> */ - template struct GenerateSequence: - GenerateSequence {}; - - template struct GenerateSequence<0, sequence...> { - typedef Sequence Type; - }; - - template inline constexpr T repeat(T value, std::size_t) { return value; } -} -#endif - /** @brief %Vector @tparam size %Vector size