Implement basicOverlaps for Storable
[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: this relies on non-portable pointer comparisons
66 {-# INLINE basicOverlaps #-}
67 basicOverlaps (MVector p m _) (MVector q n _)
68 = between p q (q `advancePtr` n) || between q p (p `advancePtr` m)
69 where
70 between x y z = x >= y && x < z
71
72 {-# INLINE basicUnsafeNew #-}
73 basicUnsafeNew n
74 = unsafePrimToPrim
75 $ do
76 fp <- mallocForeignPtrArray n
77 withForeignPtr fp $ \p -> return $ MVector p n fp
78
79 {-# INLINE basicUnsafeRead #-}
80 basicUnsafeRead (MVector p _ fp) i
81 = unsafePrimToPrim
82 $ withForeignPtr fp $ \_ -> peekElemOff p i
83
84 {-# INLINE basicUnsafeWrite #-}
85 basicUnsafeWrite (MVector p n fp) i x
86 = unsafePrimToPrim
87 $ withForeignPtr fp $ \_ -> pokeElemOff p i x
88
89 {-# INLINE basicUnsafeCopy #-}
90 basicUnsafeCopy (MVector p n fp) (MVector q _ fq)
91 = unsafePrimToPrim
92 $ withForeignPtr fp $ \_ ->
93 withForeignPtr fq $ \_ ->
94 do
95 copyBytes p q (fromIntegral (n * sizeOf (undefined :: a)))
96 return ()
97
98 -- | Create a mutable vector from a 'ForeignPtr' with an offset and a length.
99 -- Modifying data through the 'ForeignPtr' afterwards is unsafe if the vector
100 -- could have been frozen before the modification.
101 unsafeFromForeignPtr :: Storable a
102 => ForeignPtr a -- ^ pointer
103 -> Int -- ^ offset
104 -> Int -- ^ length
105 -> MVector s a
106 {-# INLINE unsafeFromForeignPtr #-}
107 unsafeFromForeignPtr fp i n = MVector (offsetToPtr fp i) n fp
108
109 -- | Yield the underlying 'ForeignPtr' together with the offset to the data
110 -- and its length. Modifying the data through the 'ForeignPtr' is
111 -- unsafe if the vector could have frozen before the modification.
112 unsafeToForeignPtr :: Storable a => MVector s a -> (ForeignPtr a, Int, Int)
113 {-# INLINE unsafeToForeignPtr #-}
114 unsafeToForeignPtr (MVector p n fp) = (fp, ptrToOffset fp p, n)
115
116 -- | Pass a pointer to the vector's data to the IO action. Modifying data
117 -- through the pointer is unsafe if the vector could have been frozen before
118 -- the modification.
119 unsafeWith :: Storable a => IOVector a -> (Ptr a -> IO b) -> IO b
120 {-# INLINE unsafeWith #-}
121 unsafeWith (MVector p n fp) m = withForeignPtr fp $ \_ -> m p
122
123 -- | Yield a part of the mutable vector without copying it. No bounds checks
124 -- are performed.
125 unsafeSlice :: Storable a => Int -- ^ starting index
126 -> Int -- ^ length of the slice
127 -> MVector s a
128 -> MVector s a
129 {-# INLINE unsafeSlice #-}
130 unsafeSlice = G.unsafeSlice
131
132 -- | Create a mutable vector of the given length. The length is not checked.
133 unsafeNew :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
134 {-# INLINE unsafeNew #-}
135 unsafeNew = G.unsafeNew
136
137 -- | Create a mutable vector of the given length and fill it with an
138 -- initial value. The length is not checked.
139 unsafeNewWith :: (PrimMonad m, Storable a)
140 => Int -> a -> m (MVector (PrimState m) a)
141 {-# INLINE unsafeNewWith #-}
142 unsafeNewWith = G.unsafeNewWith
143
144 -- | Yield the element at the given position. No bounds checks are performed.
145 unsafeRead :: (PrimMonad m, Storable a)
146 => MVector (PrimState m) a -> Int -> m a
147 {-# INLINE unsafeRead #-}
148 unsafeRead = G.unsafeRead
149
150 -- | Replace the element at the given position. No bounds checks are performed.
151 unsafeWrite :: (PrimMonad m, Storable a)
152 => MVector (PrimState m) a -> Int -> a -> m ()
153 {-# INLINE unsafeWrite #-}
154 unsafeWrite = G.unsafeWrite
155
156 -- | Swap the elements at the given positions. No bounds checks are performed.
157 unsafeSwap :: (PrimMonad m, Storable a)
158 => MVector (PrimState m) a -> Int -> Int -> m ()
159 {-# INLINE unsafeSwap #-}
160 unsafeSwap = G.unsafeSwap
161
162 -- | Copy a vector. The two vectors must have the same length and may not
163 -- overlap. This is not checked.
164 unsafeCopy :: (PrimMonad m, Storable a)
165 => MVector (PrimState m) a -- ^ target
166 -> MVector (PrimState m) a -- ^ source
167 -> m ()
168 {-# INLINE unsafeCopy #-}
169 unsafeCopy = G.unsafeCopy
170
171 -- | Grow a vector by the given number of elements. The number must be
172 -- positive but this is not checked.
173 unsafeGrow :: (PrimMonad m, Storable a)
174 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
175 {-# INLINE unsafeGrow #-}
176 unsafeGrow = G.unsafeGrow
177
178 -- | Length of the mutable vector.
179 length :: Storable a => MVector s a -> Int
180 {-# INLINE length #-}
181 length = G.length
182
183 -- Check whether two vectors overlap.
184 overlaps :: Storable a => MVector s a -> MVector s a -> Bool
185 {-# INLINE overlaps #-}
186 overlaps = G.overlaps
187
188 -- | Yield a part of the mutable vector without copying it.
189 slice :: Storable a => Int -> Int -> MVector s a -> MVector s a
190 {-# INLINE slice #-}
191 slice = G.slice
192
193 -- | Create a mutable vector of the given length.
194 new :: (PrimMonad m, Storable a) => Int -> m (MVector (PrimState m) a)
195 {-# INLINE new #-}
196 new = G.new
197
198 -- | Create a mutable vector of the given length and fill it with an
199 -- initial value.
200 newWith :: (PrimMonad m, Storable a) => Int -> a -> m (MVector (PrimState m) a)
201 {-# INLINE newWith #-}
202 newWith = G.newWith
203
204 -- | Yield the element at the given position.
205 read :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> Int -> m a
206 {-# INLINE read #-}
207 read = G.read
208
209 -- | Replace the element at the given position.
210 write :: (PrimMonad m, Storable a)
211 => MVector (PrimState m) a -> Int -> a -> m ()
212 {-# INLINE write #-}
213 write = G.write
214
215 -- | Swap the elements at the given positions.
216 swap :: (PrimMonad m, Storable a)
217 => MVector (PrimState m) a -> Int -> Int -> m ()
218 {-# INLINE swap #-}
219 swap = G.swap
220
221 -- | Reset all elements of the vector to some undefined value, clearing all
222 -- references to external objects. This is usually a noop for unboxed vectors.
223 clear :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> m ()
224 {-# INLINE clear #-}
225 clear = G.clear
226
227 -- | Set all elements of the vector to the given value.
228 set :: (PrimMonad m, Storable a) => MVector (PrimState m) a -> a -> m ()
229 {-# INLINE set #-}
230 set = G.set
231
232 -- | Copy a vector. The two vectors must have the same length and may not
233 -- overlap.
234 copy :: (PrimMonad m, Storable a)
235 => MVector (PrimState m) a -> MVector (PrimState m) a -> m ()
236 {-# INLINE copy #-}
237 copy = G.copy
238
239 -- | Grow a vector by the given number of elements. The number must be
240 -- positive.
241 grow :: (PrimMonad m, Storable a)
242 => MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
243 {-# INLINE grow #-}
244 grow = G.grow
245