module HaskellWorks.Data.Bits.PackedVector.PackedVector64
( PackedVector64(..)
, empty
, fromList
, toList
) where
import qualified Data.Vector.Storable as DVS
import Data.Int
import Data.Word
import HaskellWorks.Data.AtIndex
import HaskellWorks.Data.Bits.BitWise
import HaskellWorks.Data.Bits.LoBitsSized
import HaskellWorks.Data.Bits.PackedVector.Internal
import HaskellWorks.Data.Positioning
import HaskellWorks.Data.Unsign
import Prelude hiding (length)
data PackedVector64 = PackedVector64
{ swBuffer :: !(DVS.Vector Word64)
, swBitSize :: !Word
, swBufferLen :: !Int
} deriving (Eq, Show)
empty :: PackedVector64
empty =
PackedVector64
{ swBuffer = DVS.empty
, swBufferLen = 0
, swBitSize = 1
}
instance Container PackedVector64 where
type Elem PackedVector64 = Word64
instance Length PackedVector64 where
length = fromIntegral . swBufferLen
instance AtIndex PackedVector64 where
atIndex v i =
let bitSize = fromIntegral (swBitSize v) :: Count
bitIndex = fromIntegral (swBitSize v) * i
(q, r) = bitIndex `quotRem` 64
vv = swBuffer v
in if r <= 64 fromIntegral bitSize
then
((vv !!! q) .>. unsign r) .&. loBitsSized bitSize
else
let loBitsSize = 64 toCount r
hiBitsSize = bitSize loBitsSize
loBits = ((vv !!! q) .>. unsign r) .&. loBitsSized loBitsSize
hiBits = if r > 64 fromIntegral bitSize then (vv !!! (q + 1)) .&. loBitsSized hiBitsSize else 0
in loBits .|. (hiBits .<. loBitsSize)
(!!!) = atIndex
fromList :: Count -> [Word64] -> PackedVector64
fromList wl ws =
PackedVector64
{ swBuffer = DVS.fromList (packBits wl ws)
, swBufferLen = fromIntegral (length ws)
, swBitSize = fromIntegral wl
}
toList :: PackedVector64 -> [Word64]
toList v = unpackBits (swBufferLen v) (fromIntegral (swBitSize v)) (DVS.toList (swBuffer v))