c0c8791e0af6ebb92aad14517bf10032342b4ef2
[darcs-mirrors/vector.git] / Data / Vector / Storable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}
2
3 -- |
4 -- Module : Data.Vector.Storable
5 -- Copyright : (c) Roman Leshchinskiy 2009
6 -- License : BSD-style
7 --
8 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
9 -- Stability : experimental
10 -- Portability : non-portable
11 --
12 -- 'Storable'-based vectors.
13 --
14
15 module Data.Vector.Storable (
16 Vector,
17
18 -- * Length information
19 length, null,
20
21 -- * Construction
22 empty, singleton, cons, snoc, replicate, (++), copy,
23
24 -- * Accessing individual elements
25 (!), head, last,
26
27 -- * Subvectors
28 slice, init, tail, take, drop,
29
30 -- * Permutations
31 accum, (//), backpermute, reverse,
32
33 -- * Mapping
34 map, concatMap,
35
36 -- * Zipping and unzipping
37 zipWith, zipWith3,
38
39 -- * Filtering
40 filter, takeWhile, dropWhile,
41
42 -- * Searching
43 elem, notElem, find, findIndex,
44
45 -- * Folding
46 foldl, foldl1, foldl', foldl1', foldr, foldr1,
47
48 -- * Specialised folds
49 and, or, sum, product, maximum, minimum,
50
51 -- * Unfolding
52 unfoldr,
53
54 -- * Scans
55 prescanl, prescanl',
56 postscanl, postscanl',
57 scanl, scanl', scanl1, scanl1',
58
59 -- * Enumeration
60 enumFromTo, enumFromThenTo,
61
62 -- * Conversion to/from lists
63 toList, fromList
64 ) where
65
66 import Data.Vector.IVector ( IVector(..) )
67 import qualified Data.Vector.IVector as IV
68 import qualified Data.Vector.Storable.Mutable as Mut
69 import Data.Vector.Storable.Internal
70
71 import Foreign.Storable
72 import Foreign.ForeignPtr
73
74 import System.IO.Unsafe ( unsafePerformIO )
75
76 import Prelude hiding ( length, null,
77 replicate, (++),
78 head, last,
79 init, tail, take, drop, reverse,
80 map, concatMap,
81 zipWith, zipWith3, zip, zip3, unzip, unzip3,
82 filter, takeWhile, dropWhile,
83 elem, notElem,
84 foldl, foldl1, foldr, foldr1,
85 and, or, sum, product, minimum, maximum,
86 scanl, scanl1,
87 enumFromTo, enumFromThenTo )
88
89 import qualified Prelude
90
91 -- | 'Storable'-based vectors
92 data Vector a = Vector {-# UNPACK #-} !Int
93 {-# UNPACK #-} !Int
94 {-# UNPACK #-} !(ForeignPtr a)
95
96 instance (Show a, Storable a) => Show (Vector a) where
97 show = (Prelude.++ " :: Data.Vector.Storable.Vector")
98 . ("fromList " Prelude.++)
99 . show
100 . toList
101
102 instance Storable a => IVector Vector a where
103 {-# INLINE vnew #-}
104 vnew init = unsafePerformIO (do
105 Mut.Vector i n p <- init
106 return (Vector i n p))
107
108 {-# INLINE vlength #-}
109 vlength (Vector _ n _) = n
110
111 {-# INLINE unsafeSlice #-}
112 unsafeSlice (Vector i _ p) j n = Vector (i+j) n p
113
114 {-# INLINE unsafeIndexM #-}
115 unsafeIndexM (Vector i _ p) j = return
116 . inlinePerformIO
117 $ withForeignPtr p (`peekElemOff` (i+j))
118
119 instance (Storable a, Eq a) => Eq (Vector a) where
120 {-# INLINE (==) #-}
121 (==) = IV.eq
122
123 instance (Storable a, Ord a) => Ord (Vector a) where
124 {-# INLINE compare #-}
125 compare = IV.cmp
126
127 -- Length
128 -- ------
129
130 length :: Storable a => Vector a -> Int
131 {-# INLINE length #-}
132 length = IV.length
133
134 null :: Storable a => Vector a -> Bool
135 {-# INLINE null #-}
136 null = IV.null
137
138 -- Construction
139 -- ------------
140
141 -- | Empty vector
142 empty :: Storable a => Vector a
143 {-# INLINE empty #-}
144 empty = IV.empty
145
146 -- | Vector with exaclty one element
147 singleton :: Storable a => a -> Vector a
148 {-# INLINE singleton #-}
149 singleton = IV.singleton
150
151 -- | Vector of the given length with the given value in each position
152 replicate :: Storable a => Int -> a -> Vector a
153 {-# INLINE replicate #-}
154 replicate = IV.replicate
155
156 -- | Prepend an element
157 cons :: Storable a => a -> Vector a -> Vector a
158 {-# INLINE cons #-}
159 cons = IV.cons
160
161 -- | Append an element
162 snoc :: Storable a => Vector a -> a -> Vector a
163 {-# INLINE snoc #-}
164 snoc = IV.snoc
165
166 infixr 5 ++
167 -- | Concatenate two vectors
168 (++) :: Storable a => Vector a -> Vector a -> Vector a
169 {-# INLINE (++) #-}
170 (++) = (IV.++)
171
172 -- | Create a copy of a vector. Useful when dealing with slices.
173 copy :: Storable a => Vector a -> Vector a
174 {-# INLINE copy #-}
175 copy = IV.copy
176
177 -- Accessing individual elements
178 -- -----------------------------
179
180 -- | Indexing
181 (!) :: Storable a => Vector a -> Int -> a
182 {-# INLINE (!) #-}
183 (!) = (IV.!)
184
185 -- | First element
186 head :: Storable a => Vector a -> a
187 {-# INLINE head #-}
188 head = IV.head
189
190 -- | Last element
191 last :: Storable a => Vector a -> a
192 {-# INLINE last #-}
193 last = IV.last
194
195 -- Subarrays
196 -- ---------
197
198 -- | Yield a part of the vector without copying it. Safer version of
199 -- 'unsafeSlice'.
200 slice :: Storable a => Vector a -> Int -- ^ starting index
201 -> Int -- ^ length
202 -> Vector a
203 {-# INLINE slice #-}
204 slice = IV.slice
205
206 -- | Yield all but the last element without copying.
207 init :: Storable a => Vector a -> Vector a
208 {-# INLINE init #-}
209 init = IV.init
210
211 -- | All but the first element (without copying).
212 tail :: Storable a => Vector a -> Vector a
213 {-# INLINE tail #-}
214 tail = IV.tail
215
216 -- | Yield the first @n@ elements without copying.
217 take :: Storable a => Int -> Vector a -> Vector a
218 {-# INLINE take #-}
219 take = IV.take
220
221 -- | Yield all but the first @n@ elements without copying.
222 drop :: Storable a => Int -> Vector a -> Vector a
223 {-# INLINE drop #-}
224 drop = IV.drop
225
226 -- Permutations
227 -- ------------
228
229 accum :: Storable a => (a -> b -> a) -> Vector a -> [(Int,b)] -> Vector a
230 {-# INLINE accum #-}
231 accum = IV.accum
232
233 (//) :: Storable a => Vector a -> [(Int, a)] -> Vector a
234 {-# INLINE (//) #-}
235 (//) = (IV.//)
236
237 backpermute :: Storable a => Vector a -> Vector Int -> Vector a
238 {-# INLINE backpermute #-}
239 backpermute = IV.backpermute
240
241 reverse :: Storable a => Vector a -> Vector a
242 {-# INLINE reverse #-}
243 reverse = IV.reverse
244
245 -- Mapping
246 -- -------
247
248 -- | Map a function over a vector
249 map :: (Storable a, Storable b) => (a -> b) -> Vector a -> Vector b
250 {-# INLINE map #-}
251 map = IV.map
252
253 concatMap :: (Storable a, Storable b) => (a -> Vector b) -> Vector a -> Vector b
254 {-# INLINE concatMap #-}
255 concatMap = IV.concatMap
256
257 -- Zipping/unzipping
258 -- -----------------
259
260 -- | Zip two vectors with the given function.
261 zipWith :: (Storable a, Storable b, Storable c)
262 => (a -> b -> c) -> Vector a -> Vector b -> Vector c
263 {-# INLINE zipWith #-}
264 zipWith = IV.zipWith
265
266 -- | Zip three vectors with the given function.
267 zipWith3 :: (Storable a, Storable b, Storable c, Storable d)
268 => (a -> b -> c -> d) -> Vector a -> Vector b -> Vector c -> Vector d
269 {-# INLINE zipWith3 #-}
270 zipWith3 = IV.zipWith3
271
272 -- Filtering
273 -- ---------
274
275 -- | Drop elements which do not satisfy the predicate
276 filter :: Storable a => (a -> Bool) -> Vector a -> Vector a
277 {-# INLINE filter #-}
278 filter = IV.filter
279
280 -- | Yield the longest prefix of elements satisfying the predicate.
281 takeWhile :: Storable a => (a -> Bool) -> Vector a -> Vector a
282 {-# INLINE takeWhile #-}
283 takeWhile = IV.takeWhile
284
285 -- | Drop the longest prefix of elements that satisfy the predicate.
286 dropWhile :: Storable a => (a -> Bool) -> Vector a -> Vector a
287 {-# INLINE dropWhile #-}
288 dropWhile = IV.dropWhile
289
290 -- Searching
291 -- ---------
292
293 infix 4 `elem`
294 -- | Check whether the vector contains an element
295 elem :: (Storable a, Eq a) => a -> Vector a -> Bool
296 {-# INLINE elem #-}
297 elem = IV.elem
298
299 infix 4 `notElem`
300 -- | Inverse of `elem`
301 notElem :: (Storable a, Eq a) => a -> Vector a -> Bool
302 {-# INLINE notElem #-}
303 notElem = IV.notElem
304
305 -- | Yield 'Just' the first element matching the predicate or 'Nothing' if no
306 -- such element exists.
307 find :: Storable a => (a -> Bool) -> Vector a -> Maybe a
308 {-# INLINE find #-}
309 find = IV.find
310
311 -- | Yield 'Just' the index of the first element matching the predicate or
312 -- 'Nothing' if no such element exists.
313 findIndex :: Storable a => (a -> Bool) -> Vector a -> Maybe Int
314 {-# INLINE findIndex #-}
315 findIndex = IV.findIndex
316
317 -- Folding
318 -- -------
319
320 -- | Left fold
321 foldl :: Storable b => (a -> b -> a) -> a -> Vector b -> a
322 {-# INLINE foldl #-}
323 foldl = IV.foldl
324
325 -- | Lefgt fold on non-empty vectors
326 foldl1 :: Storable a => (a -> a -> a) -> Vector a -> a
327 {-# INLINE foldl1 #-}
328 foldl1 = IV.foldl1
329
330 -- | Left fold with strict accumulator
331 foldl' :: Storable b => (a -> b -> a) -> a -> Vector b -> a
332 {-# INLINE foldl' #-}
333 foldl' = IV.foldl'
334
335 -- | Left fold on non-empty vectors with strict accumulator
336 foldl1' :: Storable a => (a -> a -> a) -> Vector a -> a
337 {-# INLINE foldl1' #-}
338 foldl1' = IV.foldl1'
339
340 -- | Right fold
341 foldr :: Storable a => (a -> b -> b) -> b -> Vector a -> b
342 {-# INLINE foldr #-}
343 foldr = IV.foldr
344
345 -- | Right fold on non-empty vectors
346 foldr1 :: Storable a => (a -> a -> a) -> Vector a -> a
347 {-# INLINE foldr1 #-}
348 foldr1 = IV.foldr1
349
350 -- Specialised folds
351 -- -----------------
352
353 and :: Vector Bool -> Bool
354 {-# INLINE and #-}
355 and = IV.and
356
357 or :: Vector Bool -> Bool
358 {-# INLINE or #-}
359 or = IV.or
360
361 sum :: (Storable a, Num a) => Vector a -> a
362 {-# INLINE sum #-}
363 sum = IV.sum
364
365 product :: (Storable a, Num a) => Vector a -> a
366 {-# INLINE product #-}
367 product = IV.product
368
369 maximum :: (Storable a, Ord a) => Vector a -> a
370 {-# INLINE maximum #-}
371 maximum = IV.maximum
372
373 minimum :: (Storable a, Ord a) => Vector a -> a
374 {-# INLINE minimum #-}
375 minimum = IV.minimum
376
377 -- Unfolding
378 -- ---------
379
380 unfoldr :: Storable a => (b -> Maybe (a, b)) -> b -> Vector a
381 {-# INLINE unfoldr #-}
382 unfoldr = IV.unfoldr
383
384 -- Scans
385 -- -----
386
387 -- | Prefix scan
388 prescanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a
389 {-# INLINE prescanl #-}
390 prescanl = IV.prescanl
391
392 -- | Prefix scan with strict accumulator
393 prescanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a
394 {-# INLINE prescanl' #-}
395 prescanl' = IV.prescanl'
396
397 -- | Suffix scan
398 postscanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a
399 {-# INLINE postscanl #-}
400 postscanl = IV.postscanl
401
402 -- | Suffix scan with strict accumulator
403 postscanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a
404 {-# INLINE postscanl' #-}
405 postscanl' = IV.postscanl'
406
407 -- | Haskell-style scan
408 scanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a
409 {-# INLINE scanl #-}
410 scanl = IV.scanl
411
412 -- | Haskell-style scan with strict accumulator
413 scanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector b -> Vector a
414 {-# INLINE scanl' #-}
415 scanl' = IV.scanl'
416
417 -- | Scan over a non-empty 'Vector'
418 scanl1 :: Storable a => (a -> a -> a) -> Vector a -> Vector a
419 {-# INLINE scanl1 #-}
420 scanl1 = IV.scanl1
421
422 -- | Scan over a non-empty 'Vector' with a strict accumulator
423 scanl1' :: Storable a => (a -> a -> a) -> Vector a -> Vector a
424 {-# INLINE scanl1' #-}
425 scanl1' = IV.scanl1'
426
427 -- Enumeration
428 -- -----------
429
430 enumFromTo :: (Storable a, Enum a) => a -> a -> Vector a
431 {-# INLINE enumFromTo #-}
432 enumFromTo = IV.enumFromTo
433
434 enumFromThenTo :: (Storable a, Enum a) => a -> a -> a -> Vector a
435 {-# INLINE enumFromThenTo #-}
436 enumFromThenTo = IV.enumFromThenTo
437
438 -- Conversion to/from lists
439 -- ------------------------
440
441 -- | Convert a vector to a list
442 toList :: Storable a => Vector a -> [a]
443 {-# INLINE toList #-}
444 toList = IV.toList
445
446 -- | Convert a list to a vector
447 fromList :: Storable a => [a] -> Vector a
448 {-# INLINE fromList #-}
449 fromList = IV.fromList
450