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