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