module HaskellWorks.Data.EliasFano64.Internal
( mkHiBits
, packToWord8
, packToWord16
, packToWord32
, packToWord64
) where
import Data.Word
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Int.Widen
import HaskellWorks.Data.Positioning
mkHiBits :: Count -> [Word64] -> [Bool]
mkHiBits = mkHiBits' 0
mkHiBits' :: Word64 -> Count -> [Word64] -> [Bool]
mkHiBits' _ _ [] = []
mkHiBits' oldHi loBitsSize wws@(w:ws) = case w .>. loBitsSize of
newHi | oldHi < newHi -> False:mkHiBits' (oldHi + 1) loBitsSize wws
newHi | oldHi == newHi -> True :mkHiBits' oldHi loBitsSize ws
_ -> error "Values must be non-decreasing"
packToWord8 :: [Bool] -> [Word8]
packToWord8 (a:b:c:d:e:f:g:h:xs) =
( (if a then 0x01 else 0x00)
.|. (if b then 0x02 else 0x00)
.|. (if c then 0x04 else 0x00)
.|. (if d then 0x08 else 0x00)
.|. (if e then 0x10 else 0x00)
.|. (if f then 0x20 else 0x00)
.|. (if g then 0x40 else 0x00)
.|. (if h then 0x80 else 0x00)
) : packToWord8 xs
packToWord8 [] = []
packToWord8 xs = packToWord8 (take 8 (xs ++ [False]))
packToWord16 :: [Word8] -> [Word16]
packToWord16 (a:b:xs) = (widen16 a .|. (widen16 b .<. 8)):packToWord16 xs
packToWord16 (a :xs) = widen16 a :packToWord16 xs
packToWord16 [] = []
packToWord32 :: [Word16] -> [Word32]
packToWord32 (a:b:xs) = (widen32 a .|. (widen32 b .<. 16)):packToWord32 xs
packToWord32 (a :xs) = widen32 a :packToWord32 xs
packToWord32 [] = []
packToWord64 :: [Word32] -> [Word64]
packToWord64 (a:b:xs) = (widen64 a .|. (widen64 b .<. 32)):packToWord64 xs
packToWord64 (a :xs) = widen64 a :packToWord64 xs
packToWord64 [] = []