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