9068cb8b6f66b59139f483b16337be7f21447b60
[darcs-mirrors/vector.git] / Data / Vector / Primitive / Mutable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}
2
3 -- |
4 -- Module : Data.Vector.Primitive.Mutable
5 -- Copyright : (c) Roman Leshchinskiy 2008-2010
6 -- License : BSD-style
7 --
8 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
9 -- Stability : experimental
10 -- Portability : non-portable
11 --
12 -- Mutable primitive vectors.
13 --
14
15 module Data.Vector.Primitive.Mutable (
16 -- * Mutable vectors of primitive types
17 MVector(..), IOVector, STVector, Prim,
18
19 -- * Accessors
20
21 -- ** Length information
22 length, null,
23
24 -- ** Extracting subvectors
25 slice, init, tail, take, drop, splitAt,
26 unsafeSlice, unsafeInit, unsafeTail, unsafeTake, unsafeDrop,
27
28 -- ** Overlapping
29 overlaps,
30
31 -- * Construction
32
33 -- ** Initialisation
34 new, unsafeNew, replicate, clone,
35
36 -- ** Growing
37 grow, unsafeGrow,
38
39 -- ** Restricting memory usage
40 clear,
41
42 -- * Accessing individual elements
43 read, write, swap,
44 unsafeRead, unsafeWrite, unsafeSwap,
45
46 -- * Modifying vectors
47
48 -- ** Filling and copying
49 set, copy, move, unsafeCopy, unsafeMove,
50
51 -- * Deprecated operations
52 newWith, unsafeNewWith
53 ) where
54
55 import qualified Data.Vector.Generic.Mutable as G
56 import Data.Primitive.ByteArray
57 import Data.Primitive ( Prim, sizeOf )
58 import Control.Monad.Primitive
59 import Control.Monad ( liftM )
60
61 import Prelude hiding ( length, null, replicate, reverse, map, read,
62 take, drop, splitAt, init, tail )
63
64 import Data.Typeable ( Typeable )
65
66 #include "vector.h"
67
68 -- | Mutable vectors of primitive types.
69 data MVector s a = MVector {-# UNPACK #-} !Int
70 {-# UNPACK #-} !Int
71 {-# UNPACK #-} !(MutableByteArray s)
72 deriving ( Typeable )
73
74 type IOVector = MVector RealWorld
75 type STVector s = MVector s
76
77 instance Prim a => G.MVector MVector a where
78 basicLength (MVector _ n _) = n
79 basicUnsafeSlice j m (MVector i n arr)
80 = MVector (i+j) m arr
81
82 {-# INLINE basicOverlaps #-}
83 basicOverlaps (MVector i m arr1) (MVector j n arr2)
84 = sameMutableByteArray arr1 arr2
85 && (between i j (j+n) || between j i (i+m))
86 where
87 between x y z = x >= y && x < z
88
89 {-# INLINE basicUnsafeNew #-}
90 basicUnsafeNew n = MVector 0 n
91 `liftM` newByteArray (n * sizeOf (undefined :: a))
92
93 {-# INLINE basicUnsafeRead #-}
94 basicUnsafeRead (MVector i n arr) j = readByteArray arr (i+j)
95
96 {-# INLINE basicUnsafeWrite #-}
97 basicUnsafeWrite (MVector i n arr) j x = writeByteArray arr (i+j) x
98
99 {-# INLINE basicUnsafeCopy #-}
100 basicUnsafeCopy (MVector i n dst) (MVector j _ src)
101 = memcpyByteArray dst (i * sz) src (j * sz) (n * sz)
102 where
103 sz = sizeOf (undefined :: a)
104
105 {-# INLINE basicUnsafeMove #-}
106 basicUnsafeMove (MVector i n dst) (MVector j _ src)
107 = memmoveByteArray dst (i * sz) src (j * sz) (n * sz)
108 where
109 sz = sizeOf (undefined :: a)
110
111 -- Length information
112 -- ------------------
113
114 -- | Length of the mutable vector.
115 length :: Prim a => MVector s a -> Int
116 {-# INLINE length #-}
117 length = G.length
118
119 -- | Check whether the vector is empty
120 null :: Prim a => MVector s a -> Bool
121 {-# INLINE null #-}
122 null = G.null
123
124 -- Extracting subvectors
125 -- ---------------------
126
127 -- | Yield a part of the mutable vector without copying it.
128 slice :: Prim a => Int -> Int -> MVector s a -> MVector s a
129 {-# INLINE slice #-}
130 slice = G.slice
131
132 take :: Prim a => Int -> MVector s a -> MVector s a
133 {-# INLINE take #-}
134 take = G.take
135
136 drop :: Prim a => Int -> MVector s a -> MVector s a
137 {-# INLINE drop #-}
138 drop = G.drop
139
140 splitAt :: Prim a => Int -> MVector s a -> (MVector s a, MVector s a)
141 {-# INLINE splitAt #-}
142 splitAt = G.splitAt
143
144 init :: Prim a => MVector s a -> MVector s a
145 {-# INLINE init #-}
146 init = G.init
147
148 tail :: Prim a => MVector s a -> MVector s a
149 {-# INLINE tail #-}
150 tail = G.tail
151
152 -- | Yield a part of the mutable vector without copying it. No bounds checks
153 -- are performed.
154 unsafeSlice :: Prim a
155 => Int -- ^ starting index
156 -> Int -- ^ length of the slice
157 -> MVector s a
158 -> MVector s a
159 {-# INLINE unsafeSlice #-}
160 unsafeSlice = G.unsafeSlice
161
162 unsafeTake :: Prim a => Int -> MVector s a -> MVector s a
163 {-# INLINE unsafeTake #-}
164 unsafeTake = G.unsafeTake
165
166 unsafeDrop :: Prim a => Int -> MVector s a -> MVector s a
167 {-# INLINE unsafeDrop #-}
168 unsafeDrop = G.unsafeDrop
169
170 unsafeInit :: Prim a => MVector s a -> MVector s a
171 {-# INLINE unsafeInit #-}
172 unsafeInit = G.unsafeInit
173
174 unsafeTail :: Prim a => MVector s a -> MVector s a
175 {-# INLINE unsafeTail #-}
176 unsafeTail = G.unsafeTail
177
178 -- Overlapping
179 -- -----------
180
181 -- Check whether two vectors overlap.
182 overlaps :: Prim a => MVector s a -> MVector s a -> Bool
183 {-# INLINE overlaps #-}
184 overlaps = G.overlaps
185
186 -- Initialisation
187 -- --------------
188
189 -- | Create a mutable vector of the given length.
190 new :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
191 {-# INLINE new #-}
192 new = G.new
193
194 -- | Create a mutable vector of the given length. The length is not checked.
195 unsafeNew :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
196 {-# INLINE unsafeNew #-}
197 unsafeNew = G.unsafeNew
198
199 -- | Create a mutable vector of the given length (0 if the length is negative)
200 -- and fill it with an initial value.
201 replicate :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
202 {-# INLINE replicate #-}
203 replicate = G.replicate
204
205 -- | Create a copy of a mutable vector.
206 clone :: (PrimMonad m, Prim a)
207 => MVector (PrimState m) a -> m (MVector (PrimState m) a)
208 {-# INLINE clone #-}
209 clone = G.clone
210
211 -- Growing
212 -- -------
213
214 -- | Grow a vector by the given number of elements. The number must be
215 -- positive.
216 grow :: (PrimMonad m, Prim a)
217 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
218 {-# INLINE grow #-}
219 grow = G.grow
220
221 -- | Grow a vector by the given number of elements. The number must be
222 -- positive but this is not checked.
223 unsafeGrow :: (PrimMonad m, Prim a)
224 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
225 {-# INLINE unsafeGrow #-}
226 unsafeGrow = G.unsafeGrow
227
228 -- Restricting memory usage
229 -- ------------------------
230
231 -- | Reset all elements of the vector to some undefined value, clearing all
232 -- references to external objects. This is usually a noop for unboxed vectors.
233 clear :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> m ()
234 {-# INLINE clear #-}
235 clear = G.clear
236
237 -- Accessing individual elements
238 -- -----------------------------
239
240 -- | Yield the element at the given position.
241 read :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
242 {-# INLINE read #-}
243 read = G.read
244
245 -- | Replace the element at the given position.
246 write :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
247 {-# INLINE write #-}
248 write = G.write
249
250 -- | Swap the elements at the given positions.
251 swap :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()
252 {-# INLINE swap #-}
253 swap = G.swap
254
255
256 -- | Yield the element at the given position. No bounds checks are performed.
257 unsafeRead :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
258 {-# INLINE unsafeRead #-}
259 unsafeRead = G.unsafeRead
260
261 -- | Replace the element at the given position. No bounds checks are performed.
262 unsafeWrite
263 :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
264 {-# INLINE unsafeWrite #-}
265 unsafeWrite = G.unsafeWrite
266
267 -- | Swap the elements at the given positions. No bounds checks are performed.
268 unsafeSwap
269 :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()
270 {-# INLINE unsafeSwap #-}
271 unsafeSwap = G.unsafeSwap
272
273 -- Filling and copying
274 -- -------------------
275
276 -- | Set all elements of the vector to the given value.
277 set :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> a -> m ()
278 {-# INLINE set #-}
279 set = G.set
280
281 -- | Copy a vector. The two vectors must have the same length and may not
282 -- overlap.
283 copy :: (PrimMonad m, Prim a)
284 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
285 {-# INLINE copy #-}
286 copy = G.copy
287
288 -- | Copy a vector. The two vectors must have the same length and may not
289 -- overlap. This is not checked.
290 unsafeCopy :: (PrimMonad m, Prim a)
291 => MVector (PrimState m) a -- ^ target
292 -> MVector (PrimState m) a -- ^ source
293 -> m ()
294 {-# INLINE unsafeCopy #-}
295 unsafeCopy = G.unsafeCopy
296
297 -- | Move the contents of a vector. The two vectors must have the same
298 -- length.
299 --
300 -- If the vectors do not overlap, then this is equivalent to 'copy'.
301 -- Otherwise, the copying is performed as if the source vector were
302 -- copied to a temporary vector and then the temporary vector was copied
303 -- to the target vector.
304 move :: (PrimMonad m, Prim a)
305 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
306 {-# INLINE move #-}
307 move = G.move
308
309 -- | Move the contents of a vector. The two vectors must have the same
310 -- length, but this is not checked.
311 --
312 -- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'.
313 -- Otherwise, the copying is performed as if the source vector were
314 -- copied to a temporary vector and then the temporary vector was copied
315 -- to the target vector.
316 unsafeMove :: (PrimMonad m, Prim a)
317 => MVector (PrimState m) a -- ^ target
318 -> MVector (PrimState m) a -- ^ source
319 -> m ()
320 {-# INLINE unsafeMove #-}
321 unsafeMove = G.unsafeMove
322
323 -- Deprecated functions
324 -- --------------------
325
326 -- | /DEPRECATED/ Use 'replicate' instead
327 newWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
328 {-# INLINE newWith #-}
329 newWith = G.replicate
330
331 -- | /DEPRECATED/ Use 'replicate' instead
332 unsafeNewWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
333 {-# INLINE unsafeNewWith #-}
334 unsafeNewWith = G.replicate
335
336 {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
337