Add unsafe versions of accum/update operations
authorRoman Leshchinskiy <rl@cse.unsw.edu.au>
Mon, 7 Dec 2009 13:30:20 +0000 (13:30 +0000)
committerRoman Leshchinskiy <rl@cse.unsw.edu.au>
Mon, 7 Dec 2009 13:30:20 +0000 (13:30 +0000)
Data/Vector.hs
Data/Vector/Generic.hs
Data/Vector/Generic/Mutable.hs
Data/Vector/Generic/New.hs
Data/Vector/Primitive.hs
Data/Vector/Storable.hs
Data/Vector/Unboxed.hs

index edec42f..5afa0e6 100644 (file)
@@ -23,7 +23,6 @@ module Data.Vector (
 
   -- * Accessing individual elements
   (!), head, last, indexM, headM, lastM,
-  unsafeIndex, unsafeIndexM,
 
   -- * Subvectors
   slice, init, tail, take, drop,
@@ -66,7 +65,12 @@ module Data.Vector (
   enumFromTo, enumFromThenTo,
 
   -- * Conversion to/from lists
-  toList, fromList
+  toList, fromList,
+
+  -- * Unsafe operations
+  unsafeIndex, unsafeIndexM,
+  unsafeAccum, unsafeAccumulate, unsafeAccumulate_,
+  unsafeUpd, unsafeUpdate, unsafeUpdate_
 ) where
 
 import qualified Data.Vector.Generic as G
@@ -255,6 +259,19 @@ drop = G.drop
 -- Permutations
 -- ------------
 
+unsafeAccum :: (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
+{-# INLINE unsafeAccum #-}
+unsafeAccum = G.unsafeAccum
+
+unsafeAccumulate :: (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a
+{-# INLINE unsafeAccumulate #-}
+unsafeAccumulate = G.unsafeAccumulate
+
+unsafeAccumulate_
+  :: (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
+{-# INLINE unsafeAccumulate_ #-}
+unsafeAccumulate_ = G.unsafeAccumulate_
+
 accum :: (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
 {-# INLINE accum #-}
 accum = G.accum
@@ -267,6 +284,18 @@ accumulate_ :: (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
 {-# INLINE accumulate_ #-}
 accumulate_ = G.accumulate_
 
+unsafeUpd :: Vector a -> [(Int, a)] -> Vector a
+{-# INLINE unsafeUpd #-}
+unsafeUpd = G.unsafeUpd
+
+unsafeUpdate :: Vector a -> Vector (Int, a) -> Vector a
+{-# INLINE unsafeUpdate #-}
+unsafeUpdate = G.unsafeUpdate
+
+unsafeUpdate_ :: Vector a -> Vector Int -> Vector a -> Vector a
+{-# INLINE unsafeUpdate_ #-}
+unsafeUpdate_ = G.unsafeUpdate_
+
 (//) :: Vector a -> [(Int, a)] -> Vector a
 {-# INLINE (//) #-}
 (//) = (G.//)
index 20363b8..c8c29fd 100644 (file)
@@ -24,7 +24,6 @@ module Data.Vector.Generic (
 
   -- * Accessing individual elements
   (!), head, last, indexM, headM, lastM,
-  unsafeIndex, unsafeIndexM,
 
   -- * Subvectors
   slice, init, tail, take, drop,
@@ -76,7 +75,12 @@ module Data.Vector.Generic (
   stream, unstream,
 
   -- * MVector-based initialisation
-  new
+  new,
+
+  -- * Unsafe operations
+  unsafeIndex, unsafeIndexM,
+  unsafeAccum, unsafeAccumulate, unsafeAccumulate_,
+  unsafeUpd, unsafeUpdate, unsafeUpdate_
 ) where
 
 import           Data.Vector.Generic.Mutable ( MVector )
@@ -414,6 +418,26 @@ drop n v = slice v (min n' len) (max 0 (len - n'))
 -- Permutations
 -- ------------
 
+unsafeAccum_stream
+  :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a
+{-# INLINE unsafeAccum_stream #-}
+unsafeAccum_stream f v s = new (New.accum f (New.unstream (stream v)) s)
+
+unsafeAccum :: Vector v a => (a -> b -> a) -> v a -> [(Int,b)] -> v a
+{-# INLINE unsafeAccum #-}
+unsafeAccum f v us = unsafeAccum_stream f v (Stream.fromList us)
+
+unsafeAccumulate :: (Vector v a, Vector v (Int, b))
+                => (a -> b -> a) -> v a -> v (Int,b) -> v a
+{-# INLINE unsafeAccumulate #-}
+unsafeAccumulate f v us = unsafeAccum_stream f v (stream us)
+
+unsafeAccumulate_ :: (Vector v a, Vector v Int, Vector v b)
+                => (a -> b -> a) -> v a -> v Int -> v b -> v a
+{-# INLINE unsafeAccumulate_ #-}
+unsafeAccumulate_ f v is xs
+  = unsafeAccum_stream f v (Stream.zipWith (,) (stream is) (stream xs))
+
 accum_stream :: Vector v a => (a -> b -> a) -> v a -> Stream (Int,b) -> v a
 {-# INLINE accum_stream #-}
 accum_stream f v s = new (New.accum f (New.unstream (stream v)) s)
@@ -434,6 +458,23 @@ accumulate_ f v is xs = accum_stream f v (Stream.zipWith (,) (stream is)
                                                              (stream xs))
                                         
 
+unsafeUpdate_stream :: Vector v a => v a -> Stream (Int,a) -> v a
+{-# INLINE unsafeUpdate_stream #-}
+unsafeUpdate_stream v s = new (New.unsafeUpdate (New.unstream (stream v)) s)
+
+unsafeUpd :: Vector v a => v a -> [(Int, a)] -> v a
+{-# INLINE unsafeUpd #-}
+unsafeUpd v us = unsafeUpdate_stream v (Stream.fromList us)
+
+unsafeUpdate :: (Vector v a, Vector v (Int, a)) => v a -> v (Int, a) -> v a
+{-# INLINE unsafeUpdate #-}
+unsafeUpdate v w = unsafeUpdate_stream v (stream w)
+
+unsafeUpdate_ :: (Vector v a, Vector v Int) => v a -> v Int -> v a -> v a
+{-# INLINE unsafeUpdate_ #-}
+unsafeUpdate_ v is w
+  = unsafeUpdate_stream v (Stream.zipWith (,) (stream is) (stream w))
+
 update_stream :: Vector v a => v a -> Stream (Int,a) -> v a
 {-# INLINE update_stream #-}
 update_stream v s = new (New.update (New.unstream (stream v)) s)
index 5d4d72b..9c306cb 100644 (file)
@@ -23,7 +23,7 @@ module Data.Vector.Generic.Mutable (
   unsafeCopy, unsafeGrow,
 
   -- * Internal operations
-  unstream, transform, accum, update, reverse
+  unstream, transform, unsafeAccum, accum, unsafeUpdate, update, reverse
 ) where
 
 import qualified Data.Vector.Fusion.Stream      as Stream
@@ -382,6 +382,17 @@ unstreamUnknown s
               $ double2Int
               $ int2Double (length v) * gROWTH_FACTOR
 
+unsafeAccum :: (PrimMonad m, MVector v a)
+            => (a -> b -> a) -> v (PrimState m) a -> Stream (Int, b) -> m ()
+{-# INLINE unsafeAccum #-}
+unsafeAccum f !v s = Stream.mapM_ upd s
+  where
+    {-# INLINE_INNER upd #-}
+    upd (i,b) = do
+                  a <- UNSAFE_CHECK(checkIndex) "accum" i (length v)
+                     $ unsafeRead v i
+                  unsafeWrite v i (f a b)
+
 accum :: (PrimMonad m, MVector v a)
         => (a -> b -> a) -> v (PrimState m) a -> Stream (Int, b) -> m ()
 {-# INLINE accum #-}
@@ -389,8 +400,14 @@ accum f !v s = Stream.mapM_ upd s
   where
     {-# INLINE_INNER upd #-}
     upd (i,b) = do
-                  a <- read v i
-                  write v i (f a b)
+                  a <- BOUNDS_CHECK(checkIndex) "accum" i (length v)
+                     $ unsafeRead v i
+                  unsafeWrite v i (f a b)
+
+unsafeUpdate :: (PrimMonad m, MVector v a)
+                        => v (PrimState m) a -> Stream (Int, a) -> m ()
+{-# INLINE unsafeUpdate #-}
+unsafeUpdate = unsafeAccum (const id)
 
 update :: (PrimMonad m, MVector v a)
                         => v (PrimState m) a -> Stream (Int, a) -> m ()
index 4f77169..d26b876 100644 (file)
@@ -15,7 +15,7 @@
 module Data.Vector.Generic.New (
   New(..), run, unstream, transform, accum, update, reverse,
   slice, init, tail, take, drop,
-  unsafeSlice
+  unsafeSlice, unsafeAccum, unsafeUpdate
 ) where
 
 import qualified Data.Vector.Generic.Mutable as MVector
@@ -116,10 +116,18 @@ drop n m = apply (\v -> MVector.unsafeSlice v
 
   #-}
 
+unsafeAccum :: (a -> b -> a) -> New a -> Stream (Int, b) -> New a
+{-# INLINE_STREAM unsafeAccum #-}
+unsafeAccum f m s = modify m (\v -> MVector.unsafeAccum f v s)
+
 accum :: (a -> b -> a) -> New a -> Stream (Int, b) -> New a
 {-# INLINE_STREAM accum #-}
 accum f m s = modify m (\v -> MVector.accum f v s)
 
+unsafeUpdate :: New a -> Stream (Int, a) -> New a
+{-# INLINE_STREAM unsafeUpdate #-}
+unsafeUpdate m s = modify m (\v -> MVector.unsafeUpdate v s)
+
 update :: New a -> Stream (Int, a) -> New a
 {-# INLINE_STREAM update #-}
 update m s = modify m (\v -> MVector.update v s)
index 6356ec4..b99be90 100644 (file)
@@ -23,7 +23,6 @@ module Data.Vector.Primitive (
 
   -- * Accessing individual elements
   (!), head, last,
-  unsafeIndex,
 
   -- * Subvectors
   slice, init, tail, take, drop,
@@ -62,7 +61,12 @@ module Data.Vector.Primitive (
   enumFromTo, enumFromThenTo,
 
   -- * Conversion to/from lists
-  toList, fromList
+  toList, fromList,
+
+  -- * Unsafe operations
+  unsafeIndex,
+  unsafeAccum, unsafeAccumulate_,
+  unsafeUpd, unsafeUpdate_
 ) where
 
 import qualified Data.Vector.Generic           as G
@@ -234,6 +238,15 @@ drop = G.drop
 -- Permutations
 -- ------------
 
+unsafeAccum :: Prim a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
+{-# INLINE unsafeAccum #-}
+unsafeAccum = G.unsafeAccum
+
+unsafeAccumulate_ :: (Prim a, Prim b) =>
+               (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
+{-# INLINE unsafeAccumulate_ #-}
+unsafeAccumulate_ = G.unsafeAccumulate_
+
 accum :: Prim a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
 {-# INLINE accum #-}
 accum = G.accum
@@ -243,6 +256,14 @@ accumulate_ :: (Prim a, Prim b) =>
 {-# INLINE accumulate_ #-}
 accumulate_ = G.accumulate_
 
+unsafeUpd :: Prim a => Vector a -> [(Int, a)] -> Vector a
+{-# INLINE unsafeUpd #-}
+unsafeUpd = G.unsafeUpd
+
+unsafeUpdate_ :: Prim a => Vector a -> Vector Int -> Vector a -> Vector a
+{-# INLINE unsafeUpdate_ #-}
+unsafeUpdate_ = G.unsafeUpdate_
+
 (//) :: Prim a => Vector a -> [(Int, a)] -> Vector a
 {-# INLINE (//) #-}
 (//) = (G.//)
index 46dfe7c..fc11e5d 100644 (file)
@@ -23,7 +23,6 @@ module Data.Vector.Storable (
 
   -- * Accessing individual elements
   (!), head, last,
-  unsafeIndex,
 
   -- * Subvectors
   slice, init, tail, take, drop,
@@ -62,7 +61,12 @@ module Data.Vector.Storable (
   enumFromTo, enumFromThenTo,
 
   -- * Conversion to/from lists
-  toList, fromList
+  toList, fromList,
+
+  -- * Unsafe operations
+  unsafeIndex,
+  unsafeAccum, unsafeAccumulate_,
+  unsafeUpd, unsafeUpdate_
 ) where
 
 import qualified Data.Vector.Generic          as G
@@ -265,6 +269,15 @@ drop = G.drop
 -- Permutations
 -- ------------
 
+unsafeAccum :: Storable a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
+{-# INLINE unsafeAccum #-}
+unsafeAccum = G.unsafeAccum
+
+unsafeAccumulate_ :: (Storable a, Storable b) =>
+               (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
+{-# INLINE unsafeAccumulate_ #-}
+unsafeAccumulate_ = G.unsafeAccumulate_
+
 accum :: Storable a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
 {-# INLINE accum #-}
 accum = G.accum
@@ -274,6 +287,14 @@ accumulate_ :: (Storable a, Storable b) =>
 {-# INLINE accumulate_ #-}
 accumulate_ = G.accumulate_
 
+unsafeUpd :: Storable a => Vector a -> [(Int, a)] -> Vector a
+{-# INLINE unsafeUpd #-}
+unsafeUpd = G.unsafeUpd
+
+unsafeUpdate_ :: Storable a => Vector a -> Vector Int -> Vector a -> Vector a
+{-# INLINE unsafeUpdate_ #-}
+unsafeUpdate_ = G.unsafeUpdate_
+
 (//) :: Storable a => Vector a -> [(Int, a)] -> Vector a
 {-# INLINE (//) #-}
 (//) = (G.//)
index 4fb5470..125e5bf 100644 (file)
@@ -21,7 +21,6 @@ module Data.Vector.Unboxed (
 
   -- * Accessing individual elements
   (!), head, last,
-  unsafeIndex,
 
   -- * Subvectors
   slice, init, tail, take, drop,
@@ -64,7 +63,12 @@ module Data.Vector.Unboxed (
   enumFromTo, enumFromThenTo,
 
   -- * Conversion to/from lists
-  toList, fromList
+  toList, fromList,
+
+  -- * Unsafe operations
+  unsafeIndex,
+  unsafeAccum, unsafeAccumulate, unsafeAccumulate_,
+  unsafeUpd, unsafeUpdate, unsafeUpdate_
 ) where
 
 import Data.Vector.Unboxed.Base
@@ -209,6 +213,20 @@ drop = G.drop
 -- Permutations
 -- ------------
 
+unsafeAccum :: Unbox a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
+{-# INLINE unsafeAccum #-}
+unsafeAccum = G.unsafeAccum
+
+unsafeAccumulate :: (Unbox a, Unbox b)
+                => (a -> b -> a) -> Vector a -> Vector (Int,b) -> Vector a
+{-# INLINE unsafeAccumulate #-}
+unsafeAccumulate = G.unsafeAccumulate
+
+unsafeAccumulate_ :: (Unbox a, Unbox b) =>
+               (a -> b -> a) -> Vector a -> Vector Int -> Vector b -> Vector a
+{-# INLINE unsafeAccumulate_ #-}
+unsafeAccumulate_ = G.unsafeAccumulate_
+
 accum :: Unbox a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
 {-# INLINE accum #-}
 accum = G.accum
@@ -223,6 +241,18 @@ accumulate_ :: (Unbox a, Unbox b) =>
 {-# INLINE accumulate_ #-}
 accumulate_ = G.accumulate_
 
+unsafeUpd :: Unbox a => Vector a -> [(Int, a)] -> Vector a
+{-# INLINE unsafeUpd #-}
+unsafeUpd = G.unsafeUpd
+
+unsafeUpdate :: Unbox a => Vector a -> Vector (Int, a) -> Vector a
+{-# INLINE unsafeUpdate #-}
+unsafeUpdate = G.unsafeUpdate
+
+unsafeUpdate_ :: Unbox a => Vector a -> Vector Int -> Vector a -> Vector a
+{-# INLINE unsafeUpdate_ #-}
+unsafeUpdate_ = G.unsafeUpdate_
+
 (//) :: Unbox a => Vector a -> [(Int, a)] -> Vector a
 {-# INLINE (//) #-}
 (//) = (G.//)