diff --git a/doc/changelog.dox b/doc/changelog.dox index d7e881152..9a7e9d575 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -205,6 +205,9 @@ See also: - Construction using @ref Math::ZeroInit and @ref Math::IdentityInit is now explicit, to be consistent with @ref Math::NoInit construction and avoid ambiguous cases +- Changed the way @ref Math::operator<<(Corrade::Utility::Debug&, const BoolVector&) + works --- the output now has the same bit order as when constructing it + using binary literals @subsubsection changelog-latest-changes-meshtools MeshTools library diff --git a/doc/snippets/CMakeLists.txt b/doc/snippets/CMakeLists.txt index 031245b61..dfda2bcb2 100644 --- a/doc/snippets/CMakeLists.txt +++ b/doc/snippets/CMakeLists.txt @@ -55,6 +55,18 @@ if(MAGNUM_TARGET_GL) endif() set_target_properties(snippets-Magnum PROPERTIES FOLDER "Magnum/doc/snippets") +# This is taken from corrade/src/Corrade/Test/CMakeLists.txt, keep in sync +if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0") OR + (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.9") OR + (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "7.0") OR + (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")) + add_library(snippets-Magnum-cpp14 STATIC MagnumMath-cpp14.cpp) + target_link_libraries(snippets-Magnum-cpp14 PRIVATE Magnum) + set_target_properties(snippets-Magnum-cpp14 PROPERTIES + CORRADE_CXX_STANDARD 14 + FOLDER "Magnum/doc/snippets") +endif() + if(WITH_AUDIO) add_library(snippets-MagnumAudio STATIC MagnumAudio.cpp) target_link_libraries(snippets-MagnumAudio PRIVATE MagnumAudio) diff --git a/doc/snippets/MagnumMath-cpp14.cpp b/doc/snippets/MagnumMath-cpp14.cpp new file mode 100644 index 000000000..424ff3c91 --- /dev/null +++ b/doc/snippets/MagnumMath-cpp14.cpp @@ -0,0 +1,51 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Magnum/Math/BoolVector.h" +#include "Magnum/Magnum.h" + +using namespace Magnum; + +int main() { +{ +/* [BoolVector-indexing] */ +BoolVector4 a{0b0010}; +Debug{} << a[1]; // true + +Math::BoolVector<19> b{0b00001000, 0b00000011, 0b100}; +Debug{} << b[3]; // true +Debug{} << b[8]; // true +Debug{} << b[9]; // true +Debug{} << b[18]; // true +/* [BoolVector-indexing] */ +} + +{ +/* [BoolVector-debug] */ +Debug{} << BoolVector4{0b1010} + << Math::BoolVector<19>{0b00001000, 0b00000011, 0b100}; +/* [BoolVector-debug] */ +} +} diff --git a/src/Magnum/Math/BoolVector.h b/src/Magnum/Math/BoolVector.h index 2f4847bf8..4c930b1f4 100644 --- a/src/Magnum/Math/BoolVector.h +++ b/src/Magnum/Math/BoolVector.h @@ -68,6 +68,14 @@ 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-indexing Bit indexing + +Value at position 0 is the lowest bit of the first byte passed in constructor. +Value at position 8 is the lowest bit of the second byte passed in constructor. +For example: + +@snippet MagnumMath-cpp14.cpp BoolVector-indexing + @section Math-BoolVector-boolean Boolean operations The class implements @cpp && @ce, @cpp || @ce and @cpp ! @ce operators @@ -300,14 +308,45 @@ template class BoolVector { }; #ifndef CORRADE_NO_DEBUG -/** @debugoperator{BoolVector} */ +/** +@debugoperator{BoolVector} + +In order to avoid potential confusion, prints the value as a comma-separated sequence of binary literals, so the output corresponds to how the value would +be constructed. For example, + +@snippet MagnumMath-cpp14.cpp BoolVector-debug + + + +@m_class{m-noindent} + +prints as + +@code{.shell-session} +BoolVector(0b1010) BoolVector(0b00001000, 0b00000011, 0b100) +@endcode + +Note that this, on the other hand, makes mapping to bit indices less obvious +--- see @ref Math-BoolVector-indexing for more information. +*/ template Corrade::Utility::Debug& operator<<(Corrade::Utility::Debug& debug, const BoolVector& value) { - debug << "BoolVector(" << Corrade::Utility::Debug::nospace; - for(std::size_t i = 0; i != size; ++i) { - if(!i || (i%8)) debug << Corrade::Utility::Debug::nospace; - debug << (value[i] ? "1" : "0"); + debug << "BoolVector(0b" << Corrade::Utility::Debug::nospace; + + /* Print the full bytes comma-separated */ + for(std::size_t byte = 0; byte != BoolVector::DataSize - 1; ++byte) { + for(std::size_t i = 0; i != 8; ++i) + debug << (((value.data()[byte] >> (8 - i - 1)) & 1) ? "1" : "0") + << Corrade::Utility::Debug::nospace; + debug << ", 0b" << Corrade::Utility::Debug::nospace; } - return debug << Corrade::Utility::Debug::nospace << ")"; + + /* Print the last (potentially) partial byte */ + constexpr std::size_t suffixSize = size%8 ? size%8 : 8; + for(std::size_t i = 0; i != suffixSize; ++i) + debug << (((value.data()[size/8] >> (suffixSize - i - 1)) & 1) ? "1" : "0") + << Corrade::Utility::Debug::nospace; + + return debug << ")"; } #endif diff --git a/src/Magnum/Math/Test/BoolVectorTest.cpp b/src/Magnum/Math/Test/BoolVectorTest.cpp index f67ba47db..443f20667 100644 --- a/src/Magnum/Math/Test/BoolVectorTest.cpp +++ b/src/Magnum/Math/Test/BoolVectorTest.cpp @@ -198,6 +198,7 @@ void BoolVectorTest::convert() { } void BoolVectorTest::data() { + /* 0b00001000, 0b00000011, 0b100 */ constexpr BoolVector19 a(0x08, 0x03, 0x04); CORRADE_VERIFY(!a[0] && !a[1] && !a[2]); @@ -354,9 +355,10 @@ void BoolVectorTest::strictWeakOrdering() { void BoolVectorTest::debug() { std::ostringstream o; + /* 0b00100101 0b01010011 0b010 */ Debug(&o) << BoolVector19(0x25, 0x53, 0x02); - CORRADE_COMPARE(o.str(), "BoolVector(10100100 11001010 010)\n"); + CORRADE_COMPARE(o.str(), "BoolVector(0b00100101, 0b01010011, 0b010)\n"); } }}}}