module Data.Vector.Fixed.Storable (
Vec
, Vec2
, Vec3
, unsafeFromForeignPtr
, unsafeToForeignPtr
, unsafeWith
, MVec(..)
) where
import Control.Monad.Primitive
import Foreign.Storable
import Foreign.ForeignPtr
import Foreign.Marshal.Array ( advancePtr, copyArray, moveArray )
import GHC.ForeignPtr ( ForeignPtr(..), mallocPlainForeignPtrBytes )
import GHC.Ptr ( Ptr(..) )
import Prelude hiding (length,replicate,zipWith,map,foldl)
import Data.Vector.Fixed
import Data.Vector.Fixed.Internal
import Data.Vector.Fixed.Mutable
newtype Vec n a = Vec (ForeignPtr a)
newtype MVec n s a = MVec (ForeignPtr a)
type Vec2 = Vec (S (S Z))
type Vec3 = Vec (S (S (S Z)))
unsafeToForeignPtr :: Storable a => Vec n a -> ForeignPtr a
unsafeToForeignPtr (Vec fp) = fp
unsafeFromForeignPtr :: Storable a => ForeignPtr a -> Vec n a
unsafeFromForeignPtr = Vec
unsafeWith :: Storable a => (Ptr a -> IO b) -> Vec n a -> IO b
unsafeWith f (Vec fp) = f (getPtr fp)
instance (Arity n, Storable a, Show a) => Show (Vec n a) where
show v = "fromList " ++ show (toList v)
type instance Mutable (Vec n) = MVec n
instance (Arity n, Storable a) => MVector (MVec n) a where
overlaps (MVec fp) (MVec fq)
= between p q (q `advancePtr` n) || between q p (p `advancePtr` n)
where
between x y z = x >= y && x < z
p = getPtr fp
q = getPtr fq
n = arity (undefined :: n)
new = unsafePrimToPrim $ do
fp <- mallocVector $ arity (undefined :: n)
return $ MVec fp
copy (MVec fp) (MVec fq)
= unsafePrimToPrim
$ withForeignPtr fp $ \p ->
withForeignPtr fq $ \q ->
copyArray p q (arity (undefined :: n))
move (MVec fp) (MVec fq)
= unsafePrimToPrim
$ withForeignPtr fp $ \p ->
withForeignPtr fq $ \q ->
moveArray p q (arity (undefined :: n))
unsafeRead (MVec fp) i
= unsafePrimToPrim
$ withForeignPtr fp (`peekElemOff` i)
unsafeWrite (MVec fp) i x
= unsafePrimToPrim
$ withForeignPtr fp $ \p -> pokeElemOff p i x
instance (Arity n, Storable a) => IVector (Vec n) a where
unsafeFreeze (MVec fp) = return $ Vec fp
unsafeThaw (Vec fp) = return $ MVec fp
unsafeIndex (Vec fp) i
= unsafeInlineIO
$ withForeignPtr fp (`peekElemOff` i)
type instance Dim (Vec n) = n
type instance DimM (MVec n) = n
instance (Arity n, Storable a) => Vector (Vec n) a where
construct = constructVec
inspect = inspectVec
mallocVector :: forall a. Storable a => Int -> IO (ForeignPtr a)
mallocVector size
= mallocPlainForeignPtrBytes (size * sizeOf (undefined :: a))
getPtr :: ForeignPtr a -> Ptr a
getPtr (ForeignPtr addr _) = Ptr addr