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