5
5
{-# LANGUAGE MultiParamTypeClasses #-}
6
6
{-# LANGUAGE RoleAnnotations #-}
7
7
{-# LANGUAGE TypeFamilies #-}
8
+ {-# LANGUAGE TypeApplications #-}
9
+ {-# LANGUAGE ScopedTypeVariables #-}
8
10
-- |
9
11
-- Module : Data.Vector.Strict.Mutable
10
12
-- Copyright : (c) Roman Leshchinskiy 2008-2010
@@ -72,16 +74,15 @@ module Data.Vector.Strict.Mutable (
72
74
PrimMonad , PrimState , RealWorld
73
75
) where
74
76
75
- import Control.Monad ( when )
77
+ import Data.Coerce
76
78
import qualified Data.Vector.Generic.Mutable as G
77
- import Data.Vector.Internal.Check
79
+ import qualified Data.Vector.Mutable as MV
78
80
import Data.Primitive.Array
79
81
import Control.Monad.Primitive
80
82
81
83
import Prelude
82
- ( Ord , Monad (.. ), Bool , Ordering (.. ), Int , Maybe
83
- , compare , return , otherwise , error
84
- , (+) , (-) , (*) , (<) , (>) , (>=) , (&&) , (||) , ($) , (>>) , (<$>) )
84
+ ( Ord , Monad (.. ), Bool , Int , Maybe
85
+ , return , ($) , (<$>) )
85
86
86
87
import Data.Typeable ( Typeable )
87
88
@@ -90,134 +91,39 @@ import Data.Typeable ( Typeable )
90
91
type role MVector nominal representational
91
92
92
93
-- | Mutable boxed vectors keyed on the monad they live in ('IO' or @'ST' s@).
93
- data MVector s a = MVector { _offset :: {-# UNPACK #-} ! Int
94
- -- ^ Offset in underlying array
95
- , _size :: {-# UNPACK #-} ! Int
96
- -- ^ Size of slice
97
- , _array :: {-# UNPACK #-} ! (MutableArray s a )
98
- -- ^ Underlying array
99
- }
94
+ newtype MVector s a = MVector (MV. MVector s a )
100
95
deriving ( Typeable )
101
96
102
97
type IOVector = MVector RealWorld
103
98
type STVector s = MVector s
104
99
105
- -- NOTE: This seems unsafe, see http://trac.haskell.org/vector/ticket/54
106
- {-
107
- instance NFData a => NFData (MVector s a) where
108
- rnf (MVector i n arr) = unsafeInlineST $ force i
109
- where
110
- force !ix | ix < n = do x <- readArray arr ix
111
- rnf x `seq` force (ix+1)
112
- | otherwise = return ()
113
- -}
114
-
115
100
instance G. MVector MVector a where
116
101
{-# INLINE basicLength #-}
117
- basicLength (MVector _ n _) = n
118
-
102
+ basicLength = coerce (G. basicLength @ MV. MVector @ a )
119
103
{-# INLINE basicUnsafeSlice #-}
120
- basicUnsafeSlice j m (MVector i _ arr) = MVector (i+ j) m arr
121
-
104
+ basicUnsafeSlice = coerce (G. basicUnsafeSlice @ MV. MVector @ a )
122
105
{-# INLINE basicOverlaps #-}
123
- basicOverlaps (MVector i m arr1) (MVector j n arr2)
124
- = sameMutableArray arr1 arr2
125
- && (between i j (j+ n) || between j i (i+ m))
126
- where
127
- between x y z = x >= y && x < z
128
-
106
+ basicOverlaps = coerce (G. basicOverlaps @ MV. MVector @ a )
129
107
{-# INLINE basicUnsafeNew #-}
130
- basicUnsafeNew n
131
- = do
132
- arr <- newArray n uninitialised
133
- return (MVector 0 n arr)
134
-
108
+ basicUnsafeNew = coerce (G. basicUnsafeNew @ MV. MVector @ a )
135
109
{-# INLINE basicInitialize #-}
136
110
-- initialization is unnecessary for boxed vectors
137
111
basicInitialize _ = return ()
138
-
139
112
{-# INLINE basicUnsafeReplicate #-}
140
- basicUnsafeReplicate n ! x
141
- = do
142
- arr <- newArray n x
143
- return (MVector 0 n arr)
144
-
113
+ basicUnsafeReplicate n ! x = coerce (G. basicUnsafeReplicate @ MV. MVector @ a ) n x
145
114
{-# INLINE basicUnsafeRead #-}
146
- basicUnsafeRead (MVector i _ arr) j = readArray arr (i+ j)
147
-
115
+ basicUnsafeRead = coerce (G. basicUnsafeRead @ MV. MVector @ a )
148
116
{-# INLINE basicUnsafeWrite #-}
149
- basicUnsafeWrite ( MVector i _ arr) j ! x = writeArray arr (i + j) x
117
+ basicUnsafeWrite vec j ! x = (coerce ( G. basicUnsafeWrite @ MV. MVector @ a )) vec j x
150
118
151
119
{-# INLINE basicUnsafeCopy #-}
152
- basicUnsafeCopy (MVector i n dst) (MVector j _ src)
153
- = copyMutableArray dst i src j n
154
-
155
- basicUnsafeMove dst@ (MVector iDst n arrDst) src@ (MVector iSrc _ arrSrc)
156
- = case n of
157
- 0 -> return ()
158
- 1 -> readArray arrSrc iSrc >>= writeArray arrDst iDst
159
- 2 -> do
160
- x <- readArray arrSrc iSrc
161
- y <- readArray arrSrc (iSrc + 1 )
162
- writeArray arrDst iDst x
163
- writeArray arrDst (iDst + 1 ) y
164
- _
165
- | overlaps dst src
166
- -> case compare iDst iSrc of
167
- LT -> moveBackwards arrDst iDst iSrc n
168
- EQ -> return ()
169
- GT | (iDst - iSrc) * 2 < n
170
- -> moveForwardsLargeOverlap arrDst iDst iSrc n
171
- | otherwise
172
- -> moveForwardsSmallOverlap arrDst iDst iSrc n
173
- | otherwise -> G. basicUnsafeCopy dst src
120
+ basicUnsafeCopy = coerce (G. basicUnsafeCopy @ MV. MVector @ a )
174
121
122
+ {-# INLINE basicUnsafeMove #-}
123
+ basicUnsafeMove = coerce (G. basicUnsafeMove @ MV. MVector @ a )
175
124
{-# INLINE basicClear #-}
176
- basicClear v = G. set v uninitialised
177
-
178
-
179
- {-# INLINE moveBackwards #-}
180
- moveBackwards :: PrimMonad m => MutableArray (PrimState m ) a -> Int -> Int -> Int -> m ()
181
- moveBackwards ! arr ! dstOff ! srcOff ! len =
182
- check Internal " not a backwards move" (dstOff < srcOff)
183
- $ loopM len $ \ i -> readArray arr (srcOff + i) >>= writeArray arr (dstOff + i)
184
-
185
- {-# INLINE moveForwardsSmallOverlap #-}
186
- -- Performs a move when dstOff > srcOff, optimized for when the overlap of the intervals is small.
187
- moveForwardsSmallOverlap :: PrimMonad m => MutableArray (PrimState m ) a -> Int -> Int -> Int -> m ()
188
- moveForwardsSmallOverlap ! arr ! dstOff ! srcOff ! len =
189
- check Internal " not a forward move" (dstOff > srcOff)
190
- $ do
191
- tmp <- newArray overlap uninitialised
192
- loopM overlap $ \ i -> readArray arr (dstOff + i) >>= writeArray tmp i
193
- loopM nonOverlap $ \ i -> readArray arr (srcOff + i) >>= writeArray arr (dstOff + i)
194
- loopM overlap $ \ i -> readArray tmp i >>= writeArray arr (dstOff + nonOverlap + i)
195
- where nonOverlap = dstOff - srcOff; overlap = len - nonOverlap
196
-
197
- -- Performs a move when dstOff > srcOff, optimized for when the overlap of the intervals is large.
198
- moveForwardsLargeOverlap :: PrimMonad m => MutableArray (PrimState m ) a -> Int -> Int -> Int -> m ()
199
- moveForwardsLargeOverlap ! arr ! dstOff ! srcOff ! len =
200
- check Internal " not a forward move" (dstOff > srcOff)
201
- $ do
202
- queue <- newArray nonOverlap uninitialised
203
- loopM nonOverlap $ \ i -> readArray arr (srcOff + i) >>= writeArray queue i
204
- let mov ! i ! qTop = when (i < dstOff + len) $ do
205
- x <- readArray arr i
206
- y <- readArray queue qTop
207
- writeArray arr i y
208
- writeArray queue qTop x
209
- mov (i+ 1 ) (if qTop + 1 >= nonOverlap then 0 else qTop + 1 )
210
- mov dstOff 0
211
- where nonOverlap = dstOff - srcOff
212
-
213
- {-# INLINE loopM #-}
214
- loopM :: Monad m => Int -> (Int -> m a ) -> m ()
215
- loopM ! n k = let
216
- go i = when (i < n) (k i >> go (i+ 1 ))
217
- in go 0
218
-
219
- uninitialised :: a
220
- uninitialised = error " Data.Vector.Mutable: uninitialised element. If you are trying to compact a vector, use the 'Data.Vector.force' function to remove uninitialised elements from the underlying array."
125
+ basicClear = coerce (G. basicClear @ MV. MVector @ a )
126
+
221
127
222
128
-- Length information
223
129
-- ------------------
@@ -811,18 +717,16 @@ ifoldrM' = G.ifoldrM'
811
717
fromMutableArray :: PrimMonad m => MutableArray (PrimState m ) a -> m (MVector (PrimState m ) a )
812
718
{-# INLINE fromMutableArray #-}
813
719
fromMutableArray marr = stToPrim $ do
814
- mvec <- MVector 0 size <$> cloneMutableArray marr 0 size
720
+ mvec <- MVector <$> MV. fromMutableArray marr
815
721
foldM' (\ _ ! _ -> return () ) () mvec
816
722
return mvec
817
- where
818
- size = sizeofMutableArray marr
819
723
820
724
-- | /O(n)/ Make a copy of a mutable vector into a new mutable array.
821
725
--
822
726
-- @since 0.13.2.0
823
727
toMutableArray :: PrimMonad m => MVector (PrimState m ) a -> m (MutableArray (PrimState m ) a )
824
728
{-# INLINE toMutableArray #-}
825
- toMutableArray (MVector offset size marr ) = cloneMutableArray marr offset size
729
+ toMutableArray (MVector v ) = MV. toMutableArray v
826
730
827
731
-- $setup
828
732
-- >>> import Prelude (Integer)
0 commit comments