Added splitAt functions (contributed by Bas van Dijk)
[darcs-mirrors/vector.git] / Data / Vector / Primitive / Mutable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}
2
3 -- |
4 -- Module : Data.Vector.Primitive.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 primitive vectors.
13 --
14
15 module Data.Vector.Primitive.Mutable (
16 -- * Mutable vectors of primitive types
17 MVector(..), IOVector, STVector, Prim,
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.ByteArray
57 import Data.Primitive ( Prim, sizeOf )
58 import Control.Monad.Primitive
59 import Control.Monad ( liftM )
60
61 import Prelude hiding ( length, null, replicate, reverse, map, read,
62 take, drop, splitAt, init, tail )
63
64 import Data.Typeable ( Typeable )
65
66 #include "vector.h"
67
68 -- | Mutable vectors of primitive types.
69 data MVector s a = MVector {-# UNPACK #-} !Int
70 {-# UNPACK #-} !Int
71 {-# UNPACK #-} !(MutableByteArray s)
72 deriving ( Typeable )
73
74 type IOVector = MVector RealWorld
75 type STVector s = MVector s
76
77 instance Prim a => G.MVector MVector a where
78 basicLength (MVector _ n _) = n
79 basicUnsafeSlice j m (MVector i n arr)
80 = MVector (i+j) m arr
81
82 {-# INLINE basicOverlaps #-}
83 basicOverlaps (MVector i m arr1) (MVector j n arr2)
84 = sameMutableByteArray 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 = MVector 0 n
91 `liftM` newByteArray (n * sizeOf (undefined :: a))
92
93 {-# INLINE basicUnsafeRead #-}
94 basicUnsafeRead (MVector i n arr) j = readByteArray arr (i+j)
95
96 {-# INLINE basicUnsafeWrite #-}
97 basicUnsafeWrite (MVector i n arr) j x = writeByteArray arr (i+j) x
98
99 {-# INLINE basicUnsafeCopy #-}
100 basicUnsafeCopy (MVector i n dst) (MVector j _ src)
101 = memcpyByteArray dst (i * sz) src (j * sz) (n * sz)
102 where
103 sz = sizeOf (undefined :: a)
104
105 -- Length information
106 -- ------------------
107
108 -- | Length of the mutable vector.
109 length :: Prim a => MVector s a -> Int
110 {-# INLINE length #-}
111 length = G.length
112
113 -- | Check whether the vector is empty
114 null :: Prim a => MVector s a -> Bool
115 {-# INLINE null #-}
116 null = G.null
117
118 -- Extracting subvectors
119 -- ---------------------
120
121 -- | Yield a part of the mutable vector without copying it.
122 slice :: Prim a => Int -> Int -> MVector s a -> MVector s a
123 {-# INLINE slice #-}
124 slice = G.slice
125
126 take :: Prim a => Int -> MVector s a -> MVector s a
127 {-# INLINE take #-}
128 take = G.take
129
130 drop :: Prim a => Int -> MVector s a -> MVector s a
131 {-# INLINE drop #-}
132 drop = G.drop
133
134 splitAt :: Prim a => Int -> MVector s a -> (MVector s a, MVector s a)
135 {-# INLINE splitAt #-}
136 splitAt = G.splitAt
137
138 init :: Prim a => MVector s a -> MVector s a
139 {-# INLINE init #-}
140 init = G.init
141
142 tail :: Prim a => MVector s a -> MVector s a
143 {-# INLINE tail #-}
144 tail = G.tail
145
146 -- | Yield a part of the mutable vector without copying it. No bounds checks
147 -- are performed.
148 unsafeSlice :: Prim a
149 => Int -- ^ starting index
150 -> Int -- ^ length of the slice
151 -> MVector s a
152 -> MVector s a
153 {-# INLINE unsafeSlice #-}
154 unsafeSlice = G.unsafeSlice
155
156 unsafeTake :: Prim a => Int -> MVector s a -> MVector s a
157 {-# INLINE unsafeTake #-}
158 unsafeTake = G.unsafeTake
159
160 unsafeDrop :: Prim a => Int -> MVector s a -> MVector s a
161 {-# INLINE unsafeDrop #-}
162 unsafeDrop = G.unsafeDrop
163
164 unsafeInit :: Prim a => MVector s a -> MVector s a
165 {-# INLINE unsafeInit #-}
166 unsafeInit = G.unsafeInit
167
168 unsafeTail :: Prim a => MVector s a -> MVector s a
169 {-# INLINE unsafeTail #-}
170 unsafeTail = G.unsafeTail
171
172 -- Overlapping
173 -- -----------
174
175 -- Check whether two vectors overlap.
176 overlaps :: Prim a => MVector s a -> MVector s a -> Bool
177 {-# INLINE overlaps #-}
178 overlaps = G.overlaps
179
180 -- Initialisation
181 -- --------------
182
183 -- | Create a mutable vector of the given length.
184 new :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
185 {-# INLINE new #-}
186 new = G.new
187
188 -- | Create a mutable vector of the given length. The length is not checked.
189 unsafeNew :: (PrimMonad m, Prim a) => Int -> m (MVector (PrimState m) a)
190 {-# INLINE unsafeNew #-}
191 unsafeNew = G.unsafeNew
192
193 -- | Create a mutable vector of the given length (0 if the length is negative)
194 -- and fill it with an initial value.
195 replicate :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
196 {-# INLINE replicate #-}
197 replicate = G.replicate
198
199 -- | Create a copy of a mutable vector.
200 clone :: (PrimMonad m, Prim a)
201 => MVector (PrimState m) a -> m (MVector (PrimState m) a)
202 {-# INLINE clone #-}
203 clone = G.clone
204
205 -- Growing
206 -- -------
207
208 -- | Grow a vector by the given number of elements. The number must be
209 -- positive.
210 grow :: (PrimMonad m, Prim a)
211 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
212 {-# INLINE grow #-}
213 grow = G.grow
214
215 -- | Grow a vector by the given number of elements. The number must be
216 -- positive but this is not checked.
217 unsafeGrow :: (PrimMonad m, Prim a)
218 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
219 {-# INLINE unsafeGrow #-}
220 unsafeGrow = G.unsafeGrow
221
222 -- Restricting memory usage
223 -- ------------------------
224
225 -- | Reset all elements of the vector to some undefined value, clearing all
226 -- references to external objects. This is usually a noop for unboxed vectors.
227 clear :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> m ()
228 {-# INLINE clear #-}
229 clear = G.clear
230
231 -- Accessing individual elements
232 -- -----------------------------
233
234 -- | Yield the element at the given position.
235 read :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
236 {-# INLINE read #-}
237 read = G.read
238
239 -- | Replace the element at the given position.
240 write :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
241 {-# INLINE write #-}
242 write = G.write
243
244 -- | Swap the elements at the given positions.
245 swap :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()
246 {-# INLINE swap #-}
247 swap = G.swap
248
249
250 -- | Yield the element at the given position. No bounds checks are performed.
251 unsafeRead :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> m a
252 {-# INLINE unsafeRead #-}
253 unsafeRead = G.unsafeRead
254
255 -- | Replace the element at the given position. No bounds checks are performed.
256 unsafeWrite
257 :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> a -> m ()
258 {-# INLINE unsafeWrite #-}
259 unsafeWrite = G.unsafeWrite
260
261 -- | Swap the elements at the given positions. No bounds checks are performed.
262 unsafeSwap
263 :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> Int -> Int -> m ()
264 {-# INLINE unsafeSwap #-}
265 unsafeSwap = G.unsafeSwap
266
267 -- Filling and copying
268 -- -------------------
269
270 -- | Set all elements of the vector to the given value.
271 set :: (PrimMonad m, Prim a) => MVector (PrimState m) a -> a -> m ()
272 {-# INLINE set #-}
273 set = G.set
274
275 -- | Copy a vector. The two vectors must have the same length and may not
276 -- overlap.
277 copy :: (PrimMonad m, Prim a)
278 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
279 {-# INLINE copy #-}
280 copy = G.copy
281
282 -- | Copy a vector. The two vectors must have the same length and may not
283 -- overlap. This is not checked.
284 unsafeCopy :: (PrimMonad m, Prim a)
285 => MVector (PrimState m) a -- ^ target
286 -> MVector (PrimState m) a -- ^ source
287 -> m ()
288 {-# INLINE unsafeCopy #-}
289 unsafeCopy = G.unsafeCopy
290
291 -- Deprecated functions
292 -- --------------------
293
294 -- | /DEPRECATED/ Use 'replicate' instead
295 newWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
296 {-# INLINE newWith #-}
297 newWith = G.replicate
298
299 -- | /DEPRECATED/ Use 'replicate' instead
300 unsafeNewWith :: (PrimMonad m, Prim a) => Int -> a -> m (MVector (PrimState m) a)
301 {-# INLINE unsafeNewWith #-}
302 unsafeNewWith = G.replicate
303
304 {-# DEPRECATED newWith, unsafeNewWith "Use replicate instead" #-}
305