vector 0.6.0.2 → 0.7
raw patch · 21 files changed
+1529/−641 lines, 21 filesdep ~basedep ~primitive
Dependency ranges changed: base, primitive
Files
- Data/Vector.hs +60/−9
- Data/Vector/Fusion/Stream.hs +5/−1
- Data/Vector/Fusion/Stream/Monadic.hs +51/−26
- Data/Vector/Generic.hs +157/−20
- Data/Vector/Generic/Base.hs +14/−6
- Data/Vector/Generic/Mutable.hs +164/−102
- Data/Vector/Generic/New.hs +1/−1
- Data/Vector/Mutable.hs +171/−68
- Data/Vector/Primitive.hs +60/−9
- Data/Vector/Primitive/Mutable.hs +181/−77
- Data/Vector/Storable.hs +58/−28
- Data/Vector/Storable/Internal.hs +1/−1
- Data/Vector/Storable/Mutable.hs +212/−105
- Data/Vector/Unboxed.hs +54/−7
- Data/Vector/Unboxed/Base.hs +23/−14
- Data/Vector/Unboxed/Mutable.hs +186/−77
- benchmarks/Algo/Tridiag.hs +3/−7
- benchmarks/vector-benchmarks.cabal +5/−5
- internal/GenUnboxTuple.hs +10/−3
- internal/unbox-tuple-instances +100/−60
- vector.cabal +13/−15
Data/Vector.hs view
@@ -32,7 +32,7 @@ length, null, -- ** Indexing- (!), head, last,+ (!), (!?), head, last, unsafeIndex, unsafeHead, unsafeLast, -- ** Monadic indexing@@ -58,7 +58,7 @@ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo, -- ** Concatenation- cons, snoc, (++),+ cons, snoc, (++), concat, -- ** Restricting memory usage force,@@ -136,8 +136,11 @@ -- ** Lists toList, fromList, fromListN, + -- ** Other vector types+ G.convert,+ -- ** Mutable vectors- copy, unsafeCopy+ freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy ) where import qualified Data.Vector.Generic as G@@ -150,7 +153,7 @@ import Control.Monad.Primitive import Prelude hiding ( length, null,- replicate, (++),+ replicate, (++), concat, head, last, init, tail, take, drop, reverse, map, concatMap,@@ -168,6 +171,8 @@ import Data.Typeable ( Typeable ) import Data.Data ( Data(..) ) +import Data.Monoid ( Monoid(..) )+ -- | Boxed vectors, supporting efficient slicing. data Vector a = Vector {-# UNPACK #-} !Int {-# UNPACK #-} !Int@@ -187,10 +192,14 @@ type instance G.Mutable Vector = MVector instance G.Vector Vector a where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MVector i n marr)+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MVector i n marr) = Vector i n `liftM` unsafeFreezeArray marr + {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (Vector i n arr)+ = MVector i n `liftM` unsafeThawArray arr+ {-# INLINE basicLength #-} basicLength (Vector _ n _) = n @@ -225,6 +234,16 @@ {-# INLINE (>=) #-} xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT +instance Monoid (Vector a) where+ {-# INLINE mempty #-}+ mempty = empty++ {-# INLINE mappend #-}+ mappend = (++)++ {-# INLINE mconcat #-}+ mconcat = concat+ -- Length information -- ------------------ @@ -246,6 +265,11 @@ {-# INLINE (!) #-} (!) = (G.!) +-- | O(1) Safe indexing+(!?) :: Vector a -> Int -> Maybe a+{-# INLINE (!?) #-}+(!?) = (G.!?)+ -- | /O(1)/ First element head :: Vector a -> a {-# INLINE head #-}@@ -496,6 +520,11 @@ {-# INLINE (++) #-} (++) = (G.++) +-- | /O(n)/ Concatenate all vectors in the list+concat :: [Vector a] -> Vector a+{-# INLINE concat #-}+concat = G.concat+ -- Monadic initialisation -- ---------------------- @@ -689,7 +718,7 @@ -- @ modify :: (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a {-# INLINE modify #-}-modify = G.modify+modify p = G.modify p -- Mapping -- -------@@ -1278,14 +1307,36 @@ -- Conversions - Mutable vectors -- ----------------------------- +-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without+-- copying. The mutable vector may not be used after this operation.+unsafeFreeze :: PrimMonad m => MVector (PrimState m) a -> m (Vector a)+{-# INLINE unsafeFreeze #-}+unsafeFreeze = G.unsafeFreeze++-- | /O(1)/ Unsafely convert an immutable vector to a mutable one without+-- copying. The immutable vector may not be used after this operation.+unsafeThaw :: PrimMonad m => Vector a -> m (MVector (PrimState m) a)+{-# INLINE unsafeThaw #-}+unsafeThaw = G.unsafeThaw++-- | /O(n)/ Yield a mutable copy of the immutable vector.+thaw :: PrimMonad m => Vector a -> m (MVector (PrimState m) a)+{-# INLINE thaw #-}+thaw = G.thaw++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: PrimMonad m => MVector (PrimState m) a -> m (Vector a)+{-# INLINE freeze #-}+freeze = G.freeze+ -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length.+-- have the same length. This is not checked. unsafeCopy :: PrimMonad m => MVector (PrimState m) a -> Vector a -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length. This is not checked.+-- have the same length. copy :: PrimMonad m => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy
Data/Vector/Fusion/Stream.hs view
@@ -35,7 +35,7 @@ slice, init, tail, take, drop, -- * Mapping- map, concatMap, unbox,+ map, concatMap, flatten, unbox, -- * Zipping indexed, indexedR,@@ -613,4 +613,8 @@ {-# INLINE unsafeFromList #-} unsafeFromList = M.unsafeFromList +-- | Create a 'Stream' of values from a 'Stream' of streamable things+flatten :: (a -> s) -> (s -> Step s b) -> Size -> Stream a -> Stream b+{-# INLINE_STREAM flatten #-}+flatten mk istep sz = M.flatten (return . mk) (return . istep) sz . liftStream
Data/Vector/Fusion/Stream/Monadic.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ExistentialQuantification, Rank2Types #-}+{-# LANGUAGE ExistentialQuantification, Rank2Types, BangPatterns #-} -- | -- Module : Data.Vector.Fusion.Stream.Monadic@@ -31,7 +31,7 @@ slice, init, tail, take, drop, -- * Mapping- map, mapM, mapM_, trans, unbox, concatMap,+ map, mapM, mapM_, trans, unbox, concatMap, flatten, -- * Zipping indexed, indexedR, zipWithM_,@@ -223,7 +223,7 @@ {-# INLINE_STREAM head #-} head (Stream step s _) = head_loop SPEC s where- head_loop SPEC s+ head_loop !sPEC s = do r <- step s case r of@@ -238,7 +238,7 @@ {-# INLINE_STREAM last #-} last (Stream step s _) = last_loop0 SPEC s where- last_loop0 SPEC s+ last_loop0 !sPEC s = do r <- step s case r of@@ -246,7 +246,7 @@ Skip s' -> last_loop0 SPEC s' Done -> BOUNDS_ERROR(emptyStream) "last" - last_loop1 SPEC x s+ last_loop1 !sPEC x s = do r <- step s case r of@@ -260,7 +260,7 @@ Stream step s _ !! i | i < 0 = BOUNDS_ERROR(error) "!!" "negative index" | otherwise = index_loop SPEC s i where- index_loop SPEC s i+ index_loop !sPEC s i = i `seq` do r <- step s@@ -387,7 +387,7 @@ {-# INLINE_STREAM consume #-} consume (Stream step s _) = consume_loop SPEC s where- consume_loop SPEC s+ consume_loop !sPEC s = do r <- step s case r of@@ -677,7 +677,7 @@ {-# INLINE_STREAM elem #-} elem x (Stream step s _) = elem_loop SPEC s where- elem_loop SPEC s+ elem_loop !sPEC s = do r <- step s case r of@@ -704,7 +704,7 @@ {-# INLINE_STREAM findM #-} findM f (Stream step s _) = find_loop SPEC s where- find_loop SPEC s+ find_loop !sPEC s = do r <- step s case r of@@ -727,7 +727,7 @@ {-# INLINE_STREAM findIndexM #-} findIndexM f (Stream step s _) = findIndex_loop SPEC s 0 where- findIndex_loop SPEC s i+ findIndex_loop !sPEC s i = do r <- step s case r of@@ -751,7 +751,7 @@ {-# INLINE_STREAM foldlM #-} foldlM m z (Stream step s _) = foldlM_loop SPEC z s where- foldlM_loop SPEC z s+ foldlM_loop !sPEC z s = do r <- step s case r of@@ -774,7 +774,7 @@ {-# INLINE_STREAM foldl1M #-} foldl1M f (Stream step s sz) = foldl1M_loop SPEC s where- foldl1M_loop SPEC s+ foldl1M_loop !sPEC s = do r <- step s case r of@@ -797,7 +797,7 @@ {-# INLINE_STREAM foldlM' #-} foldlM' m z (Stream step s _) = foldlM'_loop SPEC z s where- foldlM'_loop SPEC z s+ foldlM'_loop !sPEC z s = z `seq` do r <- step s@@ -822,7 +822,7 @@ {-# INLINE_STREAM foldl1M' #-} foldl1M' f (Stream step s sz) = foldl1M'_loop SPEC s where- foldl1M'_loop SPEC s+ foldl1M'_loop !sPEC s = do r <- step s case r of@@ -845,7 +845,7 @@ {-# INLINE_STREAM foldrM #-} foldrM f z (Stream step s _) = foldrM_loop SPEC s where- foldrM_loop SPEC s+ foldrM_loop !sPEC s = do r <- step s case r of@@ -863,7 +863,7 @@ {-# INLINE_STREAM foldr1M #-} foldr1M f (Stream step s _) = foldr1M_loop0 SPEC s where- foldr1M_loop0 SPEC s+ foldr1M_loop0 !sPEC s = do r <- step s case r of@@ -871,7 +871,7 @@ Skip s' -> foldr1M_loop0 SPEC s' Done -> BOUNDS_ERROR(emptyStream) "foldr1M" - foldr1M_loop1 SPEC x s+ foldr1M_loop1 !sPEC x s = do r <- step s case r of@@ -886,7 +886,7 @@ {-# INLINE_STREAM and #-} and (Stream step s _) = and_loop SPEC s where- and_loop SPEC s+ and_loop !sPEC s = do r <- step s case r of@@ -899,7 +899,7 @@ {-# INLINE_STREAM or #-} or (Stream step s _) = or_loop SPEC s where- or_loop SPEC s+ or_loop !sPEC s = do r <- step s case r of@@ -931,6 +931,30 @@ Skip inner_s' -> return $ Skip (Right (Stream inner_step inner_s' sz, s)) Done -> return $ Skip (Left s) +-- | Create a 'Stream' of values from a 'Stream' of streamable things+flatten :: Monad m => (a -> m s) -> (s -> m (Step s b)) -> Size+ -> Stream m a -> Stream m b+{-# INLINE_STREAM flatten #-}+flatten mk istep sz (Stream ostep t _) = Stream step (Left t) sz+ where+ {-# INLINE_INNER step #-}+ step (Left t) = do+ r <- ostep t+ case r of+ Yield a t' -> do+ s <- mk a+ return $ Skip (Right (s,t'))+ Skip t' -> return $ Skip (Left t')+ Done -> return $ Done++ + step (Right (s,t)) = do+ r <- istep s+ case r of+ Yield x s' -> return $ Yield x (Right (s',t))+ Skip s' -> return $ Skip (Right (s',t))+ Done -> return $ Skip (Left t)+ -- Unfolding -- --------- @@ -1141,7 +1165,8 @@ -- @x+y+y@ etc. enumFromStepN :: (Num a, Monad m) => a -> a -> Int -> Stream m a {-# INLINE_STREAM enumFromStepN #-}-enumFromStepN x y n = n `seq` Stream step (x,n) (Exact (delay_inline max n 0))+enumFromStepN x y n = x `seq` y `seq` n `seq`+ Stream step (x,n) (Exact (delay_inline max n 0)) where {-# INLINE_INNER step #-} step (x,n) | n > 0 = return $ Yield x (x+y,n-1)@@ -1161,7 +1186,7 @@ -- FIXME: add "too large" test for Int enumFromTo_small :: (Integral a, Monad m) => a -> a -> Stream m a {-# INLINE_STREAM enumFromTo_small #-}-enumFromTo_small x y = Stream step x (Exact n)+enumFromTo_small x y = x `seq` y `seq` Stream step x (Exact n) where n = delay_inline max (fromIntegral y - fromIntegral x + 1) 0 @@ -1213,7 +1238,7 @@ enumFromTo_int :: (Integral a, Monad m) => a -> a -> Stream m a {-# INLINE_STREAM enumFromTo_int #-}-enumFromTo_int x y = Stream step x (Exact (len x y))+enumFromTo_int x y = x `seq` y `seq` Stream step x (Exact (len x y)) where {-# INLINE [0] len #-} len x y | x > y = 0@@ -1248,7 +1273,7 @@ enumFromTo_big_word :: (Integral a, Monad m) => a -> a -> Stream m a {-# INLINE_STREAM enumFromTo_big_word #-}-enumFromTo_big_word x y = Stream step x (Exact (len x y))+enumFromTo_big_word x y = x `seq` y `seq` Stream step x (Exact (len x y)) where {-# INLINE [0] len #-} len x y | x > y = 0@@ -1288,7 +1313,7 @@ -- FIXME: the "too large" test is totally wrong enumFromTo_big_int :: (Integral a, Monad m) => a -> a -> Stream m a {-# INLINE_STREAM enumFromTo_big_int #-}-enumFromTo_big_int x y = Stream step x (Exact (len x y))+enumFromTo_big_int x y = x `seq` y `seq` Stream step x (Exact (len x y)) where {-# INLINE [0] len #-} len x y | x > y = 0@@ -1315,7 +1340,7 @@ enumFromTo_char :: Monad m => Char -> Char -> Stream m Char {-# INLINE_STREAM enumFromTo_char #-}-enumFromTo_char x y = Stream step xn (Exact n)+enumFromTo_char x y = x `seq` y `seq` Stream step xn (Exact n) where xn = ord x yn = ord y@@ -1340,7 +1365,7 @@ enumFromTo_double :: (Monad m, Ord a, RealFrac a) => a -> a -> Stream m a {-# INLINE_STREAM enumFromTo_double #-}-enumFromTo_double n m = Stream step n (Max (len n m))+enumFromTo_double n m = n `seq` m `seq` Stream step n (Max (len n m)) where lim = m + 1/2 -- important to float out
Data/Vector/Generic.hs view
@@ -22,7 +22,7 @@ length, null, -- ** Indexing- (!), head, last,+ (!), (!?), head, last, unsafeIndex, unsafeHead, unsafeLast, -- ** Monadic indexing@@ -48,7 +48,7 @@ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo, -- ** Concatenation- cons, snoc, (++),+ cons, snoc, (++), concat, -- ** Restricting memory usage force,@@ -126,8 +126,11 @@ -- ** Lists toList, fromList, fromListN, + -- ** Different vector types+ convert,+ -- ** Mutable vectors- copy, unsafeCopy,+ freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy, -- * Fusion support @@ -155,7 +158,7 @@ import Data.Vector.Generic.New ( New ) import qualified Data.Vector.Fusion.Stream as Stream-import Data.Vector.Fusion.Stream ( Stream, MStream, inplace )+import Data.Vector.Fusion.Stream ( Stream, MStream, inplace, liftStream ) import qualified Data.Vector.Fusion.Stream.Monadic as MStream import Data.Vector.Fusion.Stream.Size import Data.Vector.Fusion.Util@@ -163,11 +166,12 @@ import Control.Monad.ST ( ST, runST ) import Control.Monad.Primitive import qualified Control.Monad as Monad+import qualified Data.List as List import Prelude hiding ( length, null,- replicate, (++),+ replicate, (++), concat, head, last, init, tail, take, drop, reverse,- map, concatMap,+ map, concat, concatMap, zipWith, zipWith3, zip, zip3, unzip, unzip3, filter, takeWhile, dropWhile, span, break, elem, notElem,@@ -218,6 +222,12 @@ v ! i = BOUNDS_CHECK(checkIndex) "(!)" i (length v) $ unId (basicUnsafeIndexM v i) +-- | O(1) Safe indexing+(!?) :: Vector v a => v a -> Int -> Maybe a+{-# INLINE_STREAM (!?) #-}+v !? i | i < 0 || i >= length v = Nothing+ | otherwise = Just $ unsafeIndex v i+ -- | /O(1)/ First element head :: Vector v a => v a -> a {-# INLINE_STREAM head #-}@@ -324,20 +334,28 @@ {-# INLINE_STREAM unsafeLastM #-} unsafeLastM v = unsafeIndexM v (length v - 1) --- FIXME: the rhs of these rules are lazy in the stream which is WRONG-{- RULES+{-# RULES -"indexM/unstream [Vector]" forall v i s.- indexM (new' v (New.unstream s)) i = return (s Stream.!! i)+"indexM/unstream [Vector]" forall s i.+ indexM (new (New.unstream s)) i = liftStream s MStream.!! i -"headM/unstream [Vector]" forall v s.- headM (new' v (New.unstream s)) = return (Stream.head s)+"headM/unstream [Vector]" forall s.+ headM (new (New.unstream s)) = MStream.head (liftStream s) -"lastM/unstream [Vector]" forall v s.- lastM (new' v (New.unstream s)) = return (Stream.last s)+"lastM/unstream [Vector]" forall s.+ lastM (new (New.unstream s)) = MStream.last (liftStream s) - -}+"unsafeIndexM/unstream [Vector]" forall s i.+ unsafeIndexM (new (New.unstream s)) i = liftStream s MStream.!! i +"unsafeHeadM/unstream [Vector]" forall s.+ unsafeHeadM (new (New.unstream s)) = MStream.head (liftStream s)++"unsafeLastM/unstream [Vector]" forall s.+ unsafeLastM (new (New.unstream s)) = MStream.last (liftStream s)++ #-}+ -- Extracting subvectors (slicing) -- ------------------------------- @@ -490,6 +508,28 @@ {-# INLINE unfoldrN #-} unfoldrN n f = unstream . Stream.unfoldrN n f +{-+construct :: Vector v a => Int -> (v a -> a) -> v a+{-# INLINE construct #-}+construct n f = runST (+ do+ v <- M.new n+ v' <- unsafeFreeze v+ fill v' 0+ )+ where+ fill v i | i < n = let x = f (unsafeTake i v)+ in+ elemseq v x $+ do+ v' <- unsafeThaw v+ M.unsafeWrite v' i x+ v'' <- unsafeFreeze v'+ fill v'' (i-1)++ fill v i = return v+-}+ -- Enumeration -- ----------- @@ -552,6 +592,25 @@ {-# INLINE (++) #-} v ++ w = unstream (stream v Stream.++ stream w) +-- | /O(n)/ Concatenate all vectors in the list+concat :: Vector v a => [v a] -> v a+{-# INLINE concat #-}+-- concat vs = create (thawMany vs)+concat vs = unstream (Stream.flatten mk step (Exact n) (Stream.fromList vs))+ where+ n = List.foldl' (\k v -> k + length v) 0 vs++ {-# INLINE_INNER step #-}+ step (v,i,k)+ | i < k = case unsafeIndexM v i of+ Box x -> Stream.Yield x (v,i+1,k)+ | otherwise = Stream.Done++ {-# INLINE mk #-}+ mk v = let k = length v+ in+ k `seq` (v,0,k)+ -- Monadic initialisation -- ---------------------- @@ -761,20 +820,38 @@ -- does not retain references to the original one even if it is lazy in its -- elements. This would not be the case if we simply used map (v!) backpermute v is = seq v+ $ seq n $ unstream $ Stream.unbox- $ Stream.map (indexM v)+ $ Stream.map index $ stream is+ where+ n = length v + {-# INLINE index #-}+ -- NOTE: we do it this way to avoid triggering LiberateCase on n in+ -- polymorphic code+ index i = BOUNDS_CHECK(checkIndex) "backpermute" i n+ $ basicUnsafeIndexM v i+ -- | Same as 'backpermute' but without bounds checking. unsafeBackpermute :: (Vector v a, Vector v Int) => v a -> v Int -> v a {-# INLINE unsafeBackpermute #-} unsafeBackpermute v is = seq v+ $ seq n $ unstream $ Stream.unbox- $ Stream.map (unsafeIndexM v)+ $ Stream.map index $ stream is+ where+ n = length v + {-# INLINE index #-}+ -- NOTE: we do it this way to avoid triggering LiberateCase on n in+ -- polymorphic code+ index i = UNSAFE_CHECK(checkIndex) "unsafeBackpermute" i n+ $ basicUnsafeIndexM v i+ -- Safe destructive updates -- ------------------------ @@ -814,7 +891,9 @@ -- | Map a function over a vector and concatenate the results. concatMap :: (Vector v a, Vector v b) => (a -> v b) -> v a -> v b {-# INLINE concatMap #-}-concatMap f = unstream . Stream.concatMap (stream . f) . stream+-- NOTE: We can't fuse concatMap anyway so don't pretend we do.+-- concatMap f = unstream . Stream.concatMap (stream . f) . stream+concatMap f = concat . Stream.toList . Stream.map f . stream -- Monadic mapping -- ---------------@@ -1522,9 +1601,67 @@ {-# INLINE fromListN #-} fromListN n = unstream . Stream.fromListN n +-- Conversions - Immutable vectors+-- -------------------------------++-- | /O(n)/ Convert different vector types+convert :: (Vector v a, Vector w a) => v a -> w a+{-# INLINE convert #-}+convert = unstream . stream+ -- Conversions - Mutable vectors -- ----------------------------- +-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without+-- copying. The mutable vector may not be used after this operation.+unsafeFreeze+ :: (PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> m (v a)+{-# INLINE unsafeFreeze #-}+unsafeFreeze = basicUnsafeFreeze+++-- | /O(1)/ Unsafely convert an immutable vector to a mutable one without+-- copying. The immutable vector may not be used after this operation.+unsafeThaw :: (PrimMonad m, Vector v a) => v a -> m (Mutable v (PrimState m) a)+{-# INLINE unsafeThaw #-}+unsafeThaw = basicUnsafeThaw++-- | /O(n)/ Yield a mutable copy of the immutable vector.+thaw :: (PrimMonad m, Vector v a) => v a -> m (Mutable v (PrimState m) a)+{-# INLINE_STREAM thaw #-}+thaw v = do+ mv <- M.unsafeNew (length v)+ unsafeCopy mv v+ return mv++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: (PrimMonad m, Vector v a) => Mutable v (PrimState m) a -> m (v a)+{-# INLINE freeze #-}+freeze mv = unsafeFreeze =<< M.clone mv++{-+-- | /O(n)/ Yield a mutable vector containing copies of each vector in the+-- list.+thawMany :: (PrimMonad m, Vector v a) => [v a] -> m (Mutable v (PrimState m) a)+{-# INLINE_STREAM thawMany #-}+-- FIXME: add rule for (stream (new (New.create (thawMany vs))))+-- NOTE: We don't try to consume the list lazily as this wouldn't significantly+-- change the space requirements anyway.+thawMany vs = do+ mv <- M.new n+ thaw_loop mv vs+ return mv+ where+ n = List.foldl' (\k v -> k + length v) 0 vs++ thaw_loop mv [] = mv `seq` return ()+ thaw_loop mv (v:vs)+ = do+ let n = length v+ unsafeCopy (M.unsafeTake n mv) v+ thaw_loop (M.unsafeDrop n mv) vs+-}+ -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must -- have the same length. copy@@ -1549,7 +1686,7 @@ -- | /O(1)/ Convert a vector to a 'Stream' stream :: Vector v a => v a -> Stream a {-# INLINE_STREAM stream #-}-stream v = v `seq` (Stream.unfoldr get 0 `Stream.sized` Exact n)+stream v = v `seq` n `seq` (Stream.unfoldr get 0 `Stream.sized` Exact n) where n = length v @@ -1588,7 +1725,7 @@ -- | /O(1)/ Convert a vector to a 'Stream', proceeding from right to left streamR :: Vector v a => v a -> Stream a {-# INLINE_STREAM streamR #-}-streamR v = v `seq` (Stream.unfoldr get n `Stream.sized` Exact n)+streamR v = v `seq` n `seq` (Stream.unfoldr get n `Stream.sized` Exact n) where n = length v
Data/Vector/Generic/Base.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE Rank2Types, MultiParamTypeClasses, FlexibleContexts,- TypeFamilies, ScopedTypeVariables #-}+ TypeFamilies, ScopedTypeVariables, BangPatterns #-} {-# OPTIONS_HADDOCK hide #-} -- |@@ -35,8 +35,10 @@ -- -- Minimum complete implementation: ----- * 'unsafeFreeze'+-- * 'basicUnsafeFreeze' --+-- * 'basicUnsafeThaw'+-- -- * 'basicLength' -- -- * 'basicUnsafeSlice'@@ -44,15 +46,21 @@ -- * 'basicUnsafeIndexM' -- class MVector (Mutable v) a => Vector v a where- -- | /Assume complexity: O(1)/+ -- | /Assumed complexity: O(1)/ -- -- Unsafely convert a mutable vector to its immutable version -- without copying. The mutable vector may not be used after -- this operation.- unsafeFreeze :: PrimMonad m => Mutable v (PrimState m) a -> m (v a)+ basicUnsafeFreeze :: PrimMonad m => Mutable v (PrimState m) a -> m (v a) -- | /Assumed complexity: O(1)/ --+ -- Unsafely convert an immutable vector to its mutable version without+ -- copying. The immutable vector may not be used after this operation.+ basicUnsafeThaw :: PrimMonad m => v a -> m (Mutable v (PrimState m) a)++ -- | /Assumed complexity: O(1)/+ -- -- Yield the length of the vector. basicLength :: v a -> Int @@ -104,9 +112,9 @@ basicUnsafeCopy :: PrimMonad m => Mutable v (PrimState m) a -> v a -> m () {-# INLINE basicUnsafeCopy #-}- basicUnsafeCopy dst src = do_copy 0+ basicUnsafeCopy !dst !src = do_copy 0 where- n = basicLength src+ !n = basicLength src do_copy i | i < n = do x <- basicUnsafeIndexM src i
Data/Vector/Generic/Mutable.hs view
@@ -15,33 +15,59 @@ -- * Class of mutable vector types MVector(..), - -- * Operations on mutable vectors- length, overlaps, new, newWith, read, write, swap, clear, set, copy, grow,+ -- * Accessors - slice, take, drop, init, tail,- unsafeSlice, unsafeInit, unsafeTail,+ -- ** Length information+ length, null, - -- * Unsafe operations- unsafeNew, unsafeNewWith, unsafeRead, unsafeWrite, unsafeSwap,- unsafeCopy, unsafeGrow,+ -- ** 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,+ -- * Internal operations unstream, unstreamR, munstream, munstreamR, transform, transformR, fill, fillR, unsafeAccum, accum, unsafeUpdate, update, reverse,- unstablePartition, unstablePartitionStream, partitionStream+ unstablePartition, unstablePartitionStream, partitionStream,++ -- * Deprecated operations+ newWith, unsafeNewWith ) where import qualified Data.Vector.Fusion.Stream as Stream import Data.Vector.Fusion.Stream ( Stream, MStream ) import qualified Data.Vector.Fusion.Stream.Monadic as MStream import Data.Vector.Fusion.Stream.Size+import Data.Vector.Fusion.Util ( delay_inline ) import Control.Monad.Primitive ( PrimMonad, PrimState ) -import Prelude hiding ( length, reverse, map, read,+import Prelude hiding ( length, null, replicate, reverse, map, read, take, drop, init, tail ) #include "vector.h"@@ -70,8 +96,8 @@ -- | Create a mutable vector of the given length and fill it with an -- initial value. This method should not be called directly, use- -- 'unsafeNewWith' instead.- basicUnsafeNewWith :: PrimMonad m => Int -> a -> m (v (PrimState m) a)+ -- 'replicate' instead.+ basicUnsafeReplicate :: PrimMonad m => Int -> a -> m (v (PrimState m) a) -- | Yield the element at the given position. This method should not be -- called directly, use 'unsafeRead' instead.@@ -101,6 +127,12 @@ basicUnsafeGrow :: PrimMonad m => v (PrimState m) a -> Int -> m (v (PrimState m) a) + -- | /DEPRECATED/ in favour of 'basicUnsafeReplicate'+ basicUnsafeNewWith :: PrimMonad m => Int -> a -> m (v (PrimState m) a)++ {-# INLINE basicUnsafeReplicate #-}+ basicUnsafeReplicate = basicUnsafeNewWith+ {-# INLINE basicUnsafeNewWith #-} basicUnsafeNewWith n x = do@@ -112,9 +144,9 @@ basicClear _ = return () {-# INLINE basicSet #-}- basicSet v x = do_set 0+ basicSet !v x = do_set 0 where- n = basicLength v+ !n = basicLength v do_set i | i < n = do basicUnsafeWrite v i x@@ -122,9 +154,9 @@ | otherwise = return () {-# INLINE basicUnsafeCopy #-}- basicUnsafeCopy dst src = do_copy 0+ basicUnsafeCopy !dst !src = do_copy 0 where- n = basicLength src+ !n = basicLength src do_copy i | i < n = do x <- basicUnsafeRead src i@@ -141,15 +173,12 @@ where n = basicLength v +{-# DEPRECATED basicUnsafeNewWith "define and use basicUnsafeReplicate instead" #-}+ -- ------------------ -- Internal functions -- ------------------ --- Check whether two vectors overlap.-overlaps :: MVector v a => v s a -> v s a -> Bool-{-# INLINE overlaps #-}-overlaps = basicOverlaps- unsafeAppend1 :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Int -> a -> m (v (PrimState m) a) {-# INLINE_INNER unsafeAppend1 #-}@@ -184,7 +213,7 @@ mstream :: (PrimMonad m, MVector v a) => v (PrimState m) a -> MStream m a {-# INLINE mstream #-}-mstream v = v `seq` (MStream.unfoldrM get 0 `MStream.sized` Exact n)+mstream v = v `seq` n `seq` (MStream.unfoldrM get 0 `MStream.sized` Exact n) where n = length v @@ -213,7 +242,7 @@ mstreamR :: (PrimMonad m, MVector v a) => v (PrimState m) a -> MStream m a {-# INLINE mstreamR #-}-mstreamR v = v `seq` (MStream.unfoldrM get n `MStream.sized` Exact n)+mstreamR v = v `seq` n `seq` (MStream.unfoldrM get n `MStream.sized` Exact n) where n = length v @@ -362,36 +391,96 @@ {-# INLINE null #-} null v = length v == 0 +-- Extracting subvectors+-- --------------------- --- Construction--- ------------+-- | Yield a part of the mutable vector without copying it.+slice :: MVector v a => Int -> Int -> v s a -> v s a+{-# INLINE slice #-}+slice i n v = BOUNDS_CHECK(checkSlice) "slice" i n (length v)+ $ unsafeSlice i n v +take :: MVector v a => Int -> v s a -> v s a+{-# INLINE take #-}+take n v = unsafeSlice 0 (min (max n 0) (length v)) v++drop :: MVector v a => Int -> v s a -> v s a+{-# INLINE drop #-}+drop n v = unsafeSlice (min m n') (max 0 (m - n')) v+ where+ n' = max n 0+ m = length v++init :: MVector v a => v s a -> v s a+{-# INLINE init #-}+init v = slice 0 (length v - 1) v++tail :: MVector v a => v s a -> v s a+{-# INLINE tail #-}+tail v = slice 1 (length v - 1) v++-- | Yield a part of the mutable vector without copying it. No bounds checks+-- are performed.+unsafeSlice :: MVector v a => Int -- ^ starting index+ -> Int -- ^ length of the slice+ -> v s a+ -> v s a+{-# INLINE unsafeSlice #-}+unsafeSlice i n v = UNSAFE_CHECK(checkSlice) "unsafeSlice" i n (length v)+ $ basicUnsafeSlice i n v++unsafeInit :: MVector v a => v s a -> v s a+{-# INLINE unsafeInit #-}+unsafeInit v = unsafeSlice 0 (length v - 1) v++unsafeTail :: MVector v a => v s a -> v s a+{-# INLINE unsafeTail #-}+unsafeTail v = unsafeSlice 1 (length v - 1) v++unsafeTake :: MVector v a => Int -> v s a -> v s a+{-# INLINE unsafeTake #-}+unsafeTake n v = unsafeSlice 0 n v++unsafeDrop :: MVector v a => Int -> v s a -> v s a+{-# INLINE unsafeDrop #-}+unsafeDrop n v = unsafeSlice n (length v - n) v++-- Overlapping+-- -----------++-- Check whether two vectors overlap.+overlaps :: MVector v a => v s a -> v s a -> Bool+{-# INLINE overlaps #-}+overlaps = basicOverlaps++-- Initialisation+-- --------------+ -- | Create a mutable vector of the given length. new :: (PrimMonad m, MVector v a) => Int -> m (v (PrimState m) a) {-# INLINE new #-} new n = BOUNDS_CHECK(checkLength) "new" n $ unsafeNew n --- | Create a mutable vector of the given length and fill it with an--- initial value.-newWith :: (PrimMonad m, MVector v a) => Int -> a -> m (v (PrimState m) a)-{-# INLINE newWith #-}-newWith n x = BOUNDS_CHECK(checkLength) "newWith" n- $ unsafeNewWith n x- -- | Create a mutable vector of the given length. The length is not checked. unsafeNew :: (PrimMonad m, MVector v a) => Int -> m (v (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew n = UNSAFE_CHECK(checkLength) "unsafeNew" n $ basicUnsafeNew n --- | Create a mutable vector of the given length and fill it with an--- initial value. The length is not checked.-unsafeNewWith :: (PrimMonad m, MVector v a) => Int -> a -> m (v (PrimState m) a)-{-# INLINE unsafeNewWith #-}-unsafeNewWith n x = UNSAFE_CHECK(checkLength) "unsafeNewWith" n- $ basicUnsafeNewWith n x+-- | Create a mutable vector of the given length (0 if the length is negative)+-- and fill it with an initial value.+replicate :: (PrimMonad m, MVector v a) => Int -> a -> m (v (PrimState m) a)+{-# INLINE replicate #-}+replicate n x = basicUnsafeReplicate (delay_inline max 0 n) x +-- | Create a copy of a mutable vector.+clone :: (PrimMonad m, MVector v a) => v (PrimState m) a -> m (v (PrimState m) a)+{-# INLINE clone #-}+clone v = do+ v' <- unsafeNew (length v)+ unsafeCopy v' v+ return v' -- Growing -- -------@@ -445,6 +534,15 @@ basicUnsafeCopy (basicUnsafeSlice by n v') v return v' +-- 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, MVector v a) => v (PrimState m) a -> m ()+{-# INLINE clear #-}+clear = basicClear+ -- Accessing individual elements -- ----------------------------- @@ -509,14 +607,8 @@ unsafeWrite v i x return y --- Block operations--- -------------------- | 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, MVector v a) => v (PrimState m) a -> m ()-{-# INLINE clear #-}-clear = basicClear+-- Filling and copying+-- ------------------- -- | Set all elements of the vector to the given value. set :: (PrimMonad m, MVector v a) => v (PrimState m) a -> a -> m ()@@ -546,60 +638,7 @@ (not (dst `overlaps` src)) $ (dst `seq` src `seq` basicUnsafeCopy dst src) --- Subvectors--- ---------- --- | Yield a part of the mutable vector without copying it.-slice :: MVector v a => Int -> Int -> v s a -> v s a-{-# INLINE slice #-}-slice i n v = BOUNDS_CHECK(checkSlice) "slice" i n (length v)- $ unsafeSlice i n v--take :: MVector v a => Int -> v s a -> v s a-{-# INLINE take #-}-take n v = unsafeSlice 0 (min (max n 0) (length v)) v--drop :: MVector v a => Int -> v s a -> v s a-{-# INLINE drop #-}-drop n v = unsafeSlice (min m n') (max 0 (m - n')) v- where- n' = max n 0- m = length v--init :: MVector v a => v s a -> v s a-{-# INLINE init #-}-init v = slice 0 (length v - 1) v--tail :: MVector v a => v s a -> v s a-{-# INLINE tail #-}-tail v = slice 1 (length v - 1) v---- | Yield a part of the mutable vector without copying it. No bounds checks--- are performed.-unsafeSlice :: MVector v a => Int -- ^ starting index- -> Int -- ^ length of the slice- -> v s a- -> v s a-{-# INLINE unsafeSlice #-}-unsafeSlice i n v = UNSAFE_CHECK(checkSlice) "unsafeSlice" i n (length v)- $ basicUnsafeSlice i n v--unsafeInit :: MVector v a => v s a -> v s a-{-# INLINE unsafeInit #-}-unsafeInit v = unsafeSlice 0 (length v - 1) v--unsafeTail :: MVector v a => v s a -> v s a-{-# INLINE unsafeTail #-}-unsafeTail v = unsafeSlice 1 (length v - 1) v--unsafeTake :: MVector v a => Int -> v s a -> v s a-{-# INLINE unsafeTake #-}-unsafeTake n v = unsafeSlice 0 n v--unsafeDrop :: MVector v a => Int -> v s a -> v s a-{-# INLINE unsafeDrop #-}-unsafeDrop n v = unsafeSlice n (length v - n) v- -- Permutations -- ------------ @@ -610,19 +649,23 @@ where {-# INLINE_INNER upd #-} upd (i,b) = do- a <- BOUNDS_CHECK(checkIndex) "accum" i (length v)+ a <- BOUNDS_CHECK(checkIndex) "accum" i n $ unsafeRead v i unsafeWrite v i (f a b) + !n = length v+ update :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Stream (Int, a) -> m () {-# INLINE update #-} update !v s = Stream.mapM_ upd s where {-# INLINE_INNER upd #-}- upd (i,b) = BOUNDS_CHECK(checkIndex) "update" i (length v)+ upd (i,b) = BOUNDS_CHECK(checkIndex) "update" i n $ unsafeWrite v i b + !n = length v+ unsafeAccum :: (PrimMonad m, MVector v a) => (a -> b -> a) -> v (PrimState m) a -> Stream (Int, b) -> m () {-# INLINE unsafeAccum #-}@@ -630,19 +673,23 @@ where {-# INLINE_INNER upd #-} upd (i,b) = do- a <- UNSAFE_CHECK(checkIndex) "accum" i (length v)+ a <- UNSAFE_CHECK(checkIndex) "accum" i n $ unsafeRead v i unsafeWrite v i (f a b) + !n = length v+ unsafeUpdate :: (PrimMonad m, MVector v a) => v (PrimState m) a -> Stream (Int, a) -> m () {-# INLINE unsafeUpdate #-} unsafeUpdate !v s = Stream.mapM_ upd s where {-# INLINE_INNER upd #-}- upd (i,b) = UNSAFE_CHECK(checkIndex) "accum" i (length v)+ upd (i,b) = UNSAFE_CHECK(checkIndex) "accum" i n $ unsafeWrite v i b + !n = length v+ reverse :: (PrimMonad m, MVector v a) => v (PrimState m) a -> m () {-# INLINE reverse #-} reverse !v = reverse_loop 0 (length v - 1)@@ -768,4 +815,19 @@ | otherwise = do v2' <- unsafeAppend1 v2 i2 x return (v1, i1, v2', i2+1)++-- Deprecated functions+-- --------------------++-- | /DEPRECATED/ Use 'replicate' instead+newWith :: (PrimMonad m, MVector v a) => Int -> a -> m (v (PrimState m) a)+{-# INLINE newWith #-}+newWith = replicate++-- | /DEPRECATED/ Use 'replicate' instead+unsafeNewWith :: (PrimMonad m, MVector v a) => Int -> a -> m (v (PrimState m) a)+{-# INLINE unsafeNewWith #-}+unsafeNewWith = replicate++{-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
Data/Vector/Generic/New.hs view
@@ -37,7 +37,7 @@ create :: (forall s. ST s (Mutable v s a)) -> New v a {-# INLINE create #-}-create = New+create p = New p run :: New v a -> ST s (Mutable v s a) {-# INLINE run #-}
Data/Vector/Mutable.hs view
@@ -16,20 +16,48 @@ -- * Mutable boxed vectors MVector(..), IOVector, STVector, - -- * Operations on mutable vectors- length, overlaps, slice, new, newWith, read, write, swap,- clear, set, copy, grow,+ -- * Accessors - -- * Unsafe operations- unsafeSlice, unsafeNew, unsafeNewWith, unsafeRead, unsafeWrite,- unsafeCopy, unsafeGrow+ -- ** 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,++ -- * Deprecated operations+ newWith, unsafeNewWith ) where import qualified Data.Vector.Generic.Mutable as G import Data.Primitive.Array import Control.Monad.Primitive -import Prelude hiding ( length, read )+import Prelude hiding ( length, null, replicate, reverse, map, read,+ take, drop, init, tail ) import Data.Typeable ( Typeable ) @@ -64,8 +92,8 @@ arr <- newArray n uninitialised return (MVector 0 n arr) - {-# INLINE basicUnsafeNewWith #-}- basicUnsafeNewWith n x+ {-# INLINE basicUnsafeReplicate #-}+ basicUnsafeReplicate n x = do arr <- newArray n x return (MVector 0 n arr)@@ -82,7 +110,43 @@ uninitialised :: a uninitialised = error "Data.Vector.Mutable: uninitialised element" +-- Length information+-- ------------------ +-- | Length of the mutable vector.+length :: MVector s a -> Int+{-# INLINE length #-}+length = G.length++-- | Check whether the vector is empty+null :: MVector s a -> Bool+{-# INLINE null #-}+null = G.null++-- Extracting subvectors+-- ---------------------++-- | Yield a part of the mutable vector without copying it.+slice :: Int -> Int -> MVector s a -> MVector s a+{-# INLINE slice #-}+slice = G.slice++take :: Int -> MVector s a -> MVector s a+{-# INLINE take #-}+take = G.take++drop :: Int -> MVector s a -> MVector s a+{-# INLINE drop #-}+drop = G.drop++init :: MVector s a -> MVector s a+{-# INLINE init #-}+init = G.init++tail :: MVector s a -> MVector s a+{-# INLINE tail #-}+tail = G.tail+ -- | Yield a part of the mutable vector without copying it. No bounds checks -- are performed. unsafeSlice :: Int -- ^ starting index@@ -92,39 +156,63 @@ {-# INLINE unsafeSlice #-} unsafeSlice = G.unsafeSlice +unsafeTake :: Int -> MVector s a -> MVector s a+{-# INLINE unsafeTake #-}+unsafeTake = G.unsafeTake++unsafeDrop :: Int -> MVector s a -> MVector s a+{-# INLINE unsafeDrop #-}+unsafeDrop = G.unsafeDrop++unsafeInit :: MVector s a -> MVector s a+{-# INLINE unsafeInit #-}+unsafeInit = G.unsafeInit++unsafeTail :: MVector s a -> MVector s a+{-# INLINE unsafeTail #-}+unsafeTail = G.unsafeTail++-- Overlapping+-- -----------++-- Check whether two vectors overlap.+overlaps :: MVector s a -> MVector s a -> Bool+{-# INLINE overlaps #-}+overlaps = G.overlaps++-- Initialisation+-- --------------++-- | Create a mutable vector of the given length.+new :: PrimMonad m => Int -> m (MVector (PrimState m) a)+{-# INLINE new #-}+new = G.new+ -- | Create a mutable vector of the given length. The length is not checked. unsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew --- | Create a mutable vector of the given length and fill it with an--- initial value. The length is not checked.-unsafeNewWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE unsafeNewWith #-}-unsafeNewWith = G.unsafeNewWith---- | Yield the element at the given position. No bounds checks are performed.-unsafeRead :: PrimMonad m => MVector (PrimState m) a -> Int -> m a-{-# INLINE unsafeRead #-}-unsafeRead = G.unsafeRead+-- | Create a mutable vector of the given length (0 if the length is negative)+-- and fill it with an initial value.+replicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE replicate #-}+replicate = G.replicate --- | Replace the element at the given position. No bounds checks are performed.-unsafeWrite :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()-{-# INLINE unsafeWrite #-}-unsafeWrite = G.unsafeWrite+-- | Create a copy of a mutable vector.+clone :: PrimMonad m => MVector (PrimState m) a -> m (MVector (PrimState m) a)+{-# INLINE clone #-}+clone = G.clone --- | Swap the elements at the given positions. No bounds checks are performed.-unsafeSwap :: PrimMonad m => MVector (PrimState m) a -> Int -> Int -> m ()-{-# INLINE unsafeSwap #-}-unsafeSwap = G.unsafeSwap+-- Growing+-- ------- --- | Copy a vector. The two vectors must have the same length and may not--- overlap. This is not checked.-unsafeCopy :: PrimMonad m => MVector (PrimState m) a -- ^ target- -> MVector (PrimState m) a -- ^ source- -> m ()-{-# INLINE unsafeCopy #-}-unsafeCopy = G.unsafeCopy+-- | Grow a vector by the given number of elements. The number must be+-- positive.+grow :: PrimMonad m+ => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)+{-# INLINE grow #-}+grow = G.grow -- | Grow a vector by the given number of elements. The number must be -- positive but this is not checked.@@ -133,31 +221,17 @@ {-# INLINE unsafeGrow #-} unsafeGrow = G.unsafeGrow --- | Length of the mutable vector.-length :: MVector s a -> Int-{-# INLINE length #-}-length = G.length---- Check whether two vectors overlap.-overlaps :: MVector s a -> MVector s a -> Bool-{-# INLINE overlaps #-}-overlaps = G.overlaps---- | Yield a part of the mutable vector without copying it.-slice :: Int -> Int -> MVector s a -> MVector s a-{-# INLINE slice #-}-slice = G.slice+-- Restricting memory usage+-- ------------------------ --- | Create a mutable vector of the given length.-new :: PrimMonad m => Int -> m (MVector (PrimState m) a)-{-# INLINE new #-}-new = G.new+-- | 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 => MVector (PrimState m) a -> m ()+{-# INLINE clear #-}+clear = G.clear --- | Create a mutable vector of the given length and fill it with an--- initial value.-newWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE newWith #-}-newWith = G.newWith+-- Accessing individual elements+-- ----------------------------- -- | Yield the element at the given position. read :: PrimMonad m => MVector (PrimState m) a -> Int -> m a@@ -174,12 +248,25 @@ {-# INLINE swap #-} swap = G.swap --- | 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 => MVector (PrimState m) a -> m ()-{-# INLINE clear #-}-clear = G.clear +-- | Yield the element at the given position. No bounds checks are performed.+unsafeRead :: PrimMonad m => MVector (PrimState m) a -> Int -> m a+{-# INLINE unsafeRead #-}+unsafeRead = G.unsafeRead++-- | Replace the element at the given position. No bounds checks are performed.+unsafeWrite :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()+{-# INLINE unsafeWrite #-}+unsafeWrite = G.unsafeWrite++-- | Swap the elements at the given positions. No bounds checks are performed.+unsafeSwap :: PrimMonad m => MVector (PrimState m) a -> Int -> Int -> m ()+{-# INLINE unsafeSwap #-}+unsafeSwap = G.unsafeSwap++-- Filling and copying+-- -------------------+ -- | Set all elements of the vector to the given value. set :: PrimMonad m => MVector (PrimState m) a -> a -> m () {-# INLINE set #-}@@ -192,10 +279,26 @@ {-# INLINE copy #-} copy = G.copy --- | Grow a vector by the given number of elements. The number must be--- positive.-grow :: PrimMonad m- => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)-{-# INLINE grow #-}-grow = G.grow+-- | Copy a vector. The two vectors must have the same length and may not+-- overlap. This is not checked.+unsafeCopy :: PrimMonad m => MVector (PrimState m) a -- ^ target+ -> MVector (PrimState m) a -- ^ source+ -> m ()+{-# INLINE unsafeCopy #-}+unsafeCopy = G.unsafeCopy++-- Deprecated functions+-- --------------------++-- | /DEPRECATED/ Use 'replicate' instead+newWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE newWith #-}+newWith = G.replicate++-- | /DEPRECATED/ Use 'replicate' instead+unsafeNewWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE unsafeNewWith #-}+unsafeNewWith = G.replicate++{-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
Data/Vector/Primitive.hs view
@@ -25,7 +25,7 @@ length, null, -- ** Indexing- (!), head, last,+ (!), (!?), head, last, unsafeIndex, unsafeHead, unsafeLast, -- ** Monadic indexing@@ -51,7 +51,7 @@ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo, -- ** Concatenation- cons, snoc, (++),+ cons, snoc, (++), concat, -- ** Restricting memory usage force,@@ -125,8 +125,11 @@ -- ** Lists toList, fromList, fromListN, + -- ** Other vector types+ G.convert,+ -- ** Mutable vectors- copy, unsafeCopy+ freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy ) where import qualified Data.Vector.Generic as G@@ -140,7 +143,7 @@ import Control.Monad.Primitive import Prelude hiding ( length, null,- replicate, (++),+ replicate, (++), concat, head, last, init, tail, take, drop, reverse, map, concatMap,@@ -158,6 +161,8 @@ import Data.Typeable ( Typeable ) import Data.Data ( Data(..) ) +import Data.Monoid ( Monoid(..) )+ -- | Unboxed vectors of primitive types data Vector a = Vector {-# UNPACK #-} !Int {-# UNPACK #-} !Int@@ -178,10 +183,14 @@ type instance G.Mutable Vector = MVector instance Prim a => G.Vector Vector a where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MVector i n marr)+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MVector i n marr) = Vector i n `liftM` unsafeFreezeByteArray marr + {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (Vector i n arr)+ = MVector i n `liftM` unsafeThawByteArray arr+ {-# INLINE basicLength #-} basicLength (Vector _ n _) = n @@ -225,6 +234,16 @@ {-# INLINE (>=) #-} xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT +instance Prim a => Monoid (Vector a) where+ {-# INLINE mempty #-}+ mempty = empty++ {-# INLINE mappend #-}+ mappend = (++)++ {-# INLINE mconcat #-}+ mconcat = concat+ -- Length -- ------ @@ -246,6 +265,11 @@ {-# INLINE (!) #-} (!) = (G.!) +-- | O(1) Safe indexing+(!?) :: Prim a => Vector a -> Int -> Maybe a+{-# INLINE (!?) #-}+(!?) = (G.!?)+ -- | /O(1)/ First element head :: Prim a => Vector a -> a {-# INLINE head #-}@@ -497,6 +521,11 @@ {-# INLINE (++) #-} (++) = (G.++) +-- | /O(n)/ Concatenate all vectors in the list+concat :: Prim a => [Vector a] -> Vector a+{-# INLINE concat #-}+concat = G.concat+ -- Monadic initialisation -- ---------------------- @@ -647,7 +676,7 @@ -- @ modify :: Prim a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a {-# INLINE modify #-}-modify = G.modify+modify p = G.modify p -- Mapping -- -------@@ -1191,15 +1220,37 @@ -- Conversions - Mutable vectors -- ----------------------------- +-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without+-- copying. The mutable vector may not be used after this operation.+unsafeFreeze :: (Prim a, PrimMonad m) => MVector (PrimState m) a -> m (Vector a)+{-# INLINE unsafeFreeze #-}+unsafeFreeze = G.unsafeFreeze++-- | /O(1)/ Unsafely convert an immutable vector to a mutable one without+-- copying. The immutable vector may not be used after this operation.+unsafeThaw :: (Prim a, PrimMonad m) => Vector a -> m (MVector (PrimState m) a)+{-# INLINE unsafeThaw #-}+unsafeThaw = G.unsafeThaw++-- | /O(n)/ Yield a mutable copy of the immutable vector.+thaw :: (Prim a, PrimMonad m) => Vector a -> m (MVector (PrimState m) a)+{-# INLINE thaw #-}+thaw = G.thaw++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: (Prim a, PrimMonad m) => MVector (PrimState m) a -> m (Vector a)+{-# INLINE freeze #-}+freeze = G.freeze+ -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length.+-- have the same length. This is not checked. unsafeCopy :: (Prim a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length. This is not checked.+-- have the same length. copy :: (Prim a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy
Data/Vector/Primitive/Mutable.hs view
@@ -16,13 +16,40 @@ -- * Mutable vectors of primitive types MVector(..), IOVector, STVector, Prim, - -- * Operations on mutable vectors- length, overlaps, slice, new, newWith, read, write, swap,- clear, set, copy, grow,+ -- * Accessors - -- * Unsafe operations- unsafeSlice, unsafeNew, unsafeNewWith, unsafeRead, unsafeWrite, unsafeSwap,- unsafeCopy, unsafeGrow+ -- ** 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,++ -- * Deprecated operations+ newWith, unsafeNewWith ) where import qualified Data.Vector.Generic.Mutable as G@@ -31,7 +58,8 @@ import Control.Monad.Primitive import Control.Monad ( liftM ) -import Prelude hiding( length, read )+import Prelude hiding ( length, null, replicate, reverse, map, read,+ take, drop, init, tail ) import Data.Typeable ( Typeable ) @@ -74,52 +102,111 @@ where sz = sizeOf (undefined :: a) +-- Length information+-- ------------------++-- | Length of the mutable vector.+length :: Prim a => MVector s a -> Int+{-# INLINE length #-}+length = G.length++-- | Check whether the vector is empty+null :: Prim a => MVector s a -> Bool+{-# INLINE null #-}+null = G.null++-- Extracting subvectors+-- ---------------------++-- | Yield a part of the mutable vector without copying it.+slice :: Prim a => Int -> Int -> MVector s a -> MVector s a+{-# INLINE slice #-}+slice = G.slice++take :: Prim a => Int -> MVector s a -> MVector s a+{-# INLINE take #-}+take = G.take++drop :: Prim a => Int -> MVector s a -> MVector s a+{-# INLINE drop #-}+drop = G.drop++init :: Prim a => MVector s a -> MVector s a+{-# INLINE init #-}+init = G.init++tail :: Prim a => MVector s a -> MVector s a+{-# INLINE tail #-}+tail = G.tail+ -- | Yield a part of the mutable vector without copying it. No bounds checks -- are performed.-unsafeSlice :: Prim a => Int -- ^ starting index- -> Int -- ^ length of the slice- -> MVector s a - -> MVector s a+unsafeSlice :: Prim a+ => Int -- ^ starting index+ -> Int -- ^ length of the slice+ -> MVector s a+ -> MVector s a {-# INLINE unsafeSlice #-} unsafeSlice = G.unsafeSlice +unsafeTake :: Prim a => Int -> MVector s a -> MVector s a+{-# INLINE unsafeTake #-}+unsafeTake = G.unsafeTake +unsafeDrop :: Prim a => Int -> MVector s a -> MVector s a+{-# INLINE unsafeDrop #-}+unsafeDrop = G.unsafeDrop++unsafeInit :: Prim a => MVector s a -> MVector s a+{-# INLINE unsafeInit #-}+unsafeInit = G.unsafeInit++unsafeTail :: Prim a => MVector s a -> MVector s a+{-# INLINE unsafeTail #-}+unsafeTail = G.unsafeTail++-- Overlapping+-- -----------++-- Check whether two vectors overlap.+overlaps :: Prim a => MVector s a -> MVector s a -> Bool+{-# INLINE overlaps #-}+overlaps = G.overlaps++-- Initialisation+-- --------------++-- | Create a mutable vector of the given length.+new :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)+{-# INLINE new #-}+new = G.new+ -- | Create a mutable vector of the given length. The length is not checked. unsafeNew :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew --- | Create a mutable vector of the given length and fill it with an--- initial value. The length is not checked.-unsafeNewWith :: (PrimMonad m, Prim a)- => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE unsafeNewWith #-}-unsafeNewWith = G.unsafeNewWith---- | Yield the element at the given position. No bounds checks are performed.-unsafeRead :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a-{-# INLINE unsafeRead #-}-unsafeRead = G.unsafeRead+-- | Create a mutable vector of the given length (0 if the length is negative)+-- and fill it with an initial value.+replicate :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE replicate #-}+replicate = G.replicate --- | Replace the element at the given position. No bounds checks are performed.-unsafeWrite :: (PrimMonad m, Prim a)- => MVector (PrimState m) a -> Int -> a -> m ()-{-# INLINE unsafeWrite #-}-unsafeWrite = G.unsafeWrite+-- | Create a copy of a mutable vector.+clone :: (PrimMonad m, Prim a)+ => MVector (PrimState m) a -> m (MVector (PrimState m) a)+{-# INLINE clone #-}+clone = G.clone --- | Swap the elements at the given positions. No bounds checks are performed.-unsafeSwap :: (PrimMonad m, Prim a)- => MVector (PrimState m) a -> Int -> Int -> m ()-{-# INLINE unsafeSwap #-}-unsafeSwap = G.unsafeSwap+-- Growing+-- ------- --- | Copy a vector. The two vectors must have the same length and may not--- overlap. This is not checked.-unsafeCopy :: (PrimMonad m, Prim a) => MVector (PrimState m) a -- ^ target- -> MVector (PrimState m) a -- ^ source- -> m ()-{-# INLINE unsafeCopy #-}-unsafeCopy = G.unsafeCopy+-- | Grow a vector by the given number of elements. The number must be+-- positive.+grow :: (PrimMonad m, Prim a) + => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)+{-# INLINE grow #-}+grow = G.grow -- | Grow a vector by the given number of elements. The number must be -- positive but this is not checked.@@ -128,31 +215,17 @@ {-# INLINE unsafeGrow #-} unsafeGrow = G.unsafeGrow --- | Length of the mutable vector.-length :: Prim a => MVector s a -> Int-{-# INLINE length #-}-length = G.length---- Check whether two vectors overlap.-overlaps :: Prim a => MVector s a -> MVector s a -> Bool-{-# INLINE overlaps #-}-overlaps = G.overlaps---- | Yield a part of the mutable vector without copying it.-slice :: Prim a => Int -> Int -> MVector s a -> MVector s a-{-# INLINE slice #-}-slice = G.slice+-- Restricting memory usage+-- ------------------------ --- | Create a mutable vector of the given length.-new :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)-{-# INLINE new #-}-new = G.new+-- | 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, Prim a) => MVector (PrimState m) a -> m ()+{-# INLINE clear #-}+clear = G.clear --- | Create a mutable vector of the given length and fill it with an--- initial value.-newWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE newWith #-}-newWith = G.newWith+-- Accessing individual elements+-- ----------------------------- -- | Yield the element at the given position. read :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a@@ -165,17 +238,31 @@ write = G.write -- | Swap the elements at the given positions.-swap :: (PrimMonad m, Prim a)- => MVector (PrimState m) a -> Int -> Int -> m ()+swap :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m () {-# INLINE swap #-} swap = G.swap --- | 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, Prim a) => MVector (PrimState m) a -> m ()-{-# INLINE clear #-}-clear = G.clear +-- | Yield the element at the given position. No bounds checks are performed.+unsafeRead :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a+{-# INLINE unsafeRead #-}+unsafeRead = G.unsafeRead++-- | Replace the element at the given position. No bounds checks are performed.+unsafeWrite+ :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()+{-# INLINE unsafeWrite #-}+unsafeWrite = G.unsafeWrite++-- | Swap the elements at the given positions. No bounds checks are performed.+unsafeSwap+ :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()+{-# INLINE unsafeSwap #-}+unsafeSwap = G.unsafeSwap++-- Filling and copying+-- -------------------+ -- | Set all elements of the vector to the given value. set :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> a -> m () {-# INLINE set #-}@@ -183,15 +270,32 @@ -- | Copy a vector. The two vectors must have the same length and may not -- overlap.-copy :: (PrimMonad m, Prim a)- => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()+copy :: (PrimMonad m, Prim a) + => MVector (PrimState m) a -> MVector (PrimState m) a -> m () {-# INLINE copy #-} copy = G.copy --- | Grow a vector by the given number of elements. The number must be--- positive.-grow :: (PrimMonad m, Prim a)- => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)-{-# INLINE grow #-}-grow = G.grow+-- | Copy a vector. The two vectors must have the same length and may not+-- overlap. This is not checked.+unsafeCopy :: (PrimMonad m, Prim a)+ => MVector (PrimState m) a -- ^ target+ -> MVector (PrimState m) a -- ^ source+ -> m ()+{-# INLINE unsafeCopy #-}+unsafeCopy = G.unsafeCopy++-- Deprecated functions+-- --------------------++-- | /DEPRECATED/ Use 'replicate' instead+newWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE newWith #-}+newWith = G.replicate++-- | /DEPRECATED/ Use 'replicate' instead+unsafeNewWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE unsafeNewWith #-}+unsafeNewWith = G.replicate++{-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
Data/Vector/Storable.hs view
@@ -22,7 +22,7 @@ length, null, -- ** Indexing- (!), head, last,+ (!), (!?), head, last, unsafeIndex, unsafeHead, unsafeLast, -- ** Monadic indexing@@ -48,7 +48,7 @@ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo, -- ** Concatenation- cons, snoc, (++),+ cons, snoc, (++), concat, -- ** Restricting memory usage force,@@ -122,8 +122,11 @@ -- ** Lists toList, fromList, fromListN, + -- ** Other vector types+ G.convert,+ -- ** Mutable vectors- copy, unsafeCopy,+ freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy, -- * Raw pointers unsafeFromForeignPtr, unsafeToForeignPtr, unsafeWith@@ -143,7 +146,7 @@ import Control.Monad.Primitive import Prelude hiding ( length, null,- replicate, (++),+ replicate, (++), concat, head, last, init, tail, take, drop, reverse, map, concatMap,@@ -161,6 +164,8 @@ import Data.Typeable ( Typeable ) import Data.Data ( Data(..) ) +import Data.Monoid ( Monoid(..) )+ #include "vector.h" -- | 'Storable'-based vectors@@ -185,9 +190,12 @@ type instance G.Mutable Vector = MVector instance Storable a => G.Vector Vector a where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MVector p n fp) = return $ Vector p n fp+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MVector p n fp) = return $ Vector p n fp + {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (Vector p n fp) = return $ MVector p n fp+ {-# INLINE basicLength #-} basicLength (Vector _ n _) = n @@ -235,27 +243,15 @@ {-# INLINE (>=) #-} xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT -{--eq_memcmp :: forall a. Storable a => Vector a -> Vector a -> Bool-{-# INLINE_STREAM eq_memcmp #-}-eq_memcmp (Vector i m p) (Vector j n q)- = m == n && inlinePerformIO- (withForeignPtr p $ \p' ->- withForeignPtr q $ \q' ->- return $- memcmp (p' `plusPtr` i) (q' `plusPtr` j)- (fromIntegral $ sizeOf (undefined :: a) * m) == 0)--foreign import ccall unsafe "string.h memcmp" memcmp- :: Ptr a -> Ptr a -> CSize -> CInt--{-# RULES+instance Storable a => Monoid (Vector a) where+ {-# INLINE mempty #-}+ mempty = empty -"(==) [Vector.Storable Int]"- G.eq = eq_memcmp :: Vector Int -> Vector Int -> Bool- #-}--}+ {-# INLINE mappend #-}+ mappend = (++) + {-# INLINE mconcat #-}+ mconcat = concat -- Length -- ------@@ -278,6 +274,11 @@ {-# INLINE (!) #-} (!) = (G.!) +-- | O(1) Safe indexing+(!?) :: Storable a => Vector a -> Int -> Maybe a+{-# INLINE (!?) #-}+(!?) = (G.!?)+ -- | /O(1)/ First element head :: Storable a => Vector a -> a {-# INLINE head #-}@@ -529,6 +530,11 @@ {-# INLINE (++) #-} (++) = (G.++) +-- | /O(n)/ Concatenate all vectors in the list+concat :: Storable a => [Vector a] -> Vector a+{-# INLINE concat #-}+concat = G.concat+ -- Monadic initialisation -- ---------------------- @@ -679,7 +685,7 @@ -- @ modify :: Storable a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a {-# INLINE modify #-}-modify = G.modify+modify p = G.modify p -- Mapping -- -------@@ -1233,15 +1239,39 @@ -- Conversions - Mutable vectors -- ----------------------------- +-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without+-- copying. The mutable vector may not be used after this operation.+unsafeFreeze+ :: (Storable a, PrimMonad m) => MVector (PrimState m) a -> m (Vector a)+{-# INLINE unsafeFreeze #-}+unsafeFreeze = G.unsafeFreeze++-- | /O(1)/ Unsafely convert an immutable vector to a mutable one without+-- copying. The immutable vector may not be used after this operation.+unsafeThaw+ :: (Storable a, PrimMonad m) => Vector a -> m (MVector (PrimState m) a)+{-# INLINE unsafeThaw #-}+unsafeThaw = G.unsafeThaw++-- | /O(n)/ Yield a mutable copy of the immutable vector.+thaw :: (Storable a, PrimMonad m) => Vector a -> m (MVector (PrimState m) a)+{-# INLINE thaw #-}+thaw = G.thaw++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: (Storable a, PrimMonad m) => MVector (PrimState m) a -> m (Vector a)+{-# INLINE freeze #-}+freeze = G.freeze+ -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length.+-- have the same length. This is not checked. unsafeCopy :: (Storable a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length. This is not checked.+-- have the same length. copy :: (Storable a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy
Data/Vector/Storable/Internal.hs view
@@ -30,7 +30,7 @@ ptrToOffset :: Storable a => ForeignPtr a -> Ptr a -> Int {-# INLINE ptrToOffset #-} ptrToOffset fp q = unsafeInlineIO- $ withForeignPtr fp $ \p -> return (distance p q)+ $ withForeignPtr fp $ \p -> return (distance q p) offsetToPtr :: Storable a => ForeignPtr a -> Int -> Ptr a {-# INLINE offsetToPtr #-}
Data/Vector/Storable/Mutable.hs view
@@ -16,16 +16,43 @@ -- * Mutable vectors of 'Storable' types MVector(..), IOVector, STVector, Storable, - -- * Operations on mutable vectors- length, overlaps, slice, new, newWith, read, write, swap,- clear, set, copy, grow,+ -- * Accessors - -- * Unsafe operations- unsafeSlice, unsafeNew, unsafeNewWith, unsafeRead, unsafeWrite, unsafeSwap,- unsafeCopy, unsafeGrow,+ -- ** Length information+ length, null, - -- * Accessing the underlying memory- unsafeFromForeignPtr, unsafeToForeignPtr, unsafeWith+ -- ** 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,++ -- * Raw pointers+ unsafeFromForeignPtr, unsafeToForeignPtr, unsafeWith,++ -- * Deprecated operations+ newWith, unsafeNewWith ) where import qualified Data.Vector.Generic.Mutable as G@@ -39,7 +66,8 @@ import Control.Monad.Primitive -import Prelude hiding( length, read )+import Prelude hiding ( length, null, replicate, reverse, map, read,+ take, drop, init, tail ) import Data.Typeable ( Typeable ) @@ -92,78 +120,111 @@ withForeignPtr fq $ \_ -> copyArray p q n --- | Create a mutable vector from a 'ForeignPtr' with an offset and a length.--- Modifying data through the 'ForeignPtr' afterwards is unsafe if the vector--- could have been frozen before the modification.-unsafeFromForeignPtr :: Storable a- => ForeignPtr a -- ^ pointer- -> Int -- ^ offset- -> Int -- ^ length- -> MVector s a-{-# INLINE unsafeFromForeignPtr #-}-unsafeFromForeignPtr fp i n = MVector (offsetToPtr fp i) n fp+-- Length information+-- ------------------ --- | Yield the underlying 'ForeignPtr' together with the offset to the data--- and its length. Modifying the data through the 'ForeignPtr' is--- unsafe if the vector could have frozen before the modification.-unsafeToForeignPtr :: Storable a => MVector s a -> (ForeignPtr a, Int, Int)-{-# INLINE unsafeToForeignPtr #-}-unsafeToForeignPtr (MVector p n fp) = (fp, ptrToOffset fp p, n)+-- | Length of the mutable vector.+length :: Storable a => MVector s a -> Int+{-# INLINE length #-}+length = G.length --- | Pass a pointer to the vector's data to the IO action. Modifying data--- through the pointer is unsafe if the vector could have been frozen before--- the modification.-unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b-{-# INLINE unsafeWith #-}-unsafeWith (MVector p n fp) m = withForeignPtr fp $ \_ -> m p+-- | Check whether the vector is empty+null :: Storable a => MVector s a -> Bool+{-# INLINE null #-}+null = G.null +-- Extracting subvectors+-- ---------------------++-- | Yield a part of the mutable vector without copying it.+slice :: Storable a => Int -> Int -> MVector s a -> MVector s a+{-# INLINE slice #-}+slice = G.slice++take :: Storable a => Int -> MVector s a -> MVector s a+{-# INLINE take #-}+take = G.take++drop :: Storable a => Int -> MVector s a -> MVector s a+{-# INLINE drop #-}+drop = G.drop++init :: Storable a => MVector s a -> MVector s a+{-# INLINE init #-}+init = G.init++tail :: Storable a => MVector s a -> MVector s a+{-# INLINE tail #-}+tail = G.tail+ -- | Yield a part of the mutable vector without copying it. No bounds checks -- are performed.-unsafeSlice :: Storable a => Int -- ^ starting index- -> Int -- ^ length of the slice- -> MVector s a- -> MVector s a+unsafeSlice :: Storable a+ => Int -- ^ starting index+ -> Int -- ^ length of the slice+ -> MVector s a+ -> MVector s a {-# INLINE unsafeSlice #-} unsafeSlice = G.unsafeSlice +unsafeTake :: Storable a => Int -> MVector s a -> MVector s a+{-# INLINE unsafeTake #-}+unsafeTake = G.unsafeTake++unsafeDrop :: Storable a => Int -> MVector s a -> MVector s a+{-# INLINE unsafeDrop #-}+unsafeDrop = G.unsafeDrop++unsafeInit :: Storable a => MVector s a -> MVector s a+{-# INLINE unsafeInit #-}+unsafeInit = G.unsafeInit++unsafeTail :: Storable a => MVector s a -> MVector s a+{-# INLINE unsafeTail #-}+unsafeTail = G.unsafeTail++-- Overlapping+-- -----------++-- Check whether two vectors overlap.+overlaps :: Storable a => MVector s a -> MVector s a -> Bool+{-# INLINE overlaps #-}+overlaps = G.overlaps++-- Initialisation+-- --------------++-- | Create a mutable vector of the given length.+new :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)+{-# INLINE new #-}+new = G.new+ -- | Create a mutable vector of the given length. The length is not checked. unsafeNew :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew --- | Create a mutable vector of the given length and fill it with an--- initial value. The length is not checked.-unsafeNewWith :: (PrimMonad m, Storable a)- => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE unsafeNewWith #-}-unsafeNewWith = G.unsafeNewWith---- | Yield the element at the given position. No bounds checks are performed.-unsafeRead :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -> Int -> m a-{-# INLINE unsafeRead #-}-unsafeRead = G.unsafeRead+-- | Create a mutable vector of the given length (0 if the length is negative)+-- and fill it with an initial value.+replicate :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE replicate #-}+replicate = G.replicate --- | Replace the element at the given position. No bounds checks are performed.-unsafeWrite :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -> Int -> a -> m ()-{-# INLINE unsafeWrite #-}-unsafeWrite = G.unsafeWrite+-- | Create a copy of a mutable vector.+clone :: (PrimMonad m, Storable a)+ => MVector (PrimState m) a -> m (MVector (PrimState m) a)+{-# INLINE clone #-}+clone = G.clone --- | Swap the elements at the given positions. No bounds checks are performed.-unsafeSwap :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -> Int -> Int -> m ()-{-# INLINE unsafeSwap #-}-unsafeSwap = G.unsafeSwap+-- Growing+-- ------- --- | Copy a vector. The two vectors must have the same length and may not--- overlap. This is not checked.-unsafeCopy :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -- ^ target- -> MVector (PrimState m) a -- ^ source- -> m ()-{-# INLINE unsafeCopy #-}-unsafeCopy = G.unsafeCopy+-- | Grow a vector by the given number of elements. The number must be+-- positive.+grow :: (PrimMonad m, Storable a) + => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)+{-# INLINE grow #-}+grow = G.grow -- | Grow a vector by the given number of elements. The number must be -- positive but this is not checked.@@ -172,31 +233,17 @@ {-# INLINE unsafeGrow #-} unsafeGrow = G.unsafeGrow --- | Length of the mutable vector.-length :: Storable a => MVector s a -> Int-{-# INLINE length #-}-length = G.length---- Check whether two vectors overlap.-overlaps :: Storable a => MVector s a -> MVector s a -> Bool-{-# INLINE overlaps #-}-overlaps = G.overlaps---- | Yield a part of the mutable vector without copying it.-slice :: Storable a => Int -> Int -> MVector s a -> MVector s a-{-# INLINE slice #-}-slice = G.slice+-- Restricting memory usage+-- ------------------------ --- | Create a mutable vector of the given length.-new :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)-{-# INLINE new #-}-new = G.new+-- | 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, Storable a) => MVector (PrimState m) a -> m ()+{-# INLINE clear #-}+clear = G.clear --- | Create a mutable vector of the given length and fill it with an--- initial value.-newWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE newWith #-}-newWith = G.newWith+-- Accessing individual elements+-- ----------------------------- -- | Yield the element at the given position. read :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a@@ -204,23 +251,38 @@ read = G.read -- | Replace the element at the given position.-write :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -> Int -> a -> m ()+write+ :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m () {-# INLINE write #-} write = G.write -- | Swap the elements at the given positions.-swap :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -> Int -> Int -> m ()+swap+ :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m () {-# INLINE swap #-} swap = G.swap --- | 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, Storable a) => MVector (PrimState m) a -> m ()-{-# INLINE clear #-}-clear = G.clear +-- | Yield the element at the given position. No bounds checks are performed.+unsafeRead :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a+{-# INLINE unsafeRead #-}+unsafeRead = G.unsafeRead++-- | Replace the element at the given position. No bounds checks are performed.+unsafeWrite+ :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m ()+{-# INLINE unsafeWrite #-}+unsafeWrite = G.unsafeWrite++-- | Swap the elements at the given positions. No bounds checks are performed.+unsafeSwap+ :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m ()+{-# INLINE unsafeSwap #-}+unsafeSwap = G.unsafeSwap++-- Filling and copying+-- -------------------+ -- | Set all elements of the vector to the given value. set :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> a -> m () {-# INLINE set #-}@@ -228,15 +290,60 @@ -- | Copy a vector. The two vectors must have the same length and may not -- overlap.-copy :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()+copy :: (PrimMonad m, Storable a) + => MVector (PrimState m) a -> MVector (PrimState m) a -> m () {-# INLINE copy #-} copy = G.copy --- | Grow a vector by the given number of elements. The number must be--- positive.-grow :: (PrimMonad m, Storable a)- => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)-{-# INLINE grow #-}-grow = G.grow+-- | Copy a vector. The two vectors must have the same length and may not+-- overlap. This is not checked.+unsafeCopy :: (PrimMonad m, Storable a)+ => MVector (PrimState m) a -- ^ target+ -> MVector (PrimState m) a -- ^ source+ -> m ()+{-# INLINE unsafeCopy #-}+unsafeCopy = G.unsafeCopy++-- Raw pointers+-- ------------++-- | Create a mutable vector from a 'ForeignPtr' with an offset and a length.+-- Modifying data through the 'ForeignPtr' afterwards is unsafe if the vector+-- could have been frozen before the modification.+unsafeFromForeignPtr :: Storable a+ => ForeignPtr a -- ^ pointer+ -> Int -- ^ offset+ -> Int -- ^ length+ -> MVector s a+{-# INLINE unsafeFromForeignPtr #-}+unsafeFromForeignPtr fp i n = MVector (offsetToPtr fp i) n fp++-- | Yield the underlying 'ForeignPtr' together with the offset to the data+-- and its length. Modifying the data through the 'ForeignPtr' is+-- unsafe if the vector could have frozen before the modification.+unsafeToForeignPtr :: Storable a => MVector s a -> (ForeignPtr a, Int, Int)+{-# INLINE unsafeToForeignPtr #-}+unsafeToForeignPtr (MVector p n fp) = (fp, ptrToOffset fp p, n)++-- | Pass a pointer to the vector's data to the IO action. Modifying data+-- through the pointer is unsafe if the vector could have been frozen before+-- the modification.+unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b+{-# INLINE unsafeWith #-}+unsafeWith (MVector p n fp) m = withForeignPtr fp $ \_ -> m p++-- Deprecated functions+-- --------------------++-- | /DEPRECATED/ Use 'replicate' instead+newWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE newWith #-}+newWith = G.replicate++-- | /DEPRECATED/ Use 'replicate' instead+unsafeNewWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE unsafeNewWith #-}+unsafeNewWith = G.replicate++{-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
Data/Vector/Unboxed.hs view
@@ -45,7 +45,7 @@ length, null, -- ** Indexing- (!), head, last,+ (!), (!?), head, last, unsafeIndex, unsafeHead, unsafeLast, -- ** Monadic indexing@@ -71,7 +71,7 @@ enumFromN, enumFromStepN, enumFromTo, enumFromThenTo, -- ** Concatenation- cons, snoc, (++),+ cons, snoc, (++), concat, -- ** Restricting memory usage force,@@ -149,8 +149,11 @@ -- ** Lists toList, fromList, fromListN, + -- ** Other vector types+ G.convert,+ -- ** Mutable vectors- copy, unsafeCopy+ freeze, thaw, copy, unsafeFreeze, unsafeThaw, unsafeCopy ) where import Data.Vector.Unboxed.Base@@ -161,7 +164,7 @@ import Control.Monad.Primitive import Prelude hiding ( length, null,- replicate, (++),+ replicate, (++), concat, head, last, init, tail, take, drop, reverse, map, concatMap,@@ -175,6 +178,8 @@ mapM, mapM_ ) import qualified Prelude +import Data.Monoid ( Monoid(..) )+ #include "vector.h" -- See http://trac.haskell.org/vector/ticket/12@@ -202,6 +207,16 @@ {-# INLINE (>=) #-} xs >= ys = Stream.cmp (G.stream xs) (G.stream ys) /= LT +instance Unbox a => Monoid (Vector a) where+ {-# INLINE mempty #-}+ mempty = empty++ {-# INLINE mappend #-}+ mappend = (++)++ {-# INLINE mconcat #-}+ mconcat = concat+ instance (Show a, Unbox a) => Show (Vector a) where show = (Prelude.++ " :: Data.Vector.Unboxed.Vector") . ("fromList " Prelude.++) . show . toList @@ -226,6 +241,11 @@ {-# INLINE (!) #-} (!) = (G.!) +-- | O(1) Safe indexing+(!?) :: Unbox a => Vector a -> Int -> Maybe a+{-# INLINE (!?) #-}+(!?) = (G.!?)+ -- | /O(1)/ First element head :: Unbox a => Vector a -> a {-# INLINE head #-}@@ -476,6 +496,11 @@ {-# INLINE (++) #-} (++) = (G.++) +-- | /O(n)/ Concatenate all vectors in the list+concat :: Unbox a => [Vector a] -> Vector a+{-# INLINE concat #-}+concat = G.concat+ -- Monadic initialisation -- ---------------------- @@ -673,7 +698,7 @@ -- @ modify :: Unbox a => (forall s. MVector s a -> ST s ()) -> Vector a -> Vector a {-# INLINE modify #-}-modify = G.modify+modify p = G.modify p -- Mapping -- -------@@ -1223,15 +1248,37 @@ -- Conversions - Mutable vectors -- ----------------------------- +-- | /O(1)/ Unsafe convert a mutable vector to an immutable one without+-- copying. The mutable vector may not be used after this operation.+unsafeFreeze :: (Unbox a, PrimMonad m) => MVector (PrimState m) a -> m (Vector a)+{-# INLINE unsafeFreeze #-}+unsafeFreeze = G.unsafeFreeze++-- | /O(1)/ Unsafely convert an immutable vector to a mutable one without+-- copying. The immutable vector may not be used after this operation.+unsafeThaw :: (Unbox a, PrimMonad m) => Vector a -> m (MVector (PrimState m) a)+{-# INLINE unsafeThaw #-}+unsafeThaw = G.unsafeThaw++-- | /O(n)/ Yield a mutable copy of the immutable vector.+thaw :: (Unbox a, PrimMonad m) => Vector a -> m (MVector (PrimState m) a)+{-# INLINE thaw #-}+thaw = G.thaw++-- | /O(n)/ Yield an immutable copy of the mutable vector.+freeze :: (Unbox a, PrimMonad m) => MVector (PrimState m) a -> m (Vector a)+{-# INLINE freeze #-}+freeze = G.freeze+ -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length.+-- have the same length. This is not checked. unsafeCopy :: (Unbox a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE unsafeCopy #-} unsafeCopy = G.unsafeCopy -- | /O(n)/ Copy an immutable vector into a mutable one. The two vectors must--- have the same length. This is not checked.+-- have the same length. copy :: (Unbox a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m () {-# INLINE copy #-} copy = G.copy
Data/Vector/Unboxed/Base.hs view
@@ -106,9 +106,12 @@ basicUnsafeGrow (MV_Unit n) m = return $ MV_Unit (n+m) instance G.Vector Vector () where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MV_Unit n) = return $ V_Unit n+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MV_Unit n) = return $ V_Unit n + {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (V_Unit n) = return $ MV_Unit n+ {-# INLINE basicLength #-} basicLength (V_Unit n) = n @@ -135,7 +138,7 @@ ; {-# INLINE basicUnsafeSlice #-} \ ; {-# INLINE basicOverlaps #-} \ ; {-# INLINE basicUnsafeNew #-} \-; {-# INLINE basicUnsafeNewWith #-} \+; {-# INLINE basicUnsafeReplicate #-} \ ; {-# INLINE basicUnsafeRead #-} \ ; {-# INLINE basicUnsafeWrite #-} \ ; {-# INLINE basicClear #-} \@@ -146,7 +149,7 @@ ; basicUnsafeSlice i n (con v) = con $ M.basicUnsafeSlice i n v \ ; basicOverlaps (con v1) (con v2) = M.basicOverlaps v1 v2 \ ; basicUnsafeNew n = con `liftM` M.basicUnsafeNew n \-; basicUnsafeNewWith n x = con `liftM` M.basicUnsafeNewWith n x \+; basicUnsafeReplicate n x = con `liftM` M.basicUnsafeReplicate n x \ ; basicUnsafeRead (con v) i = M.basicUnsafeRead v i \ ; basicUnsafeWrite (con v) i x = M.basicUnsafeWrite v i x \ ; basicClear (con v) = M.basicClear v \@@ -156,12 +159,14 @@ #define primVector(ty,con,mcon) \ instance G.Vector Vector ty where { \- {-# INLINE unsafeFreeze #-} \+ {-# INLINE basicUnsafeFreeze #-} \+; {-# INLINE basicUnsafeThaw #-} \ ; {-# INLINE basicLength #-} \ ; {-# INLINE basicUnsafeSlice #-} \ ; {-# INLINE basicUnsafeIndexM #-} \ ; {-# INLINE elemseq #-} \-; unsafeFreeze (mcon v) = con `liftM` G.unsafeFreeze v \+; basicUnsafeFreeze (mcon v) = con `liftM` G.basicUnsafeFreeze v \+; basicUnsafeThaw (con v) = mcon `liftM` G.basicUnsafeThaw v \ ; basicLength (con v) = G.basicLength v \ ; basicUnsafeSlice i n (con v) = con $ G.basicUnsafeSlice i n v \ ; basicUnsafeIndexM (con v) i = G.basicUnsafeIndexM v i \@@ -273,7 +278,7 @@ {-# INLINE basicUnsafeSlice #-} {-# INLINE basicOverlaps #-} {-# INLINE basicUnsafeNew #-}- {-# INLINE basicUnsafeNewWith #-}+ {-# INLINE basicUnsafeReplicate #-} {-# INLINE basicUnsafeRead #-} {-# INLINE basicUnsafeWrite #-} {-# INLINE basicClear #-}@@ -284,7 +289,7 @@ basicUnsafeSlice i n (MV_Bool v) = MV_Bool $ M.basicUnsafeSlice i n v basicOverlaps (MV_Bool v1) (MV_Bool v2) = M.basicOverlaps v1 v2 basicUnsafeNew n = MV_Bool `liftM` M.basicUnsafeNew n- basicUnsafeNewWith n x = MV_Bool `liftM` M.basicUnsafeNewWith n (fromBool x)+ basicUnsafeReplicate n x = MV_Bool `liftM` M.basicUnsafeReplicate n (fromBool x) basicUnsafeRead (MV_Bool v) i = toBool `liftM` M.basicUnsafeRead v i basicUnsafeWrite (MV_Bool v) i x = M.basicUnsafeWrite v i (fromBool x) basicClear (MV_Bool v) = M.basicClear v@@ -293,12 +298,14 @@ basicUnsafeGrow (MV_Bool v) n = MV_Bool `liftM` M.basicUnsafeGrow v n instance G.Vector Vector Bool where- {-# INLINE unsafeFreeze #-}+ {-# INLINE basicUnsafeFreeze #-}+ {-# INLINE basicUnsafeThaw #-} {-# INLINE basicLength #-} {-# INLINE basicUnsafeSlice #-} {-# INLINE basicUnsafeIndexM #-} {-# INLINE elemseq #-}- unsafeFreeze (MV_Bool v) = V_Bool `liftM` G.unsafeFreeze v+ basicUnsafeFreeze (MV_Bool v) = V_Bool `liftM` G.basicUnsafeFreeze v+ basicUnsafeThaw (V_Bool v) = MV_Bool `liftM` G.basicUnsafeThaw v basicLength (V_Bool v) = G.basicLength v basicUnsafeSlice i n (V_Bool v) = V_Bool $ G.basicUnsafeSlice i n v basicUnsafeIndexM (V_Bool v) i = toBool `liftM` G.basicUnsafeIndexM v i@@ -319,7 +326,7 @@ {-# INLINE basicUnsafeSlice #-} {-# INLINE basicOverlaps #-} {-# INLINE basicUnsafeNew #-}- {-# INLINE basicUnsafeNewWith #-}+ {-# INLINE basicUnsafeReplicate #-} {-# INLINE basicUnsafeRead #-} {-# INLINE basicUnsafeWrite #-} {-# INLINE basicClear #-}@@ -330,7 +337,7 @@ basicUnsafeSlice i n (MV_Complex v) = MV_Complex $ M.basicUnsafeSlice i n v basicOverlaps (MV_Complex v1) (MV_Complex v2) = M.basicOverlaps v1 v2 basicUnsafeNew n = MV_Complex `liftM` M.basicUnsafeNew n- basicUnsafeNewWith n (x :+ y) = MV_Complex `liftM` M.basicUnsafeNewWith n (x,y)+ basicUnsafeReplicate n (x :+ y) = MV_Complex `liftM` M.basicUnsafeReplicate n (x,y) basicUnsafeRead (MV_Complex v) i = uncurry (:+) `liftM` M.basicUnsafeRead v i basicUnsafeWrite (MV_Complex v) i (x :+ y) = M.basicUnsafeWrite v i (x,y) basicClear (MV_Complex v) = M.basicClear v@@ -339,12 +346,14 @@ basicUnsafeGrow (MV_Complex v) n = MV_Complex `liftM` M.basicUnsafeGrow v n instance (RealFloat a, Unbox a) => G.Vector Vector (Complex a) where- {-# INLINE unsafeFreeze #-}+ {-# INLINE basicUnsafeFreeze #-}+ {-# INLINE basicUnsafeThaw #-} {-# INLINE basicLength #-} {-# INLINE basicUnsafeSlice #-} {-# INLINE basicUnsafeIndexM #-} {-# INLINE elemseq #-}- unsafeFreeze (MV_Complex v) = V_Complex `liftM` G.unsafeFreeze v+ basicUnsafeFreeze (MV_Complex v) = V_Complex `liftM` G.basicUnsafeFreeze v+ basicUnsafeThaw (V_Complex v) = MV_Complex `liftM` G.basicUnsafeThaw v basicLength (V_Complex v) = G.basicLength v basicUnsafeSlice i n (V_Complex v) = V_Complex $ G.basicUnsafeSlice i n v basicUnsafeIndexM (V_Complex v) i
Data/Vector/Unboxed/Mutable.hs view
@@ -14,70 +14,162 @@ -- * Mutable vectors of primitive types MVector(..), IOVector, STVector, Unbox, - -- * Operations on mutable vectors- length, overlaps, slice, new, newWith, read, write, swap,- clear, set, copy, grow,+ -- * 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,++ -- * Zipping and unzipping zip, zip3, zip4, zip5, zip6, unzip, unzip3, unzip4, unzip5, unzip6, - -- * Unsafe operations- unsafeSlice, unsafeNew, unsafeNewWith, unsafeRead, unsafeWrite, unsafeSwap,- unsafeCopy, unsafeGrow+ -- * Accessing individual elements+ read, write, swap,+ unsafeRead, unsafeWrite, unsafeSwap,++ -- * Modifying vectors++ -- ** Filling and copying+ set, copy, unsafeCopy,++ -- * Deprecated operations+ newWith, unsafeNewWith+ ) where import Data.Vector.Unboxed.Base import qualified Data.Vector.Generic.Mutable as G import Control.Monad.Primitive -import Prelude hiding ( zip, zip3, unzip, unzip3, length, read )+import Prelude hiding ( length, null, replicate, reverse, map, read,+ take, drop, init, tail,+ zip, zip3, unzip, unzip3 ) #include "vector.h" +-- Length information+-- ------------------++-- | Length of the mutable vector.+length :: Unbox a => MVector s a -> Int+{-# INLINE length #-}+length = G.length++-- | Check whether the vector is empty+null :: Unbox a => MVector s a -> Bool+{-# INLINE null #-}+null = G.null++-- Extracting subvectors+-- ---------------------++-- | Yield a part of the mutable vector without copying it.+slice :: Unbox a => Int -> Int -> MVector s a -> MVector s a+{-# INLINE slice #-}+slice = G.slice++take :: Unbox a => Int -> MVector s a -> MVector s a+{-# INLINE take #-}+take = G.take++drop :: Unbox a => Int -> MVector s a -> MVector s a+{-# INLINE drop #-}+drop = G.drop++init :: Unbox a => MVector s a -> MVector s a+{-# INLINE init #-}+init = G.init++tail :: Unbox a => MVector s a -> MVector s a+{-# INLINE tail #-}+tail = G.tail+ -- | Yield a part of the mutable vector without copying it. No bounds checks -- are performed.-unsafeSlice :: Unbox a => Int -- ^ starting index- -> Int -- ^ length of the slice- -> MVector s a- -> MVector s a+unsafeSlice :: Unbox a+ => Int -- ^ starting index+ -> Int -- ^ length of the slice+ -> MVector s a+ -> MVector s a {-# INLINE unsafeSlice #-} unsafeSlice = G.unsafeSlice +unsafeTake :: Unbox a => Int -> MVector s a -> MVector s a+{-# INLINE unsafeTake #-}+unsafeTake = G.unsafeTake++unsafeDrop :: Unbox a => Int -> MVector s a -> MVector s a+{-# INLINE unsafeDrop #-}+unsafeDrop = G.unsafeDrop++unsafeInit :: Unbox a => MVector s a -> MVector s a+{-# INLINE unsafeInit #-}+unsafeInit = G.unsafeInit++unsafeTail :: Unbox a => MVector s a -> MVector s a+{-# INLINE unsafeTail #-}+unsafeTail = G.unsafeTail++-- Overlapping+-- -----------++-- Check whether two vectors overlap.+overlaps :: Unbox a => MVector s a -> MVector s a -> Bool+{-# INLINE overlaps #-}+overlaps = G.overlaps++-- Initialisation+-- --------------++-- | Create a mutable vector of the given length.+new :: (PrimMonad m, Unbox a) => Int -> m (MVector (PrimState m) a)+{-# INLINE new #-}+new = G.new+ -- | Create a mutable vector of the given length. The length is not checked. unsafeNew :: (PrimMonad m, Unbox a) => Int -> m (MVector (PrimState m) a) {-# INLINE unsafeNew #-} unsafeNew = G.unsafeNew --- | Create a mutable vector of the given length and fill it with an--- initial value. The length is not checked.-unsafeNewWith :: (PrimMonad m, Unbox a)- => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE unsafeNewWith #-}-unsafeNewWith = G.unsafeNewWith---- | Yield the element at the given position. No bounds checks are performed.-unsafeRead :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> m a-{-# INLINE unsafeRead #-}-unsafeRead = G.unsafeRead+-- | Create a mutable vector of the given length (0 if the length is negative)+-- and fill it with an initial value.+replicate :: (PrimMonad m, Unbox a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE replicate #-}+replicate = G.replicate --- | Replace the element at the given position. No bounds checks are performed.-unsafeWrite :: (PrimMonad m, Unbox a)- => MVector (PrimState m) a -> Int -> a -> m ()-{-# INLINE unsafeWrite #-}-unsafeWrite = G.unsafeWrite+-- | Create a copy of a mutable vector.+clone :: (PrimMonad m, Unbox a)+ => MVector (PrimState m) a -> m (MVector (PrimState m) a)+{-# INLINE clone #-}+clone = G.clone --- | Swap the elements at the given positions. No bounds checks are performed.-unsafeSwap :: (PrimMonad m, Unbox a)- => MVector (PrimState m) a -> Int -> Int -> m ()-{-# INLINE unsafeSwap #-}-unsafeSwap = G.unsafeSwap+-- Growing+-- ------- --- | Copy a vector. The two vectors must have the same length and may not--- overlap. This is not checked.-unsafeCopy :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -- ^ target- -> MVector (PrimState m) a -- ^ source- -> m ()-{-# INLINE unsafeCopy #-}-unsafeCopy = G.unsafeCopy+-- | Grow a vector by the given number of elements. The number must be+-- positive.+grow :: (PrimMonad m, Unbox a) + => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)+{-# INLINE grow #-}+grow = G.grow -- | Grow a vector by the given number of elements. The number must be -- positive but this is not checked.@@ -86,31 +178,17 @@ {-# INLINE unsafeGrow #-} unsafeGrow = G.unsafeGrow --- | Length of the mutable vector.-length :: Unbox a => MVector s a -> Int-{-# INLINE length #-}-length = G.length---- Check whether two vectors overlap.-overlaps :: Unbox a => MVector s a -> MVector s a -> Bool-{-# INLINE overlaps #-}-overlaps = G.overlaps---- | Yield a part of the mutable vector without copying it.-slice :: Unbox a => Int -> Int -> MVector s a -> MVector s a-{-# INLINE slice #-}-slice = G.slice+-- Restricting memory usage+-- ------------------------ --- | Create a mutable vector of the given length.-new :: (PrimMonad m, Unbox a) => Int -> m (MVector (PrimState m) a)-{-# INLINE new #-}-new = G.new+-- | 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, Unbox a) => MVector (PrimState m) a -> m ()+{-# INLINE clear #-}+clear = G.clear --- | Create a mutable vector of the given length and fill it with an--- initial value.-newWith :: (PrimMonad m, Unbox a) => Int -> a -> m (MVector (PrimState m) a)-{-# INLINE newWith #-}-newWith = G.newWith+-- Accessing individual elements+-- ----------------------------- -- | Yield the element at the given position. read :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> m a@@ -123,17 +201,31 @@ write = G.write -- | Swap the elements at the given positions.-swap :: (PrimMonad m, Unbox a)- => MVector (PrimState m) a -> Int -> Int -> m ()+swap :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> Int -> m () {-# INLINE swap #-} swap = G.swap --- | 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, Unbox a) => MVector (PrimState m) a -> m ()-{-# INLINE clear #-}-clear = G.clear +-- | Yield the element at the given position. No bounds checks are performed.+unsafeRead :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> m a+{-# INLINE unsafeRead #-}+unsafeRead = G.unsafeRead++-- | Replace the element at the given position. No bounds checks are performed.+unsafeWrite+ :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> a -> m ()+{-# INLINE unsafeWrite #-}+unsafeWrite = G.unsafeWrite++-- | Swap the elements at the given positions. No bounds checks are performed.+unsafeSwap+ :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> Int -> Int -> m ()+{-# INLINE unsafeSwap #-}+unsafeSwap = G.unsafeSwap++-- Filling and copying+-- -------------------+ -- | Set all elements of the vector to the given value. set :: (PrimMonad m, Unbox a) => MVector (PrimState m) a -> a -> m () {-# INLINE set #-}@@ -141,17 +233,34 @@ -- | Copy a vector. The two vectors must have the same length and may not -- overlap.-copy :: (PrimMonad m, Unbox a)- => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()+copy :: (PrimMonad m, Unbox a) + => MVector (PrimState m) a -> MVector (PrimState m) a -> m () {-# INLINE copy #-} copy = G.copy --- | Grow a vector by the given number of elements. The number must be--- positive.-grow :: (PrimMonad m, Unbox a)- => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)-{-# INLINE grow #-}-grow = G.grow+-- | Copy a vector. The two vectors must have the same length and may not+-- overlap. This is not checked.+unsafeCopy :: (PrimMonad m, Unbox a)+ => MVector (PrimState m) a -- ^ target+ -> MVector (PrimState m) a -- ^ source+ -> m ()+{-# INLINE unsafeCopy #-}+unsafeCopy = G.unsafeCopy++-- Deprecated functions+-- --------------------++-- | /DEPRECATED/ Use 'replicate' instead+newWith :: (PrimMonad m, Unbox a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE newWith #-}+newWith = G.replicate++-- | /DEPRECATED/ Use 'replicate' instead+unsafeNewWith :: (PrimMonad m, Unbox a) => Int -> a -> m (MVector (PrimState m) a)+{-# INLINE unsafeNewWith #-}+unsafeNewWith = G.replicate++{-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-} #define DEFINE_MUTABLE #include "unbox-tuple-instances"
benchmarks/Algo/Tridiag.hs view
@@ -5,16 +5,12 @@ tridiag :: (Vector Double, Vector Double, Vector Double, Vector Double) -> Vector Double {-# NOINLINE tridiag #-}-tridiag (as,bs,cs,ds) = xs+tridiag (as,bs,cs,ds) = V.prescanr' (\(c,d) x' -> d - c*x') 0+ $ V.prescanl' modify (0,0)+ $ V.zip (V.zip as bs) (V.zip cs ds) where- (cs',ds') = V.unzip- $ V.prescanl' modify (0,0)- $ V.zip (V.zip as bs) (V.zip cs ds)- modify (c',d') ((a,b),(c,d)) = let id = 1 / (b - c'*a) in id `seq` (c*id, (d-d'*a)*id)-- xs = V.prescanr' (\(c,d) x' -> d - c*x') 0 (V.zip cs' ds')
benchmarks/vector-benchmarks.cabal view
@@ -1,5 +1,5 @@ Name: vector-benchmarks-Version: 0.6.0.1+Version: 0.7 License: BSD3 License-File: LICENSE Author: Roman Leshchinskiy <rl@cse.unsw.edu.au>@@ -13,13 +13,13 @@ Build-Depends: base >= 2 && < 5, array, criterion >= 0.5 && < 0.6,- mwc-random >= 0.5 && < 0.6,- vector == 0.6.0.1+ mwc-random >= 0.5 && < 0.8,+ vector == 0.7 if impl(ghc<6.13)- Ghc-Options: -finline-if-enough-args -fno-method-sharing+ Ghc-Options: -finline-if-enough-args - Ghc-Options: -O2+ Ghc-Options: -O2 -fno-method-sharing Other-Modules: Algo.ListRank
internal/GenUnboxTuple.hs view
@@ -135,7 +135,7 @@ mk_do [v <+> text "<-" <+> qM rec <+> var 'n' | v <- varss] $ text "return $" <+> con "MV" <+> var 'n' <+> sep varss) - gen_unsafeNewWith rec+ gen_unsafeReplicate rec = (var 'n' <+> tuple vars, mk_do [vs <+> text "<-" <+> qM rec <+> var 'n' <+> v | v <- vars | vs <- varss]@@ -178,6 +178,12 @@ $ text "return $" <+> con "V" <+> var 'n' <+> sep [vs <> char '\'' | vs <- varss]) + gen_unsafeThaw rec+ = (pat "V",+ mk_do [vs <> char '\'' <+> text "<-" <+> qG rec <+> vs | vs <- varss]+ $ text "return $" <+> con "MV" <+> var 'n'+ <+> sep [vs <> char '\'' | vs <- varss])+ gen_basicUnsafeIndexM rec = (pat "V" <+> var 'i', mk_do [v <+> text "<-" <+> qG rec <+> vs <+> var 'i'@@ -206,7 +212,7 @@ ,("basicUnsafeSlice", gen_unsafeSlice "M" "MV") ,("basicOverlaps", gen_overlaps) ,("basicUnsafeNew", gen_unsafeNew)- ,("basicUnsafeNewWith", gen_unsafeNewWith)+ ,("basicUnsafeReplicate", gen_unsafeReplicate) ,("basicUnsafeRead", gen_unsafeRead) ,("basicUnsafeWrite", gen_unsafeWrite) ,("basicClear", gen_clear)@@ -214,7 +220,8 @@ ,("basicUnsafeCopy", gen_unsafeCopy "MV" qM) ,("basicUnsafeGrow", gen_unsafeGrow)] - methods_Vector = [("unsafeFreeze", gen_unsafeFreeze)+ methods_Vector = [("basicUnsafeFreeze", gen_unsafeFreeze)+ ,("basicUnsafeThaw", gen_unsafeThaw) ,("basicLength", gen_length "V") ,("basicUnsafeSlice", gen_unsafeSlice "G" "V") ,("basicUnsafeIndexM", gen_basicUnsafeIndexM)
internal/unbox-tuple-instances view
@@ -23,11 +23,11 @@ as <- M.basicUnsafeNew n_ bs <- M.basicUnsafeNew n_ return $ MV_2 n_ as bs- {-# INLINE basicUnsafeNewWith #-}- basicUnsafeNewWith n_ (a, b)+ {-# INLINE basicUnsafeReplicate #-}+ basicUnsafeReplicate n_ (a, b) = do- as <- M.basicUnsafeNewWith n_ a- bs <- M.basicUnsafeNewWith n_ b+ as <- M.basicUnsafeReplicate n_ a+ bs <- M.basicUnsafeReplicate n_ b return $ MV_2 n_ as bs {-# INLINE basicUnsafeRead #-} basicUnsafeRead (MV_2 n_ as bs) i_@@ -62,12 +62,18 @@ bs' <- M.basicUnsafeGrow bs m_ return $ MV_2 (m_+n_) as' bs' instance (Unbox a, Unbox b) => G.Vector Vector (a, b) where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MV_2 n_ as bs)+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MV_2 n_ as bs) = do- as' <- G.unsafeFreeze as- bs' <- G.unsafeFreeze bs+ as' <- G.basicUnsafeFreeze as+ bs' <- G.basicUnsafeFreeze bs return $ V_2 n_ as' bs'+ {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (V_2 n_ as bs)+ = do+ as' <- G.basicUnsafeThaw as+ bs' <- G.basicUnsafeThaw bs+ return $ MV_2 n_ as' bs' {-# INLINE basicLength #-} basicLength (V_2 n_ as bs) = n_ {-# INLINE basicUnsafeSlice #-}@@ -151,12 +157,12 @@ bs <- M.basicUnsafeNew n_ cs <- M.basicUnsafeNew n_ return $ MV_3 n_ as bs cs- {-# INLINE basicUnsafeNewWith #-}- basicUnsafeNewWith n_ (a, b, c)+ {-# INLINE basicUnsafeReplicate #-}+ basicUnsafeReplicate n_ (a, b, c) = do- as <- M.basicUnsafeNewWith n_ a- bs <- M.basicUnsafeNewWith n_ b- cs <- M.basicUnsafeNewWith n_ c+ as <- M.basicUnsafeReplicate n_ a+ bs <- M.basicUnsafeReplicate n_ b+ cs <- M.basicUnsafeReplicate n_ c return $ MV_3 n_ as bs cs {-# INLINE basicUnsafeRead #-} basicUnsafeRead (MV_3 n_ as bs cs) i_@@ -199,13 +205,20 @@ instance (Unbox a, Unbox b, Unbox c) => G.Vector Vector (a, b, c) where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MV_3 n_ as bs cs)+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MV_3 n_ as bs cs) = do- as' <- G.unsafeFreeze as- bs' <- G.unsafeFreeze bs- cs' <- G.unsafeFreeze cs+ as' <- G.basicUnsafeFreeze as+ bs' <- G.basicUnsafeFreeze bs+ cs' <- G.basicUnsafeFreeze cs return $ V_3 n_ as' bs' cs'+ {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (V_3 n_ as bs cs)+ = do+ as' <- G.basicUnsafeThaw as+ bs' <- G.basicUnsafeThaw bs+ cs' <- G.basicUnsafeThaw cs+ return $ MV_3 n_ as' bs' cs' {-# INLINE basicLength #-} basicLength (V_3 n_ as bs cs) = n_ {-# INLINE basicUnsafeSlice #-}@@ -311,13 +324,13 @@ cs <- M.basicUnsafeNew n_ ds <- M.basicUnsafeNew n_ return $ MV_4 n_ as bs cs ds- {-# INLINE basicUnsafeNewWith #-}- basicUnsafeNewWith n_ (a, b, c, d)+ {-# INLINE basicUnsafeReplicate #-}+ basicUnsafeReplicate n_ (a, b, c, d) = do- as <- M.basicUnsafeNewWith n_ a- bs <- M.basicUnsafeNewWith n_ b- cs <- M.basicUnsafeNewWith n_ c- ds <- M.basicUnsafeNewWith n_ d+ as <- M.basicUnsafeReplicate n_ a+ bs <- M.basicUnsafeReplicate n_ b+ cs <- M.basicUnsafeReplicate n_ c+ ds <- M.basicUnsafeReplicate n_ d return $ MV_4 n_ as bs cs ds {-# INLINE basicUnsafeRead #-} basicUnsafeRead (MV_4 n_ as bs cs ds) i_@@ -370,14 +383,22 @@ Unbox b, Unbox c, Unbox d) => G.Vector Vector (a, b, c, d) where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MV_4 n_ as bs cs ds)+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MV_4 n_ as bs cs ds) = do- as' <- G.unsafeFreeze as- bs' <- G.unsafeFreeze bs- cs' <- G.unsafeFreeze cs- ds' <- G.unsafeFreeze ds+ as' <- G.basicUnsafeFreeze as+ bs' <- G.basicUnsafeFreeze bs+ cs' <- G.basicUnsafeFreeze cs+ ds' <- G.basicUnsafeFreeze ds return $ V_4 n_ as' bs' cs' ds'+ {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (V_4 n_ as bs cs ds)+ = do+ as' <- G.basicUnsafeThaw as+ bs' <- G.basicUnsafeThaw bs+ cs' <- G.basicUnsafeThaw cs+ ds' <- G.basicUnsafeThaw ds+ return $ MV_4 n_ as' bs' cs' ds' {-# INLINE basicLength #-} basicLength (V_4 n_ as bs cs ds) = n_ {-# INLINE basicUnsafeSlice #-}@@ -517,14 +538,14 @@ ds <- M.basicUnsafeNew n_ es <- M.basicUnsafeNew n_ return $ MV_5 n_ as bs cs ds es- {-# INLINE basicUnsafeNewWith #-}- basicUnsafeNewWith n_ (a, b, c, d, e)+ {-# INLINE basicUnsafeReplicate #-}+ basicUnsafeReplicate n_ (a, b, c, d, e) = do- as <- M.basicUnsafeNewWith n_ a- bs <- M.basicUnsafeNewWith n_ b- cs <- M.basicUnsafeNewWith n_ c- ds <- M.basicUnsafeNewWith n_ d- es <- M.basicUnsafeNewWith n_ e+ as <- M.basicUnsafeReplicate n_ a+ bs <- M.basicUnsafeReplicate n_ b+ cs <- M.basicUnsafeReplicate n_ c+ ds <- M.basicUnsafeReplicate n_ d+ es <- M.basicUnsafeReplicate n_ e return $ MV_5 n_ as bs cs ds es {-# INLINE basicUnsafeRead #-} basicUnsafeRead (MV_5 n_ as bs cs ds es) i_@@ -585,15 +606,24 @@ Unbox c, Unbox d, Unbox e) => G.Vector Vector (a, b, c, d, e) where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MV_5 n_ as bs cs ds es)+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MV_5 n_ as bs cs ds es) = do- as' <- G.unsafeFreeze as- bs' <- G.unsafeFreeze bs- cs' <- G.unsafeFreeze cs- ds' <- G.unsafeFreeze ds- es' <- G.unsafeFreeze es+ as' <- G.basicUnsafeFreeze as+ bs' <- G.basicUnsafeFreeze bs+ cs' <- G.basicUnsafeFreeze cs+ ds' <- G.basicUnsafeFreeze ds+ es' <- G.basicUnsafeFreeze es return $ V_5 n_ as' bs' cs' ds' es'+ {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (V_5 n_ as bs cs ds es)+ = do+ as' <- G.basicUnsafeThaw as+ bs' <- G.basicUnsafeThaw bs+ cs' <- G.basicUnsafeThaw cs+ ds' <- G.basicUnsafeThaw ds+ es' <- G.basicUnsafeThaw es+ return $ MV_5 n_ as' bs' cs' ds' es' {-# INLINE basicLength #-} basicLength (V_5 n_ as bs cs ds es) = n_ {-# INLINE basicUnsafeSlice #-}@@ -775,15 +805,15 @@ es <- M.basicUnsafeNew n_ fs <- M.basicUnsafeNew n_ return $ MV_6 n_ as bs cs ds es fs- {-# INLINE basicUnsafeNewWith #-}- basicUnsafeNewWith n_ (a, b, c, d, e, f)+ {-# INLINE basicUnsafeReplicate #-}+ basicUnsafeReplicate n_ (a, b, c, d, e, f) = do- as <- M.basicUnsafeNewWith n_ a- bs <- M.basicUnsafeNewWith n_ b- cs <- M.basicUnsafeNewWith n_ c- ds <- M.basicUnsafeNewWith n_ d- es <- M.basicUnsafeNewWith n_ e- fs <- M.basicUnsafeNewWith n_ f+ as <- M.basicUnsafeReplicate n_ a+ bs <- M.basicUnsafeReplicate n_ b+ cs <- M.basicUnsafeReplicate n_ c+ ds <- M.basicUnsafeReplicate n_ d+ es <- M.basicUnsafeReplicate n_ e+ fs <- M.basicUnsafeReplicate n_ f return $ MV_6 n_ as bs cs ds es fs {-# INLINE basicUnsafeRead #-} basicUnsafeRead (MV_6 n_ as bs cs ds es fs) i_@@ -852,16 +882,26 @@ Unbox d, Unbox e, Unbox f) => G.Vector Vector (a, b, c, d, e, f) where- {-# INLINE unsafeFreeze #-}- unsafeFreeze (MV_6 n_ as bs cs ds es fs)+ {-# INLINE basicUnsafeFreeze #-}+ basicUnsafeFreeze (MV_6 n_ as bs cs ds es fs) = do- as' <- G.unsafeFreeze as- bs' <- G.unsafeFreeze bs- cs' <- G.unsafeFreeze cs- ds' <- G.unsafeFreeze ds- es' <- G.unsafeFreeze es- fs' <- G.unsafeFreeze fs+ as' <- G.basicUnsafeFreeze as+ bs' <- G.basicUnsafeFreeze bs+ cs' <- G.basicUnsafeFreeze cs+ ds' <- G.basicUnsafeFreeze ds+ es' <- G.basicUnsafeFreeze es+ fs' <- G.basicUnsafeFreeze fs return $ V_6 n_ as' bs' cs' ds' es' fs'+ {-# INLINE basicUnsafeThaw #-}+ basicUnsafeThaw (V_6 n_ as bs cs ds es fs)+ = do+ as' <- G.basicUnsafeThaw as+ bs' <- G.basicUnsafeThaw bs+ cs' <- G.basicUnsafeThaw cs+ ds' <- G.basicUnsafeThaw ds+ es' <- G.basicUnsafeThaw es+ fs' <- G.basicUnsafeThaw fs+ return $ MV_6 n_ as' bs' cs' ds' es' fs' {-# INLINE basicLength #-} basicLength (V_6 n_ as bs cs ds es fs) = n_ {-# INLINE basicUnsafeSlice #-}
vector.cabal view
@@ -1,5 +1,5 @@ Name: vector-Version: 0.6.0.2+Version: 0.7 License: BSD3 License-File: LICENSE Author: Roman Leshchinskiy <rl@cse.unsw.edu.au>@@ -38,27 +38,25 @@ . * <http://trac.haskell.org/vector> .- Changes since version 0.6.0.1- .- * Workaround for GHC bug #4120- .- Changes since version 0.6+ Changes in version 0.7 .- * Improved documentation+ * New functions for freezing, copying and thawing vectors: @freeze@,+ @thaw@, @unsafeThaw@ and @clone@ .- Changes since version 0.5+ * @newWith@ and @newUnsafeWith@ on mutable vectors replaced by+ @replicate@ .- * More efficient representation of @Storable@ vectors+ * New function: @concat@ .- * Block copy operations used when possible+ * New function for safe indexing: @(!?)@ .- * @Typeable@ and @Data@ instances+ * @Monoid@ instances for all vector types .- * Monadic combinators (@replicateM@, @mapM@ etc.)+ * Significant recycling and fusion improvements .- * Better support for recycling (see @create@ and @modify@)+ * Bug fixes .- * Performance improvements+ * Support for GHC 7.0 . Cabal-Version: >= 1.2.3@@ -142,7 +140,7 @@ Install-Includes: vector.h - Build-Depends: base >= 4 && < 5, ghc >= 6.9, primitive >= 0.3 && < 0.4+ Build-Depends: base >= 4 && < 5, ghc >= 6.9, primitive >= 0.3.1 && < 0.4 if impl(ghc<6.13) Ghc-Options: -finline-if-enough-args -fno-method-sharing