diff options
Diffstat (limited to 'test/test_bitvec.cpp')
-rw-r--r-- | test/test_bitvec.cpp | 278 |
1 files changed, 278 insertions, 0 deletions
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; +} |