{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE Rank2Types          #-}
{-# LANGUAGE ScopedTypeVariables #-}

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

import Data.Word
import HaskellWorks.Data.Vector.AsVector8ns (asVector8ns)

import qualified Data.ByteString      as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Vector.Storable as DVS

class AsVector64ns a where
  -- | Represent the value as a list of Vector of 'n' Word64 chunks.  The last chunk will
  -- also be of the specified chunk size filled with trailing zeros.
  asVector64ns :: Int -> a -> [DVS.Vector Word64]

instance AsVector64ns LBS.ByteString where
  asVector64ns :: Int -> ByteString -> [Vector Word64]
asVector64ns Int
n = Int -> [ByteString] -> [Vector Word64]
forall a. AsVector64ns a => Int -> a -> [Vector Word64]
asVector64ns Int
n ([ByteString] -> [Vector Word64])
-> (ByteString -> [ByteString]) -> ByteString -> [Vector Word64]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> [ByteString]
LBS.toChunks
  {-# INLINE asVector64ns #-}

instance AsVector64ns [BS.ByteString] where
  asVector64ns :: Int -> [ByteString] -> [Vector Word64]
asVector64ns Int
n [ByteString]
bss = Vector Word8 -> Vector Word64
forall a b. (Storable a, Storable b) => Vector a -> Vector b
DVS.unsafeCast (Vector Word8 -> Vector Word64)
-> [Vector Word8] -> [Vector Word64]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> [ByteString] -> [Vector Word8]
forall a. AsVector8ns a => Int -> a -> [Vector Word8]
asVector8ns (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
8) [ByteString]
bss
  {-# INLINE asVector64ns #-}