{-# LANGUAGE FlexibleInstances #-}

module HaskellWorks.Data.Simd.Internal.Marshal where

import Data.Word

import qualified Data.Vector.Storable as DVS
import qualified Foreign.ForeignPtr   as F

{- HLINT ignore "Redundant do"        -}

unsafeToElemSizedForeignPtr :: Int -> DVS.Vector Word64 -> (F.ForeignPtr Word8, Int, Int)
unsafeToElemSizedForeignPtr :: Int -> Vector Word64 -> (ForeignPtr Word8, Int, Int)
unsafeToElemSizedForeignPtr Int
elemSize Vector Word64
v = case forall a b. (Storable a, Storable b) => Vector a -> Vector b
DVS.unsafeCast Vector Word64
v :: DVS.Vector Word8 of
  Vector Word8
au -> case forall a. Vector a -> (ForeignPtr a, Int, Int)
DVS.unsafeToForeignPtr Vector Word8
au of
    t :: (ForeignPtr Word8, Int, Int)
t@(ForeignPtr Word8
_, Int
_, Int
srcALength) -> if Int
sizeMismatch forall a. Eq a => a -> a -> Bool
== Int
0
      then (ForeignPtr Word8, Int, Int)
t
      else forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Byte string with mismatched element size: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> [Char]
show Int
sizeMismatch
      where w64sLen :: Int
w64sLen       = Int
srcALength forall a. Integral a => a -> a -> a
`div` Int
elemSize
            sizeMismatch :: Int
sizeMismatch  = Int
srcALength forall a. Num a => a -> a -> a
- Int
w64sLen forall a. Num a => a -> a -> a
* Int
elemSize