module Data.Repa.Array.Material.Foreign
( F (..)
, Name (..)
, Array (..)
, Buffer (..)
, fromForeignPtr, toForeignPtr
, fromStorableVector, toStorableVector
, fromByteString, toByteString)
where
import Data.Repa.Array.Delayed
import Data.Repa.Array.Window
import Data.Repa.Array.Index
import Data.Repa.Array.Internals.Target
import Data.Repa.Array.Internals.Bulk
import Data.Word
import Foreign.ForeignPtr
import Foreign.Storable
import Data.Repa.Fusion.Unpack
import Data.ByteString (ByteString)
import qualified Data.ByteString.Internal as BS
import Control.Monad
import qualified Data.Vector.Storable as S
import qualified Data.Vector.Storable.Mutable as M
import Control.Monad.Primitive
#include "repa-array.h"
data F = Foreign { foreignLength :: Int }
deriving (Show, Eq)
instance Layout F where
data Name F = F
type Index F = Int
name = F
create F len = Foreign len
extent (Foreign len) = len
toIndex _ ix = ix
fromIndex _ ix = ix
deriving instance Eq (Name F)
deriving instance Show (Name F)
instance Storable a => Bulk F a where
data Array F a = FArray !(S.Vector a)
layout (FArray v) = Foreign (S.length v)
index (FArray v) i = S.unsafeIndex v i
deriving instance (S.Storable a, Show a) => Show (Array F a)
instance Unpack (Array F a) (S.Vector a) where
unpack (FArray v) = v
repack _ v = FArray v
instance Storable a => Windowable F a where
window st len (FArray vec)
= FArray (S.slice st len vec)
instance Storable a => Target F a where
data Buffer s F a = FBuffer !(M.MVector s a)
unsafeNewBuffer (Foreign n) = FBuffer `liftM` M.unsafeNew n
unsafeReadBuffer (FBuffer mv) i = M.unsafeRead mv i
unsafeWriteBuffer (FBuffer mv) i a = M.unsafeWrite mv i a
unsafeGrowBuffer (FBuffer mv) x = FBuffer `liftM` M.unsafeGrow mv x
unsafeThawBuffer (FArray v) = FBuffer `liftM` S.unsafeThaw v
unsafeFreezeBuffer (FBuffer mv) = FArray `liftM` S.unsafeFreeze mv
unsafeSliceBuffer i n (FBuffer mv) = return $ FBuffer (M.unsafeSlice i n mv)
touchBuffer (FBuffer (M.MVector _ p)) = unsafePrimToPrim $ touchForeignPtr p
bufferLayout (FBuffer mv) = Foreign $ M.length mv
instance Unpack (Buffer s F a) (M.MVector s a) where
unpack (FBuffer mv) = mv
repack _ mv = FBuffer mv
fromForeignPtr :: Storable a => Int -> ForeignPtr a -> Array F a
fromForeignPtr n p = FArray $ S.unsafeFromForeignPtr p 0 n
toForeignPtr :: Storable a => Array F a -> (Int, Int, ForeignPtr a)
toForeignPtr (FArray (S.unsafeToForeignPtr -> (p,i,n))) = (i,n,p)
toStorableVector :: Array F a -> S.Vector a
toStorableVector (FArray vec) = vec
fromStorableVector :: S.Vector a -> Array F a
fromStorableVector vec = FArray vec
toByteString :: Array F Word8 -> ByteString
toByteString (FArray (S.unsafeToForeignPtr -> (p,i,n)))
= BS.PS p i n
fromByteString :: ByteString -> Array F Word8
fromByteString (BS.PS p i n)
= FArray (S.unsafeFromForeignPtr p i n)
instance (Eq a, Storable a) => Eq (Array F a) where
(FArray a1) == (FArray a2) = a1 == a2