d437a54fe7273acf4f58bd676b70ec5f34ca5847
[darcs-mirrors/vector.git] / Data / Vector / Storable / Mutable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
2
3 -- |
4 -- Module : Data.Vector.Storable.Mutable
5 -- Copyright : (c) Roman Leshchinskiy 2009-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 vectors based on Storable.
13 --
14
15 module Data.Vector.Storable.Mutable(
16 -- * Mutable vectors of 'Storable' types
17 MVector(..), IOVector, STVector, Storable,
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 -- * Raw pointers
52 unsafeFromForeignPtr, unsafeToForeignPtr, unsafeWith,
53
54 -- * Deprecated operations
55 newWith, unsafeNewWith
56 ) where
57
58 import qualified Data.Vector.Generic.Mutable as G
59 import Data.Vector.Storable.Internal
60
61 import Foreign.Storable
62 import Foreign.ForeignPtr
63
64 #if __GLASGOW_HASKELL__ >= 605
65 import GHC.ForeignPtr (mallocPlainForeignPtrBytes)
66 #endif
67
68 import Foreign.Ptr
69 import Foreign.Marshal.Array ( advancePtr, copyArray, moveArray )
70 import Foreign.C.Types ( CInt )
71
72 import Control.Monad.Primitive
73
74 import Prelude hiding ( length, null, replicate, reverse, map, read,
75 take, drop, splitAt, init, tail )
76
77 import Data.Typeable ( Typeable )
78
79 #include "vector.h"
80
81 -- | Mutable 'Storable'-based vectors
82 data MVector s a = MVector {-# UNPACK #-} !(Ptr a)
83 {-# UNPACK #-} !Int
84 {-# UNPACK #-} !(ForeignPtr a)
85 deriving ( Typeable )
86
87 type IOVector = MVector RealWorld
88 type STVector s = MVector s
89
90 instance Storable a => G.MVector MVector a where
91 {-# INLINE basicLength #-}
92 basicLength (MVector _ n _) = n
93
94 {-# INLINE basicUnsafeSlice #-}
95 basicUnsafeSlice j m (MVector p n fp) = MVector (p `advancePtr` j) m fp
96
97 -- FIXME: this relies on non-portable pointer comparisons
98 {-# INLINE basicOverlaps #-}
99 basicOverlaps (MVector p m _) (MVector q n _)
100 = between p q (q `advancePtr` n) || between q p (p `advancePtr` m)
101 where
102 between x y z = x >= y && x < z
103
104 {-# INLINE basicUnsafeNew #-}
105 basicUnsafeNew n
106 = unsafePrimToPrim
107 $ do
108 fp <- mallocVector n
109 withForeignPtr fp $ \p -> return $ MVector p n fp
110
111 {-# INLINE basicUnsafeRead #-}
112 basicUnsafeRead (MVector p _ fp) i
113 = unsafePrimToPrim
114 $ withForeignPtr fp $ \_ -> peekElemOff p i
115
116 {-# INLINE basicUnsafeWrite #-}
117 basicUnsafeWrite (MVector p n fp) i x
118 = unsafePrimToPrim
119 $ withForeignPtr fp $ \_ -> pokeElemOff p i x
120
121 {-# INLINE basicUnsafeCopy #-}
122 basicUnsafeCopy (MVector p n fp) (MVector q _ fq)
123 = unsafePrimToPrim
124 $ withForeignPtr fp $ \_ ->
125 withForeignPtr fq $ \_ ->
126 copyArray p q n
127
128 {-# INLINE basicUnsafeMove #-}
129 basicUnsafeMove (MVector p n fp) (MVector q _ fq)
130 = unsafePrimToPrim
131 $ withForeignPtr fp $ \_ ->
132 withForeignPtr fq $ \_ ->
133 moveArray p q n
134
135 {-# INLINE mallocVector #-}
136 mallocVector :: Storable a => Int -> IO (ForeignPtr a)
137 mallocVector =
138 #if __GLASGOW_HASKELL__ >= 605
139 doMalloc undefined
140 where
141 doMalloc :: Storable b => b -> Int -> IO (ForeignPtr b)
142 doMalloc dummy size = mallocPlainForeignPtrBytes (size * sizeOf dummy)
143 #else
144 mallocForeignPtrArray
145 #endif
146
147 -- Length information
148 -- ------------------
149
150 -- | Length of the mutable vector.
151 length :: Storable a => MVector s a -> Int
152 {-# INLINE length #-}
153 length = G.length
154
155 -- | Check whether the vector is empty
156 null :: Storable a => MVector s a -> Bool
157 {-# INLINE null #-}
158 null = G.null
159
160 -- Extracting subvectors
161 -- ---------------------
162
163 -- | Yield a part of the mutable vector without copying it.
164 slice :: Storable a => Int -> Int -> MVector s a -> MVector s a
165 {-# INLINE slice #-}
166 slice = G.slice
167
168 take :: Storable a => Int -> MVector s a -> MVector s a
169 {-# INLINE take #-}
170 take = G.take
171
172 drop :: Storable a => Int -> MVector s a -> MVector s a
173 {-# INLINE drop #-}
174 drop = G.drop
175
176 splitAt :: Storable a => Int -> MVector s a -> (MVector s a, MVector s a)
177 {-# INLINE splitAt #-}
178 splitAt = G.splitAt
179
180 init :: Storable a => MVector s a -> MVector s a
181 {-# INLINE init #-}
182 init = G.init
183
184 tail :: Storable a => MVector s a -> MVector s a
185 {-# INLINE tail #-}
186 tail = G.tail
187
188 -- | Yield a part of the mutable vector without copying it. No bounds checks
189 -- are performed.
190 unsafeSlice :: Storable a
191 => Int -- ^ starting index
192 -> Int -- ^ length of the slice
193 -> MVector s a
194 -> MVector s a
195 {-# INLINE unsafeSlice #-}
196 unsafeSlice = G.unsafeSlice
197
198 unsafeTake :: Storable a => Int -> MVector s a -> MVector s a
199 {-# INLINE unsafeTake #-}
200 unsafeTake = G.unsafeTake
201
202 unsafeDrop :: Storable a => Int -> MVector s a -> MVector s a
203 {-# INLINE unsafeDrop #-}
204 unsafeDrop = G.unsafeDrop
205
206 unsafeInit :: Storable a => MVector s a -> MVector s a
207 {-# INLINE unsafeInit #-}
208 unsafeInit = G.unsafeInit
209
210 unsafeTail :: Storable a => MVector s a -> MVector s a
211 {-# INLINE unsafeTail #-}
212 unsafeTail = G.unsafeTail
213
214 -- Overlapping
215 -- -----------
216
217 -- Check whether two vectors overlap.
218 overlaps :: Storable a => MVector s a -> MVector s a -> Bool
219 {-# INLINE overlaps #-}
220 overlaps = G.overlaps
221
222 -- Initialisation
223 -- --------------
224
225 -- | Create a mutable vector of the given length.
226 new :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
227 {-# INLINE new #-}
228 new = G.new
229
230 -- | Create a mutable vector of the given length. The length is not checked.
231 unsafeNew :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
232 {-# INLINE unsafeNew #-}
233 unsafeNew = G.unsafeNew
234
235 -- | Create a mutable vector of the given length (0 if the length is negative)
236 -- and fill it with an initial value.
237 replicate :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
238 {-# INLINE replicate #-}
239 replicate = G.replicate
240
241 -- | Create a copy of a mutable vector.
242 clone :: (PrimMonad m, Storable a)
243 => MVector (PrimState m) a -> m (MVector (PrimState m) a)
244 {-# INLINE clone #-}
245 clone = G.clone
246
247 -- Growing
248 -- -------
249
250 -- | Grow a vector by the given number of elements. The number must be
251 -- positive.
252 grow :: (PrimMonad m, Storable a)
253 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
254 {-# INLINE grow #-}
255 grow = G.grow
256
257 -- | Grow a vector by the given number of elements. The number must be
258 -- positive but this is not checked.
259 unsafeGrow :: (PrimMonad m, Storable a)
260 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
261 {-# INLINE unsafeGrow #-}
262 unsafeGrow = G.unsafeGrow
263
264 -- Restricting memory usage
265 -- ------------------------
266
267 -- | Reset all elements of the vector to some undefined value, clearing all
268 -- references to external objects. This is usually a noop for unboxed vectors.
269 clear :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> m ()
270 {-# INLINE clear #-}
271 clear = G.clear
272
273 -- Accessing individual elements
274 -- -----------------------------
275
276 -- | Yield the element at the given position.
277 read :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
278 {-# INLINE read #-}
279 read = G.read
280
281 -- | Replace the element at the given position.
282 write
283 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m ()
284 {-# INLINE write #-}
285 write = G.write
286
287 -- | Swap the elements at the given positions.
288 swap
289 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m ()
290 {-# INLINE swap #-}
291 swap = G.swap
292
293
294 -- | Yield the element at the given position. No bounds checks are performed.
295 unsafeRead :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
296 {-# INLINE unsafeRead #-}
297 unsafeRead = G.unsafeRead
298
299 -- | Replace the element at the given position. No bounds checks are performed.
300 unsafeWrite
301 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m ()
302 {-# INLINE unsafeWrite #-}
303 unsafeWrite = G.unsafeWrite
304
305 -- | Swap the elements at the given positions. No bounds checks are performed.
306 unsafeSwap
307 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m ()
308 {-# INLINE unsafeSwap #-}
309 unsafeSwap = G.unsafeSwap
310
311 -- Filling and copying
312 -- -------------------
313
314 -- | Set all elements of the vector to the given value.
315 set :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> a -> m ()
316 {-# INLINE set #-}
317 set = G.set
318
319 -- | Copy a vector. The two vectors must have the same length and may not
320 -- overlap.
321 copy :: (PrimMonad m, Storable a)
322 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
323 {-# INLINE copy #-}
324 copy = G.copy
325
326 -- | Copy a vector. The two vectors must have the same length and may not
327 -- overlap. This is not checked.
328 unsafeCopy :: (PrimMonad m, Storable a)
329 => MVector (PrimState m) a -- ^ target
330 -> MVector (PrimState m) a -- ^ source
331 -> m ()
332 {-# INLINE unsafeCopy #-}
333 unsafeCopy = G.unsafeCopy
334
335 -- | Move the contents of a vector. The two vectors must have the same
336 -- length.
337 --
338 -- If the vectors do not overlap, then this is equivalent to 'copy'.
339 -- Otherwise, the copying is performed as if the source vector were
340 -- copied to a temporary vector and then the temporary vector was copied
341 -- to the target vector.
342 move :: (PrimMonad m, Storable a)
343 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
344 {-# INLINE move #-}
345 move = G.move
346
347 -- | Move the contents of a vector. The two vectors must have the same
348 -- length, but this is not checked.
349 --
350 -- If the vectors do not overlap, then this is equivalent to 'unsafeCopy'.
351 -- Otherwise, the copying is performed as if the source vector were
352 -- copied to a temporary vector and then the temporary vector was copied
353 -- to the target vector.
354 unsafeMove :: (PrimMonad m, Storable a)
355 => MVector (PrimState m) a -- ^ target
356 -> MVector (PrimState m) a -- ^ source
357 -> m ()
358 {-# INLINE unsafeMove #-}
359 unsafeMove = G.unsafeMove
360
361 -- Raw pointers
362 -- ------------
363
364 -- | Create a mutable vector from a 'ForeignPtr' with an offset and a length.
365 -- Modifying data through the 'ForeignPtr' afterwards is unsafe if the vector
366 -- could have been frozen before the modification.
367 unsafeFromForeignPtr :: Storable a
368 => ForeignPtr a -- ^ pointer
369 -> Int -- ^ offset
370 -> Int -- ^ length
371 -> MVector s a
372 {-# INLINE unsafeFromForeignPtr #-}
373 unsafeFromForeignPtr fp i n = MVector (offsetToPtr fp i) n fp
374
375 -- | Yield the underlying 'ForeignPtr' together with the offset to the data
376 -- and its length. Modifying the data through the 'ForeignPtr' is
377 -- unsafe if the vector could have frozen before the modification.
378 unsafeToForeignPtr :: Storable a => MVector s a -> (ForeignPtr a, Int, Int)
379 {-# INLINE unsafeToForeignPtr #-}
380 unsafeToForeignPtr (MVector p n fp) = (fp, ptrToOffset fp p, n)
381
382 -- | Pass a pointer to the vector's data to the IO action. Modifying data
383 -- through the pointer is unsafe if the vector could have been frozen before
384 -- the modification.
385 unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
386 {-# INLINE unsafeWith #-}
387 unsafeWith (MVector p n fp) m = withForeignPtr fp $ \_ -> m p
388
389 -- Deprecated functions
390 -- --------------------
391
392 -- | /DEPRECATED/ Use 'replicate' instead
393 newWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
394 {-# INLINE newWith #-}
395 newWith = G.replicate
396
397 -- | /DEPRECATED/ Use 'replicate' instead
398 unsafeNewWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
399 {-# INLINE unsafeNewWith #-}
400 unsafeNewWith = G.replicate
401
402 {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
403