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