about summary refs log tree commit diff
path: root/third_party/bazel/rules_haskell/examples/vector/Data/Vector/Primitive/Mutable.hs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/bazel/rules_haskell/examples/vector/Data/Vector/Primitive/Mutable.hs')
-rw-r--r--third_party/bazel/rules_haskell/examples/vector/Data/Vector/Primitive/Mutable.hs366
1 files changed, 366 insertions, 0 deletions
diff --git a/third_party/bazel/rules_haskell/examples/vector/Data/Vector/Primitive/Mutable.hs b/third_party/bazel/rules_haskell/examples/vector/Data/Vector/Primitive/Mutable.hs
new file mode 100644
index 0000000000..33aca812e2
--- /dev/null
+++ b/third_party/bazel/rules_haskell/examples/vector/Data/Vector/Primitive/Mutable.hs
@@ -0,0 +1,366 @@
+{-# LANGUAGE CPP, DeriveDataTypeable, MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}
+
+-- |
+-- Module      : Data.Vector.Primitive.Mutable
+-- Copyright   : (c) Roman Leshchinskiy 2008-2010
+-- License     : BSD-style
+--
+-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
+-- Stability   : experimental
+-- Portability : non-portable
+--
+-- Mutable primitive vectors.
+--
+
+module Data.Vector.Primitive.Mutable (
+  -- * Mutable vectors of primitive types
+  MVector(..), IOVector, STVector, Prim,
+
+  -- * Accessors
+
+  -- ** Length information
+  length, null,
+
+  -- ** Extracting subvectors
+  slice, init, tail, take, drop, splitAt,
+  unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
+
+  -- ** Overlapping
+  overlaps,
+
+  -- * Construction
+
+  -- ** Initialisation
+  new, unsafeNew, replicate, replicateM, clone,
+
+  -- ** Growing
+  grow, unsafeGrow,
+
+  -- ** Restricting memory usage
+  clear,
+
+  -- * Accessing individual elements
+  read, write, modify, swap,
+  unsafeRead, unsafeWrite, unsafeModify, unsafeSwap,
+
+  -- * Modifying vectors
+  nextPermutation,
+
+  -- ** Filling and copying
+  set, copy, move, unsafeCopy, unsafeMove
+) where
+
+import qualified Data.Vector.Generic.Mutable as G
+import           Data.Primitive.ByteArray
+import           Data.Primitive ( Prim, sizeOf )
+import           Data.Word ( Word8 )
+import           Control.Monad.Primitive
+import           Control.Monad ( liftM )
+
+import Control.DeepSeq ( NFData(rnf) )
+
+import Prelude hiding ( length, null, replicate, reverse, map, read,
+                        take, drop, splitAt, init, tail )
+
+import Data.Typeable ( Typeable )
+
+-- Data.Vector.Internal.Check is unnecessary
+#define NOT_VECTOR_MODULE
+#include "vector.h"
+
+-- | Mutable vectors of primitive types.
+data MVector s a = MVector {-# UNPACK #-} !Int
+                           {-# UNPACK #-} !Int
+                           {-# UNPACK #-} !(MutableByteArray s) -- ^ offset, length, underlying mutable byte array
+        deriving ( Typeable )
+
+type IOVector = MVector RealWorld
+type STVector s = MVector s
+
+instance NFData (MVector s a) where
+  rnf (MVector _ _ _) = ()
+
+instance Prim a => G.MVector MVector a where
+  basicLength (MVector _ n _) = n
+  basicUnsafeSlice j m (MVector i _ arr)
+    = MVector (i+j) m arr
+
+  {-# INLINE basicOverlaps #-}
+  basicOverlaps (MVector i m arr1) (MVector j n arr2)
+    = sameMutableByteArray arr1 arr2
+      && (between i j (j+n) || between j i (i+m))
+    where
+      between x y z = x >= y && x < z
+
+  {-# INLINE basicUnsafeNew #-}
+  basicUnsafeNew n
+    | n < 0 = error $ "Primitive.basicUnsafeNew: negative length: " ++ show n
+    | n > mx = error $ "Primitive.basicUnsafeNew: length to large: " ++ show n
+    | otherwise = MVector 0 n `liftM` newByteArray (n * size)
+    where
+      size = sizeOf (undefined :: a)
+      mx = maxBound `div` size :: Int
+
+  {-# INLINE basicInitialize #-}
+  basicInitialize (MVector off n v) =
+      setByteArray v (off * size) (n * size) (0 :: Word8)
+    where
+      size = sizeOf (undefined :: a)
+
+
+  {-# INLINE basicUnsafeRead #-}
+  basicUnsafeRead (MVector i _ arr) j = readByteArray arr (i+j)
+
+  {-# INLINE basicUnsafeWrite #-}
+  basicUnsafeWrite (MVector i _ arr) j x = writeByteArray arr (i+j) x
+
+  {-# INLINE basicUnsafeCopy #-}
+  basicUnsafeCopy (MVector i n dst) (MVector j _ src)
+    = copyMutableByteArray dst (i*sz) src (j*sz) (n*sz)
+    where
+      sz = sizeOf (undefined :: a)
+
+  {-# INLINE basicUnsafeMove #-}
+  basicUnsafeMove (MVector i n dst) (MVector j _ src)
+    = moveByteArray dst (i*sz) src (j*sz) (n * sz)
+    where
+      sz = sizeOf (undefined :: a)
+
+  {-# INLINE basicSet #-}
+  basicSet (MVector i n arr) x = setByteArray arr i n x
+
+-- 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
+
+splitAt :: Prim a => Int -> MVector s a -> (MVector s a, MVector s a)
+{-# INLINE splitAt #-}
+splitAt = G.splitAt
+
+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
+{-# 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 memory is not initialized.
+unsafeNew :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
+{-# INLINE unsafeNew #-}
+unsafeNew = G.unsafeNew
+
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with an initial value.
+replicate :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
+{-# INLINE replicate #-}
+replicate = G.replicate
+
+-- | Create a mutable vector of the given length (0 if the length is negative)
+-- and fill it with values produced by repeatedly executing the monadic action.
+replicateM :: (PrimMonad m, Prim a) => Int -> m a -> m (MVector (PrimState m) a)
+{-# INLINE replicateM #-}
+replicateM = G.replicateM
+
+-- | 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
+
+-- Growing
+-- -------
+
+-- | 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.
+unsafeGrow :: (PrimMonad m, Prim a)
+               => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
+{-# INLINE unsafeGrow #-}
+unsafeGrow = G.unsafeGrow
+
+-- Restricting memory usage
+-- ------------------------
+
+-- | Reset all elements of the vector to some undefined value, clearing all
+-- references to external objects. This is usually a noop for unboxed vectors.
+clear :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> m ()
+{-# INLINE clear #-}
+clear = G.clear
+
+-- Accessing individual elements
+-- -----------------------------
+
+-- | Yield the element at the given position.
+read :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
+{-# INLINE read #-}
+read = G.read
+
+-- | Replace the element at the given position.
+write :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
+{-# INLINE write #-}
+write = G.write
+
+-- | Modify the element at the given position.
+modify :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> (a -> a) -> Int -> m ()
+{-# INLINE modify #-}
+modify = G.modify
+
+-- | Swap the elements at the given positions.
+swap :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()
+{-# INLINE swap #-}
+swap = G.swap
+
+
+-- | 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
+
+-- | Modify the element at the given position. No bounds checks are performed.
+unsafeModify :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> (a -> a) -> Int -> m ()
+{-# INLINE unsafeModify #-}
+unsafeModify = G.unsafeModify
+
+-- | 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 #-}
+set = G.set
+
+-- | Copy a vector. The two vectors must have the same length and may not
+-- overlap.
+copy :: (PrimMonad m, Prim a)
+     => MVector (PrimState m) a   -- ^ target
+     -> MVector (PrimState m) a   -- ^ source
+     -> m ()
+{-# INLINE copy #-}
+copy = G.copy
+
+-- | 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
+
+-- | Move the contents of a vector. The two vectors must have the same
+-- length.
+--
+-- If the vectors do not overlap, then this is equivalent to 'copy'.
+-- Otherwise, the copying is performed as if the source vector were
+-- copied to a temporary vector and then the temporary vector was copied
+-- to the target vector.
+move :: (PrimMonad m, Prim a)
+                 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
+{-# INLINE move #-}
+move = G.move
+
+-- | Move the contents of a vector. The two vectors must have the same
+-- length, but this is not checked.
+--
+-- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'.
+-- Otherwise, the copying is performed as if the source vector were
+-- copied to a temporary vector and then the temporary vector was copied
+-- to the target vector.
+unsafeMove :: (PrimMonad m, Prim a)
+                          => MVector (PrimState m) a   -- ^ target
+                          -> MVector (PrimState m) a   -- ^ source
+                          -> m ()
+{-# INLINE unsafeMove #-}
+unsafeMove = G.unsafeMove
+
+-- | Compute the next (lexicographically) permutation of given vector in-place.
+--   Returns False when input is the last permtuation
+nextPermutation :: (PrimMonad m,Ord e,Prim e) => MVector (PrimState m) e -> m Bool
+{-# INLINE nextPermutation #-}
+nextPermutation = G.nextPermutation