diff options
author | David Robillard <d@drobilla.net> | 2018-08-19 17:09:03 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2018-09-29 14:49:17 +0200 |
commit | 0013efd3cc0c2aa9150c983babd52d3de8e32744 (patch) | |
tree | 221316a01103a25decc2866c581125c5465e1c5e | |
parent | ff4d8986a35b6a67a2162208145371fcf427d040 (diff) | |
download | chilbert-0013efd3cc0c2aa9150c983babd52d3de8e32744.tar.gz chilbert-0013efd3cc0c2aa9150c983babd52d3de8e32744.tar.bz2 chilbert-0013efd3cc0c2aa9150c983babd52d3de8e32744.zip |
Clean up implementation header and inline code used only there
-rw-r--r-- | chilbert/GetBits.hpp | 44 | ||||
-rw-r--r-- | chilbert/GetLocation.hpp | 37 | ||||
-rw-r--r-- | chilbert/Hilbert.ipp | 254 | ||||
-rw-r--r-- | chilbert/SetBits.hpp | 44 | ||||
-rw-r--r-- | chilbert/SetLocation.hpp | 37 |
5 files changed, 161 insertions, 255 deletions
diff --git a/chilbert/GetBits.hpp b/chilbert/GetBits.hpp deleted file mode 100644 index 196751d..0000000 --- a/chilbert/GetBits.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - 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_GETBITS_HPP -#define CHILBERT_GETBITS_HPP - -#include "chilbert/Operations.hpp" - -namespace chilbert { - -/** Copy a range of bits from one field to the start of another. - * - * @param h Source bit field - * @param n Number of bits - * @param i Start bit index in source - * @param w Destination bit field - */ -template <class H, class I> -inline void -get_bits(const H& h, const size_t n, const size_t i, I& w) -{ - for (size_t j = 0; j < n; j++) { - set_bit(w, j, test_bit(h, i + j)); - } -} - -} // namespace chilbert - -#endif diff --git a/chilbert/GetLocation.hpp b/chilbert/GetLocation.hpp deleted file mode 100644 index 3594c80..0000000 --- a/chilbert/GetLocation.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - 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_GETLOCATION_HPP -#define CHILBERT_GETLOCATION_HPP - -#include "chilbert/Operations.hpp" - -namespace chilbert { - -template <class P, class I> -inline void -get_location(const P* const p, const size_t n, const size_t i, I& l) -{ - for (size_t j = 0; j < n; ++j) { - set_bit(l, j, test_bit(p[j], i)); - } -} - -} // namespace chilbert - -#endif diff --git a/chilbert/Hilbert.ipp b/chilbert/Hilbert.ipp index 44b5b5f..81eb7fd 100644 --- a/chilbert/Hilbert.ipp +++ b/chilbert/Hilbert.ipp @@ -21,26 +21,24 @@ #include "chilbert/BigBitVec.hpp" #include "chilbert/FixBitVec.hpp" -#include "chilbert/GetBits.hpp" -#include "chilbert/GetLocation.hpp" #include "chilbert/GrayCodeRank.hpp" #include "chilbert/Hilbert.hpp" -#include "chilbert/SetBits.hpp" -#include "chilbert/SetLocation.hpp" #include "chilbert/StaticBitVec.hpp" #include <cassert> #include <climits> +#include <numeric> #include <type_traits> -// The dimension across which the Hilbert curve travels -// principally. -// D0 is d + 1, where d is the actual dimension you want to -// walk across. -// MUST HAVE 0 <= D0 < n -#define D0 1 - namespace chilbert { +namespace detail { + +/** The dimension across which the Hilbert curve travels principally. + * + * D0 is d + 1, where d is the actual dimension you want to walk across. + * MUST HAVE 0 <= D0 < n. + */ +static constexpr size_t D0 = 1; template <class T> size_t @@ -65,6 +63,70 @@ num_bits(const StaticBitVec<N>&, void* = nullptr) return N; } +/** Copy a range of bits from one field to the start of another. + * + * @param h Source bit field + * @param n Number of bits + * @param i Start bit index in source + * @param[out] w Destination bit field + */ +template <class H, class I> +inline void +get_bits(const H& h, const size_t n, const size_t i, I& w) +{ + for (size_t j = 0; j < n; j++) { + set_bit(w, j, test_bit(h, i + j)); + } +} + +/** Set a range of bits in one field from the start of another. + * + * @param[out] h Destination bit field + * @param n Number of bits + * @param i Start bit index in destination + * @param w Source bit field + */ +template <class H, class I> +inline void +set_bits(H& h, const size_t n, const size_t i, const I& w) +{ + for (size_t j = 0; j < n; j++) { + set_bit(h, i + j, test_bit(w, j)); + } +} + +/** Set the leading bits in `l` to bit `i` from the corresponding value in `p`. + * + * @param p Point. + * @param n Number of bits to set. + * @param i Bit position to copy from values in `p`. + * @param[out] l Output bits. + */ +template <class P, class I> +inline void +get_location(const P* const p, const size_t n, const size_t i, I& l) +{ + for (size_t j = 0; j < n; ++j) { + set_bit(l, j, test_bit(p[j], i)); + } +} + +/** Set bit `i` in values in `p` to the corresponding leadings bits in `l`. + * + * @param[out] p Point. + * @param n Number of bits to set. + * @param i Bit position to set in values in `p`. + * @param l Input bits. + */ +template <class P, class I> +inline void +set_location(P* const p, const size_t n, const size_t i, const I& l) +{ + for (size_t j = 0; j < n; j++) { + set_bit(p[j], i, test_bit(l, j)); + } +} + // 'Transforms' a point. template <class I> inline void @@ -131,13 +193,12 @@ update2(const I& l, const I& t, const size_t n, I& e, size_t& d) template <class P, class H, class I> inline void -_coords_to_index(const P* const p, - const size_t m, - const size_t n, - H& h, - I&& scratch, - size_t* const ds = nullptr // #HACK -) +coords_to_index(const P* const p, + const size_t m, + const size_t n, + H& h, + I&& scratch, + size_t* const ds = nullptr) { I e{std::move(scratch)}; I l{e}; @@ -153,7 +214,6 @@ _coords_to_index(const P* const p, size_t d = D0; size_t ho = m * n; for (intptr_t i = static_cast<intptr_t>(m - 1); i >= 0; i--) { - // #HACK if (ds) { ds[i] = d; } @@ -182,25 +242,9 @@ _coords_to_index(const P* const p, gray_code_inv(h); } -template <class P, class H> -inline void -coords_to_index(const P* const p, const size_t m, const size_t n, H& h) -{ - assert(num_bits(h) >= n * m); - assert(num_bits(p[0]) >= m); - - if (n <= FBV_BITS) { - // Intermediate variables will fit in fixed width - _coords_to_index<P, H, CFixBitVec>(p, m, n, h, CFixBitVec(n)); - } else { - // Otherwise, they must be BigBitVecs - _coords_to_index<P, H, CBigBitVec>(p, m, n, h, CBigBitVec(n)); - } -} - template <class P, class H, class I> inline void -_index_to_coords(P* p, const size_t m, const size_t n, const H& h, I&& scratch) +index_to_coords(P* p, const size_t m, const size_t n, const H& h, I&& scratch) { I e{std::move(scratch)}; I l{e}; @@ -240,33 +284,15 @@ _index_to_coords(P* p, const size_t m, const size_t n, const H& h, I&& scratch) } } -template <class P, class H> -inline void -index_to_coords(P* const p, const size_t m, const size_t n, const H& h) -{ - assert(m > 0); - assert(n > 0); - assert(num_bits(h) >= n * m); - assert(num_bits(p[0]) >= m); - - if (n <= FBV_BITS) { - // Intermediate variables will fit in fixed width - _index_to_coords<P, H, CFixBitVec>(p, m, n, h, CFixBitVec(n)); - } else { - // Otherwise, they must be BigBitVecs - _index_to_coords<P, H, CBigBitVec>(p, m, n, h, CBigBitVec(n)); - } -} - template <class P, class HC, class I> inline void -_coords_to_compact_index(const P* const p, - const size_t* const ms, - const size_t n, - HC& hc, - I&& scratch, - size_t M = 0, - size_t m = 0) +coords_to_compact_index(const P* const p, + const size_t* const ms, + const size_t n, + HC& hc, + I&& scratch, + size_t M = 0, + size_t m = 0) { // Get total precision and max precision if not supplied if (M == 0 || m == 0) { @@ -291,46 +317,28 @@ _coords_to_compact_index(const P* const p, if (mn > FBV_BITS) { CBigBitVec h(mn); - _coords_to_index<P, CBigBitVec, I>(p, m, n, h, std::move(scratch), ds); + detail::coords_to_index<P, CBigBitVec, I>( + p, m, n, h, std::move(scratch), ds); compact_index<CBigBitVec, HC>(ms, ds, n, m, h, hc); } else { CFixBitVec h(mn); - _coords_to_index<P, CFixBitVec, I>(p, m, n, h, std::move(scratch), ds); + detail::coords_to_index<P, CFixBitVec, I>( + p, m, n, h, std::move(scratch), ds); compact_index<CFixBitVec, HC>(ms, ds, n, m, h, hc); } delete[] ds; } -template <class P, class HC> -inline void -coords_to_compact_index(const P* const p, - const size_t* const ms, - size_t n, - HC& hc, - const size_t M, - const size_t m) -{ - if (n <= FBV_BITS) { - // Intermediate variables will fit in fixed width - _coords_to_compact_index<P, HC, CFixBitVec>( - p, ms, n, hc, CFixBitVec(n), M, m); - } else { - // Otherwise, they must be BigBitVecs - _coords_to_compact_index<P, HC, CBigBitVec>( - p, ms, n, hc, CBigBitVec(n), M, m); - } -} - template <class P, class HC, class I> inline void -_compact_index_to_coords(P* const p, - const size_t* ms, - const size_t n, - const HC& hc, - I&& scratch, - size_t M, - size_t m) +compact_index_to_coords(P* const p, + const size_t* ms, + const size_t n, + const HC& hc, + I&& scratch, + size_t M, + size_t m) { I e{std::move(scratch)}; I l{e}; @@ -359,7 +367,7 @@ _compact_index_to_coords(P* const p, e.reset(); l.reset(); for (size_t j = 0; j < n; j++) { - p[j] = 0; + reset_bits(p[j]); } // Work from MSB to LSB @@ -396,6 +404,64 @@ _compact_index_to_coords(P* const p, } } +} // namespace detail + +template <class P, class H> +inline void +coords_to_index(const P* const p, const size_t m, const size_t n, H& h) +{ + assert(detail::num_bits(h) >= n * m); + assert(detail::num_bits(p[0]) >= m); + + if (n <= FBV_BITS) { + // Intermediate variables will fit in fixed width + detail::coords_to_index<P, H, CFixBitVec>(p, m, n, h, CFixBitVec(n)); + } else { + // Otherwise, they must be BigBitVecs + detail::coords_to_index<P, H, CBigBitVec>(p, m, n, h, CBigBitVec(n)); + } +} + +template <class P, class H> +inline void +index_to_coords(P* const p, const size_t m, const size_t n, const H& h) +{ + assert(m > 0); + assert(n > 0); + assert(detail::num_bits(h) >= n * m); + assert(detail::num_bits(p[0]) >= m); + + if (n <= FBV_BITS) { + // Intermediate variables will fit in fixed width + detail::index_to_coords<P, H, CFixBitVec>(p, m, n, h, CFixBitVec(n)); + } else { + // Otherwise, they must be BigBitVecs + detail::index_to_coords<P, H, CBigBitVec>(p, m, n, h, CBigBitVec(n)); + } +} + +template <class P, class HC> +inline void +coords_to_compact_index(const P* const p, + const size_t* const ms, + size_t n, + HC& hc, + const size_t M, + const size_t m) +{ + assert(hc.size() >= std::accumulate(ms, ms + n, size_t(0))); + + if (n <= FBV_BITS) { + // Intermediate variables will fit in fixed width + detail::coords_to_compact_index<P, HC, CFixBitVec>( + p, ms, n, hc, CFixBitVec(n), M, m); + } else { + // Otherwise, they must be BigBitVecs + detail::coords_to_compact_index<P, HC, CBigBitVec>( + p, ms, n, hc, CBigBitVec(n), M, m); + } +} + template <class P, class HC> inline void compact_index_to_coords(P* const p, @@ -405,15 +471,17 @@ compact_index_to_coords(P* const p, const size_t M, const size_t m) { + assert(hc.size() >= std::accumulate(ms, ms + n, size_t(0))); + if (n <= FBV_BITS) { // Intermediate variables will fit in fixed width CFixBitVec scratch(n); - _compact_index_to_coords<P, HC, CFixBitVec>( + detail::compact_index_to_coords<P, HC, CFixBitVec>( p, ms, n, hc, std::move(scratch), M, m); } else { // Otherwise, they must be BigBitVecs CBigBitVec scratch(n); - _compact_index_to_coords<P, HC, CBigBitVec>( + detail::compact_index_to_coords<P, HC, CBigBitVec>( p, ms, n, hc, std::move(scratch), M, m); } } diff --git a/chilbert/SetBits.hpp b/chilbert/SetBits.hpp deleted file mode 100644 index cc5d602..0000000 --- a/chilbert/SetBits.hpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - 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_SETBITS_HPP -#define CHILBERT_SETBITS_HPP - -#include "chilbert/Operations.hpp" - -namespace chilbert { - -/** Set a range of bits in one field from the start of another. - * - * @param h Destination bit field - * @param n Number of bits - * @param i Start bit index in destination - * @param w Source bit field - */ -template <class H, class I> -inline void -set_bits(H& h, const size_t n, const size_t i, const I& w) -{ - for (size_t j = 0; j < n; j++) { - set_bit(h, i + j, test_bit(w, j)); - } -} - -} // namespace chilbert - -#endif diff --git a/chilbert/SetLocation.hpp b/chilbert/SetLocation.hpp deleted file mode 100644 index 344c0f8..0000000 --- a/chilbert/SetLocation.hpp +++ /dev/null @@ -1,37 +0,0 @@ -/* - 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_SETLOCATION_HPP -#define CHILBERT_SETLOCATION_HPP - -#include "chilbert/Operations.hpp" - -namespace chilbert { - -template <class P, class I> -inline void -set_location(P* const p, const size_t n, const size_t i, const I& l) -{ - for (size_t j = 0; j < n; j++) { - set_bit(p[j], i, test_bit(l, j)); - } -} - -} // namespace chilbert - -#endif |