Clean up interface to mutable vectors
[darcs-mirrors/vector.git] / Data / Vector / Mutable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-}
2
3 -- |
4 -- Module : Data.Vector.Mutable
5 -- Copyright : (c) Roman Leshchinskiy 2008-2009
6 -- License : BSD-style
7 --
8 -- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>
9 -- Stability : experimental
10 -- Portability : non-portable
11 --
12 -- Mutable boxed vectors.
13 --
14
15 module Data.Vector.Mutable (
16 -- * Mutable boxed vectors
17 MVector(..), IOVector, STVector,
18
19 -- * Operations on mutable vectors
20 length, overlaps, slice, new, newWith, read, write, clear, set, copy, grow,
21
22 -- * Unsafe operations
23 unsafeSlice, unsafeNew, unsafeNewWith, unsafeRead, unsafeWrite,
24 unsafeCopy, unsafeGrow
25 ) where
26
27 import qualified Data.Vector.Generic.Mutable as G
28 import Data.Primitive.Array
29 import Control.Monad.Primitive
30 import Control.Monad.ST ( ST )
31
32 import Prelude hiding ( length, read )
33
34 #include "vector.h"
35
36 -- | Mutable boxed vectors keyed on the monad they live in ('IO' or @'ST' s@).
37 data MVector s a = MVector {-# UNPACK #-} !Int
38 {-# UNPACK #-} !Int
39 {-# UNPACK #-} !(MutableArray s a)
40
41 type IOVector = MVector RealWorld
42 type STVector s = MVector s
43
44 instance G.MVector MVector a where
45 {-# INLINE basicLength #-}
46 basicLength (MVector _ n _) = n
47
48 {-# INLINE basicUnsafeSlice #-}
49 basicUnsafeSlice (MVector i n arr) j m = MVector (i+j) m arr
50
51 {-# INLINE basicOverlaps #-}
52 basicOverlaps (MVector i m arr1) (MVector j n arr2)
53 = sameMutableArray arr1 arr2
54 && (between i j (j+n) || between j i (i+m))
55 where
56 between x y z = x >= y && x < z
57
58 {-# INLINE basicUnsafeNew #-}
59 basicUnsafeNew n
60 = do
61 arr <- newArray n uninitialised
62 return (MVector 0 n arr)
63
64 {-# INLINE basicUnsafeNewWith #-}
65 basicUnsafeNewWith n x
66 = do
67 arr <- newArray n x
68 return (MVector 0 n arr)
69
70 {-# INLINE basicUnsafeRead #-}
71 basicUnsafeRead (MVector i n arr) j = readArray arr (i+j)
72
73 {-# INLINE basicUnsafeWrite #-}
74 basicUnsafeWrite (MVector i n arr) j x = writeArray arr (i+j) x
75
76 {-# INLINE basicClear #-}
77 basicClear v = G.set v uninitialised
78
79 uninitialised :: a
80 uninitialised = error "Data.Vector.Mutable: uninitialised element"
81
82
83 -- | Yield a part of the mutable vector without copying it. No bounds checks
84 -- are performed.
85 unsafeSlice :: MVector s a -> Int -- ^ starting index
86 -> Int -- ^ length of the slice
87 -> MVector s a
88 {-# INLINE unsafeSlice #-}
89 unsafeSlice = G.unsafeSlice
90
91
92 -- | Create a mutable vector of the given length. The length is not checked.
93 unsafeNew :: PrimMonad m => Int -> m (MVector (PrimState m) a)
94 {-# INLINE unsafeNew #-}
95 unsafeNew = G.unsafeNew
96
97 -- | Create a mutable vector of the given length and fill it with an
98 -- initial value. The length is not checked.
99 unsafeNewWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
100 {-# INLINE unsafeNewWith #-}
101 unsafeNewWith = G.unsafeNewWith
102
103 -- | Yield the element at the given position. No bounds checks are performed.
104 unsafeRead :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
105 {-# INLINE unsafeRead #-}
106 unsafeRead = G.unsafeRead
107
108 -- | Replace the element at the given position. No bounds checks are performed.
109 unsafeWrite :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
110 {-# INLINE unsafeWrite #-}
111 unsafeWrite = G.unsafeWrite
112
113 -- | Copy a vector. The two vectors must have the same length and may not
114 -- overlap. This is not checked.
115 unsafeCopy :: PrimMonad m => MVector (PrimState m) a -- ^ target
116 -> MVector (PrimState m) a -- ^ source
117 -> m ()
118 {-# INLINE unsafeCopy #-}
119 unsafeCopy = G.unsafeCopy
120
121 -- | Grow a vector by the given number of elements. The number must be
122 -- positive but this is not checked.
123 unsafeGrow :: PrimMonad m
124 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
125 {-# INLINE unsafeGrow #-}
126 unsafeGrow = G.unsafeGrow
127
128 -- | Length of the mutable vector.
129 length :: MVector s a -> Int
130 {-# INLINE length #-}
131 length = G.length
132
133 -- Check whether two vectors overlap.
134 overlaps :: MVector s a -> MVector s a -> Bool
135 {-# INLINE overlaps #-}
136 overlaps = G.overlaps
137
138 -- | Yield a part of the mutable vector without copying it.
139 slice :: MVector s a -> Int -> Int -> MVector s a
140 {-# INLINE slice #-}
141 slice = G.slice
142
143 -- | Create a mutable vector of the given length.
144 new :: PrimMonad m => Int -> m (MVector (PrimState m) a)
145 {-# INLINE new #-}
146 new = G.new
147
148 -- | Create a mutable vector of the given length and fill it with an
149 -- initial value.
150 newWith :: PrimMonad m => Int -> a -> m (MVector (PrimState m) a)
151 {-# INLINE newWith #-}
152 newWith = G.newWith
153
154 -- | Yield the element at the given position.
155 read :: PrimMonad m => MVector (PrimState m) a -> Int -> m a
156 {-# INLINE read #-}
157 read = G.read
158
159 -- | Replace the element at the given position.
160 write :: PrimMonad m => MVector (PrimState m) a -> Int -> a -> m ()
161 {-# INLINE write #-}
162 write = G.write
163
164 -- | Reset all elements of the vector to some undefined value, clearing all
165 -- references to external objects. This is usually a noop for unboxed vectors.
166 clear :: PrimMonad m => MVector (PrimState m) a -> m ()
167 {-# INLINE clear #-}
168 clear = G.clear
169
170 -- | Set all elements of the vector to the given value.
171 set :: PrimMonad m => MVector (PrimState m) a -> a -> m ()
172 {-# INLINE set #-}
173 set = G.set
174
175 -- | Copy a vector. The two vectors must have the same length and may not
176 -- overlap.
177 copy :: PrimMonad m
178 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
179 {-# INLINE copy #-}
180 copy = G.copy
181
182 -- | Grow a vector by the given number of elements. The number must be
183 -- positive.
184 grow :: PrimMonad m
185 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
186 {-# INLINE grow #-}
187 grow = G.grow
188