aboutsummaryrefslogtreecommitdiffstats
path: root/chilbert
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-08-19 17:09:03 +0200
committerDavid Robillard <d@drobilla.net>2018-09-29 14:49:17 +0200
commit0013efd3cc0c2aa9150c983babd52d3de8e32744 (patch)
tree221316a01103a25decc2866c581125c5465e1c5e /chilbert
parentff4d8986a35b6a67a2162208145371fcf427d040 (diff)
downloadchilbert-0013efd3cc0c2aa9150c983babd52d3de8e32744.tar.gz
chilbert-0013efd3cc0c2aa9150c983babd52d3de8e32744.tar.bz2
chilbert-0013efd3cc0c2aa9150c983babd52d3de8e32744.zip
Clean up implementation header and inline code used only there
Diffstat (limited to 'chilbert')
-rw-r--r--chilbert/GetBits.hpp44
-rw-r--r--chilbert/GetLocation.hpp37
-rw-r--r--chilbert/Hilbert.ipp254
-rw-r--r--chilbert/SetBits.hpp44
-rw-r--r--chilbert/SetLocation.hpp37
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