packages feed

primitive 0.9.0.0 → 0.9.1.0

raw patch · 12 files changed

+225/−135 lines, 12 filesdep +containersdep −ghc-primdep ~base

Dependencies added: containers

Dependencies removed: ghc-prim

Dependency ranges changed: base

Files

Control/Monad/Primitive.hs view
@@ -239,14 +239,14 @@   {-# INLINE internal #-} #endif --- | 'PrimMonad''s state token type can be annoying to handle+-- | 'PrimMonad'\'s state token type can be annoying to handle --   in constraints. This typeclass lets users (visually) notice --   'PrimState' equality constraints less, by witnessing that --   @s ~ 'PrimState' m@. class (PrimMonad m, s ~ PrimState m) => MonadPrim s m instance (PrimMonad m, s ~ PrimState m) => MonadPrim s m --- | 'PrimBase''s state token type can be annoying to handle+-- | 'PrimBase'\'s state token type can be annoying to handle --   in constraints. This typeclass lets users (visually) notice --   'PrimState' equality constraints less, by witnessing that --   @s ~ 'PrimState' m@.
Data/Primitive.hs view
@@ -65,9 +65,11 @@ variants produce the same results and differ only in their strictness. Monads that are sufficiently affine include: -* 'IO' and 'ST'-* Any combination of 'MaybeT', 'ExceptT', 'StateT' and 'Writer' on top-  of another sufficiently affine monad.+* 'IO' and 'Control.Monad.ST'+* Any combination of 'Control.Monad.Trans.Maybe.MaybeT',+  'Control.Monad.Trans.Except.ExceptT', 'Control.Monad.Trans.State.Lazy.StateT'+  and 'Control.Monad.Trans.Writer.Lazy.WriterT' on top of another sufficiently+  affine monad. * Any Monad which does not include backtracking or other mechanisms where an effect can   happen more than once is an affine Monad in the sense we care about. @ContT@, @LogicT@, @ListT@ are all   examples of search/control monads which are NOT affine: they can run a sub computation more than once.
Data/Primitive/Array.hs view
@@ -52,9 +52,6 @@ import qualified Data.Foldable as F import Data.Semigroup import Data.Functor.Identity-#if !MIN_VERSION_base(4,10,0)-import GHC.Base (runRW#)-#endif  import Text.Read (Read (..), parens, prec) import Text.ParserCombinators.ReadPrec (ReadPrec)@@ -586,18 +583,28 @@  -- | Create an array from a list of a known length. If the length -- of the list does not match the given length, this throws an exception.++-- Note [fromListN]+-- ~~~~~~~~~~~~~~~~+-- We want arrayFromListN to be a "good consumer" in list fusion, so we define+-- the function using foldr and inline it to help fire fusion rules.+-- If fusion occurs with a "good producer", it may reduce to a fold on some+-- structure. In certain cases (such as for Data.Set) GHC is not be able to+-- optimize the index to an unboxed Int# (see GHC #24628), so we explicitly use+-- an Int# here. arrayFromListN :: Int -> [a] -> Array a+{-# INLINE arrayFromListN #-} arrayFromListN n l =   createArray n (die "fromListN" "uninitialized element") $ \sma ->-    let go !ix [] = if ix == n+    let z ix# = if I# ix# == n           then return ()           else die "fromListN" "list length less than specified size"-        go !ix (x : xs) = if ix < n+        f x k = GHC.Exts.oneShot $ \ix# -> if I# ix# < n           then do-            writeArray sma ix x-            go (ix+1) xs+            writeArray sma (I# ix#) x+            k (ix# +# 1#)           else die "fromListN" "list length greater than specified size"-    in go 0 l+    in foldr f z l 0#  -- | Create an array from a list. arrayFromList :: [a] -> Array a@@ -789,14 +796,7 @@  -- | @since 0.6.4.0 instance Read1 Array where-#if MIN_VERSION_base(4,10,0)   liftReadPrec = arrayLiftReadPrec-#else-  -- This is just the default implementation of liftReadsPrec, but-  -- it is not present in older versions of base.-  liftReadsPrec rp rl = RdPrc.readPrec_to_S $-    arrayLiftReadPrec (RdPrc.readS_to_Prec rp) (RdPrc.readS_to_Prec (const rl))-#endif  -- Note [Forgiving Array Read Instance] -- We're really forgiving here. We accept
Data/Primitive/ByteArray.hs view
@@ -44,7 +44,7 @@   compareByteArrays,    -- * Freezing and thawing-  freezeByteArray, thawByteArray, runByteArray,+  freezeByteArray, thawByteArray, runByteArray, createByteArray,   unsafeFreezeByteArray, unsafeThawByteArray,    -- * Block operations@@ -62,6 +62,8 @@ #if __GLASGOW_HASKELL__ >= 802   isByteArrayPinned, isMutableByteArrayPinned, #endif+  byteArrayAsForeignPtr,+  mutableByteArrayAsForeignPtr,   byteArrayContents,   withByteArrayContents,   mutableByteArrayContents,@@ -74,18 +76,17 @@ import Data.Primitive.Types import Data.Proxy -#if MIN_VERSION_base(4,10,0) import qualified GHC.ST as GHCST-#endif -import Foreign.C.Types import Data.Word ( Word8 ) #if __GLASGOW_HASKELL__ >= 802 import qualified GHC.Exts as Exts #endif import GHC.Exts hiding (setByteArray#)+import GHC.ForeignPtr (ForeignPtr(..), ForeignPtrContents(..))  #if __GLASGOW_HASKELL__ < 804+import Foreign.C.Types import System.IO.Unsafe (unsafeDupablePerformIO) #endif @@ -128,6 +129,23 @@   = primitive (\s# -> case newAlignedPinnedByteArray# n# k# s# of                         (# s'#, arr# #) -> (# s'#, MutableByteArray arr# #)) +-- | Create a foreign pointer that points to the array's data. This operation+-- is only safe on /pinned/ byte arrays.  The array's data is not garbage+-- collected while references to the foreign pointer exist. Writing to the+-- array through the foreign pointer results in undefined behavior.+byteArrayAsForeignPtr :: ByteArray -> ForeignPtr Word8+{-# INLINE byteArrayAsForeignPtr #-}+byteArrayAsForeignPtr (ByteArray arr#) = ForeignPtr (byteArrayContents# arr#) (PlainPtr (unsafeCoerce# arr#))+++-- | Variant of 'byteArrayAsForeignPtr' for mutable byte arrays. Similarly, this+-- is only safe on /pinned/ mutable byte arrays. This function differs from the+-- variant for immutable arrays in that it is safe to write to the array though+-- the foreign pointer.+mutableByteArrayAsForeignPtr :: MutableByteArray RealWorld -> ForeignPtr Word8+{-# INLINE mutableByteArrayAsForeignPtr #-}+mutableByteArrayAsForeignPtr (MutableByteArray arr#) = ForeignPtr (mutableByteArrayContentsShim arr#) (PlainPtr arr#)+ -- | Yield a pointer to the array's data. This operation is only safe on -- /pinned/ byte arrays. Byte arrays allocated by 'newPinnedByteArray' and -- 'newAlignedPinnedByteArray' are guaranteed to be pinned. Byte arrays@@ -369,19 +387,20 @@  -- | Create a 'ByteArray' from a list of a known length. If the length -- of the list does not match the given length, this throws an exception.++-- See Note [fromListN] in Data.Primitive.Array byteArrayFromListN :: forall a. Prim a => Int -> [a] -> ByteArray-byteArrayFromListN n ys = runST $ do-    marr <- newByteArray (n * sizeOfType @a)-    let go !ix [] = if ix == n-          then return ()-          else die "byteArrayFromListN" "list length less than specified size"-        go !ix (x : xs) = if ix < n-          then do-            writeByteArray marr ix x-            go (ix + 1) xs-          else die "byteArrayFromListN" "list length greater than specified size"-    go 0 ys-    unsafeFreezeByteArray marr+{-# INLINE byteArrayFromListN #-}+byteArrayFromListN n ys = createByteArray (n * sizeOfType @a) $ \marr ->+  let z ix# = if I# ix# == n+        then return ()+        else die "byteArrayFromListN" "list length less than specified size"+      f x k = GHC.Exts.oneShot $ \ix# -> if I# ix# < n+        then do+          writeByteArray marr (I# ix#) x+          k (ix# +# 1#)+        else die "byteArrayFromListN" "list length greater than specified size"+  in foldr f z ys 0#  unI# :: Int -> Int# unI# (I# n#) = n#@@ -416,7 +435,13 @@ {-# INLINE copyMutableByteArray #-} copyMutableByteArray (MutableByteArray dst#) doff                      (MutableByteArray src#) soff sz-  = primitive_ (copyMutableByteArray# src# (unI# soff) dst# (unI# doff) (unI# sz))+  = primitive_ (op src# (unI# soff) dst# (unI# doff) (unI# sz))+  where+#if MIN_VERSION_base(4,19,0)+    op = copyMutableByteArrayNonOverlapping#+#else+    op = copyMutableByteArray#+#endif  -- | Copy a slice of a byte array to an unmanaged pointer address. These must not -- overlap. The offset and length are given in elements, not in bytes.@@ -525,9 +550,7 @@ {-# INLINE moveByteArray #-} moveByteArray (MutableByteArray dst#) doff               (MutableByteArray src#) soff sz-  = unsafePrimToPrim-  $ memmove_mba dst# (fromIntegral doff) src# (fromIntegral soff)-                     (fromIntegral sz)+  = primitive_ (copyMutableByteArray# src# (unI# soff) dst# (unI# doff) (unI# sz))  -- | Fill a slice of a mutable byte array with a value. The offset and length -- are given in elements of type @a@ rather than in bytes.@@ -557,11 +580,6 @@ {-# INLINE fillByteArray #-} fillByteArray = setByteArray -foreign import ccall unsafe "primitive-memops.h hsprimitive_memmove"-  memmove_mba :: MutableByteArray# s -> CPtrdiff-              -> MutableByteArray# s -> CPtrdiff-              -> CSize -> IO ()- -- | Lexicographic comparison of equal-length slices into two byte arrays. -- This wraps the @compareByteArrays#@ primop, which wraps @memcmp@. compareByteArrays@@ -592,6 +610,10 @@ {-# NOINLINE emptyByteArray #-} emptyByteArray = runST (newByteArray 0 >>= unsafeFreezeByteArray) +emptyByteArray# :: (# #) -> ByteArray#+{-# NOINLINE emptyByteArray# #-}+emptyByteArray# _ = case emptyByteArray of ByteArray arr# -> arr#+ die :: String -> String -> a die fun problem = error $ "Data.Primitive.ByteArray." ++ fun ++ ": " ++ problem @@ -604,10 +626,8 @@   -> Int       -- ^ number of bytes to copy   -> ByteArray {-# INLINE cloneByteArray #-}-cloneByteArray src off n = runByteArray $ do-  dst <- newByteArray n+cloneByteArray src off n = createByteArray n $ \dst ->   copyByteArray dst 0 src off n-  return dst  -- | Return a newly allocated mutable array with the specified subrange of -- the provided mutable array. The provided mutable array should contain the@@ -629,7 +649,6 @@ runByteArray   :: (forall s. ST s (MutableByteArray s))   -> ByteArray-#if MIN_VERSION_base(4,10,0) /* In new GHCs, runRW# is available. */ runByteArray m = ByteArray (runByteArray# m)  runByteArray#@@ -641,9 +660,20 @@  unST :: ST s a -> State# s -> (# State# s, a #) unST (GHCST.ST f) = f-#else /* In older GHCs, runRW# is not available. */-runByteArray m = runST $ m >>= unsafeFreezeByteArray-#endif++-- Create an uninitialized array of the given size in bytes, apply the function+-- to it, and freeze the result.+--+-- /Note:/ this function does not check if the input is non-negative.+--+-- @since FIXME+createByteArray :: Int -> (forall s. MutableByteArray s -> ST s ()) -> ByteArray+{-# INLINE createByteArray #-}+createByteArray 0 _ = ByteArray (emptyByteArray# (# #))+createByteArray n f = runByteArray $ do+  marr <- newByteArray n+  f marr+  pure marr  {- $charElementAccess GHC provides two sets of element accessors for 'Char'. One set faithfully
Data/Primitive/MutVar.hs view
@@ -19,16 +19,24 @@   readMutVar,   writeMutVar, +  -- * Modify   atomicModifyMutVar,   atomicModifyMutVar',   modifyMutVar,-  modifyMutVar'+  modifyMutVar',+  -- * Interop with STRef and IORef+  mutVarFromIORef,+  mutVarToIORef,+  mutVarFromSTRef,+  mutVarToSTRef ) where  import Control.Monad.Primitive ( PrimMonad(..), primitive_ )+import GHC.IORef (IORef(IORef))+import GHC.STRef (STRef(STRef)) import GHC.Exts ( MutVar#, sameMutVar#, newMutVar#                 , readMutVar#, writeMutVar#, atomicModifyMutVar#-                , isTrue# )+                , isTrue#, RealWorld) import Data.Typeable ( Typeable )  -- | A 'MutVar' behaves like a single-element mutable array associated@@ -103,3 +111,23 @@ modifyMutVar' (MutVar mv#) g = primitive_ $ \s# ->   case readMutVar# mv# s# of     (# s'#, a #) -> let a' = g a in a' `seq` writeMutVar# mv# a' s'#++-- | Convert 'MutVar' to 'IORef'+mutVarToIORef :: MutVar RealWorld a -> IORef a+{-# INLINE mutVarToIORef #-}+mutVarToIORef (MutVar mv#) = IORef (STRef mv#)++-- | Convert 'MutVar' to 'IORef'+mutVarFromIORef :: IORef a -> MutVar RealWorld a+{-# INLINE mutVarFromIORef #-}+mutVarFromIORef (IORef (STRef mv#)) = MutVar mv#++-- | Convert 'MutVar' to 'STRef'+mutVarToSTRef :: MutVar s a -> STRef s a+{-# INLINE mutVarToSTRef #-}+mutVarToSTRef (MutVar mv#) = STRef mv#++-- | Convert 'MutVar' to 'STRef'+mutVarFromSTRef :: STRef s a -> MutVar s a+{-# INLINE mutVarFromSTRef #-}+mutVarFromSTRef (STRef mv#) = MutVar mv#
Data/Primitive/PrimArray.hs view
@@ -46,6 +46,7 @@   , freezePrimArray   , thawPrimArray   , runPrimArray+  , createPrimArray   , unsafeFreezePrimArray   , unsafeThawPrimArray     -- * Block Operations@@ -124,9 +125,7 @@ import qualified Data.List as L import qualified Data.Primitive.ByteArray as PB import qualified Data.Primitive.Types as PT-#if MIN_VERSION_base(4,10,0) import qualified GHC.ST as GHCST-#endif import Language.Haskell.TH.Syntax (Lift (..))  import Data.Semigroup@@ -138,10 +137,10 @@ import Data.Primitive.Internal.Operations (mutableByteArrayContentsShim)  -- | Arrays of unboxed elements. This accepts types like 'Double', 'Char',--- 'Int' and 'Word', as well as their fixed-length variants ('Word8',--- 'Word16', etc.). Since the elements are unboxed, a 'PrimArray' is strict--- in its elements. This differs from the behavior of 'Data.Primitive.Array.Array',--- which is lazy in its elements.+-- 'Int' and 'Word', as well as their fixed-length variants ('Data.Word.Word8',+-- 'Data.Word.Word16', etc.). Since the elements are unboxed, a 'PrimArray' is+-- strict in its elements. This differs from the behavior of+-- 'Data.Primitive.Array.Array', which is lazy in its elements. data PrimArray a = PrimArray ByteArray#  type role PrimArray nominal@@ -233,22 +232,20 @@  -- | Create a 'PrimArray' from a list of a known length. If the length -- of the list does not match the given length, this throws an exception.++-- See Note [fromListN] in Data.Primitive.Array primArrayFromListN :: forall a. Prim a => Int -> [a] -> PrimArray a-primArrayFromListN len vs = runST run where-  run :: forall s. ST s (PrimArray a)-  run = do-    arr <- newPrimArray len-    let go :: [a] -> Int -> ST s ()-        go [] !ix = if ix == len-          then return ()-          else die "fromListN" "list length less than specified size"-        go (a : as) !ix = if ix < len-          then do-            writePrimArray arr ix a-            go as (ix + 1)-          else die "fromListN" "list length greater than specified size"-    go vs 0-    unsafeFreezePrimArray arr+{-# INLINE primArrayFromListN #-}+primArrayFromListN len vs = createPrimArray len $ \arr ->+  let z ix# = if I# ix# == len+        then return ()+        else die "fromListN" "list length less than specified size"+      f a k = GHC.Exts.oneShot $ \ix# -> if I# ix# < len+        then do+          writePrimArray arr (I# ix#) a+          k (ix# +# 1#)+        else die "fromListN" "list length greater than specified size"+  in foldr f z vs 0#  -- | Convert a 'PrimArray' to a list. {-# INLINE primArrayToList #-}@@ -282,6 +279,10 @@   (# s1#, arr# #) -> case unsafeFreezeByteArray# arr# s1# of     (# s2#, arr'# #) -> (# s2#, PrimArray arr'# #) +emptyPrimArray# :: (# #) -> ByteArray#+{-# NOINLINE emptyPrimArray# #-}+emptyPrimArray# _ = case emptyPrimArray of PrimArray arr# -> arr#+ -- | Create a new mutable primitive array of the given length. The -- underlying memory is left uninitialized. --@@ -391,7 +392,7 @@ -- | Copy a slice of an immutable primitive array to a pointer. -- The offset and length are given in elements of type @a@. -- This function assumes that the 'Prim' instance of @a@--- agrees with the 'Storable' instance.+-- agrees with the 'Foreign.Storable.Storable' instance. -- -- /Note:/ this function does not do bounds or overlap checking. copyPrimArrayToPtr :: forall m a. (PrimMonad m, Prim a)@@ -410,7 +411,7 @@ -- | Copy a slice of a mutable primitive array to a pointer. -- The offset and length are given in elements of type @a@. -- This function assumes that the 'Prim' instance of @a@--- agrees with the 'Storable' instance.+-- agrees with the 'Foreign.Storable.Storable' instance. -- -- /Note:/ this function does not do bounds or overlap checking. copyMutablePrimArrayToPtr :: forall m a. (PrimMonad m, Prim a)@@ -429,7 +430,7 @@ -- | Copy from a pointer to a mutable primitive array. -- The offset and length are given in elements of type @a@. -- This function assumes that the 'Prim' instance of @a@--- agrees with the 'Storable' instance.+-- agrees with the 'Foreign.Storable.Storable' instance. -- -- /Note:/ this function does not do bounds or overlap checking. copyPtrToMutablePrimArray :: forall m a. (PrimMonad m, Prim a)@@ -764,15 +765,14 @@   => (a -> b)   -> PrimArray a   -> PrimArray b-mapPrimArray f arr = runST $ do-  let !sz = sizeofPrimArray arr-  marr <- newPrimArray sz+mapPrimArray f arr = createPrimArray sz $ \marr ->   let go !ix = when (ix < sz) $ do         let b = f (indexPrimArray arr ix)         writePrimArray marr ix b         go (ix + 1)-  go 0-  unsafeFreezePrimArray marr+  in go 0+  where+    !sz = sizeofPrimArray arr  -- | Indexed map over the elements of a primitive array. {-# INLINE imapPrimArray #-}@@ -780,15 +780,14 @@   => (Int -> a -> b)   -> PrimArray a   -> PrimArray b-imapPrimArray f arr = runST $ do-  let !sz = sizeofPrimArray arr-  marr <- newPrimArray sz+imapPrimArray f arr = createPrimArray sz $ \marr ->   let go !ix = when (ix < sz) $ do         let b = f ix (indexPrimArray arr ix)         writePrimArray marr ix b         go (ix + 1)-  go 0-  unsafeFreezePrimArray marr+  in go 0+  where+    !sz = sizeofPrimArray arr  -- | Filter elements of a primitive array according to a predicate. {-# INLINE filterPrimArray #-}@@ -958,13 +957,11 @@   => Int -- ^ length   -> (Int -> a) -- ^ element from index   -> PrimArray a-generatePrimArray len f = runST $ do-  marr <- newPrimArray len+generatePrimArray len f = createPrimArray len $ \marr ->   let go !ix = when (ix < len) $ do         writePrimArray marr ix (f ix)         go (ix + 1)-  go 0-  unsafeFreezePrimArray marr+  in go 0  -- | Create a primitive array by copying the element the given -- number of times.@@ -973,10 +970,8 @@   => Int -- ^ length   -> a -- ^ element   -> PrimArray a-replicatePrimArray len a = runST $ do-  marr <- newPrimArray len+replicatePrimArray len a = createPrimArray len $ \marr ->   setPrimArray marr 0 len a-  unsafeFreezePrimArray marr  -- | Generate a primitive array by evaluating the applicative generator -- function at each index.@@ -1095,8 +1090,9 @@                         (# s'#, arr# #) -> (# s'#, MutablePrimArray arr# #))  -- | Yield a pointer to the array's data. This operation is only safe on--- /pinned/ prim arrays allocated by 'newPinnedByteArray' or--- 'newAlignedPinnedByteArray'.+-- /pinned/ prim arrays allocated by+-- 'Data.Primitive.ByteArray.newPinnedByteArray' or+-- 'Data.Primitive.ByteArray.newAlignedPinnedByteArray'. -- -- @since 0.7.1.0 primArrayContents :: PrimArray a -> Ptr a@@ -1104,8 +1100,9 @@ primArrayContents (PrimArray arr#) = Ptr (byteArrayContents# arr#)  -- | Yield a pointer to the array's data. This operation is only safe on--- /pinned/ byte arrays allocated by 'newPinnedByteArray' or--- 'newAlignedPinnedByteArray'.+-- /pinned/ byte arrays allocated by+-- 'Data.Primitive.ByteArray.newPinnedByteArray' or+-- 'Data.Primitive.ByteArray.newAlignedPinnedByteArray'. -- -- @since 0.7.1.0 mutablePrimArrayContents :: MutablePrimArray s a -> Ptr a@@ -1122,10 +1119,8 @@   -> Int     -- ^ number of elements to copy   -> PrimArray a {-# INLINE clonePrimArray #-}-clonePrimArray src off n = runPrimArray $ do-  dst <- newPrimArray n+clonePrimArray src off n = createPrimArray n $ \dst ->   copyPrimArray dst 0 src off n-  return dst  -- | Return a newly allocated mutable array with the specified subrange of -- the provided mutable array. The provided mutable array should contain the@@ -1147,7 +1142,6 @@ runPrimArray   :: (forall s. ST s (MutablePrimArray s a))   -> PrimArray a-#if MIN_VERSION_base(4,10,0) /* In new GHCs, runRW# is available. */ runPrimArray m = PrimArray (runPrimArray# m)  runPrimArray#@@ -1159,9 +1153,21 @@  unST :: ST s a -> State# s -> (# State# s, a #) unST (GHCST.ST f) = f-#else /* In older GHCs, runRW# is not available. */-runPrimArray m = runST $ m >>= unsafeFreezePrimArray-#endif++-- | Create an uninitialized array of the given length, apply the function to+-- it, and freeze the result.+--+-- /Note:/ this function does not check if the input is non-negative.+--+-- @since FIXME+createPrimArray+  :: Prim a => Int -> (forall s. MutablePrimArray s a -> ST s ()) -> PrimArray a+{-# INLINE createPrimArray #-}+createPrimArray 0 _ = PrimArray (emptyPrimArray# (# #))+createPrimArray n f = runPrimArray $ do+  marr <- newPrimArray n+  f marr+  pure marr  -- | A composition of 'primArrayContents' and 'keepAliveUnlifted'. -- The callback function must not return the pointer. The argument
Data/Primitive/SmallArray.hs view
@@ -88,9 +88,6 @@ import Text.ParserCombinators.ReadP import Text.ParserCombinators.ReadPrec (ReadPrec) import qualified Text.ParserCombinators.ReadPrec as RdPrc-#if !MIN_VERSION_base(4,10,0)-import GHC.Base (runRW#)-#endif  import Data.Functor.Classes (Eq1(..), Ord1(..), Show1(..), Read1(..)) import Language.Haskell.TH.Syntax (Lift(..))@@ -191,12 +188,12 @@ -- > f sa = case indexSmallArrayM sa 0 of -- >   Box x -> ... ----- 'x' is not a closure that references 'sa' as it would be if we instead+-- @x@ is not a closure that references @sa@ as it would be if we instead -- wrote: -- -- > let x = indexSmallArray sa 0 ----- It also does not prevent 'sa' from being garbage collected.+-- It also does not prevent @sa@ from being garbage collected. -- -- Note that 'Identity' is not adequate for this use, as it is a newtype, and -- cannot be evaluated without evaluating the element.@@ -892,14 +889,7 @@  -- | @since 0.6.4.0 instance Read1 SmallArray where-#if MIN_VERSION_base(4,10,0)   liftReadPrec = smallArrayLiftReadPrec-#else-  -- This is just the default implementation of liftReadsPrec, but-  -- it is not present in older versions of base.-  liftReadsPrec rp rl = RdPrc.readPrec_to_S $-    smallArrayLiftReadPrec (RdPrc.readS_to_Prec rp) (RdPrc.readS_to_Prec (const rl))-#endif  smallArrayDataType :: DataType smallArrayDataType =@@ -924,18 +914,19 @@ -- | Create a 'SmallArray' from a list of a known length. If the length -- of the list does not match the given length, this throws an exception. smallArrayFromListN :: Int -> [a] -> SmallArray a+{-# INLINE smallArrayFromListN #-} smallArrayFromListN n l =   createSmallArray n       (die "smallArrayFromListN" "uninitialized element") $ \sma ->-  let go !ix [] = if ix == n+  let z ix# = if I# ix# == n         then return ()         else die "smallArrayFromListN" "list length less than specified size"-      go !ix (x : xs) = if ix < n+      f x k = GHC.Exts.oneShot $ \ix# -> if I# ix# < n         then do-          writeSmallArray sma ix x-          go (ix + 1) xs+          writeSmallArray sma (I# ix#) x+          k (ix# +# 1#)         else die "smallArrayFromListN" "list length greater than specified size"-  in go 0 l+  in foldr f z l 0#  -- | Create a 'SmallArray' from a list. smallArrayFromList :: [a] -> SmallArray a
Data/Primitive/Types.hs view
@@ -410,9 +410,7 @@ deriving instance Prim CSigAtomic deriving instance Prim CLLong deriving instance Prim CULLong-#if MIN_VERSION_base(4,10,0) deriving instance Prim CBool-#endif deriving instance Prim CIntPtr deriving instance Prim CUIntPtr deriving instance Prim CIntMax
bench/main.hs view
@@ -9,6 +9,7 @@ import Control.Monad.ST import Data.Primitive import Control.Monad.Trans.State.Strict+import Data.Set (Set)  -- These are fixed implementations of certain operations. In the event -- that primitive changes its implementation of a function, these@@ -25,6 +26,8 @@ import qualified PrimArray.Compare import qualified PrimArray.Traverse +import qualified Data.Set as Set+ main :: IO () main = defaultMain   [ bgroup "Array"@@ -34,6 +37,9 @@         , bench "unsafe" (nf (\x -> runST (runStateT (Array.Traverse.Unsafe.traversePoly cheap x) 0)) numbers)         ]       ]+    , bgroup "arrayFromListN"+      [ bench "set-to-list-to-array" (whnf arrayFromSet setOfIntegers1024)+      ]     ]   , bgroup "ByteArray"     [ bgroup "compare"@@ -61,6 +67,16 @@       ]     ]   ]++setOfIntegers1024 :: Set Integer+{-# noinline setOfIntegers1024 #-}+setOfIntegers1024 = Set.fromList [1..1024]++-- The performance of this is used to confirm whether or not arrayFromListN is+-- actining as a good consumer for list fusion.+arrayFromSet :: Set Integer -> Array Integer+{-# noinline arrayFromSet #-}+arrayFromSet s = arrayFromListN (Set.size s) (Set.toList s)  cheap :: Int -> StateT Int (ST s) Int cheap i = modify (\x -> x + i) >> return (i * i)
changelog.md view
@@ -1,3 +1,22 @@+## Changes in version 0.9.1.0++  * Make fromListN functions good consumers for list fusion.++  * Add functions to improve `MutVar`'s interoperability with `IORef` and `STRef`.++  * Add `createPrimArray` and `createByteArray`.++  * Add `byteArrayAsForeignPtr` and `mutableByteArrayAsForeignPtr`.++  * Use `copyMutableByteArrayNonOverlapping#` in the implementation of `copyMutableByteArray`+    on sufficiently new GHCs. This does not change the contract for `copyMutableByteArray`.+    This function has always been documented as having undefined behavior when the slices+    overlap. However, overlaps previously were handled gracefully (with the semantics+    of C's `memmove`). Going forward, users who do not uphold `copyMutableByteArray`'s+    precondition will be met with unpredictable results.++  * Drop support for GHC 8.0.+ ## Changes in version 0.9.0.0    * Add `withByteArrayContents`, `withMutableByteArrayContents`,
primitive.cabal view
@@ -1,6 +1,6 @@ Cabal-Version:  2.0 Name:           primitive-Version:        0.9.0.0+Version:        0.9.1.0 License:        BSD3 License-File:   LICENSE @@ -19,15 +19,17 @@                     test/LICENSE  Tested-With:-  GHC == 8.0.2   GHC == 8.2.2   GHC == 8.4.4   GHC == 8.6.5   GHC == 8.8.4   GHC == 8.10.7   GHC == 9.0.2-  GHC == 9.2.5-  GHC == 9.4.4+  GHC == 9.2.8+  GHC == 9.4.8+  GHC == 9.6.6+  GHC == 9.8.2+  GHC == 9.10.1  Library   Default-Language: Haskell2010@@ -55,7 +57,7 @@         Data.Primitive.Internal.Operations         Data.Primitive.Internal.Read -  Build-Depends: base >= 4.9 && < 4.20+  Build-Depends: base >= 4.10 && < 4.22                , deepseq >= 1.1 && < 1.6                , transformers >= 0.5 && < 0.7                , template-haskell >= 2.11@@ -70,7 +72,6 @@    Include-Dirs: cbits   Install-Includes: primitive-memops.h-  includes: primitive-memops.h   c-sources: cbits/primitive-memops.c   if !os(solaris)       cc-options: -ftree-vectorize@@ -86,11 +87,10 @@   type: exitcode-stdio-1.0   build-depends: base                , base-orphans-               , ghc-prim                , primitive                , quickcheck-classes-base >= 0.6 && <0.7-               , QuickCheck >= 2.13 && < 2.15-               , tasty ^>= 1.2 || ^>= 1.3 || ^>= 1.4+               , QuickCheck >= 2.13 && < 2.16+               , tasty >= 1.2 && < 1.6                , tasty-quickcheck                , tagged                , transformers >= 0.5@@ -113,6 +113,7 @@     PrimArray.Traverse   build-depends:       base+    , containers     , primitive     , deepseq     , tasty-bench
test/Main.hs view
@@ -32,7 +32,6 @@  import Data.Functor.Identity (Identity(..)) import qualified Data.Monoid as Monoid-import Data.Ord (Down(..)) import Data.Semigroup (stimes, stimesMonoid) import qualified Data.Semigroup as Semigroup #if !(MIN_VERSION_base(4,11,0))