diff options
author | David Robillard <d@drobilla.net> | 2018-08-19 16:27:07 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-09-29 14:48:53 +0200 |
commit | fa3d8f677b6a30c2115e7d167d4938e293dfad81 (patch) | |
tree | 052d5eb0bb3bad3e415d0f967ddfd96b65d5b06d | |
parent | b5954ef2de4f205108be0cf5a06f88540194bed9 (diff) | |
download | chilbert-fa3d8f677b6a30c2115e7d167d4938e293dfad81.tar.gz chilbert-fa3d8f677b6a30c2115e7d167d4938e293dfad81.tar.bz2 chilbert-fa3d8f677b6a30c2115e7d167d4938e293dfad81.zip |
Add StaticBitVec type
-rw-r--r-- | chilbert/Hilbert.ipp | 8 | ||||
-rw-r--r-- | chilbert/StaticBitVec.hpp | 112 | ||||
-rw-r--r-- | test/test_bitvec.cpp | 11 | ||||
-rw-r--r-- | test/test_gray_code_rank.cpp | 10 | ||||
-rw-r--r-- | test/test_hilbert.cpp | 23 |
5 files changed, 164 insertions, 0 deletions
diff --git a/chilbert/Hilbert.ipp b/chilbert/Hilbert.ipp index 9d23271..726b204 100644 --- a/chilbert/Hilbert.ipp +++ b/chilbert/Hilbert.ipp @@ -27,6 +27,7 @@ #include "chilbert/Hilbert.hpp" #include "chilbert/SetBits.hpp" #include "chilbert/SetLocation.hpp" +#include "chilbert/StaticBitVec.hpp" #include <cassert> @@ -72,6 +73,13 @@ num_bits(const T& vec, return vec.size(); } +template <size_t N> +size_t +num_bits(const StaticBitVec<N>&, void* = nullptr) +{ + return N; +} + // 'Transforms' a point. template <class I> inline void diff --git a/chilbert/StaticBitVec.hpp b/chilbert/StaticBitVec.hpp new file mode 100644 index 0000000..1501746 --- /dev/null +++ b/chilbert/StaticBitVec.hpp @@ -0,0 +1,112 @@ +/* + Copyright (C) 2018 David Robillard <d@drobilla.net> + Copyright (C) 2006-2007 Chris Hamilton <chamilton@cs.dal.ca> + + 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/>. +*/ + +#ifndef CHILBERT_STATICBITVEC_HPP +#define CHILBERT_STATICBITVEC_HPP + +#include "chilbert/BitVecIndex.hpp" +#include "chilbert/BitVecIterator.hpp" +#include "chilbert/BitVecMask.hpp" +#include "chilbert/MultiBitVec.hpp" +#include "chilbert/Operations.hpp" + +#include <algorithm> +#include <array> +#include <cassert> +#include <climits> +#include <cstddef> +#include <cstdlib> +#include <cstring> + +namespace chilbert { + +template <size_t N> +class StaticBitVec : public MultiBitVec<StaticBitVec<N>> +{ +public: + using Rack = typename MultiBitVec<StaticBitVec<N>>::Rack; + + using MultiBitVec<StaticBitVec<N>>::bits_per_rack; + + StaticBitVec() = default; + + /// Constructor for compatibility with CBigBitVec + explicit StaticBitVec(const size_t bits) + { + assert(bits == size()); + } + + /// Constructor for compatibility with CBigBitVec + StaticBitVec(const size_t bits, const Rack value) + : StaticBitVec{bits} + { + m_racks[0] = value; + } + + /// Return the size in bits + size_t size() const { return N; } + + /// Return a reference to the `index`th rack +#ifndef NDEBUG + const auto& rack(const size_t index) const { return m_racks.at(index); } + auto& rack(const size_t index) { return m_racks.at(index); } +#else + const auto& rack(const size_t index) const { return m_racks[index]; } + auto& rack(const size_t index) { return m_racks[index]; } +#endif + + /// Return a raw pointer to the racks + Rack* data() { return m_racks.data(); } + const Rack* data() const { return m_racks.data(); } + + /// Return the total size of all racks in bytes + static constexpr size_t data_size() { return num_racks() * sizeof(Rack); } + + /// Return the number of racks + static constexpr size_t num_racks() + { + return (std::max(N, size_t(1)) + bits_per_rack - 1) / bits_per_rack; + } + +private: + std::array<Rack, num_racks()> m_racks{}; +}; + +template <size_t N> +struct is_bitvec<StaticBitVec<N>> +{ + constexpr static bool value = true; +}; + +template <size_t N> +void +grayCode(StaticBitVec<N>& value) +{ + grayCode(static_cast<MultiBitVec<StaticBitVec<N>>&>(value)); +} + +template <size_t N> +void +grayCodeInv(StaticBitVec<N>& value) +{ + grayCodeInv(static_cast<MultiBitVec<StaticBitVec<N>>&>(value)); +} + +} // namespace chilbert + +#endif diff --git a/test/test_bitvec.cpp b/test/test_bitvec.cpp index 0b6e534..b891aca 100644 --- a/test/test_bitvec.cpp +++ b/test/test_bitvec.cpp @@ -21,6 +21,7 @@ #include "chilbert/BigBitVec.hpp" #include "chilbert/FixBitVec.hpp" +#include "chilbert/StaticBitVec.hpp" #include <cassert> #include <cstddef> @@ -348,5 +349,15 @@ main() test<chilbert::CBigBitVec, 65>(ctx); test<chilbert::CBigBitVec, 997>(ctx); + test<chilbert::StaticBitVec<0>, 0>(ctx); + test<chilbert::StaticBitVec<1>, 1>(ctx); + test<chilbert::StaticBitVec<31>, 31>(ctx); + test<chilbert::StaticBitVec<32>, 32>(ctx); + test<chilbert::StaticBitVec<33>, 33>(ctx); + test<chilbert::StaticBitVec<63>, 63>(ctx); + test<chilbert::StaticBitVec<64>, 64>(ctx); + test<chilbert::StaticBitVec<65>, 65>(ctx); + test<chilbert::StaticBitVec<997>, 997>(ctx); + return 0; } diff --git a/test/test_gray_code_rank.cpp b/test/test_gray_code_rank.cpp index a421159..8be40f1 100644 --- a/test/test_gray_code_rank.cpp +++ b/test/test_gray_code_rank.cpp @@ -22,6 +22,7 @@ #include "chilbert/BigBitVec.hpp" #include "chilbert/FixBitVec.hpp" #include "chilbert/GrayCodeRank.hpp" +#include "chilbert/StaticBitVec.hpp" #include <algorithm> #include <array> @@ -138,5 +139,14 @@ main() test<chilbert::CBigBitVec, 96, 65>(ctx); test<chilbert::CBigBitVec, 1024, 997>(ctx); + test<chilbert::StaticBitVec<1>, 64, 1>(ctx); + test<chilbert::StaticBitVec<31>, 64, 31>(ctx); + test<chilbert::StaticBitVec<32>, 64, 32>(ctx); + test<chilbert::StaticBitVec<33>, 64, 33>(ctx); + test<chilbert::StaticBitVec<60>, 64, 60>(ctx); + test<chilbert::StaticBitVec<64>, 64, 64>(ctx); + test<chilbert::StaticBitVec<65>, 96, 65>(ctx); + test<chilbert::StaticBitVec<997>, 1024, 997>(ctx); + return 0; } diff --git a/test/test_hilbert.cpp b/test/test_hilbert.cpp index 6a3d1b8..36a2992 100644 --- a/test/test_hilbert.cpp +++ b/test/test_hilbert.cpp @@ -22,6 +22,7 @@ #include "chilbert/BigBitVec.hpp" #include "chilbert/FixBitVec.hpp" #include "chilbert/Hilbert.hpp" +#include "chilbert/StaticBitVec.hpp" #include <gmpxx.h> @@ -182,6 +183,17 @@ main() test_standard<chilbert::CBigBitVec, 32, 64>(ctx); test_standard<chilbert::CBigBitVec, 63, 128>(ctx); + test_standard<chilbert::StaticBitVec<4 * 2>, 4, 2>(ctx); + test_standard<chilbert::StaticBitVec<32 * 2>, 32, 2>(ctx); + test_standard<chilbert::StaticBitVec<16 * 4>, 16, 4>(ctx); + test_standard<chilbert::StaticBitVec<8 * 8>, 8, 8>(ctx); + test_standard<chilbert::StaticBitVec<4 * 16>, 4, 16>(ctx); + test_standard<chilbert::StaticBitVec<2 * 32>, 2, 32>(ctx); + test_standard<chilbert::StaticBitVec<1 * 64>, 1, 64>(ctx); + test_standard<chilbert::StaticBitVec<4 * 65>, 4, 65>(ctx); + test_standard<chilbert::StaticBitVec<32 * 64>, 32, 64>(ctx); + test_standard<chilbert::StaticBitVec<63 * 128>, 63, 128>(ctx); + test_compact<chilbert::CFixBitVec, 4, 2>(ctx); test_compact<chilbert::CFixBitVec, 32, 2>(ctx); test_compact<chilbert::CFixBitVec, 16, 4>(ctx); @@ -194,5 +206,16 @@ main() test_compact<chilbert::CBigBitVec, 32, 64>(ctx); test_compact<chilbert::CBigBitVec, 63, 128>(ctx); + test_compact<chilbert::StaticBitVec<4 * 2>, 4, 2>(ctx); + test_compact<chilbert::StaticBitVec<32 * 2>, 32, 2>(ctx); + test_compact<chilbert::StaticBitVec<16 * 4>, 16, 4>(ctx); + test_compact<chilbert::StaticBitVec<8 * 8>, 8, 8>(ctx); + test_compact<chilbert::StaticBitVec<4 * 16>, 4, 16>(ctx); + test_compact<chilbert::StaticBitVec<2 * 32>, 2, 32>(ctx); + test_compact<chilbert::StaticBitVec<1 * 64>, 1, 64>(ctx); + test_compact<chilbert::StaticBitVec<4 * 65>, 4, 65>(ctx); + test_compact<chilbert::StaticBitVec<32 * 64>, 32, 64>(ctx); + test_compact<chilbert::StaticBitVec<63 * 128>, 63, 128>(ctx); + return 0; } |