aboutsummaryrefslogtreecommitdiffstats
path: root/chilbert
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-08-05 14:38:52 +0200
committerDavid Robillard <d@drobilla.net>2018-08-07 20:01:26 +0200
commitf8e91a2717fc617516d72d122aee26620667cfdc (patch)
tree5eaa8237c0c2082a60e16d1ac21b5ab3570e9a9f /chilbert
parent29813ada1005d3344320da48006ea5419181f7e0 (diff)
downloadchilbert-f8e91a2717fc617516d72d122aee26620667cfdc.tar.gz
chilbert-f8e91a2717fc617516d72d122aee26620667cfdc.tar.bz2
chilbert-f8e91a2717fc617516d72d122aee26620667cfdc.zip
Support integral points in both directions
Diffstat (limited to 'chilbert')
-rw-r--r--chilbert/Algorithm.hpp8
-rw-r--r--chilbert/BigBitVec.hpp36
-rw-r--r--chilbert/FixBitVec.hpp22
-rw-r--r--chilbert/Operations.hpp15
4 files changed, 44 insertions, 37 deletions
diff --git a/chilbert/Algorithm.hpp b/chilbert/Algorithm.hpp
index 0200456..e522554 100644
--- a/chilbert/Algorithm.hpp
+++ b/chilbert/Algorithm.hpp
@@ -160,7 +160,7 @@ namespace chilbert
e.reset();
d = D0;
l.reset();
- h.reset();
+ h = 0U;
// Work from MSB to LSB
for ( i = m-1; i >= 0; i-- )
@@ -188,7 +188,7 @@ namespace chilbert
update2<I>(l,t,w,n,e,d);
}
- h.grayCodeInv();
+ grayCodeInv(h);
return;
}
@@ -238,7 +238,7 @@ namespace chilbert
d = D0;
l.reset();
for ( j = 0; j < n; j++ )
- p[j] = 0;
+ p[j] = 0U;
ho = m*n;
@@ -408,7 +408,7 @@ namespace chilbert
d = D0;
l.reset();
for ( j = 0; j < n; j++ )
- p[j].reset();
+ p[j] = 0;
// Work from MSB to LSB
for ( i = m-1; i >= 0; i-- )
diff --git a/chilbert/BigBitVec.hpp b/chilbert/BigBitVec.hpp
index df50d6e..b5c049a 100644
--- a/chilbert/BigBitVec.hpp
+++ b/chilbert/BigBitVec.hpp
@@ -693,23 +693,6 @@ public:
}
- // Gray Code Inverse
- CBigBitVec &
- grayCodeInv()
- {
- int i;
- FBV_UINT s = 0;
-
- for ( i = m_iRacks-1; i >= 0; i-- )
- {
- m_pcRacks[i].grayCodeInv();
- if ( s ) m_pcRacks[i].flip();
- s = m_pcRacks[i].rack() & 1;
- }
- return (*this);
- }
-
-
// Complement
CBigBitVec &
flip()
@@ -755,7 +738,8 @@ public:
}
-private:
+private:
+ friend void grayCodeInv<CBigBitVec>(CBigBitVec&);
// Right rotates entire racks (in place).
void
@@ -795,6 +779,22 @@ private:
int m_iRacks;
};
+template <>
+void
+grayCodeInv(CBigBitVec& value)
+{
+ FBV_UINT s = 0;
+
+ for (int i = value.rackCount() - 1; i >= 0; --i) {
+ CFixBitVec& rack = value.m_pcRacks[i];
+ grayCodeInv(rack);
+ if (s) {
+ rack.flip();
+ }
+ s = rack.test(0);
+ }
+}
+
} // namespace chilbert
#endif
diff --git a/chilbert/FixBitVec.hpp b/chilbert/FixBitVec.hpp
index 3cdd6ff..3a72599 100644
--- a/chilbert/FixBitVec.hpp
+++ b/chilbert/FixBitVec.hpp
@@ -355,21 +355,6 @@ public:
return (*this);
}
- // Calculates the Gray Code Inverse
- CFixBitVec &
- grayCodeInv()
- {
- m_uiRack ^= (m_uiRack>>1);
- m_uiRack ^= (m_uiRack>>2);
- m_uiRack ^= (m_uiRack>>4);
- m_uiRack ^= (m_uiRack>> 8);
- m_uiRack ^= (m_uiRack>>16);
-#if FBV_BITS == 64
- m_uiRack ^= (m_uiRack>>32);
-#endif
- return (*this);
- }
-
// Ones-complements the rack
CFixBitVec &
flip()
@@ -416,6 +401,13 @@ private:
FBV_UINT m_uiRack;
};
+template <>
+void
+grayCodeInv(CFixBitVec& value)
+{
+ grayCodeInv<FBV_UINT>(value.rack());
+}
+
} // namespace chilbert
#endif
diff --git a/chilbert/Operations.hpp b/chilbert/Operations.hpp
index e4a23b5..c50136a 100644
--- a/chilbert/Operations.hpp
+++ b/chilbert/Operations.hpp
@@ -22,6 +22,7 @@
#include <cassert>
#include <climits>
#include <cstddef>
+#include <cstdint>
#include <type_traits>
namespace chilbert {
@@ -87,6 +88,20 @@ ffs<unsigned long long>(const unsigned long long field)
return __builtin_ffsll(field);
}
+/// Calculates the inverse Gray Code of `value` in place
+template <typename T>
+std::enable_if_t<!std::is_integral<T>::value> grayCodeInv(T& value);
+
+/// Implementation of grayCodeInv for any integral type
+template <typename T>
+std::enable_if_t<std::is_integral<T>::value>
+grayCodeInv(T& value)
+{
+ for (T shift = 1; shift < sizeof(T) * CHAR_BIT; shift <<= 1) {
+ value ^= (value >> shift);
+ }
+}
+
} // namespace chilbert
#endif