{-# LANGUAGE MagicHash, UnboxedTuples #-}
module Internal.Foreign
( app
, appVector, appVectorLen
, appMatrix, appMatrixLen, appMatrixRaw, appMatrixRawLen
, unsafeMatrixToVector, unsafeMatrixToForeignPtr
) where
import Foreign.C.Types(CInt)
import Internal.Vector
import Internal.Matrix
import qualified Data.Vector.Storable as S
import Foreign (Ptr, ForeignPtr, Storable)
import GHC.Base (IO(..), realWorld#)
{-# INLINE unsafeInlinePerformIO #-}
unsafeInlinePerformIO :: IO a -> a
unsafeInlinePerformIO (IO f) = case f realWorld# of
(# _, x #) -> x
{-# INLINE app #-}
app :: (a -> b) -> a -> b
app f = f
{-# INLINE appVector #-}
appVector :: Storable a => (Ptr a -> b) -> Vector a -> b
appVector f x = unsafeInlinePerformIO (S.unsafeWith x (return . f))
{-# INLINE appVectorLen #-}
appVectorLen :: Storable a => (CInt -> Ptr a -> b) -> Vector a -> b
appVectorLen f x = unsafeInlinePerformIO (S.unsafeWith x (return . f (fromIntegral (S.length x))))
{-# INLINE appMatrix #-}
appMatrix :: Element a => (Ptr a -> b) -> Matrix a -> b
appMatrix f x = unsafeInlinePerformIO (S.unsafeWith (flatten x) (return . f))
{-# INLINE appMatrixLen #-}
appMatrixLen :: Element a => (CInt -> CInt -> Ptr a -> b) -> Matrix a -> b
appMatrixLen f x = unsafeInlinePerformIO (S.unsafeWith (flatten x) (return . f r c))
where
r = fromIntegral (rows x)
c = fromIntegral (cols x)
{-# INLINE appMatrixRaw #-}
appMatrixRaw :: Storable a => (Ptr a -> b) -> Matrix a -> b
appMatrixRaw f x = unsafeInlinePerformIO (S.unsafeWith (xdat x) (return . f))
{-# INLINE appMatrixRawLen #-}
appMatrixRawLen :: Element a => (CInt -> CInt -> Ptr a -> b) -> Matrix a -> b
appMatrixRawLen f x = unsafeInlinePerformIO (S.unsafeWith (xdat x) (return . f r c))
where
r = fromIntegral (rows x)
c = fromIntegral (cols x)
infixl 1 `app`
infixl 1 `appVector`
infixl 1 `appMatrix`
infixl 1 `appMatrixRaw`
{-# INLINE unsafeMatrixToVector #-}
unsafeMatrixToVector :: Matrix a -> Vector a
unsafeMatrixToVector = xdat
{-# INLINE unsafeMatrixToForeignPtr #-}
unsafeMatrixToForeignPtr :: Storable a => Matrix a -> (ForeignPtr a, Int)
unsafeMatrixToForeignPtr m = S.unsafeToForeignPtr0 (xdat m)