diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | chilbert/FixBitVec.hpp | 6 | ||||
-rw-r--r-- | test/test_bitvec.cpp | 278 | ||||
-rw-r--r-- | test/test_fsb.cpp | 45 |
4 files changed, 286 insertions, 47 deletions
@@ -1,7 +1,7 @@ CXXFLAGS += -I. -std=c++14 -Wall -Wextra -Wno-unused-parameter HEADERS = $(wildcard chilbert/*.hpp) -TESTS = test/test_fsb +TESTS = test/test_bitvec all: $(TESTS) @@ -13,7 +13,7 @@ test/%: test/%.cpp $(HEADERS) FORCE: -test/%.test: test/test_fsb FORCE +test/%.test: $(TESTS) FORCE @test/$* test: $(addsuffix .test, $(TESTS)) diff --git a/chilbert/FixBitVec.hpp b/chilbert/FixBitVec.hpp index 05af40e..9df2ada 100644 --- a/chilbert/FixBitVec.hpp +++ b/chilbert/FixBitVec.hpp @@ -40,6 +40,12 @@ typedef uint64_t FBV_UINT; class CFixBitVec { public: + CFixBitVec(int bits = FBV_BITS) + : m_rack{0} + { + assert(bits <= FBV_BITS); + } + /// Return the size in bits int size() const { return FBV_BITS; } diff --git a/test/test_bitvec.cpp b/test/test_bitvec.cpp new file mode 100644 index 0000000..e547122 --- /dev/null +++ b/test/test_bitvec.cpp @@ -0,0 +1,278 @@ +/* + Copyright (C) 2018 David Robillard <d@drobilla.net> + + This program is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free Software + Foundation, either version 2 of the License, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along with + this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +#undef NDEBUG + +#include "chilbert/BigBitVec.hpp" +#include "chilbert/FixBitVec.hpp" + +#include <cassert> +#include <cstddef> +#include <cstdlib> + +template <class T, size_t N> +T +make_zero_bitvec() +{ + T v(N); + v.reset(); + return v; +} + +template <class T, size_t N> +T +make_random_bitvec() +{ + T v(N); + for (size_t i = 0; i < N; ++i) { + v.set(i, rand() & 1); + } + return v; +} + +template <class T, size_t N> +void +test_and() +{ + const T a = make_random_bitvec<T, N>(); + const T b = make_random_bitvec<T, N>(); + T r = a; + assert((a & b) == (r &= b)); + + for (size_t i = 0; i < N; ++i) { + assert(r.test(i) == (a.test(i) && b.test(i))); + } +} + +template <class T, size_t N> +void +test_or() +{ + const T a = make_random_bitvec<T, N>(); + const T b = make_random_bitvec<T, N>(); + T r = a; + assert((a | b) == (r |= b)); + + for (size_t i = 0; i < N; ++i) { + assert(r.test(i) == (a.test(i) || b.test(i))); + } +} + +template <class T, size_t N> +void +test_xor() +{ + const T a = make_random_bitvec<T, N>(); + const T b = make_random_bitvec<T, N>(); + T r = a; + assert((a ^ b) == (r ^= b)); + + for (size_t i = 0; i < N; ++i) { + assert(r.test(i) == (a.test(i) != b.test(i))); + } +} + +template <class T, size_t N> +void +test_flip_one() +{ + T v = make_zero_bitvec<T, N>(); + for (size_t i = 0; i < N; ++i) { + assert(v.none()); + v.flip(i); + for (size_t j = 0; j < N; ++j) { + assert(v.test(j) == (j == i)); + } + + v.flip(i); + assert(v.none()); + } +} + +template <class T, size_t N> +void +test_flip_all() +{ + const T a = make_random_bitvec<T, N>(); + T r = a; + r.flip(); + for (size_t i = 0; i < N; ++i) { + assert(r.test(i) == !a.test(i)); + } +} + +template <class T, size_t N> +void +test_none() +{ + T v = make_zero_bitvec<T, N>(); + assert(v.none()); + v.set(); + assert(v.none() == (N == 0)); + if (N > 1) { + v.reset(N / 2); + assert(!v.none()); + v.reset(); + v.set(N / 2); + assert(!v.none()); + } +} + +template <class T, size_t N> +void +test_set_reset_one() +{ + T v = make_zero_bitvec<T, N>(); + for (size_t i = 0; i < N; ++i) { + assert(v.none()); + v.set(i); + for (size_t j = 0; j < N; ++j) { + assert(v.test(j) == (j == i)); + } + + v.reset(i); + assert(v.none()); + } +} + +template <class T, size_t N> +void +test_set_all() +{ + T v = make_zero_bitvec<T, N>(); + v.set(); + for (size_t i = 0; i < N; ++i) { + assert(v.test(i)); + } +} + +template <class T, size_t N> +void +test_reset_all() +{ + T v = make_zero_bitvec<T, N>(); + v.set(); + v.reset(); + for (size_t i = 0; i < N; ++i) { + assert(!v.test(i)); + } +} + +template <class T, size_t N> +void +test_left_shift() +{ + for (size_t s = 0; s < N; ++s) { + const T v = make_random_bitvec<T, N>(); + T r = v; + assert((v << s) == (r <<= s)); + + for (size_t i = s; i < N - s; ++i) { + assert(r.test(i + s) == v.test(i)); + } + } +} + +template <class T, size_t N> +void +test_right_shift() +{ + for (size_t s = 0; s < N; ++s) { + const T v = make_random_bitvec<T, N>(); + T r = v; + assert((v >> s) == (r >>= s)); + + for (size_t i = s; i < N - s; ++i) { + assert(r.test(i - s) == v.test(i)); + } + } +} + +template <class T, size_t N> +void +test_find_first() +{ + T v = make_zero_bitvec<T, N>(); + for (size_t i = 0; i < N; ++i) { + v.reset(); + v.set(i); + for (size_t j = i + 1; j < N; ++j) { + v.set(j, rand() & 1); + } + assert(size_t(v.find_first()) == i + 1); + } +} + +template <class T, size_t N> +void +test_gray_code() +{ + const T v = make_random_bitvec<T, N>(); + T r = v; + grayCode(r); + + if (N > 0) { + assert(r == (v ^ (v >> 1))); + + T s = r; + grayCodeInv(s); + assert(s == v); + } +} + +template <class T, size_t N> +void +test() +{ + test_and<T, N>(); + test_or<T, N>(); + test_xor<T, N>(); + test_flip_one<T, N>(); + test_flip_all<T, N>(); + test_none<T, N>(); + test_set_reset_one<T, N>(); + test_set_all<T, N>(); + test_reset_all<T, N>(); + test_left_shift<T, N>(); + test_right_shift<T, N>(); + test_find_first<T, N>(); + test_gray_code<T, N>(); +} + +int +main() +{ + // test<chilbert::CFixBitVec, 0>(); + test<chilbert::CFixBitVec, 1>(); + test<chilbert::CFixBitVec, 31>(); + test<chilbert::CFixBitVec, 32>(); + test<chilbert::CFixBitVec, 33>(); + test<chilbert::CFixBitVec, 63>(); + test<chilbert::CFixBitVec, 64>(); + + test<chilbert::CBigBitVec, 0>(); + test<chilbert::CBigBitVec, 1>(); + test<chilbert::CBigBitVec, 31>(); + test<chilbert::CBigBitVec, 32>(); + test<chilbert::CBigBitVec, 33>(); + test<chilbert::CBigBitVec, 63>(); + test<chilbert::CBigBitVec, 64>(); + test<chilbert::CBigBitVec, 65>(); + test<chilbert::CBigBitVec, 997>(); + + return 0; +} diff --git a/test/test_fsb.cpp b/test/test_fsb.cpp deleted file mode 100644 index b059394..0000000 --- a/test/test_fsb.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2018 David Robillard <d@drobilla.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#undef NDEBUG - -#include "chilbert/BigBitVec.hpp" -#include "chilbert/FixBitVec.hpp" - -#include <cassert> - -using namespace chilbert; - -template <typename T> -int -test_fsb(const T& empty_field) -{ - assert(empty_field.none()); - for (int i = 0; i < empty_field.size(); ++i) { - T field = empty_field; - field.set(i); - assert(field.find_first() == i + 1); - } - - return 0; -} - -int -main() -{ - return test_fsb(CFixBitVec{}) || test_fsb(CBigBitVec{1024}); -} |