module Compat ( unsafeIOToST , uncons , packCStringLen , unsafeUseAsCStringLen , popCount , zeroBits ) where import Control.Monad.ST (unsafeIOToST) import Data.Bits (Bits, (.&.), shiftR, clearBit, bit) import qualified Data.ByteString as BS import Data.Word (Word8, Word64) import Foreign.C.String (CStringLen) uncons :: BS.ByteString -> Maybe (Word8, BS.ByteString) uncons s = if BS.null s then Nothing else Just (BS.head s, BS.tail s) unsafeUseAsCStringLen :: BS.ByteString -> (CStringLen -> IO a) -> IO a unsafeUseAsCStringLen = BS.useAsCStringLen packCStringLen :: CStringLen -> IO BS.ByteString packCStringLen = return . BS.packCStringLen popCount :: Word64 -> Int popCount = fromIntegral . sum . map (.&. 1) . take 64 . iterate (`shiftR` 1) zeroBits :: Bits b => b zeroBits = clearBit (bit 0) 0