module Data.Graph.Haggle.Internal.BitSet (
BitSet,
newBitSet,
setBit,
testBit
) where
import Control.Monad.ST
import qualified Data.Bits as B
import Data.Vector.Unboxed.Mutable ( STVector )
import qualified Data.Vector.Unboxed.Mutable as V
import Data.Word ( Word64 )
data BitSet s = BS (STVector s Word64) {-# UNPACK #-} !Int
bitsPerWord :: Int
bitsPerWord = 64
newBitSet :: Int -> ST s (BitSet s)
newBitSet n = do
let nWords = (n `div` bitsPerWord) + 1
v <- V.replicate nWords 0
return $ BS v n
setBit :: BitSet s -> Int -> ST s ()
setBit (BS v sz) bitIx
| bitIx >= sz = return ()
| otherwise = do
let wordIx = bitIx `div` bitsPerWord
bitPos = bitIx `mod` bitsPerWord
oldWord <- V.read v wordIx
let newWord = B.setBit oldWord bitPos
V.write v wordIx newWord
testBit :: BitSet s -> Int -> ST s Bool
testBit (BS v sz) bitIx
| bitIx >= sz = return False
| otherwise = do
let wordIx = bitIx `div` bitsPerWord
bitPos = bitIx `mod` bitsPerWord
w <- V.read v wordIx
return $ B.testBit w bitPos