Skip to content

Commit 74ecbce

Browse files
committed
Storable: add Unsafe modules
1 parent 0925bc2 commit 74ecbce

File tree

6 files changed

+511
-439
lines changed

6 files changed

+511
-439
lines changed

vector/src/Data/Vector/Storable.hs

Lines changed: 6 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -170,147 +170,19 @@ module Data.Vector.Storable (
170170
import Control.Applicative (Applicative)
171171
import qualified Data.Vector.Generic as G
172172
import Data.Vector.Storable.Mutable ( MVector(..) )
173-
import Data.Vector.Storable.Internal
174-
import qualified Data.Vector.Fusion.Bundle as Bundle
175-
176-
import Foreign.Storable
177-
import Foreign.ForeignPtr
178-
import Foreign.Ptr
179-
import Foreign.Marshal.Array ( advancePtr, copyArray )
180-
181-
import Control.DeepSeq ( NFData(rnf), NFData1(liftRnf))
173+
import Data.Vector.Storable.Unsafe
182174

183175
import Control.Monad.ST ( ST )
184176
import Control.Monad.Primitive
185-
177+
import Foreign.Storable
178+
import Foreign.ForeignPtr
186179
import Prelude
187-
( Eq, Ord, Num, Enum, Monoid, Traversable, Monad, Read, Show, Bool, Ordering(..), Int, Maybe, Either, IO
188-
, compare, mempty, mappend, mconcat, showsPrec, return, seq, undefined, div
189-
, (*), (<), (<=), (>), (>=), (==), (/=), (&&), (.), ($) )
190-
191-
import Data.Data ( Data(..) )
192-
import Text.Read ( Read(..), readListPrecDefault )
193-
import Data.Semigroup ( Semigroup(..) )
194-
import Data.Coerce
195-
import qualified GHC.Exts as Exts
196-
import Unsafe.Coerce
180+
( Eq, Ord, Num, Enum, Monoid, Traversable, Monad, Bool, Ordering(..), Int, Maybe, Either
181+
, undefined, div
182+
, (*), (==), (&&))
197183

198184
#include "vector.h"
199185

200-
type role Vector nominal
201-
202-
-- | /O(1)/ Unsafely coerce a mutable vector from one element type to another,
203-
-- representationally equal type. The operation just changes the type of the
204-
-- underlying pointer and does not modify the elements.
205-
--
206-
-- This is marginally safer than 'unsafeCast', since this function imposes an
207-
-- extra 'Coercible' constraint. This function is still not safe, however,
208-
-- since it cannot guarantee that the two types have memory-compatible
209-
-- 'Storable' instances.
210-
unsafeCoerceVector :: Coercible a b => Vector a -> Vector b
211-
unsafeCoerceVector = unsafeCoerce
212-
213-
-- | 'Storable'-based vectors.
214-
data Vector a = Vector {-# UNPACK #-} !Int
215-
{-# UNPACK #-} !(ForeignPtr a)
216-
217-
instance NFData (Vector a) where
218-
rnf (Vector _ _) = ()
219-
220-
-- | @since 0.12.1.0
221-
instance NFData1 Vector where
222-
liftRnf _ (Vector _ _) = ()
223-
224-
instance (Show a, Storable a) => Show (Vector a) where
225-
showsPrec = G.showsPrec
226-
227-
instance (Read a, Storable a) => Read (Vector a) where
228-
readPrec = G.readPrec
229-
readListPrec = readListPrecDefault
230-
231-
instance (Data a, Storable a) => Data (Vector a) where
232-
gfoldl = G.gfoldl
233-
toConstr _ = G.mkVecConstr "Data.Vector.Storable.Vector"
234-
gunfold = G.gunfold
235-
dataTypeOf _ = G.mkVecType "Data.Vector.Storable.Vector"
236-
dataCast1 = G.dataCast
237-
238-
239-
type instance G.Mutable Vector = MVector
240-
241-
instance Storable a => G.Vector Vector a where
242-
{-# INLINE basicUnsafeFreeze #-}
243-
basicUnsafeFreeze (MVector n fp) = return $ Vector n fp
244-
245-
{-# INLINE basicUnsafeThaw #-}
246-
basicUnsafeThaw (Vector n fp) = return $ MVector n fp
247-
248-
{-# INLINE basicLength #-}
249-
basicLength (Vector n _) = n
250-
251-
{-# INLINE basicUnsafeSlice #-}
252-
basicUnsafeSlice i n (Vector _ fp) = Vector n (updPtr (`advancePtr` i) fp)
253-
254-
{-# INLINE basicUnsafeIndexM #-}
255-
basicUnsafeIndexM (Vector _ fp) i = return
256-
. unsafeInlineIO
257-
$ unsafeWithForeignPtr fp $ \p ->
258-
peekElemOff p i
259-
260-
{-# INLINE basicUnsafeCopy #-}
261-
basicUnsafeCopy (MVector n fp) (Vector _ fq)
262-
= unsafePrimToPrim
263-
$ unsafeWithForeignPtr fp $ \p ->
264-
unsafeWithForeignPtr fq $ \q ->
265-
copyArray p q n
266-
267-
{-# INLINE elemseq #-}
268-
elemseq _ = seq
269-
270-
-- See http://trac.haskell.org/vector/ticket/12
271-
instance (Storable a, Eq a) => Eq (Vector a) where
272-
{-# INLINE (==) #-}
273-
xs == ys = Bundle.eq (G.stream xs) (G.stream ys)
274-
275-
-- See http://trac.haskell.org/vector/ticket/12
276-
instance (Storable a, Ord a) => Ord (Vector a) where
277-
{-# INLINE compare #-}
278-
compare xs ys = Bundle.cmp (G.stream xs) (G.stream ys)
279-
280-
{-# INLINE (<) #-}
281-
xs < ys = Bundle.cmp (G.stream xs) (G.stream ys) == LT
282-
283-
{-# INLINE (<=) #-}
284-
xs <= ys = Bundle.cmp (G.stream xs) (G.stream ys) /= GT
285-
286-
{-# INLINE (>) #-}
287-
xs > ys = Bundle.cmp (G.stream xs) (G.stream ys) == GT
288-
289-
{-# INLINE (>=) #-}
290-
xs >= ys = Bundle.cmp (G.stream xs) (G.stream ys) /= LT
291-
292-
instance Storable a => Semigroup (Vector a) where
293-
{-# INLINE (<>) #-}
294-
(<>) = (++)
295-
296-
{-# INLINE sconcat #-}
297-
sconcat = G.concatNE
298-
299-
instance Storable a => Monoid (Vector a) where
300-
{-# INLINE mempty #-}
301-
mempty = empty
302-
303-
{-# INLINE mappend #-}
304-
mappend = (<>)
305-
306-
{-# INLINE mconcat #-}
307-
mconcat = concat
308-
309-
instance Storable a => Exts.IsList (Vector a) where
310-
type Item (Vector a) = a
311-
fromList = fromList
312-
fromListN = fromListN
313-
toList = toList
314186

315187
-- Length
316188
-- ------
@@ -2093,58 +1965,6 @@ copy = G.copy
20931965
-- Conversions - Raw pointers
20941966
-- --------------------------
20951967

2096-
-- | /O(1)/ Create a vector from a 'ForeignPtr' with an offset and a length.
2097-
--
2098-
-- The data may not be modified through the pointer afterwards.
2099-
--
2100-
-- If your offset is 0 it is more efficient to use 'unsafeFromForeignPtr0'.
2101-
unsafeFromForeignPtr :: Storable a
2102-
=> ForeignPtr a -- ^ pointer
2103-
-> Int -- ^ offset
2104-
-> Int -- ^ length
2105-
-> Vector a
2106-
{-# INLINE_FUSED unsafeFromForeignPtr #-}
2107-
unsafeFromForeignPtr fp i n = unsafeFromForeignPtr0 fp' n
2108-
where
2109-
fp' = updPtr (`advancePtr` i) fp
2110-
2111-
{-# RULES
2112-
"unsafeFromForeignPtr fp 0 n -> unsafeFromForeignPtr0 fp n " forall fp n.
2113-
unsafeFromForeignPtr fp 0 n = unsafeFromForeignPtr0 fp n #-}
2114-
2115-
2116-
-- | /O(1)/ Create a vector from a 'ForeignPtr' and a length.
2117-
--
2118-
-- It is assumed the pointer points directly to the data (no offset).
2119-
-- Use 'unsafeFromForeignPtr' if you need to specify an offset.
2120-
--
2121-
-- The data may not be modified through the pointer afterwards.
2122-
unsafeFromForeignPtr0 :: ForeignPtr a -- ^ pointer
2123-
-> Int -- ^ length
2124-
-> Vector a
2125-
{-# INLINE unsafeFromForeignPtr0 #-}
2126-
unsafeFromForeignPtr0 fp n = Vector n fp
2127-
2128-
-- | /O(1)/ Yield the underlying 'ForeignPtr' together with the offset to the
2129-
-- data and its length. The data may not be modified through the 'ForeignPtr'.
2130-
unsafeToForeignPtr :: Vector a -> (ForeignPtr a, Int, Int)
2131-
{-# INLINE unsafeToForeignPtr #-}
2132-
unsafeToForeignPtr (Vector n fp) = (fp, 0, n)
2133-
2134-
-- | /O(1)/ Yield the underlying 'ForeignPtr' together with its length.
2135-
--
2136-
-- You can assume that the pointer points directly to the data (no offset).
2137-
--
2138-
-- The data may not be modified through the 'ForeignPtr'.
2139-
unsafeToForeignPtr0 :: Vector a -> (ForeignPtr a, Int)
2140-
{-# INLINE unsafeToForeignPtr0 #-}
2141-
unsafeToForeignPtr0 (Vector n fp) = (fp, n)
2142-
2143-
-- | Pass a pointer to the vector's data to the IO action. The data may not be
2144-
-- modified through the 'Ptr.
2145-
unsafeWith :: Storable a => Vector a -> (Ptr a -> IO b) -> IO b
2146-
{-# INLINE unsafeWith #-}
2147-
unsafeWith (Vector _ fp) = withForeignPtr fp
21481968

21491969
-- $setup
21501970
-- >>> import Prelude (Bool(..), Double, ($), (+), (/), succ, even, min, max, id, Ord(..))

0 commit comments

Comments
 (0)