Skip to content

Commit dafe833

Browse files
committed
Move both mutable and immutable vectors to Unsafe module
1 parent a139101 commit dafe833

File tree

4 files changed

+280
-241
lines changed

4 files changed

+280
-241
lines changed

vector/src/Data/Vector/Primitive.hs

Lines changed: 5 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -158,150 +158,17 @@ module Data.Vector.Primitive (
158158
) where
159159

160160
import qualified Data.Vector.Generic as G
161-
import Data.Vector.Primitive.Mutable ( MVector(..) )
161+
import Data.Vector.Primitive.Unsafe (Vector(..),MVector(..),unsafeCoerceVector)
162162
import Data.Vector.Internal.Check
163-
import qualified Data.Vector.Fusion.Bundle as Bundle
164-
import Data.Primitive.ByteArray
165163
import Data.Primitive ( Prim, sizeOf )
166164

167-
import Control.DeepSeq ( NFData(rnf)
168-
#if MIN_VERSION_deepseq(1,4,3)
169-
, NFData1(liftRnf)
170-
#endif
171-
)
172-
173-
import Control.Monad ( liftM )
174165
import Control.Monad.ST ( ST )
175166
import Control.Monad.Primitive
176167

177168
import Prelude
178-
( Eq, Ord, Num, Enum, Monoid, Traversable, Monad, Read, Show, Bool, Ordering(..), Int, Maybe, Either
179-
, compare, mempty, mappend, mconcat, showsPrec, return, otherwise, seq, error, undefined
180-
, (+), (*), (<), (<=), (>), (>=), (==), (/=), ($!) )
181-
182-
import Data.Data ( Data(..) )
183-
import Text.Read ( Read(..), readListPrecDefault )
184-
import Data.Semigroup ( Semigroup(..) )
185-
186-
import Data.Coerce
187-
import Unsafe.Coerce
188-
import qualified GHC.Exts as Exts
189-
190-
type role Vector nominal
191-
192-
-- | /O(1)/ Unsafely coerce an immutable vector from one element type to another,
193-
-- representationally equal type. The operation just changes the type of the
194-
-- underlying pointer and does not modify the elements.
195-
--
196-
-- This is marginally safer than 'unsafeCast', since this function imposes an
197-
-- extra 'Coercible' constraint. The constraint guarantees that the element types
198-
-- are representationally equal. It however cannot guarantee
199-
-- that their respective 'Prim' instances are compatible.
200-
unsafeCoerceVector :: Coercible a b => Vector a -> Vector b
201-
unsafeCoerceVector = unsafeCoerce
202-
203-
-- | Unboxed vectors of primitive types.
204-
data Vector a = Vector {-# UNPACK #-} !Int -- ^ offset
205-
{-# UNPACK #-} !Int -- ^ length
206-
{-# UNPACK #-} !ByteArray -- ^ underlying byte array
207-
208-
instance NFData (Vector a) where
209-
rnf (Vector _ _ _) = ()
210-
211-
#if MIN_VERSION_deepseq(1,4,3)
212-
-- | @since 0.12.1.0
213-
instance NFData1 Vector where
214-
liftRnf _ (Vector _ _ _) = ()
215-
#endif
216-
217-
instance (Show a, Prim a) => Show (Vector a) where
218-
showsPrec = G.showsPrec
219-
220-
instance (Read a, Prim a) => Read (Vector a) where
221-
readPrec = G.readPrec
222-
readListPrec = readListPrecDefault
223-
224-
instance (Data a, Prim a) => Data (Vector a) where
225-
gfoldl = G.gfoldl
226-
toConstr _ = G.mkVecConstr "Data.Vector.Primitive.Vector"
227-
gunfold = G.gunfold
228-
dataTypeOf _ = G.mkVecType "Data.Vector.Primitive.Vector"
229-
dataCast1 = G.dataCast
230-
231-
232-
type instance G.Mutable Vector = MVector
233-
234-
instance Prim a => G.Vector Vector a where
235-
{-# INLINE basicUnsafeFreeze #-}
236-
basicUnsafeFreeze (MVector i n marr)
237-
= Vector i n `liftM` unsafeFreezeByteArray marr
238-
239-
{-# INLINE basicUnsafeThaw #-}
240-
basicUnsafeThaw (Vector i n arr)
241-
= MVector i n `liftM` unsafeThawByteArray arr
242-
243-
{-# INLINE basicLength #-}
244-
basicLength (Vector _ n _) = n
245-
246-
{-# INLINE basicUnsafeSlice #-}
247-
basicUnsafeSlice j n (Vector i _ arr) = Vector (i+j) n arr
248-
249-
{-# INLINE basicUnsafeIndexM #-}
250-
basicUnsafeIndexM (Vector i _ arr) j = return $! indexByteArray arr (i+j)
251-
252-
{-# INLINE basicUnsafeCopy #-}
253-
basicUnsafeCopy (MVector i n dst) (Vector j _ src)
254-
= copyByteArray dst (i*sz) src (j*sz) (n*sz)
255-
where
256-
sz = sizeOf (undefined :: a)
257-
258-
{-# INLINE elemseq #-}
259-
elemseq _ = seq
260-
261-
-- See http://trac.haskell.org/vector/ticket/12
262-
instance (Prim a, Eq a) => Eq (Vector a) where
263-
{-# INLINE (==) #-}
264-
xs == ys = Bundle.eq (G.stream xs) (G.stream ys)
265-
266-
-- See http://trac.haskell.org/vector/ticket/12
267-
instance (Prim a, Ord a) => Ord (Vector a) where
268-
{-# INLINE compare #-}
269-
compare xs ys = Bundle.cmp (G.stream xs) (G.stream ys)
270-
271-
{-# INLINE (<) #-}
272-
xs < ys = Bundle.cmp (G.stream xs) (G.stream ys) == LT
273-
274-
{-# INLINE (<=) #-}
275-
xs <= ys = Bundle.cmp (G.stream xs) (G.stream ys) /= GT
276-
277-
{-# INLINE (>) #-}
278-
xs > ys = Bundle.cmp (G.stream xs) (G.stream ys) == GT
279-
280-
{-# INLINE (>=) #-}
281-
xs >= ys = Bundle.cmp (G.stream xs) (G.stream ys) /= LT
282-
283-
instance Prim a => Semigroup (Vector a) where
284-
{-# INLINE (<>) #-}
285-
(<>) = (++)
286-
287-
{-# INLINE sconcat #-}
288-
sconcat = G.concatNE
289-
290-
instance Prim a => Monoid (Vector a) where
291-
{-# INLINE mempty #-}
292-
mempty = empty
293-
294-
{-# INLINE mappend #-}
295-
mappend = (<>)
296-
297-
{-# INLINE mconcat #-}
298-
mconcat = concat
299-
300-
instance Prim a => Exts.IsList (Vector a) where
301-
type Item (Vector a) = a
302-
fromList = fromList
303-
fromListN = fromListN
304-
toList = toList
169+
( Eq, Ord, Num, Enum, Monoid, Traversable, Monad, Bool, Ordering(..), Int, Maybe, Either
170+
, otherwise, error, undefined
171+
, (==))
305172

306173

307174
-- Length
@@ -1952,4 +1819,4 @@ copy :: (Prim a, PrimMonad m) => MVector (PrimState m) a -> Vector a -> m ()
19521819
copy = G.copy
19531820

19541821
-- $setup
1955-
-- >>> import Prelude (($), min, even, max, succ, id, Ord(..))
1822+
-- >>> import Prelude (($), min, even, max, succ, id, Ord(..), Num(..))

vector/src/Data/Vector/Primitive/Mutable.hs

Lines changed: 6 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -69,107 +69,23 @@ module Data.Vector.Primitive.Mutable (
6969
) where
7070

7171
import qualified Data.Vector.Generic.Mutable as G
72-
import Data.Primitive.ByteArray
7372
import Data.Primitive ( Prim, sizeOf )
7473
import Data.Vector.Internal.Check
75-
import Data.Word ( Word8 )
74+
import Data.Vector.Primitive.Unsafe (MVector,IOVector,STVector,unsafeCoerceMVector,unsafeCast)
75+
import qualified Data.Vector.Primitive.Unsafe as U
7676
import Control.Monad.Primitive
77-
import Control.Monad ( liftM )
7877

79-
import Control.DeepSeq ( NFData(rnf)
80-
#if MIN_VERSION_deepseq(1,4,3)
81-
, NFData1(liftRnf)
82-
#endif
83-
)
8478

8579
import Prelude
8680
( Ord, Bool, Int, Maybe, Ordering(..)
87-
, otherwise, error, undefined, div, show, maxBound
88-
, (+), (*), (<), (>), (>=), (==), (&&), (||), ($), (++) )
81+
, otherwise, error, undefined
82+
, (==))
8983

90-
import Data.Coerce
91-
import Unsafe.Coerce
9284

9385
-- Data.Vector.Internal.Check is unnecessary
9486
#define NOT_VECTOR_MODULE
9587
#include "vector.h"
9688

97-
type role MVector nominal nominal
98-
99-
-- | /O(1)/ Unsafely coerce a mutable vector from one element type to another,
100-
-- representationally equal type. The operation just changes the type of the
101-
-- underlying pointer and does not modify the elements.
102-
--
103-
-- Note that this function is unsafe. The @Coercible@ constraint guarantees
104-
-- that the element types are representationally equal. It however cannot
105-
-- guarantee that their respective 'Prim' instances are compatible.
106-
unsafeCoerceMVector :: Coercible a b => MVector s a -> MVector s b
107-
unsafeCoerceMVector = unsafeCoerce
108-
109-
-- | Mutable vectors of primitive types.
110-
data MVector s a = MVector {-# UNPACK #-} !Int -- ^ offset
111-
{-# UNPACK #-} !Int -- ^ length
112-
{-# UNPACK #-} !(MutableByteArray s) -- ^ underlying mutable byte array
113-
114-
type IOVector = MVector RealWorld
115-
type STVector s = MVector s
116-
117-
instance NFData (MVector s a) where
118-
rnf (MVector _ _ _) = ()
119-
120-
#if MIN_VERSION_deepseq(1,4,3)
121-
instance NFData1 (MVector s) where
122-
liftRnf _ (MVector _ _ _) = ()
123-
#endif
124-
125-
instance Prim a => G.MVector MVector a where
126-
basicLength (MVector _ n _) = n
127-
basicUnsafeSlice j m (MVector i _ arr)
128-
= MVector (i+j) m arr
129-
130-
{-# INLINE basicOverlaps #-}
131-
basicOverlaps (MVector i m arr1) (MVector j n arr2)
132-
= sameMutableByteArray arr1 arr2
133-
&& (between i j (j+n) || between j i (i+m))
134-
where
135-
between x y z = x >= y && x < z
136-
137-
{-# INLINE basicUnsafeNew #-}
138-
basicUnsafeNew n
139-
| n < 0 = error $ "Primitive.basicUnsafeNew: negative length: " ++ show n
140-
| n > mx = error $ "Primitive.basicUnsafeNew: length too large: " ++ show n
141-
| otherwise = MVector 0 n `liftM` newByteArray (n * size)
142-
where
143-
size = sizeOf (undefined :: a)
144-
mx = maxBound `div` size :: Int
145-
146-
{-# INLINE basicInitialize #-}
147-
basicInitialize (MVector off n v) =
148-
setByteArray v (off * size) (n * size) (0 :: Word8)
149-
where
150-
size = sizeOf (undefined :: a)
151-
152-
153-
{-# INLINE basicUnsafeRead #-}
154-
basicUnsafeRead (MVector i _ arr) j = readByteArray arr (i+j)
155-
156-
{-# INLINE basicUnsafeWrite #-}
157-
basicUnsafeWrite (MVector i _ arr) j x = writeByteArray arr (i+j) x
158-
159-
{-# INLINE basicUnsafeCopy #-}
160-
basicUnsafeCopy (MVector i n dst) (MVector j _ src)
161-
= copyMutableByteArray dst (i*sz) src (j*sz) (n*sz)
162-
where
163-
sz = sizeOf (undefined :: a)
164-
165-
{-# INLINE basicUnsafeMove #-}
166-
basicUnsafeMove (MVector i n dst) (MVector j _ src)
167-
= moveByteArray dst (i*sz) src (j*sz) (n * sz)
168-
where
169-
sz = sizeOf (undefined :: a)
170-
171-
{-# INLINE basicSet #-}
172-
basicSet (MVector i n arr) x = setByteArray arr i n x
17389

17490
-- Length information
17591
-- ------------------
@@ -724,18 +640,5 @@ ifoldrM' :: (PrimMonad m, Prim a) => (Int -> a -> b -> m b) -> b -> MVector (Pri
724640
{-# INLINE ifoldrM' #-}
725641
ifoldrM' = G.ifoldrM'
726642

727-
-- Unsafe conversions
728-
-- ------------------
729-
730-
-- | /O(1)/ Unsafely cast a vector from one element type to another.
731-
-- This operation just changes the type of the vector and does not
732-
-- modify the elements.
733-
--
734-
-- This function will throw an error if elements are of mismatching sizes.
735-
--
736-
-- | @since 0.13.0.0
737-
unsafeCast :: forall a b s. (HasCallStack, Prim a, Prim b) => MVector s a -> MVector s b
738-
{-# INLINE unsafeCast #-}
739-
unsafeCast (MVector o n ba)
740-
| sizeOf (undefined :: a) == sizeOf (undefined :: b) = MVector o n ba
741-
| otherwise = error "Element size mismatch"
643+
-- $setup
644+
-- >>> import Prelude (($), Num(..))

0 commit comments

Comments
 (0)