module Data.Vector.Storable.Mutable(
MVector(..), IOVector, STVector, Storable,
length, null,
slice, init, tail, take, drop, splitAt,
unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
overlaps,
new, unsafeNew, replicate, replicateM, clone,
grow, unsafeGrow,
clear,
read, write, modify, swap,
unsafeRead, unsafeWrite, unsafeModify, unsafeSwap,
set, copy, move, unsafeCopy, unsafeMove,
unsafeCast,
unsafeFromForeignPtr, unsafeFromForeignPtr0,
unsafeToForeignPtr, unsafeToForeignPtr0,
unsafeWith
) where
import Control.DeepSeq ( NFData(rnf) )
import qualified Data.Vector.Generic.Mutable as G
import Data.Vector.Storable.Internal
import Foreign.Storable
import Foreign.ForeignPtr
#if __GLASGOW_HASKELL__ >= 605
import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
#endif
import Foreign.Ptr
import Foreign.Marshal.Array ( advancePtr, copyArray, moveArray )
import Control.Monad.Primitive
import Data.Primitive.Addr
import Data.Primitive.Types (Prim)
import GHC.Word (Word8, Word16, Word32, Word64)
import GHC.Ptr (Ptr(..))
import Prelude hiding ( length, null, replicate, reverse, map, read,
take, drop, splitAt, init, tail )
import Data.Typeable ( Typeable )
#define NOT_VECTOR_MODULE
#include "vector.h"
data MVector s a = MVector !Int
!(ForeignPtr a)
deriving ( Typeable )
type IOVector = MVector RealWorld
type STVector s = MVector s
instance NFData (MVector s a) where
rnf (MVector _ _) = ()
instance Storable a => G.MVector MVector a where
basicLength (MVector n _) = n
basicUnsafeSlice j m (MVector _ fp) = MVector m (updPtr (`advancePtr` j) fp)
basicOverlaps (MVector m fp) (MVector n fq)
= between p q (q `advancePtr` n) || between q p (p `advancePtr` m)
where
between x y z = x >= y && x < z
p = getPtr fp
q = getPtr fq
basicUnsafeNew n
| n < 0 = error $ "Storable.basicUnsafeNew: negative length: " ++ show n
| n > mx = error $ "Storable.basicUnsafeNew: length too large: " ++ show n
| otherwise = unsafePrimToPrim $ do
fp <- mallocVector n
return $ MVector n fp
where
size = sizeOf (undefined :: a)
mx = maxBound `quot` size :: Int
basicInitialize = storableZero
basicUnsafeRead (MVector _ fp) i
= unsafePrimToPrim
$ withForeignPtr fp (`peekElemOff` i)
basicUnsafeWrite (MVector _ fp) i x
= unsafePrimToPrim
$ withForeignPtr fp $ \p -> pokeElemOff p i x
basicSet = storableSet
basicUnsafeCopy (MVector n fp) (MVector _ fq)
= unsafePrimToPrim
$ withForeignPtr fp $ \p ->
withForeignPtr fq $ \q ->
copyArray p q n
basicUnsafeMove (MVector n fp) (MVector _ fq)
= unsafePrimToPrim
$ withForeignPtr fp $ \p ->
withForeignPtr fq $ \q ->
moveArray p q n
storableZero :: forall a m. (Storable a, PrimMonad m) => MVector (PrimState m) a -> m ()
storableZero (MVector n fp) = unsafePrimToPrim . withForeignPtr fp $ \(Ptr p) -> do
let q = Addr p
setAddr q byteSize (0 :: Word8)
where
x :: a
x = undefined
byteSize :: Int
byteSize = n * sizeOf x
storableSet :: (Storable a, PrimMonad m) => MVector (PrimState m) a -> a -> m ()
storableSet (MVector n fp) x
| n == 0 = return ()
| otherwise = unsafePrimToPrim $
case sizeOf x of
1 -> storableSetAsPrim n fp x (undefined :: Word8)
2 -> storableSetAsPrim n fp x (undefined :: Word16)
4 -> storableSetAsPrim n fp x (undefined :: Word32)
8 -> storableSetAsPrim n fp x (undefined :: Word64)
_ -> withForeignPtr fp $ \p -> do
poke p x
let do_set i
| 2*i < n = do
copyArray (p `advancePtr` i) p i
do_set (2*i)
| otherwise = copyArray (p `advancePtr` i) p (ni)
do_set 1
storableSetAsPrim
:: (Storable a, Prim b) => Int -> ForeignPtr a -> a -> b -> IO ()
storableSetAsPrim n fp x y = withForeignPtr fp $ \(Ptr p) -> do
poke (Ptr p) x
let q = Addr p
w <- readOffAddr q 0
setAddr (q `plusAddr` sizeOf x) (n1) (w `asTypeOf` y)
mallocVector :: Storable a => Int -> IO (ForeignPtr a)
mallocVector =
#if __GLASGOW_HASKELL__ >= 605
doMalloc undefined
where
doMalloc :: Storable b => b -> Int -> IO (ForeignPtr b)
doMalloc dummy size = mallocPlainForeignPtrBytes (size * sizeOf dummy)
#else
mallocForeignPtrArray
#endif
length :: Storable a => MVector s a -> Int
length = G.length
null :: Storable a => MVector s a -> Bool
null = G.null
slice :: Storable a => Int -> Int -> MVector s a -> MVector s a
slice = G.slice
take :: Storable a => Int -> MVector s a -> MVector s a
take = G.take
drop :: Storable a => Int -> MVector s a -> MVector s a
drop = G.drop
splitAt :: Storable a => Int -> MVector s a -> (MVector s a, MVector s a)
splitAt = G.splitAt
init :: Storable a => MVector s a -> MVector s a
init = G.init
tail :: Storable a => MVector s a -> MVector s a
tail = G.tail
unsafeSlice :: Storable a
=> Int
-> Int
-> MVector s a
-> MVector s a
unsafeSlice = G.unsafeSlice
unsafeTake :: Storable a => Int -> MVector s a -> MVector s a
unsafeTake = G.unsafeTake
unsafeDrop :: Storable a => Int -> MVector s a -> MVector s a
unsafeDrop = G.unsafeDrop
unsafeInit :: Storable a => MVector s a -> MVector s a
unsafeInit = G.unsafeInit
unsafeTail :: Storable a => MVector s a -> MVector s a
unsafeTail = G.unsafeTail
overlaps :: Storable a => MVector s a -> MVector s a -> Bool
overlaps = G.overlaps
new :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
new = G.new
unsafeNew :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
unsafeNew = G.unsafeNew
replicate :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
replicate = G.replicate
replicateM :: (PrimMonad m, Storable a) => Int -> m a -> m (MVector (PrimState m) a)
replicateM = G.replicateM
clone :: (PrimMonad m, Storable a)
=> MVector (PrimState m) a -> m (MVector (PrimState m) a)
clone = G.clone
grow :: (PrimMonad m, Storable a)
=> MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
grow = G.grow
unsafeGrow :: (PrimMonad m, Storable a)
=> MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
unsafeGrow = G.unsafeGrow
clear :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> m ()
clear = G.clear
read :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
read = G.read
write
:: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m ()
write = G.write
modify :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> (a -> a) -> Int -> m ()
modify = G.modify
swap
:: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m ()
swap = G.swap
unsafeRead :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
unsafeRead = G.unsafeRead
unsafeWrite
:: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m ()
unsafeWrite = G.unsafeWrite
unsafeModify :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> (a -> a) -> Int -> m ()
unsafeModify = G.unsafeModify
unsafeSwap
:: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m ()
unsafeSwap = G.unsafeSwap
set :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> a -> m ()
set = G.set
copy :: (PrimMonad m, Storable a)
=> MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
copy = G.copy
unsafeCopy :: (PrimMonad m, Storable a)
=> MVector (PrimState m) a
-> MVector (PrimState m) a
-> m ()
unsafeCopy = G.unsafeCopy
move :: (PrimMonad m, Storable a)
=> MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
move = G.move
unsafeMove :: (PrimMonad m, Storable a)
=> MVector (PrimState m) a
-> MVector (PrimState m) a
-> m ()
unsafeMove = G.unsafeMove
unsafeCast :: forall a b s.
(Storable a, Storable b) => MVector s a -> MVector s b
unsafeCast (MVector n fp)
= MVector ((n * sizeOf (undefined :: a)) `div` sizeOf (undefined :: b))
(castForeignPtr fp)
unsafeFromForeignPtr :: Storable a
=> ForeignPtr a
-> Int
-> Int
-> MVector s a
unsafeFromForeignPtr fp i n = unsafeFromForeignPtr0 fp' n
where
fp' = updPtr (`advancePtr` i) fp
unsafeFromForeignPtr0 :: Storable a
=> ForeignPtr a
-> Int
-> MVector s a
unsafeFromForeignPtr0 fp n = MVector n fp
unsafeToForeignPtr :: Storable a => MVector s a -> (ForeignPtr a, Int, Int)
unsafeToForeignPtr (MVector n fp) = (fp, 0, n)
unsafeToForeignPtr0 :: Storable a => MVector s a -> (ForeignPtr a, Int)
unsafeToForeignPtr0 (MVector n fp) = (fp, n)
unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
unsafeWith (MVector _ fp) = withForeignPtr fp