2d58dc4aae9506c3108597076f703b8e25086860
[darcs-mirrors/vector.git] / Data / Vector / Mutable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
2
3 -- |
4 -- Module : Data.Vector.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 boxed vectors.
13 --
14
15 module Data.Vector.Mutable (
16 -- * Mutable boxed vectors
17 MVector(..), IOVector, STVector,
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.Array
57 import Control.Monad.Primitive
58
59 import Prelude hiding ( length, null, replicate, reverse, map, read,
60 take, drop, init, tail )
61
62 import Data.Typeable ( Typeable )
63
64 #include "vector.h"
65
66 -- | Mutable boxed vectors keyed on the monad they live in ('IO' or @'ST' s@).
67 data MVector s a = MVector {-# UNPACK #-} !Int
68 {-# UNPACK #-} !Int
69 {-# UNPACK #-} !(MutableArray s a)
70 deriving ( Typeable )
71
72 type IOVector = MVector RealWorld
73 type STVector s = MVector s
74
75 instance G.MVector MVector a where
76 {-# INLINE basicLength #-}
77 basicLength (MVector _ n _) = n
78
79 {-# INLINE basicUnsafeSlice #-}
80 basicUnsafeSlice j m (MVector i n arr) = MVector (i+j) m arr
81
82 {-# INLINE basicOverlaps #-}
83 basicOverlaps (MVector i m arr1) (MVector j n arr2)
84 = sameMutableArray 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
91 = do
92 arr <- newArray n uninitialised
93 return (MVector 0 n arr)
94
95 {-# INLINE basicUnsafeReplicate #-}
96 basicUnsafeReplicate n x
97 = do
98 arr <- newArray n x
99 return (MVector 0 n arr)
100
101 {-# INLINE basicUnsafeRead #-}
102 basicUnsafeRead (MVector i n arr) j = readArray arr (i+j)
103
104 {-# INLINE basicUnsafeWrite #-}
105 basicUnsafeWrite (MVector i n arr) j x = writeArray arr (i+j) x
106
107 {-# INLINE basicClear #-}
108 basicClear v = G.set v uninitialised
109
110 uninitialised :: a
111 uninitialised = error "Data.Vector.Mutable: uninitialised element"
112
113 -- Length information
114 -- ------------------
115
116 -- | Length of the mutable vector.
117 length :: MVector s a -> Int
118 {-# INLINE length #-}
119 length = G.length
120
121 -- | Check whether the vector is empty
122 null :: MVector s a -> Bool
123 {-# INLINE null #-}
124 null = G.null
125
126 -- Extracting subvectors
127 -- ---------------------
128
129 -- | Yield a part of the mutable vector without copying it.
130 slice :: Int -> Int -> MVector s a -> MVector s a
131 {-# INLINE slice #-}
132 slice = G.slice
133
134 take :: Int -> MVector s a -> MVector s a
135 {-# INLINE take #-}
136 take = G.take
137
138 drop :: Int -> MVector s a -> MVector s a
139 {-# INLINE drop #-}
140 drop = G.drop
141
142 init :: MVector s a -> MVector s a
143 {-# INLINE init #-}
144 init = G.init
145
146 tail :: MVector s a -> MVector s a
147 {-# INLINE tail #-}
148 tail = G.tail
149
150 -- | Yield a part of the mutable vector without copying it. No bounds checks
151 -- are performed.
152 unsafeSlice :: Int -- ^ starting index
153 -> Int -- ^ length of the slice
154 -> MVector s a
155 -> MVector s a
156 {-# INLINE unsafeSlice #-}
157 unsafeSlice = G.unsafeSlice
158
159 unsafeTake :: Int -> MVector s a -> MVector s a
160 {-# INLINE unsafeTake #-}
161 unsafeTake = G.unsafeTake
162
163 unsafeDrop :: Int -> MVector s a -> MVector s a
164 {-# INLINE unsafeDrop #-}
165 unsafeDrop = G.unsafeDrop
166
167 unsafeInit :: MVector s a -> MVector s a
168 {-# INLINE unsafeInit #-}
169 unsafeInit = G.unsafeInit
170
171 unsafeTail :: MVector s a -> MVector s a
172 {-# INLINE unsafeTail #-}
173 unsafeTail = G.unsafeTail
174
175 -- Overlapping
176 -- -----------
177
178 -- Check whether two vectors overlap.
179 overlaps :: MVector s a -> MVector s a -> Bool
180 {-# INLINE overlaps #-}
181 overlaps = G.overlaps
182
183 -- Initialisation
184 -- --------------
185
186 -- | Create a mutable vector of the given length.
187 new :: PrimMonad m => Int -> m (MVector (PrimState m) a)
188 {-# INLINE new #-}
189 new = G.new
190
191 -- | Create a mutable vector of the given length. The length is not checked.
192 unsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) a)
193 {-# INLINE unsafeNew #-}
194 unsafeNew = G.unsafeNew
195
196 -- | Create a mutable vector of the given length (0 if the length is negative)
197 -- and fill it with an initial value.
198 replicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
199 {-# INLINE replicate #-}
200 replicate = G.replicate
201
202 -- | Create a copy of a mutable vector.
203 clone :: PrimMonad m => MVector (PrimState m) a -> m (MVector (PrimState m) a)
204 {-# INLINE clone #-}
205 clone = G.clone
206
207 -- Growing
208 -- -------
209
210 -- | Grow a vector by the given number of elements. The number must be
211 -- positive.
212 grow :: PrimMonad m
213 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
214 {-# INLINE grow #-}
215 grow = G.grow
216
217 -- | Grow a vector by the given number of elements. The number must be
218 -- positive but this is not checked.
219 unsafeGrow :: PrimMonad m
220 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
221 {-# INLINE unsafeGrow #-}
222 unsafeGrow = G.unsafeGrow
223
224 -- Restricting memory usage
225 -- ------------------------
226
227 -- | Reset all elements of the vector to some undefined value, clearing all
228 -- references to external objects. This is usually a noop for unboxed vectors.
229 clear :: PrimMonad m => MVector (PrimState m) a -> m ()
230 {-# INLINE clear #-}
231 clear = G.clear
232
233 -- Accessing individual elements
234 -- -----------------------------
235
236 -- | Yield the element at the given position.
237 read :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
238 {-# INLINE read #-}
239 read = G.read
240
241 -- | Replace the element at the given position.
242 write :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
243 {-# INLINE write #-}
244 write = G.write
245
246 -- | Swap the elements at the given positions.
247 swap :: PrimMonad m => MVector (PrimState m) a -> Int -> Int -> m ()
248 {-# INLINE swap #-}
249 swap = G.swap
250
251
252 -- | Yield the element at the given position. No bounds checks are performed.
253 unsafeRead :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
254 {-# INLINE unsafeRead #-}
255 unsafeRead = G.unsafeRead
256
257 -- | Replace the element at the given position. No bounds checks are performed.
258 unsafeWrite :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
259 {-# INLINE unsafeWrite #-}
260 unsafeWrite = G.unsafeWrite
261
262 -- | Swap the elements at the given positions. No bounds checks are performed.
263 unsafeSwap :: PrimMonad m => MVector (PrimState m) a -> Int -> Int -> m ()
264 {-# INLINE unsafeSwap #-}
265 unsafeSwap = G.unsafeSwap
266
267 -- Filling and copying
268 -- -------------------
269
270 -- | Set all elements of the vector to the given value.
271 set :: PrimMonad m => MVector (PrimState m) a -> a -> m ()
272 {-# INLINE set #-}
273 set = G.set
274
275 -- | Copy a vector. The two vectors must have the same length and may not
276 -- overlap.
277 copy :: PrimMonad m
278 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
279 {-# INLINE copy #-}
280 copy = G.copy
281
282 -- | Copy a vector. The two vectors must have the same length and may not
283 -- overlap. This is not checked.
284 unsafeCopy :: PrimMonad m => MVector (PrimState m) a -- ^ target
285 -> MVector (PrimState m) a -- ^ source
286 -> m ()
287 {-# INLINE unsafeCopy #-}
288 unsafeCopy = G.unsafeCopy
289
290 -- Deprecated functions
291 -- --------------------
292
293 -- | /DEPRECATED/ Use 'replicate' instead
294 newWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
295 {-# INLINE newWith #-}
296 newWith = G.replicate
297
298 -- | /DEPRECATED/ Use 'replicate' instead
299 unsafeNewWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
300 {-# INLINE unsafeNewWith #-}
301 unsafeNewWith = G.replicate
302
303 {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
304