Added splitAt functions (contributed by Bas van Dijk)
[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, 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, 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, splitAt, 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 {-# INLINE splitAt #-}
143 splitAt :: Int -> MVector s a -> (MVector s a, MVector s a)
144 splitAt = G.splitAt
145
146 init :: MVector s a -> MVector s a
147 {-# INLINE init #-}
148 init = G.init
149
150 tail :: MVector s a -> MVector s a
151 {-# INLINE tail #-}
152 tail = G.tail
153
154 -- | Yield a part of the mutable vector without copying it. No bounds checks
155 -- are performed.
156 unsafeSlice :: Int -- ^ starting index
157 -> Int -- ^ length of the slice
158 -> MVector s a
159 -> MVector s a
160 {-# INLINE unsafeSlice #-}
161 unsafeSlice = G.unsafeSlice
162
163 unsafeTake :: Int -> MVector s a -> MVector s a
164 {-# INLINE unsafeTake #-}
165 unsafeTake = G.unsafeTake
166
167 unsafeDrop :: Int -> MVector s a -> MVector s a
168 {-# INLINE unsafeDrop #-}
169 unsafeDrop = G.unsafeDrop
170
171 unsafeInit :: MVector s a -> MVector s a
172 {-# INLINE unsafeInit #-}
173 unsafeInit = G.unsafeInit
174
175 unsafeTail :: MVector s a -> MVector s a
176 {-# INLINE unsafeTail #-}
177 unsafeTail = G.unsafeTail
178
179 -- Overlapping
180 -- -----------
181
182 -- Check whether two vectors overlap.
183 overlaps :: MVector s a -> MVector s a -> Bool
184 {-# INLINE overlaps #-}
185 overlaps = G.overlaps
186
187 -- Initialisation
188 -- --------------
189
190 -- | Create a mutable vector of the given length.
191 new :: PrimMonad m => Int -> m (MVector (PrimState m) a)
192 {-# INLINE new #-}
193 new = G.new
194
195 -- | Create a mutable vector of the given length. The length is not checked.
196 unsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) a)
197 {-# INLINE unsafeNew #-}
198 unsafeNew = G.unsafeNew
199
200 -- | Create a mutable vector of the given length (0 if the length is negative)
201 -- and fill it with an initial value.
202 replicate :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
203 {-# INLINE replicate #-}
204 replicate = G.replicate
205
206 -- | Create a copy of a mutable vector.
207 clone :: PrimMonad m => 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
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
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 => 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 => 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 => 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 => 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 => 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 :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
263 {-# INLINE unsafeWrite #-}
264 unsafeWrite = G.unsafeWrite
265
266 -- | Swap the elements at the given positions. No bounds checks are performed.
267 unsafeSwap :: PrimMonad m => MVector (PrimState m) a -> Int -> Int -> m ()
268 {-# INLINE unsafeSwap #-}
269 unsafeSwap = G.unsafeSwap
270
271 -- Filling and copying
272 -- -------------------
273
274 -- | Set all elements of the vector to the given value.
275 set :: PrimMonad m => MVector (PrimState m) a -> a -> m ()
276 {-# INLINE set #-}
277 set = G.set
278
279 -- | Copy a vector. The two vectors must have the same length and may not
280 -- overlap.
281 copy :: PrimMonad m
282 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
283 {-# INLINE copy #-}
284 copy = G.copy
285
286 -- | Copy a vector. The two vectors must have the same length and may not
287 -- overlap. This is not checked.
288 unsafeCopy :: PrimMonad m => MVector (PrimState m) a -- ^ target
289 -> MVector (PrimState m) a -- ^ source
290 -> m ()
291 {-# INLINE unsafeCopy #-}
292 unsafeCopy = G.unsafeCopy
293
294 -- Deprecated functions
295 -- --------------------
296
297 -- | /DEPRECATED/ Use 'replicate' instead
298 newWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
299 {-# INLINE newWith #-}
300 newWith = G.replicate
301
302 -- | /DEPRECATED/ Use 'replicate' instead
303 unsafeNewWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
304 {-# INLINE unsafeNewWith #-}
305 unsafeNewWith = G.replicate
306
307 {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
308