Added splitAt functions (contributed by Bas van Dijk)
[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, 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, splitAt, 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 splitAt :: Storable a => Int -> MVector s a -> (MVector s a, MVector s a)
153 {-# INLINE splitAt #-}
154 splitAt = G.splitAt
155
156 init :: Storable a => MVector s a -> MVector s a
157 {-# INLINE init #-}
158 init = G.init
159
160 tail :: Storable a => MVector s a -> MVector s a
161 {-# INLINE tail #-}
162 tail = G.tail
163
164 -- | Yield a part of the mutable vector without copying it. No bounds checks
165 -- are performed.
166 unsafeSlice :: Storable a
167 => Int -- ^ starting index
168 -> Int -- ^ length of the slice
169 -> MVector s a
170 -> MVector s a
171 {-# INLINE unsafeSlice #-}
172 unsafeSlice = G.unsafeSlice
173
174 unsafeTake :: Storable a => Int -> MVector s a -> MVector s a
175 {-# INLINE unsafeTake #-}
176 unsafeTake = G.unsafeTake
177
178 unsafeDrop :: Storable a => Int -> MVector s a -> MVector s a
179 {-# INLINE unsafeDrop #-}
180 unsafeDrop = G.unsafeDrop
181
182 unsafeInit :: Storable a => MVector s a -> MVector s a
183 {-# INLINE unsafeInit #-}
184 unsafeInit = G.unsafeInit
185
186 unsafeTail :: Storable a => MVector s a -> MVector s a
187 {-# INLINE unsafeTail #-}
188 unsafeTail = G.unsafeTail
189
190 -- Overlapping
191 -- -----------
192
193 -- Check whether two vectors overlap.
194 overlaps :: Storable a => MVector s a -> MVector s a -> Bool
195 {-# INLINE overlaps #-}
196 overlaps = G.overlaps
197
198 -- Initialisation
199 -- --------------
200
201 -- | Create a mutable vector of the given length.
202 new :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
203 {-# INLINE new #-}
204 new = G.new
205
206 -- | Create a mutable vector of the given length. The length is not checked.
207 unsafeNew :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
208 {-# INLINE unsafeNew #-}
209 unsafeNew = G.unsafeNew
210
211 -- | Create a mutable vector of the given length (0 if the length is negative)
212 -- and fill it with an initial value.
213 replicate :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
214 {-# INLINE replicate #-}
215 replicate = G.replicate
216
217 -- | Create a copy of a mutable vector.
218 clone :: (PrimMonad m, Storable a)
219 => MVector (PrimState m) a -> m (MVector (PrimState m) a)
220 {-# INLINE clone #-}
221 clone = G.clone
222
223 -- Growing
224 -- -------
225
226 -- | Grow a vector by the given number of elements. The number must be
227 -- positive.
228 grow :: (PrimMonad m, Storable a)
229 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
230 {-# INLINE grow #-}
231 grow = G.grow
232
233 -- | Grow a vector by the given number of elements. The number must be
234 -- positive but this is not checked.
235 unsafeGrow :: (PrimMonad m, Storable a)
236 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
237 {-# INLINE unsafeGrow #-}
238 unsafeGrow = G.unsafeGrow
239
240 -- Restricting memory usage
241 -- ------------------------
242
243 -- | Reset all elements of the vector to some undefined value, clearing all
244 -- references to external objects. This is usually a noop for unboxed vectors.
245 clear :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> m ()
246 {-# INLINE clear #-}
247 clear = G.clear
248
249 -- Accessing individual elements
250 -- -----------------------------
251
252 -- | Yield the element at the given position.
253 read :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
254 {-# INLINE read #-}
255 read = G.read
256
257 -- | Replace the element at the given position.
258 write
259 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m ()
260 {-# INLINE write #-}
261 write = G.write
262
263 -- | Swap the elements at the given positions.
264 swap
265 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m ()
266 {-# INLINE swap #-}
267 swap = G.swap
268
269
270 -- | Yield the element at the given position. No bounds checks are performed.
271 unsafeRead :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
272 {-# INLINE unsafeRead #-}
273 unsafeRead = G.unsafeRead
274
275 -- | Replace the element at the given position. No bounds checks are performed.
276 unsafeWrite
277 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> a -> m ()
278 {-# INLINE unsafeWrite #-}
279 unsafeWrite = G.unsafeWrite
280
281 -- | Swap the elements at the given positions. No bounds checks are performed.
282 unsafeSwap
283 :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> Int -> m ()
284 {-# INLINE unsafeSwap #-}
285 unsafeSwap = G.unsafeSwap
286
287 -- Filling and copying
288 -- -------------------
289
290 -- | Set all elements of the vector to the given value.
291 set :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> a -> m ()
292 {-# INLINE set #-}
293 set = G.set
294
295 -- | Copy a vector. The two vectors must have the same length and may not
296 -- overlap.
297 copy :: (PrimMonad m, Storable a)
298 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
299 {-# INLINE copy #-}
300 copy = G.copy
301
302 -- | Copy a vector. The two vectors must have the same length and may not
303 -- overlap. This is not checked.
304 unsafeCopy :: (PrimMonad m, Storable a)
305 => MVector (PrimState m) a -- ^ target
306 -> MVector (PrimState m) a -- ^ source
307 -> m ()
308 {-# INLINE unsafeCopy #-}
309 unsafeCopy = G.unsafeCopy
310
311 -- Raw pointers
312 -- ------------
313
314 -- | Create a mutable vector from a 'ForeignPtr' with an offset and a length.
315 -- Modifying data through the 'ForeignPtr' afterwards is unsafe if the vector
316 -- could have been frozen before the modification.
317 unsafeFromForeignPtr :: Storable a
318 => ForeignPtr a -- ^ pointer
319 -> Int -- ^ offset
320 -> Int -- ^ length
321 -> MVector s a
322 {-# INLINE unsafeFromForeignPtr #-}
323 unsafeFromForeignPtr fp i n = MVector (offsetToPtr fp i) n fp
324
325 -- | Yield the underlying 'ForeignPtr' together with the offset to the data
326 -- and its length. Modifying the data through the 'ForeignPtr' is
327 -- unsafe if the vector could have frozen before the modification.
328 unsafeToForeignPtr :: Storable a => MVector s a -> (ForeignPtr a, Int, Int)
329 {-# INLINE unsafeToForeignPtr #-}
330 unsafeToForeignPtr (MVector p n fp) = (fp, ptrToOffset fp p, n)
331
332 -- | Pass a pointer to the vector's data to the IO action. Modifying data
333 -- through the pointer is unsafe if the vector could have been frozen before
334 -- the modification.
335 unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
336 {-# INLINE unsafeWith #-}
337 unsafeWith (MVector p n fp) m = withForeignPtr fp $ \_ -> m p
338
339 -- Deprecated functions
340 -- --------------------
341
342 -- | /DEPRECATED/ Use 'replicate' instead
343 newWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
344 {-# INLINE newWith #-}
345 newWith = G.replicate
346
347 -- | /DEPRECATED/ Use 'replicate' instead
348 unsafeNewWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
349 {-# INLINE unsafeNewWith #-}
350 unsafeNewWith = G.replicate
351
352 {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
353