Clean up interface to mutable vectors
[darcs-mirrors/vector.git] / Data / Vector / Primitive / Mutable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables,
2 FlexibleContexts #-}
3
4 -- |
5 -- Module : Data.Vector.Primitive.Mutable
6 -- Copyright : (c) Roman Leshchinskiy 2008-2009
7 -- License : BSD-style
8 --
9 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
10 -- Stability : experimental
11 -- Portability : non-portable
12 --
13 -- Mutable primitive vectors.
14 --
15
16 module Data.Vector.Primitive.Mutable (
17 -- * Mutable vectors of primitive types
18 MVector(..), IOVector, STVector, Prim,
19
20 -- * Operations on mutable vectors
21 length, overlaps, slice, new, newWith, read, write, clear, set, copy, grow,
22
23 -- * Unsafe operations
24 unsafeSlice, unsafeNew, unsafeNewWith, unsafeRead, unsafeWrite,
25 unsafeCopy, unsafeGrow
26 ) where
27
28 import qualified Data.Vector.Generic.Mutable as G
29 import Data.Primitive.ByteArray
30 import Data.Primitive ( Prim, sizeOf )
31 import Control.Monad.Primitive
32 import Control.Monad.ST ( ST )
33 import Control.Monad ( liftM )
34
35 import Prelude hiding( length, read )
36
37 #include "vector.h"
38
39 -- | Mutable vectors of primitive types.
40 data MVector s a = MVector {-# UNPACK #-} !Int
41 {-# UNPACK #-} !Int
42 {-# UNPACK #-} !(MutableByteArray s)
43
44 type IOVector = MVector RealWorld
45 type STVector s = MVector s
46
47 instance Prim a => G.MVector MVector a where
48 basicLength (MVector _ n _) = n
49 basicUnsafeSlice (MVector i n arr) j m
50 = MVector (i+j) m arr
51
52 {-# INLINE basicOverlaps #-}
53 basicOverlaps (MVector i m arr1) (MVector j n arr2)
54 = sameMutableByteArray arr1 arr2
55 && (between i j (j+n) || between j i (i+m))
56 where
57 between x y z = x >= y && x < z
58
59 {-# INLINE basicUnsafeNew #-}
60 basicUnsafeNew n = MVector 0 n
61 `liftM` newByteArray (n * sizeOf (undefined :: a))
62
63 {-# INLINE basicUnsafeRead #-}
64 basicUnsafeRead (MVector i n arr) j = readByteArray arr (i+j)
65
66 {-# INLINE basicUnsafeWrite #-}
67 basicUnsafeWrite (MVector i n arr) j x = writeByteArray arr (i+j) x
68
69 -- | Yield a part of the mutable vector without copying it. No bounds checks
70 -- are performed.
71 unsafeSlice :: Prim a => MVector s a -> Int -- ^ starting index
72 -> Int -- ^ length of the slice
73 -> MVector s a
74 {-# INLINE unsafeSlice #-}
75 unsafeSlice = G.unsafeSlice
76
77
78 -- | Create a mutable vector of the given length. The length is not checked.
79 unsafeNew :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
80 {-# INLINE unsafeNew #-}
81 unsafeNew = G.unsafeNew
82
83 -- | Create a mutable vector of the given length and fill it with an
84 -- initial value. The length is not checked.
85 unsafeNewWith :: (PrimMonad m, Prim a)
86 => Int -> a -> m (MVector (PrimState m) a)
87 {-# INLINE unsafeNewWith #-}
88 unsafeNewWith = G.unsafeNewWith
89
90 -- | Yield the element at the given position. No bounds checks are performed.
91 unsafeRead :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
92 {-# INLINE unsafeRead #-}
93 unsafeRead = G.unsafeRead
94
95 -- | Replace the element at the given position. No bounds checks are performed.
96 unsafeWrite :: (PrimMonad m, Prim a)
97 => MVector (PrimState m) a -> Int -> a -> m ()
98 {-# INLINE unsafeWrite #-}
99 unsafeWrite = G.unsafeWrite
100
101
102 -- | Copy a vector. The two vectors must have the same length and may not
103 -- overlap. This is not checked.
104 unsafeCopy :: (PrimMonad m, Prim a) => MVector (PrimState m) a -- ^ target
105 -> MVector (PrimState m) a -- ^ source
106 -> m ()
107 {-# INLINE unsafeCopy #-}
108 unsafeCopy = G.unsafeCopy
109
110 -- | Grow a vector by the given number of elements. The number must be
111 -- positive but this is not checked.
112 unsafeGrow :: (PrimMonad m, Prim a)
113 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
114 {-# INLINE unsafeGrow #-}
115 unsafeGrow = G.unsafeGrow
116
117 -- | Length of the mutable vector.
118 length :: Prim a => MVector s a -> Int
119 {-# INLINE length #-}
120 length = G.length
121
122 -- Check whether two vectors overlap.
123 overlaps :: Prim a => MVector s a -> MVector s a -> Bool
124 {-# INLINE overlaps #-}
125 overlaps = G.overlaps
126
127 -- | Yield a part of the mutable vector without copying it.
128 slice :: Prim a => MVector s a -> Int -> Int -> MVector s a
129 {-# INLINE slice #-}
130 slice = G.slice
131
132 -- | Create a mutable vector of the given length.
133 new :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
134 {-# INLINE new #-}
135 new = G.new
136
137 -- | Create a mutable vector of the given length and fill it with an
138 -- initial value.
139 newWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
140 {-# INLINE newWith #-}
141 newWith = G.newWith
142
143 -- | Yield the element at the given position.
144 read :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
145 {-# INLINE read #-}
146 read = G.read
147
148 -- | Replace the element at the given position.
149 write :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
150 {-# INLINE write #-}
151 write = G.write
152
153 -- | Reset all elements of the vector to some undefined value, clearing all
154 -- references to external objects. This is usually a noop for unboxed vectors.
155 clear :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> m ()
156 {-# INLINE clear #-}
157 clear = G.clear
158
159 -- | Set all elements of the vector to the given value.
160 set :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> a -> m ()
161 {-# INLINE set #-}
162 set = G.set
163
164 -- | Copy a vector. The two vectors must have the same length and may not
165 -- overlap.
166 copy :: (PrimMonad m, Prim a)
167 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
168 {-# INLINE copy #-}
169 copy = G.copy
170
171 -- | Grow a vector by the given number of elements. The number must be
172 -- positive.
173 grow :: (PrimMonad m, Prim a)
174 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
175 {-# INLINE grow #-}
176 grow = G.grow
177