4fc8d38648046ed72bcb5457d983ed08c49bd714
[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,
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, unsafeCopy,
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, 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 -- Length information
106 -- ------------------
107
108 -- | Length of the mutable vector.
109 length :: Prim a => MVector s a -> Int
110 {-# INLINE length #-}
111 length = G.length
112
113 -- | Check whether the vector is empty
114 null :: Prim a => MVector s a -> Bool
115 {-# INLINE null #-}
116 null = G.null
117
118 -- Extracting subvectors
119 -- ---------------------
120
121 -- | Yield a part of the mutable vector without copying it.
122 slice :: Prim a => Int -> Int -> MVector s a -> MVector s a
123 {-# INLINE slice #-}
124 slice = G.slice
125
126 take :: Prim a => Int -> MVector s a -> MVector s a
127 {-# INLINE take #-}
128 take = G.take
129
130 drop :: Prim a => Int -> MVector s a -> MVector s a
131 {-# INLINE drop #-}
132 drop = G.drop
133
134 init :: Prim a => MVector s a -> MVector s a
135 {-# INLINE init #-}
136 init = G.init
137
138 tail :: Prim a => MVector s a -> MVector s a
139 {-# INLINE tail #-}
140 tail = G.tail
141
142 -- | Yield a part of the mutable vector without copying it. No bounds checks
143 -- are performed.
144 unsafeSlice :: Prim a
145 => Int -- ^ starting index
146 -> Int -- ^ length of the slice
147 -> MVector s a
148 -> MVector s a
149 {-# INLINE unsafeSlice #-}
150 unsafeSlice = G.unsafeSlice
151
152 unsafeTake :: Prim a => Int -> MVector s a -> MVector s a
153 {-# INLINE unsafeTake #-}
154 unsafeTake = G.unsafeTake
155
156 unsafeDrop :: Prim a => Int -> MVector s a -> MVector s a
157 {-# INLINE unsafeDrop #-}
158 unsafeDrop = G.unsafeDrop
159
160 unsafeInit :: Prim a => MVector s a -> MVector s a
161 {-# INLINE unsafeInit #-}
162 unsafeInit = G.unsafeInit
163
164 unsafeTail :: Prim a => MVector s a -> MVector s a
165 {-# INLINE unsafeTail #-}
166 unsafeTail = G.unsafeTail
167
168 -- Overlapping
169 -- -----------
170
171 -- Check whether two vectors overlap.
172 overlaps :: Prim a => MVector s a -> MVector s a -> Bool
173 {-# INLINE overlaps #-}
174 overlaps = G.overlaps
175
176 -- Initialisation
177 -- --------------
178
179 -- | Create a mutable vector of the given length.
180 new :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
181 {-# INLINE new #-}
182 new = G.new
183
184 -- | Create a mutable vector of the given length. The length is not checked.
185 unsafeNew :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
186 {-# INLINE unsafeNew #-}
187 unsafeNew = G.unsafeNew
188
189 -- | Create a mutable vector of the given length (0 if the length is negative)
190 -- and fill it with an initial value.
191 replicate :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
192 {-# INLINE replicate #-}
193 replicate = G.replicate
194
195 -- | Create a copy of a mutable vector.
196 clone :: (PrimMonad m, Prim a)
197 => MVector (PrimState m) a -> m (MVector (PrimState m) a)
198 {-# INLINE clone #-}
199 clone = G.clone
200
201 -- Growing
202 -- -------
203
204 -- | Grow a vector by the given number of elements. The number must be
205 -- positive.
206 grow :: (PrimMonad m, Prim a)
207 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
208 {-# INLINE grow #-}
209 grow = G.grow
210
211 -- | Grow a vector by the given number of elements. The number must be
212 -- positive but this is not checked.
213 unsafeGrow :: (PrimMonad m, Prim a)
214 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
215 {-# INLINE unsafeGrow #-}
216 unsafeGrow = G.unsafeGrow
217
218 -- Restricting memory usage
219 -- ------------------------
220
221 -- | Reset all elements of the vector to some undefined value, clearing all
222 -- references to external objects. This is usually a noop for unboxed vectors.
223 clear :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> m ()
224 {-# INLINE clear #-}
225 clear = G.clear
226
227 -- Accessing individual elements
228 -- -----------------------------
229
230 -- | Yield the element at the given position.
231 read :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
232 {-# INLINE read #-}
233 read = G.read
234
235 -- | Replace the element at the given position.
236 write :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
237 {-# INLINE write #-}
238 write = G.write
239
240 -- | Swap the elements at the given positions.
241 swap :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()
242 {-# INLINE swap #-}
243 swap = G.swap
244
245
246 -- | Yield the element at the given position. No bounds checks are performed.
247 unsafeRead :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
248 {-# INLINE unsafeRead #-}
249 unsafeRead = G.unsafeRead
250
251 -- | Replace the element at the given position. No bounds checks are performed.
252 unsafeWrite
253 :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
254 {-# INLINE unsafeWrite #-}
255 unsafeWrite = G.unsafeWrite
256
257 -- | Swap the elements at the given positions. No bounds checks are performed.
258 unsafeSwap
259 :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()
260 {-# INLINE unsafeSwap #-}
261 unsafeSwap = G.unsafeSwap
262
263 -- Filling and copying
264 -- -------------------
265
266 -- | Set all elements of the vector to the given value.
267 set :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> a -> m ()
268 {-# INLINE set #-}
269 set = G.set
270
271 -- | Copy a vector. The two vectors must have the same length and may not
272 -- overlap.
273 copy :: (PrimMonad m, Prim a)
274 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
275 {-# INLINE copy #-}
276 copy = G.copy
277
278 -- | Copy a vector. The two vectors must have the same length and may not
279 -- overlap. This is not checked.
280 unsafeCopy :: (PrimMonad m, Prim a)
281 => MVector (PrimState m) a -- ^ target
282 -> MVector (PrimState m) a -- ^ source
283 -> m ()
284 {-# INLINE unsafeCopy #-}
285 unsafeCopy = G.unsafeCopy
286
287 -- Deprecated functions
288 -- --------------------
289
290 -- | /DEPRECATED/ Use 'replicate' instead
291 newWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
292 {-# INLINE newWith #-}
293 newWith = G.replicate
294
295 -- | /DEPRECATED/ Use 'replicate' instead
296 unsafeNewWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
297 {-# INLINE unsafeNewWith #-}
298 unsafeNewWith = G.replicate
299
300 {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
301