From f8e91a2717fc617516d72d122aee26620667cfdc Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 5 Aug 2018 14:38:52 +0200 Subject: Support integral points in both directions --- chilbert/Algorithm.hpp | 8 ++++---- chilbert/BigBitVec.hpp | 36 ++++++++++++++++++------------------ chilbert/FixBitVec.hpp | 22 +++++++--------------- chilbert/Operations.hpp | 15 +++++++++++++++ 4 files changed, 44 insertions(+), 37 deletions(-) (limited to 'chilbert') 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(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&); // 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(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 #include #include +#include #include namespace chilbert { @@ -87,6 +88,20 @@ ffs(const unsigned long long field) return __builtin_ffsll(field); } +/// Calculates the inverse Gray Code of `value` in place +template +std::enable_if_t::value> grayCodeInv(T& value); + +/// Implementation of grayCodeInv for any integral type +template +std::enable_if_t::value> +grayCodeInv(T& value) +{ + for (T shift = 1; shift < sizeof(T) * CHAR_BIT; shift <<= 1) { + value ^= (value >> shift); + } +} + } // namespace chilbert #endif -- cgit v1.2.1