{-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE ScopedTypeVariables #-} #ifndef MIN_VERSION_base #define MIN_VERSION_base(x,y,z) 1 #endif module Data.Vector.Hybrid.Mutable ( MVector , IOVector , STVector -- * Accessors -- ** Length information , length, null -- ** Extracting subvectors , slice, init, tail, take, drop , unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop -- ** Overlapping , overlaps -- * Construction -- ** Initialisation , new, unsafeNew, replicate, clone -- ** Growing , grow, unsafeGrow -- ** Restricting memory usage , clear -- * Accessing individual elements , read, write, swap , unsafeRead, unsafeWrite, unsafeSwap -- * Modifying vectors -- ** Filling and copying , set, copy, unsafeCopy -- * Unsafe Construction and deconstruction , unsafeZip, projectFst, projectSnd -- * Deprecated operations , newWith, unsafeNewWith ) where import Control.Monad.Primitive import qualified Data.Vector.Generic.Mutable as G import Data.Vector.Hybrid.Internal import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail ) type IOVector u v = MVector u v RealWorld type STVector = MVector -- Length information -- ------------------ -- | Length of the mutable vector. length :: G.MVector u a => MVector u v s (a, b) -> Int length (MV ks _) = G.length ks {-# INLINE length #-} -- | Check whether the vector is empty null :: G.MVector u a => MVector u v s (a, b) -> Bool null (MV ks _) = G.null ks {-# INLINE null #-} -- Extracting subvectors -- --------------------- -- | Yield a part of the mutable vector without copying it. slice :: (G.MVector u a, G.MVector v b) => Int -> Int -> MVector u v s (a, b) -> MVector u v s (a, b) slice = G.slice {-# INLINE slice #-} take :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) take = G.take {-# INLINE take #-} drop :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) drop = G.drop {-# INLINE drop #-} init :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) init = G.init {-# INLINE init #-} tail :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) tail = G.tail {-# INLINE tail #-} -- | Yield a part of the mutable vector without copying it. No bounds checks -- are performed. unsafeSlice :: (G.MVector u a, G.MVector v b) => Int -- ^ starting index -> Int -- ^ length of the slice -> MVector u v s (a, b) -> MVector u v s (a, b) unsafeSlice = G.unsafeSlice {-# INLINE unsafeSlice #-} unsafeTake :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) unsafeTake = G.unsafeTake {-# INLINE unsafeTake #-} unsafeDrop :: (G.MVector u a, G.MVector v b) => Int -> MVector u v s (a, b) -> MVector u v s (a, b) unsafeDrop = G.unsafeDrop {-# INLINE unsafeDrop #-} unsafeInit :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) unsafeInit = G.unsafeInit {-# INLINE unsafeInit #-} unsafeTail :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) unsafeTail = G.unsafeTail {-# INLINE unsafeTail #-} -- Overlapping -- ----------- -- Check whether two vectors overlap. overlaps :: (G.MVector u a, G.MVector v b) => MVector u v s (a, b) -> MVector u v s (a, b) -> Bool overlaps = G.overlaps {-# INLINE overlaps #-} -- Initialisation -- -------------- -- | Create a mutable vector of the given length. new :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> m (MVector u v (PrimState m) (a, b)) new = G.new {-# INLINE new #-} -- | Create a mutable vector of the given length. The length is not checked. unsafeNew :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> m (MVector u v (PrimState m) (a, b)) unsafeNew = G.unsafeNew {-# INLINE unsafeNew #-} -- | Create a mutable vector of the given length (0 if the length is negative) -- and fill it with an initial value. replicate :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> (a, b) -> m (MVector u v (PrimState m) (a, b)) replicate = G.replicate {-# INLINE replicate #-} -- | Create a copy of a mutable vector. clone :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> m (MVector u v (PrimState m) (a, b)) clone = G.clone {-# INLINE clone #-} -- Growing -- ------- -- | Grow a vector by the given number of elements. The number must be -- positive. grow :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> m (MVector u v (PrimState m) (a, b)) grow = G.grow {-# INLINE grow #-} -- | Grow a vector by the given number of elements. The number must be -- positive but this is not checked. unsafeGrow :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> m (MVector u v (PrimState m) (a, b)) unsafeGrow = G.unsafeGrow {-# INLINE unsafeGrow #-} -- Restricting memory usage -- ------------------------ -- | Reset all elements of the vector to some undefined value, clearing all -- references to external objects. This is usually a noop for unboxed vectors. clear :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> m () clear = G.clear {-# INLINE clear #-} -- Accessing individual elements -- ----------------------------- -- | Yield the element at the given position. read :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> m (a, b) read = G.read {-# INLINE read #-} -- | Replace the element at the given position. write :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> (a, b) -> m () write = G.write {-# INLINE write #-} -- | Swap the elements at the given positions. swap :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> Int -> m () swap = G.swap {-# INLINE swap #-} -- | Yield the element at the given position. No bounds checks are performed. unsafeRead :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> m (a, b) unsafeRead = G.unsafeRead {-# INLINE unsafeRead #-} -- | Replace the element at the given position. No bounds checks are performed. unsafeWrite :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> (a, b) -> m () unsafeWrite = G.unsafeWrite {-# INLINE unsafeWrite #-} -- | Swap the elements at the given positions. No bounds checks are performed. unsafeSwap :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> Int -> Int -> m () unsafeSwap = G.unsafeSwap {-# INLINE unsafeSwap #-} -- Filling and copying -- ------------------- -- | Set all elements of the vector to the given value. set :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> (a, b) -> m () set = G.set {-# INLINE set #-} -- | Copy a vector. The two vectors must have the same length and may not -- overlap. copy :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -> MVector u v (PrimState m) (a, b) -> m () copy = G.copy {-# INLINE copy #-} -- | Copy a vector. The two vectors must have the same length and may not -- overlap. This is not checked. unsafeCopy :: (PrimMonad m, G.MVector u a, G.MVector v b) => MVector u v (PrimState m) (a, b) -- ^ target -> MVector u v (PrimState m) (a, b) -- ^ source -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy -- Unsafe composition and decomposition -- ------------------------------------ -- | The mutable vectors are assumed to be of the same length and to not overlap. This is not checked. unsafeZip :: u s a -> v s b -> MVector u v s (a, b) unsafeZip = MV {-# INLINE unsafeZip #-} projectFst :: MVector u v s (a, b) -> u s a projectFst (MV ks _) = ks {-# INLINE projectFst #-} projectSnd :: MVector u v s (a, b) -> v s b projectSnd (MV _ vs) = vs {-# INLINE projectSnd #-} -- Deprecated functions -- -------------------- -- | /DEPRECATED/ Use 'replicate' instead newWith :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> (a, b) -> m (MVector u v (PrimState m) (a, b)) newWith = G.replicate {-# INLINE newWith #-} -- | /DEPRECATED/ Use 'replicate' instead unsafeNewWith :: (PrimMonad m, G.MVector u a, G.MVector v b) => Int -> (a, b) -> m (MVector u v (PrimState m) (a, b)) unsafeNewWith = G.replicate {-# INLINE unsafeNewWith #-} {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}