{-# LANGUAGE FlexibleInstances #-}

module HaskellWorks.Data.Vector.AsVector64
  ( AsVector64(..)
  ) where

import Data.Word

import qualified Data.ByteString          as BS
import qualified Data.ByteString.Internal as BSI
import qualified Data.Vector.Storable     as DVS

class AsVector64 a where
  asVector64 :: a -> DVS.Vector Word64

instance AsVector64 (DVS.Vector Word64) where
  asVector64 :: Vector Word64 -> Vector Word64
asVector64 = forall a. a -> a
id
  {-# INLINE asVector64 #-}

instance AsVector64 BS.ByteString where
  asVector64 :: ByteString -> Vector Word64
asVector64 ByteString
bs = if Int
vLen forall a. Num a => a -> a -> a
* Int
8 forall a. Eq a => a -> a -> Bool
== ByteString -> Int
BS.length ByteString
bs
    then case ByteString -> (ForeignPtr Word8, Int, Int)
BSI.toForeignPtr ByteString
bs of
      (ForeignPtr Word8
fptr, Int
start, Int
offset) -> forall a b. (Storable a, Storable b) => Vector a -> Vector b
DVS.unsafeCast (forall a. Storable a => ForeignPtr a -> Int -> Int -> Vector a
DVS.unsafeFromForeignPtr ForeignPtr Word8
fptr Int
start Int
offset)
    else case ByteString -> (ForeignPtr Word8, Int, Int)
BSI.toForeignPtr (ByteString
bs forall a. Semigroup a => a -> a -> a
<> Int -> Word8 -> ByteString
BS.replicate (Int
vLen forall a. Num a => a -> a -> a
* Int
8 forall a. Num a => a -> a -> a
- ByteString -> Int
BS.length ByteString
bs) Word8
0) of
      (ForeignPtr Word8
fptr, Int
start, Int
offset) -> forall a b. (Storable a, Storable b) => Vector a -> Vector b
DVS.unsafeCast (forall a. Storable a => ForeignPtr a -> Int -> Int -> Vector a
DVS.unsafeFromForeignPtr ForeignPtr Word8
fptr Int
start Int
offset)
    where vLen :: Int
vLen = (ByteString -> Int
BS.length ByteString
bs forall a. Num a => a -> a -> a
+ Int
7) forall a. Integral a => a -> a -> a
`div` Int
8
  {-# INLINE asVector64 #-}