module Data.Vector.Mutable.Dynamic(
MVector, STVector, IOVector,
new, replicate, unsafeNew, unsafeReplicate,
read, write, readFront, readBack,
unsafeRead, unsafeWrite, unsafeReadFront, unsafeReadBack, set,
freeze, thaw, frozen, unsafeFreeze, unsafeThaw, unsafeFrozen,
length, null,
clone, copy, move, unsafeCopy, unsafeMove,
clear, reserve, unsafeReserve, trim, pushBack, popBack, unsafePopBack, extend
) where
import Prelude hiding (read, length, replicate, null)
import Data.Data (Typeable)
import Control.Monad
import Control.Monad.ST
import Control.Monad.Primitive
import Data.Primitive.MutVar
import qualified Data.Vector.Mutable as MV
import qualified Data.Vector as V
newtype MVector s a = MVector (MutVar s (MVectorData s a)) deriving (Typeable)
type IOVector = MVector RealWorld
type STVector = MVector
data MVectorData s a = MVectorData {
_size :: !Int,
_data :: !(MV.MVector s a)}
deriving (Typeable)
newReserve :: Int
newReserve = 5
freeze :: PrimMonad m => MVector (PrimState m) a -> m (V.Vector a)
freeze (MVector v) = do
MVectorData s v <- readMutVar v
V.freeze (MV.unsafeSlice 0 s v)
unsafeFreeze :: PrimMonad m => MVector (PrimState m) a -> m (V.Vector a)
unsafeFreeze (MVector v) = do
MVectorData s v <- readMutVar v
V.unsafeFreeze (MV.unsafeSlice 0 s v)
thaw :: PrimMonad m => V.Vector a -> m (MVector (PrimState m) a)
thaw v = do
vdat <- V.thaw v
v <- newMutVar (MVectorData (V.length v) vdat)
return (MVector v)
unsafeThaw :: PrimMonad m => V.Vector a -> m (MVector (PrimState m) a)
unsafeThaw v = do
vdat <- V.unsafeThaw v
v <- newMutVar (MVectorData (V.length v) vdat)
return (MVector v)
length :: PrimMonad m => MVector (PrimState m) a -> m Int
length (MVector v) = liftM (MV.length . _data) (readMutVar v)
null :: PrimMonad m => MVector (PrimState m) a -> m Bool
null (MVector v) = do
MVectorData s _ <- readMutVar v
return (s == 0)
new :: PrimMonad m => Int -> m (MVector (PrimState m) a)
new i = do
v <- MV.new (i + newReserve)
liftM MVector $ newMutVar (MVectorData i v)
unsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) a)
unsafeNew i = do
v <- MV.unsafeNew (i + newReserve)
liftM MVector $ newMutVar (MVectorData i v)
replicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
replicate i a = do
v <- MV.new i
MV.set v a
liftM MVector $ newMutVar (MVectorData i v)
unsafeReplicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
unsafeReplicate i a = do
v <- MV.unsafeNew i
MV.set v a
liftM MVector $ newMutVar (MVectorData i v)
read :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
read (MVector v) i = do
MVectorData s v <- readMutVar v
if (i >= s || i < 0) then
error "Data.Vector.Mutable.Dynamic: read: index out of bounds"
else
MV.unsafeRead v i
unsafeRead :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
unsafeRead (MVector v) i = (`MV.unsafeRead` i) . _data =<< readMutVar v
write :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
write (MVector v) i a = do
MVectorData s v <- readMutVar v
if (i >= s || i < 0) then
error "Data.Vector.Mutable.Dynamic: write: index out of bounds"
else
MV.unsafeWrite v i a
unsafeWrite :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
unsafeWrite (MVector v) i a = do
v <- readMutVar v
MV.unsafeWrite (_data v) i a
clear :: PrimMonad m => MVector (PrimState m) a -> m ()
clear (MVector var) = do
v <- MV.unsafeNew newReserve
writeMutVar var (MVectorData 0 v)
set :: PrimMonad m => MVector (PrimState m) a -> a -> m ()
set (MVector v) a = do
MVectorData s v <- readMutVar v
MV.set (MV.unsafeSlice 0 s v) a
copy :: PrimMonad m => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
copy (MVector v1) (MVector v2) = do
v1 <- readMutVar v1
v2 <- readMutVar v2
MV.copy (_data v1) (_data v2)
unsafeCopy :: PrimMonad m => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
unsafeCopy (MVector v1) (MVector v2) = do
v1 <- readMutVar v1
v2 <- readMutVar v2
MV.unsafeCopy (_data v1) (_data v2)
move :: PrimMonad m => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
move (MVector v1) (MVector v2) = do
v1 <- readMutVar v1
v2 <- readMutVar v2
MV.move (_data v1) (_data v2)
unsafeMove :: PrimMonad m => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
unsafeMove (MVector v1) (MVector v2) = do
v1 <- readMutVar v1
v2 <- readMutVar v2
MV.unsafeMove (_data v1) (_data v2)
clone :: PrimMonad m => MVector (PrimState m) a -> m (MVector (PrimState m) a)
clone (MVector v) = do
MVectorData s v <- readMutVar v
v' <- MV.clone v
var <- newMutVar (MVectorData s v')
return (MVector var)
reserve :: PrimMonad m => MVector (PrimState m) a -> Int -> m ()
reserve (MVector v) i = do
MVectorData s v' <- readMutVar v
if (i < 0) then
error "Data.Vector.Mutable.Dynamic: reserve: negative argument"
else if (s + i <= MV.length v') then
return ()
else do
v'' <- MV.unsafeGrow v' i
writeMutVar v (MVectorData s v'')
unsafeReserve :: PrimMonad m => MVector (PrimState m) a -> Int -> m ()
unsafeReserve (MVector v) i = do
MVectorData s v' <- readMutVar v
if (s + i <= MV.length v') then
return ()
else do
v'' <- MV.unsafeGrow v' i
writeMutVar v (MVectorData s v'')
trim :: PrimMonad m => MVector (PrimState m) a -> m ()
trim v = unsafeReserve v 0
pushBack :: PrimMonad m => MVector (PrimState m) a -> a -> m ()
pushBack (MVector v) a = do
MVectorData s v' <- readMutVar v
if (s == MV.length v') then do
v'' <- MV.unsafeGrow v' (s * 2 + 1)
MV.unsafeWrite v'' s a
writeMutVar v (MVectorData (s + 1) v'')
else do
MV.unsafeWrite v' s a
writeMutVar v (MVectorData (s + 1) v')
popBack :: PrimMonad m => MVector (PrimState m) a -> m a
popBack (MVector v) = do
MVectorData s v' <- readMutVar v
if (s <= 0) then
error "Data.Vector.Mutable.Dynamic: popBack: empty vector"
else do
a <- MV.unsafeRead v' (s 1)
when (s < quot (MV.length v') 2) $ do
v'' <- MV.unsafeGrow v' (s 1)
writeMutVar v (MVectorData (s 1) v'')
return a
unsafePopBack :: PrimMonad m => MVector (PrimState m) a -> m a
unsafePopBack (MVector v) = do
MVectorData s v' <- readMutVar v
a <- MV.unsafeRead v' (s 1)
when (s < quot (MV.length v') 2) $ do
v'' <- MV.unsafeGrow v' (s 1)
writeMutVar v (MVectorData (s 1) v'')
return a
readBack :: PrimMonad m => MVector (PrimState m) a -> m a
readBack (MVector v) = do
MVectorData s v <- readMutVar v
if (s <= 0) then
error "Data.Vector.Mutable.Dynamic: reading the back of an empty vector"
else
MV.unsafeRead v (MV.length v 1)
unsafeReadBack :: PrimMonad m => MVector (PrimState m) a -> m a
unsafeReadBack (MVector v) = do
MVectorData s v <- readMutVar v
MV.unsafeRead v (MV.length v 1)
readFront :: PrimMonad m => MVector (PrimState m) a -> m a
readFront (MVector v) = do
MVectorData s v <- readMutVar v
if (s <= 0) then
error "Data.Vector.Mutable.Dynamic: reading the front of an empty vector"
else
MV.unsafeRead v 0
unsafeReadFront :: PrimMonad m => MVector (PrimState m) a -> m a
unsafeReadFront (MVector v) = do
MVectorData s v <- readMutVar v
MV.unsafeRead v 0
extend :: PrimMonad m => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
extend (MVector a) (MVector b) = do
MVectorData sa va <- readMutVar a
MVectorData sb vb <- readMutVar b
if (sa + sb > MV.length va) then do
va' <- MV.unsafeGrow va (sa + sb)
MV.unsafeCopy (MV.unsafeSlice sa sb va') (MV.unsafeSlice 0 sb vb)
writeMutVar a (MVectorData (sa + sb) va')
else do
MV.unsafeCopy (MV.unsafeSlice sa sb va) (MV.unsafeSlice 0 sb vb)
writeMutVar a (MVectorData (sa + sb) va)
frozen :: PrimMonad m => MVector (PrimState m) a -> (V.Vector a -> b) -> m b
frozen v f = liftM f (freeze v)
unsafeFrozen :: PrimMonad m => MVector (PrimState m) a -> (V.Vector a -> b) -> m b
unsafeFrozen v f = liftM f (unsafeFreeze v)