37eca9d34c51ac87bd69416e31fa1a82e8fe0176
[darcs-mirrors/vector.git] / Data / Vector / Storable / Mutable.hs
1 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}
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 -- * 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, unsafeSwap,
25 unsafeCopy, unsafeGrow,
26
27 -- * Accessing the underlying memory
28 unsafeFromForeignPtr, unsafeToForeignPtr, unsafeWith
29 ) where
30
31 import qualified Data.Vector.Generic.Mutable as G
32 import Data.Vector.Storable.Internal
33
34 import Foreign.Storable
35 import Foreign.ForeignPtr
36 import Foreign.Ptr
37 import Foreign.Marshal.Array ( advancePtr )
38 import Foreign.Marshal.Utils ( copyBytes )
39 import Foreign.C.Types ( CInt )
40
41 import Control.Monad.Primitive
42
43 import Prelude hiding( length, read )
44
45 import Data.Typeable ( Typeable )
46
47 #include "vector.h"
48
49 -- | Mutable 'Storable'-based vectors
50 data MVector s a = MVector {-# UNPACK #-} !(Ptr a)
51 {-# UNPACK #-} !Int
52 {-# UNPACK #-} !(ForeignPtr a)
53 deriving ( Typeable )
54
55 type IOVector = MVector RealWorld
56 type STVector s = MVector s
57
58 instance Storable a => G.MVector MVector a where
59 {-# INLINE basicLength #-}
60 basicLength (MVector _ n _) = n
61
62 {-# INLINE basicUnsafeSlice #-}
63 basicUnsafeSlice j m (MVector p n fp) = MVector (p `advancePtr` j) m fp
64
65 -- FIXME: implement this properly
66 {-# INLINE basicOverlaps #-}
67 basicOverlaps (MVector _ _ _) (MVector _ _ _) = True
68
69 {-# INLINE basicUnsafeNew #-}
70 basicUnsafeNew n
71 = unsafePrimToPrim
72 $ do
73 fp <- mallocForeignPtrArray n
74 withForeignPtr fp $ \p -> return $ MVector p n fp
75
76 {-# INLINE basicUnsafeRead #-}
77 basicUnsafeRead (MVector p _ fp) i
78 = unsafePrimToPrim
79 $ withForeignPtr fp $ \_ -> peekElemOff p i
80
81 {-# INLINE basicUnsafeWrite #-}
82 basicUnsafeWrite (MVector p n fp) i x
83 = unsafePrimToPrim
84 $ withForeignPtr fp $ \_ -> pokeElemOff p i x
85
86 {-# INLINE basicUnsafeCopy #-}
87 basicUnsafeCopy (MVector p n fp) (MVector q _ fq)
88 = unsafePrimToPrim
89 $ withForeignPtr fp $ \_ ->
90 withForeignPtr fq $ \_ ->
91 do
92 copyBytes p q (fromIntegral (n * sizeOf (undefined :: a)))
93 return ()
94
95 -- | Create a mutable vector from a 'ForeignPtr' with an offset and a length.
96 -- Modifying data through the 'ForeignPtr' afterwards is unsafe if the vector
97 -- could have been frozen before the modification.
98 unsafeFromForeignPtr :: Storable a
99 => ForeignPtr a -- ^ pointer
100 -> Int -- ^ offset
101 -> Int -- ^ length
102 -> MVector s a
103 {-# INLINE unsafeFromForeignPtr #-}
104 unsafeFromForeignPtr fp i n = MVector (offsetToPtr fp i) n fp
105
106 -- | Yield the underlying 'ForeignPtr' together with the offset to the data
107 -- and its length. Modifying the data through the 'ForeignPtr' is
108 -- unsafe if the vector could have frozen before the modification.
109 unsafeToForeignPtr :: Storable a => MVector s a -> (ForeignPtr a, Int, Int)
110 {-# INLINE unsafeToForeignPtr #-}
111 unsafeToForeignPtr (MVector p n fp) = (fp, ptrToOffset fp p, n)
112
113 -- | Pass a pointer to the vector's data to the IO action. Modifying data
114 -- through the pointer is unsafe if the vector could have been frozen before
115 -- the modification.
116 unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
117 {-# INLINE unsafeWith #-}
118 unsafeWith (MVector p n fp) m = withForeignPtr fp $ \_ -> m p
119
120 -- | Yield a part of the mutable vector without copying it. No bounds checks
121 -- are performed.
122 unsafeSlice :: Storable a => Int -- ^ starting index
123 -> Int -- ^ length of the slice
124 -> MVector s a
125 -> MVector s a
126 {-# INLINE unsafeSlice #-}
127 unsafeSlice = G.unsafeSlice
128
129 -- | Create a mutable vector of the given length. The length is not checked.
130 unsafeNew :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
131 {-# INLINE unsafeNew #-}
132 unsafeNew = G.unsafeNew
133
134 -- | Create a mutable vector of the given length and fill it with an
135 -- initial value. The length is not checked.
136 unsafeNewWith :: (PrimMonad m, Storable a)
137 => Int -> a -> m (MVector (PrimState m) a)
138 {-# INLINE unsafeNewWith #-}
139 unsafeNewWith = G.unsafeNewWith
140
141 -- | Yield the element at the given position. No bounds checks are performed.
142 unsafeRead :: (PrimMonad m, Storable a)
143 => MVector (PrimState m) a -> Int -> m a
144 {-# INLINE unsafeRead #-}
145 unsafeRead = G.unsafeRead
146
147 -- | Replace the element at the given position. No bounds checks are performed.
148 unsafeWrite :: (PrimMonad m, Storable a)
149 => MVector (PrimState m) a -> Int -> a -> m ()
150 {-# INLINE unsafeWrite #-}
151 unsafeWrite = G.unsafeWrite
152
153 -- | Swap the elements at the given positions. No bounds checks are performed.
154 unsafeSwap :: (PrimMonad m, Storable a)
155 => MVector (PrimState m) a -> Int -> Int -> m ()
156 {-# INLINE unsafeSwap #-}
157 unsafeSwap = G.unsafeSwap
158
159 -- | Copy a vector. The two vectors must have the same length and may not
160 -- overlap. This is not checked.
161 unsafeCopy :: (PrimMonad m, Storable a)
162 => MVector (PrimState m) a -- ^ target
163 -> MVector (PrimState m) a -- ^ source
164 -> m ()
165 {-# INLINE unsafeCopy #-}
166 unsafeCopy = G.unsafeCopy
167
168 -- | Grow a vector by the given number of elements. The number must be
169 -- positive but this is not checked.
170 unsafeGrow :: (PrimMonad m, Storable a)
171 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
172 {-# INLINE unsafeGrow #-}
173 unsafeGrow = G.unsafeGrow
174
175 -- | Length of the mutable vector.
176 length :: Storable a => MVector s a -> Int
177 {-# INLINE length #-}
178 length = G.length
179
180 -- Check whether two vectors overlap.
181 overlaps :: Storable a => MVector s a -> MVector s a -> Bool
182 {-# INLINE overlaps #-}
183 overlaps = G.overlaps
184
185 -- | Yield a part of the mutable vector without copying it.
186 slice :: Storable a => Int -> Int -> MVector s a -> MVector s a
187 {-# INLINE slice #-}
188 slice = G.slice
189
190 -- | Create a mutable vector of the given length.
191 new :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
192 {-# INLINE new #-}
193 new = G.new
194
195 -- | Create a mutable vector of the given length and fill it with an
196 -- initial value.
197 newWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
198 {-# INLINE newWith #-}
199 newWith = G.newWith
200
201 -- | Yield the element at the given position.
202 read :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
203 {-# INLINE read #-}
204 read = G.read
205
206 -- | Replace the element at the given position.
207 write :: (PrimMonad m, Storable a)
208 => MVector (PrimState m) a -> Int -> a -> m ()
209 {-# INLINE write #-}
210 write = G.write
211
212 -- | Swap the elements at the given positions.
213 swap :: (PrimMonad m, Storable a)
214 => MVector (PrimState m) a -> Int -> Int -> m ()
215 {-# INLINE swap #-}
216 swap = G.swap
217
218 -- | Reset all elements of the vector to some undefined value, clearing all
219 -- references to external objects. This is usually a noop for unboxed vectors.
220 clear :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> m ()
221 {-# INLINE clear #-}
222 clear = G.clear
223
224 -- | Set all elements of the vector to the given value.
225 set :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> a -> m ()
226 {-# INLINE set #-}
227 set = G.set
228
229 -- | Copy a vector. The two vectors must have the same length and may not
230 -- overlap.
231 copy :: (PrimMonad m, Storable a)
232 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
233 {-# INLINE copy #-}
234 copy = G.copy
235
236 -- | Grow a vector by the given number of elements. The number must be
237 -- positive.
238 grow :: (PrimMonad m, Storable a)
239 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
240 {-# INLINE grow #-}
241 grow = G.grow
242