/* Copyright (C) 2018 David Robillard Copyright (C) 2006-2007 Chris Hamilton 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 . */ #ifndef CHILBERT_FIXBITVEC_HPP #define CHILBERT_FIXBITVEC_HPP #include "chilbert/Operations.hpp" #include #include namespace chilbert { // This must be an unsigned integer that is either // 32 or 64 bits. Otherwise, there are places in the // code that simply will not work. // For speed, this should be the native word size. typedef uint64_t FBV_UINT; #define FBV_BITS 64 #define FBV0 ((FBV_UINT)0) #define FBV1 ((FBV_UINT)1) #define FBV1S (~FBV0) #define FBVN1S(n) (n==FBV_BITS?FBV1S:(FBV1< 0 ); } // Sets the value of the nth bit. CFixBitVec & set( int iIndex, bool bBit = true ) { assert( 0 <= iIndex && iIndex < FBV_BITS ); FBV_UINT m = (FBV1<>=( int iBits ) { m_uiRack >>= iBits; return (*this); } // Shift right operation. CFixBitVec operator>>( int iBits ) const { CFixBitVec t(*this); t >>= iBits; return t; } // Right rotation, in place. CFixBitVec & rotr( int iBits, int iWidth ) { assert( iBits >= 0 ); assert( iWidth > 0 ); assert( iBits < iWidth ); m_uiRack &= FBVN1S(iWidth); m_uiRack = (m_uiRack>>iBits) | (m_uiRack<<(iWidth-iBits)); m_uiRack &= FBVN1S(iWidth); return (*this); } // Left rotation, in place. CFixBitVec & rotl( int iBits, int iWidth ) { assert( iBits >= 0 ); assert( iWidth > 0 ); assert( iBits < iWidth ); m_uiRack &= FBVN1S(iWidth); m_uiRack = (m_uiRack<>(iWidth-iBits)); m_uiRack &= FBVN1S(iWidth); return (*this); } // Is the bit rack zero valued? bool none() const { return m_uiRack == 0; } // Returns the index of the first set bit, numbered from // 1 to n. 0 means there were no set bits. int fsb() const { return chilbert::ffs(m_uiRack); } // Ones-complements the rack CFixBitVec & flip() { m_uiRack = ~m_uiRack; return (*this); } // Returns the first rack. FBV_UINT & rack() { return m_uiRack; } FBV_UINT rack() const { return m_uiRack; } // Return a pointer to the racks FBV_UINT * racks() { return &m_uiRack; } const FBV_UINT * racks() const { return &m_uiRack; } // Returns the number of racks. int rackCount() { return 1; } private: static_assert( 8*sizeof(FBV_UINT) == FBV_BITS, "" ); static_assert( (sizeof(FBV_UINT) == 4) || (sizeof(FBV_UINT) == 8), "" ); FBV_UINT m_uiRack; }; template <> void grayCode(CFixBitVec& value) { value.rack() ^= (value.rack() >> 1); } template <> void grayCodeInv(CFixBitVec& value) { grayCodeInv(value.rack()); } } // namespace chilbert #endif