{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}


-- |
-- Module      : Data.Primitive.PrimArray
-- Copyright   : (c) Roman Leshchinskiy 2009-2012
-- License     : BSD-style
--
-- Maintainer  : Roman Leshchinskiy <rl@cse.unsw.edu.au>
-- Portability : non-portable
--
-- Arrays of unboxed primitive types. The function provided by this module
-- match the behavior of those provided by @Data.Primitive.ByteArray@, and
-- the underlying types and primops that back them are the same.
-- However, the type constructors 'PrimArray' and 'MutablePrimArray' take one additional
-- argument than their respective counterparts 'ByteArray' and 'MutableByteArray'.
-- This argument is used to designate the type of element in the array.
-- Consequently, all function this modules accepts length and incides in
-- terms of elements, not bytes.
--
-- @since 0.6.4.0
module Data.Primitive.PrimArray
  ( -- * Types
    PrimArray(..)
  , MutablePrimArray(..)
    -- * Allocation
  , newPrimArray
  , resizeMutablePrimArray
#if __GLASGOW_HASKELL__ >= 710
  , shrinkMutablePrimArray
#endif
    -- * Element Access
  , readPrimArray
  , writePrimArray
  , indexPrimArray
    -- * Freezing and Thawing
  , unsafeFreezePrimArray
  , unsafeThawPrimArray
    -- * Block Operations
  , copyPrimArray
  , copyMutablePrimArray
#if __GLASGOW_HASKELL__ >= 708
  , copyPrimArrayToPtr
  , copyMutablePrimArrayToPtr
#endif
  , setPrimArray
    -- * Information
  , sameMutablePrimArray
  , getSizeofMutablePrimArray
  , sizeofMutablePrimArray
  , sizeofPrimArray
    -- * List Conversion
  , primArrayToList
  , primArrayFromList
  , primArrayFromListN
    -- * Folding
  , foldrPrimArray
  , foldrPrimArray'
  , foldlPrimArray
  , foldlPrimArray'
  , foldlPrimArrayM'
    -- * Effectful Folding
  , traversePrimArray_
  , itraversePrimArray_
    -- * Map/Create
  , mapPrimArray
  , imapPrimArray
  , generatePrimArray
  , replicatePrimArray
  , filterPrimArray
  , mapMaybePrimArray
    -- * Effectful Map/Create
    -- $effectfulMapCreate
    -- ** Lazy Applicative
  , traversePrimArray
  , itraversePrimArray
  , generatePrimArrayA
  , replicatePrimArrayA
  , filterPrimArrayA
  , mapMaybePrimArrayA
    -- ** Strict Primitive Monadic
  , traversePrimArrayP
  , itraversePrimArrayP
  , generatePrimArrayP
  , replicatePrimArrayP
  , filterPrimArrayP
  , mapMaybePrimArrayP
  ) where

import GHC.Exts
import GHC.Base ( Int(..) )
import Data.Primitive.Internal.Compat (isTrue#)
import Data.Primitive.Types
import Data.Primitive.ByteArray (ByteArray(..))
import Data.Monoid (Monoid(..),(<>))
import Control.Applicative
import Control.Monad.Primitive
import Control.Monad.ST
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,7,0)
import GHC.Exts (IsList(..))
#endif

#if MIN_VERSION_base(4,9,0)
import Data.Semigroup (Semigroup)
import qualified Data.Semigroup as SG
#endif

-- | 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 'Array', which is lazy
-- in its elements.
data PrimArray a = PrimArray ByteArray#

-- | Mutable primitive arrays associated with a primitive state token.
-- These can be written to and read from in a monadic context that supports
-- sequencing such as 'IO' or 'ST'. Typically, a mutable primitive array will
-- be built and then convert to an immutable primitive array using
-- 'unsafeFreezePrimArray'. However, it is also acceptable to simply discard
-- a mutable primitive array since it lives in managed memory and will be
-- garbage collected when no longer referenced.
data MutablePrimArray s a = MutablePrimArray (MutableByteArray# s)

sameByteArray :: ByteArray# -> ByteArray# -> Bool
sameByteArray :: ByteArray# -> ByteArray# -> Bool
sameByteArray ba1 :: ByteArray#
ba1 ba2 :: ByteArray#
ba2 =
    case () -> () -> Int#
forall a. a -> a -> Int#
reallyUnsafePtrEquality# (ByteArray# -> ()
unsafeCoerce# ByteArray#
ba1 :: ()) (ByteArray# -> ()
unsafeCoerce# ByteArray#
ba2 :: ()) of
#if __GLASGOW_HASKELL__ >= 708
      r :: Int#
r -> Int# -> Bool
isTrue# Int#
r
#else
      1# -> True
      _ -> False
#endif

-- | @since 0.6.4.0
instance (Eq a, Prim a) => Eq (PrimArray a) where
  a1 :: PrimArray a
a1@(PrimArray ba1# :: ByteArray#
ba1#) == :: PrimArray a -> PrimArray a -> Bool
== a2 :: PrimArray a
a2@(PrimArray ba2# :: ByteArray#
ba2#)
    | ByteArray# -> ByteArray# -> Bool
sameByteArray ByteArray#
ba1# ByteArray#
ba2# = Bool
True
    | Int
sz1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= Int
sz2 = Bool
False
    | Bool
otherwise = Int -> Bool
loop (Int -> Int -> Int
forall a. Integral a => a -> a -> a
quot Int
sz1 (a -> Int
forall a. Prim a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a)) Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)
    where
    -- Here, we take the size in bytes, not in elements. We do this
    -- since it allows us to defer performing the division to
    -- calculate the size in elements.
    sz1 :: Int
sz1 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba1#)
    sz2 :: Int
sz2 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba2#)
    loop :: Int -> Bool
loop !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = Bool
True
      | Bool
otherwise = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a1 Int
i a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a2 Int
i Bool -> Bool -> Bool
&& Int -> Bool
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-1)
  {-# INLINE (==) #-}

-- | Lexicographic ordering. Subject to change between major versions.
--
--   @since 0.6.4.0
instance (Ord a, Prim a) => Ord (PrimArray a) where
  compare :: PrimArray a -> PrimArray a -> Ordering
compare a1 :: PrimArray a
a1@(PrimArray ba1# :: ByteArray#
ba1#) a2 :: PrimArray a
a2@(PrimArray ba2# :: ByteArray#
ba2#)
    | ByteArray# -> ByteArray# -> Bool
sameByteArray ByteArray#
ba1# ByteArray#
ba2# = Ordering
EQ
    | Bool
otherwise = Int -> Ordering
loop 0
    where
    sz1 :: Int
sz1 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba1#)
    sz2 :: Int
sz2 = ByteArray -> Int
PB.sizeofByteArray (ByteArray# -> ByteArray
ByteArray ByteArray#
ba2#)
    sz :: Int
sz = Int -> Int -> Int
forall a. Integral a => a -> a -> a
quot (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
sz1 Int
sz2) (a -> Int
forall a. Prim a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined :: a))
    loop :: Int -> Ordering
loop !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a1 Int
i) (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a2 Int
i) Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Int -> Ordering
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+1)
      | Bool
otherwise = Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
sz1 Int
sz2
  {-# INLINE compare #-}

#if MIN_VERSION_base(4,7,0)
-- | @since 0.6.4.0
instance Prim a => IsList (PrimArray a) where
  type Item (PrimArray a) = a
  fromList :: [Item (PrimArray a)] -> PrimArray a
fromList = [Item (PrimArray a)] -> PrimArray a
forall a. Prim a => [a] -> PrimArray a
primArrayFromList
  fromListN :: Int -> [Item (PrimArray a)] -> PrimArray a
fromListN = Int -> [Item (PrimArray a)] -> PrimArray a
forall a. Prim a => Int -> [a] -> PrimArray a
primArrayFromListN
  toList :: PrimArray a -> [Item (PrimArray a)]
toList = PrimArray a -> [Item (PrimArray a)]
forall a. Prim a => PrimArray a -> [a]
primArrayToList
#endif

-- | @since 0.6.4.0
instance (Show a, Prim a) => Show (PrimArray a) where
  showsPrec :: Int -> PrimArray a -> ShowS
showsPrec p :: Int
p a :: PrimArray a
a = Bool -> ShowS -> ShowS
showParen (Int
p Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 10) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
    String -> ShowS
showString "fromListN " ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShowS
forall a. Show a => a -> ShowS
shows (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
a) ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString " "
      ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> ShowS
forall a. Show a => a -> ShowS
shows (PrimArray a -> [a]
forall a. Prim a => PrimArray a -> [a]
primArrayToList PrimArray a
a)

die :: String -> String -> a
die :: String -> String -> a
die fun :: String
fun problem :: String
problem = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ "Data.Primitive.PrimArray." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
fun String -> ShowS
forall a. [a] -> [a] -> [a]
++ ": " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
problem

primArrayFromList :: Prim a => [a] -> PrimArray a
primArrayFromList :: [a] -> PrimArray a
primArrayFromList vs :: [a]
vs = Int -> [a] -> PrimArray a
forall a. Prim a => Int -> [a] -> PrimArray a
primArrayFromListN ([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
L.length [a]
vs) [a]
vs

primArrayFromListN :: forall a. Prim a => Int -> [a] -> PrimArray a
primArrayFromListN :: Int -> [a] -> PrimArray a
primArrayFromListN len :: Int
len vs :: [a]
vs = (forall s. ST s (PrimArray a)) -> PrimArray a
forall a. (forall s. ST s a) -> a
runST forall s. ST s (PrimArray a)
run where
  run :: forall s. ST s (PrimArray a)
  run :: ST s (PrimArray a)
run = do
    MutablePrimArray s a
arr <- Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
len
    let go :: [a] -> Int -> ST s ()
        go :: [a] -> Int -> ST s ()
go [] !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len
          then () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
          else String -> String -> ST s ()
forall a. String -> String -> a
die "fromListN" "list length less than specified size"
        go (a :: a
a : as :: [a]
as) !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len
          then do
            MutablePrimArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
arr Int
ix a
a
            [a] -> Int -> ST s ()
go [a]
as (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
          else String -> String -> ST s ()
forall a. String -> String -> a
die "fromListN" "list length greater than specified size"
    [a] -> Int -> ST s ()
go [a]
vs 0
    MutablePrimArray (PrimState (ST s)) a -> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
arr

-- | Convert the primitive array to a list.
{-# INLINE primArrayToList #-}
primArrayToList :: forall a. Prim a => PrimArray a -> [a]
primArrayToList :: PrimArray a -> [a]
primArrayToList xs :: PrimArray a
xs = (forall b. (a -> b -> b) -> b -> b) -> [a]
forall a. (forall b. (a -> b -> b) -> b -> b) -> [a]
build (\c :: a -> b -> b
c n :: b
n -> (a -> b -> b) -> b -> PrimArray a -> b
forall a b. Prim a => (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray a -> b -> b
c b
n PrimArray a
xs)

primArrayToByteArray :: PrimArray a -> PB.ByteArray
primArrayToByteArray :: PrimArray a -> ByteArray
primArrayToByteArray (PrimArray x :: ByteArray#
x) = ByteArray# -> ByteArray
PB.ByteArray ByteArray#
x

byteArrayToPrimArray :: ByteArray -> PrimArray a
byteArrayToPrimArray :: ByteArray -> PrimArray a
byteArrayToPrimArray (PB.ByteArray x :: ByteArray#
x) = ByteArray# -> PrimArray a
forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
x

#if MIN_VERSION_base(4,9,0)
-- | @since 0.6.4.0
instance Semigroup (PrimArray a) where
  x :: PrimArray a
x <> :: PrimArray a -> PrimArray a -> PrimArray a
<> y :: PrimArray a
y = ByteArray -> PrimArray a
forall a. ByteArray -> PrimArray a
byteArrayToPrimArray (PrimArray a -> ByteArray
forall a. PrimArray a -> ByteArray
primArrayToByteArray PrimArray a
x ByteArray -> ByteArray -> ByteArray
forall a. Semigroup a => a -> a -> a
SG.<> PrimArray a -> ByteArray
forall a. PrimArray a -> ByteArray
primArrayToByteArray PrimArray a
y)
  sconcat :: NonEmpty (PrimArray a) -> PrimArray a
sconcat = ByteArray -> PrimArray a
forall a. ByteArray -> PrimArray a
byteArrayToPrimArray (ByteArray -> PrimArray a)
-> (NonEmpty (PrimArray a) -> ByteArray)
-> NonEmpty (PrimArray a)
-> PrimArray a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty ByteArray -> ByteArray
forall a. Semigroup a => NonEmpty a -> a
SG.sconcat (NonEmpty ByteArray -> ByteArray)
-> (NonEmpty (PrimArray a) -> NonEmpty ByteArray)
-> NonEmpty (PrimArray a)
-> ByteArray
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PrimArray a -> ByteArray)
-> NonEmpty (PrimArray a) -> NonEmpty ByteArray
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PrimArray a -> ByteArray
forall a. PrimArray a -> ByteArray
primArrayToByteArray
  stimes :: b -> PrimArray a -> PrimArray a
stimes i :: b
i arr :: PrimArray a
arr = ByteArray -> PrimArray a
forall a. ByteArray -> PrimArray a
byteArrayToPrimArray (b -> ByteArray -> ByteArray
forall a b. (Semigroup a, Integral b) => b -> a -> a
SG.stimes b
i (PrimArray a -> ByteArray
forall a. PrimArray a -> ByteArray
primArrayToByteArray PrimArray a
arr))
#endif

-- | @since 0.6.4.0
instance Monoid (PrimArray a) where
  mempty :: PrimArray a
mempty = PrimArray a
forall a. PrimArray a
emptyPrimArray
#if !(MIN_VERSION_base(4,11,0))
  mappend x y = byteArrayToPrimArray (mappend (primArrayToByteArray x) (primArrayToByteArray y))
#endif
  mconcat :: [PrimArray a] -> PrimArray a
mconcat = ByteArray -> PrimArray a
forall a. ByteArray -> PrimArray a
byteArrayToPrimArray (ByteArray -> PrimArray a)
-> ([PrimArray a] -> ByteArray) -> [PrimArray a] -> PrimArray a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ByteArray] -> ByteArray
forall a. Monoid a => [a] -> a
mconcat ([ByteArray] -> ByteArray)
-> ([PrimArray a] -> [ByteArray]) -> [PrimArray a] -> ByteArray
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PrimArray a -> ByteArray) -> [PrimArray a] -> [ByteArray]
forall a b. (a -> b) -> [a] -> [b]
map PrimArray a -> ByteArray
forall a. PrimArray a -> ByteArray
primArrayToByteArray

-- | The empty primitive array.
emptyPrimArray :: PrimArray a
{-# NOINLINE emptyPrimArray #-}
emptyPrimArray :: PrimArray a
emptyPrimArray = (forall s. ST s (PrimArray a)) -> PrimArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray a)) -> PrimArray a)
-> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ (State# (PrimState (ST s))
 -> (# State# (PrimState (ST s)), PrimArray a #))
-> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState (ST s))
  -> (# State# (PrimState (ST s)), PrimArray a #))
 -> ST s (PrimArray a))
-> (State# (PrimState (ST s))
    -> (# State# (PrimState (ST s)), PrimArray a #))
-> ST s (PrimArray a)
forall a b. (a -> b) -> a -> b
$ \s0# :: State# (PrimState (ST s))
s0# -> case Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# 0# State# s
State# (PrimState (ST s))
s0# of
  (# s1# :: State# s
s1#, arr# :: MutableByteArray# s
arr# #) -> case MutableByteArray# s -> State# s -> (# State# s, ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# s
arr# State# s
s1# of
    (# s2# :: State# s
s2#, arr'# :: ByteArray#
arr'# #) -> (# State# s
State# (PrimState (ST s))
s2#, ByteArray# -> PrimArray a
forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
arr'# #)

-- | Create a new mutable primitive array of the given length. The
-- underlying memory is left uninitialized.
newPrimArray :: forall m a. (PrimMonad m, Prim a) => Int -> m (MutablePrimArray (PrimState m) a)
{-# INLINE newPrimArray #-}
newPrimArray :: Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray (I# n# :: Int#
n#)
  = (State# (PrimState m)
 -> (# State# (PrimState m), MutablePrimArray (PrimState m) a #))
-> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\s# :: State# (PrimState m)
s# ->
      case Int#
-> State# (PrimState m)
-> (# State# (PrimState m), MutableByteArray# (PrimState m) #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# (Int#
n# Int# -> Int# -> Int#
*# a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)) State# (PrimState m)
s# of
        (# s'# :: State# (PrimState m)
s'#, arr# :: MutableByteArray# (PrimState m)
arr# #) -> (# State# (PrimState m)
s'#, MutableByteArray# (PrimState m) -> MutablePrimArray (PrimState m) a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# (PrimState m)
arr# #)
    )

-- | Resize a mutable primitive array. The new size is given in elements.
--
-- This will either resize the array in-place or, if not possible, allocate the
-- contents into a new, unpinned array and copy the original array\'s contents.
--
-- To avoid undefined behaviour, the original 'MutablePrimArray' shall not be
-- accessed anymore after a 'resizeMutablePrimArray' has been performed.
-- Moreover, no reference to the old one should be kept in order to allow
-- garbage collection of the original 'MutablePrimArray' in case a new
-- 'MutablePrimArray' had to be allocated.
resizeMutablePrimArray :: forall m a. (PrimMonad m, Prim a)
  => MutablePrimArray (PrimState m) a
  -> Int -- ^ new size
  -> m (MutablePrimArray (PrimState m) a)
{-# INLINE resizeMutablePrimArray #-}
#if __GLASGOW_HASKELL__ >= 710
resizeMutablePrimArray :: MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray (MutablePrimArray arr# :: MutableByteArray# (PrimState m)
arr#) (I# n# :: Int#
n#)
  = (State# (PrimState m)
 -> (# State# (PrimState m), MutablePrimArray (PrimState m) a #))
-> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\s# :: State# (PrimState m)
s# -> case MutableByteArray# (PrimState m)
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), MutableByteArray# (PrimState m) #)
forall d.
MutableByteArray# d
-> Int# -> State# d -> (# State# d, MutableByteArray# d #)
resizeMutableByteArray# MutableByteArray# (PrimState m)
arr# (Int#
n# Int# -> Int# -> Int#
*# a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)) State# (PrimState m)
s# of
                        (# s'# :: State# (PrimState m)
s'#, arr'# :: MutableByteArray# (PrimState m)
arr'# #) -> (# State# (PrimState m)
s'#, MutableByteArray# (PrimState m) -> MutablePrimArray (PrimState m) a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# (PrimState m)
arr'# #))
#else
resizeMutablePrimArray arr n
  = do arr' <- newPrimArray n
       copyMutablePrimArray arr' 0 arr 0 (min (sizeofMutablePrimArray arr) n)
       return arr'
#endif

-- Although it is possible to shim resizeMutableByteArray for old GHCs, this
-- is not the case with shrinkMutablePrimArray.
#if __GLASGOW_HASKELL__ >= 710
-- | Shrink a mutable primitive array. The new size is given in elements.
-- It must be smaller than the old size. The array will be resized in place.
-- This function is only available when compiling with GHC 7.10 or newer.
shrinkMutablePrimArray :: forall m a. (PrimMonad m, Prim a)
  => MutablePrimArray (PrimState m) a
  -> Int -- ^ new size
  -> m ()
{-# INLINE shrinkMutablePrimArray #-}
shrinkMutablePrimArray :: MutablePrimArray (PrimState m) a -> Int -> m ()
shrinkMutablePrimArray (MutablePrimArray arr# :: MutableByteArray# (PrimState m)
arr#) (I# n# :: Int#
n#)
  = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (MutableByteArray# (PrimState m)
-> Int# -> State# (PrimState m) -> State# (PrimState m)
forall d. MutableByteArray# d -> Int# -> State# d -> State# d
shrinkMutableByteArray# MutableByteArray# (PrimState m)
arr# (Int#
n# Int# -> Int# -> Int#
*# a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
#endif

readPrimArray :: (Prim a, PrimMonad m) => MutablePrimArray (PrimState m) a -> Int -> m a
{-# INLINE readPrimArray #-}
readPrimArray :: MutablePrimArray (PrimState m) a -> Int -> m a
readPrimArray (MutablePrimArray arr# :: MutableByteArray# (PrimState m)
arr#) (I# i# :: Int#
i#)
  = (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (MutableByteArray# (PrimState m)
-> Int# -> State# (PrimState m) -> (# State# (PrimState m), a #)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# (PrimState m)
arr# Int#
i#)

-- | Write an element to the given index.
writePrimArray ::
     (Prim a, PrimMonad m)
  => MutablePrimArray (PrimState m) a -- ^ array
  -> Int -- ^ index
  -> a -- ^ element
  -> m ()
{-# INLINE writePrimArray #-}
writePrimArray :: MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutablePrimArray arr# :: MutableByteArray# (PrimState m)
arr#) (I# i# :: Int#
i#) x :: a
x
  = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (MutableByteArray# (PrimState m)
-> Int# -> a -> State# (PrimState m) -> State# (PrimState m)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# (PrimState m)
arr# Int#
i# a
x)

-- | Copy part of a mutable array into another mutable array.
--   In the case that the destination and
--   source arrays are the same, the regions may overlap.
copyMutablePrimArray :: forall m a.
     (PrimMonad m, Prim a)
  => MutablePrimArray (PrimState m) a -- ^ destination array
  -> Int -- ^ offset into destination array
  -> MutablePrimArray (PrimState m) a -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of elements to copy
  -> m ()
{-# INLINE copyMutablePrimArray #-}
copyMutablePrimArray :: MutablePrimArray (PrimState m) a
-> Int -> MutablePrimArray (PrimState m) a -> Int -> Int -> m ()
copyMutablePrimArray (MutablePrimArray dst# :: MutableByteArray# (PrimState m)
dst#) (I# doff# :: Int#
doff#) (MutablePrimArray src# :: MutableByteArray# (PrimState m)
src#) (I# soff# :: Int#
soff#) (I# n# :: Int#
n#)
  = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (MutableByteArray# (PrimState m)
-> Int#
-> MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> State# (PrimState m)
forall d.
MutableByteArray# d
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
copyMutableByteArray#
      MutableByteArray# (PrimState m)
src#
      (Int#
soff# Int# -> Int# -> Int#
*# (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
      MutableByteArray# (PrimState m)
dst#
      (Int#
doff# Int# -> Int# -> Int#
*# (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
      (Int#
n# Int# -> Int# -> Int#
*# (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
    )

-- | Copy part of an array into another mutable array.
copyPrimArray :: forall m a.
     (PrimMonad m, Prim a)
  => MutablePrimArray (PrimState m) a -- ^ destination array
  -> Int -- ^ offset into destination array
  -> PrimArray a -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of elements to copy
  -> m ()
{-# INLINE copyPrimArray #-}
copyPrimArray :: MutablePrimArray (PrimState m) a
-> Int -> PrimArray a -> Int -> Int -> m ()
copyPrimArray (MutablePrimArray dst# :: MutableByteArray# (PrimState m)
dst#) (I# doff# :: Int#
doff#) (PrimArray src# :: ByteArray#
src#) (I# soff# :: Int#
soff#) (I# n# :: Int#
n#)
  = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (ByteArray#
-> Int#
-> MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> State# (PrimState m)
forall d.
ByteArray#
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
copyByteArray#
      ByteArray#
src#
      (Int#
soff# Int# -> Int# -> Int#
*# (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
      MutableByteArray# (PrimState m)
dst#
      (Int#
doff# Int# -> Int# -> Int#
*# (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
      (Int#
n# Int# -> Int# -> Int#
*# (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))
    )

#if __GLASGOW_HASKELL__ >= 708
-- | Copy a slice of an immutable primitive array to an address.
--   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. This function is only
--   available when building with GHC 7.8 or newer.
copyPrimArrayToPtr :: forall m a. (PrimMonad m, Prim a)
  => Ptr a -- ^ destination pointer
  -> PrimArray a -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of prims to copy
  -> m ()
{-# INLINE copyPrimArrayToPtr #-}
copyPrimArrayToPtr :: Ptr a -> PrimArray a -> Int -> Int -> m ()
copyPrimArrayToPtr (Ptr addr# :: Addr#
addr#) (PrimArray ba# :: ByteArray#
ba#) (I# soff# :: Int#
soff#) (I# n# :: Int#
n#) =
    (State# (PrimState m) -> (# State# (PrimState m), () #)) -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\ s# :: State# (PrimState m)
s# ->
        let s'# :: State# (PrimState m)
s'# = ByteArray#
-> Int#
-> Addr#
-> Int#
-> State# (PrimState m)
-> State# (PrimState m)
forall d.
ByteArray# -> Int# -> Addr# -> Int# -> State# d -> State# d
copyByteArrayToAddr# ByteArray#
ba# (Int#
soff# Int# -> Int# -> Int#
*# Int#
siz#) Addr#
addr# (Int#
n# Int# -> Int# -> Int#
*# Int#
siz#) State# (PrimState m)
s#
        in (# State# (PrimState m)
s'#, () #))
  where siz# :: Int#
siz# = a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)

-- | Copy a slice of an immutable primitive array to an address.
--   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. This function is only
--   available when building with GHC 7.8 or newer.
copyMutablePrimArrayToPtr :: forall m a. (PrimMonad m, Prim a)
  => Ptr a -- ^ destination pointer
  -> MutablePrimArray (PrimState m) a -- ^ source array
  -> Int -- ^ offset into source array
  -> Int -- ^ number of prims to copy
  -> m ()
{-# INLINE copyMutablePrimArrayToPtr #-}
copyMutablePrimArrayToPtr :: Ptr a -> MutablePrimArray (PrimState m) a -> Int -> Int -> m ()
copyMutablePrimArrayToPtr (Ptr addr# :: Addr#
addr#) (MutablePrimArray mba# :: MutableByteArray# (PrimState m)
mba#) (I# soff# :: Int#
soff#) (I# n# :: Int#
n#) =
    (State# (PrimState m) -> (# State# (PrimState m), () #)) -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\ s# :: State# (PrimState m)
s# ->
        let s'# :: State# (PrimState m)
s'# = MutableByteArray# (PrimState m)
-> Int#
-> Addr#
-> Int#
-> State# (PrimState m)
-> State# (PrimState m)
forall d.
MutableByteArray# d
-> Int# -> Addr# -> Int# -> State# d -> State# d
copyMutableByteArrayToAddr# MutableByteArray# (PrimState m)
mba# (Int#
soff# Int# -> Int# -> Int#
*# Int#
siz#) Addr#
addr# (Int#
n# Int# -> Int# -> Int#
*# Int#
siz#) State# (PrimState m)
s#
        in (# State# (PrimState m)
s'#, () #))
  where siz# :: Int#
siz# = a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)
#endif

-- | Fill a slice of a mutable primitive array with a value.
setPrimArray
  :: (Prim a, PrimMonad m)
  => MutablePrimArray (PrimState m) a -- ^ array to fill
  -> Int -- ^ offset into array
  -> Int -- ^ number of values to fill
  -> a -- ^ value to fill with
  -> m ()
{-# INLINE setPrimArray #-}
setPrimArray :: MutablePrimArray (PrimState m) a -> Int -> Int -> a -> m ()
setPrimArray (MutablePrimArray dst# :: MutableByteArray# (PrimState m)
dst#) (I# doff# :: Int#
doff#) (I# sz# :: Int#
sz#) x :: a
x
  = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> a
-> State# (PrimState m)
-> State# (PrimState m)
forall a s.
Prim a =>
MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s
PT.setByteArray# MutableByteArray# (PrimState m)
dst# Int#
doff# Int#
sz# a
x)

-- | Get the size of a mutable primitive array in elements. Unlike 'sizeofMutablePrimArray',
-- this function ensures sequencing in the presence of resizing.
getSizeofMutablePrimArray :: forall m a. (PrimMonad m, Prim a)
  => MutablePrimArray (PrimState m) a -- ^ array
  -> m Int
{-# INLINE getSizeofMutablePrimArray #-}
#if __GLASGOW_HASKELL__ >= 801
getSizeofMutablePrimArray :: MutablePrimArray (PrimState m) a -> m Int
getSizeofMutablePrimArray (MutablePrimArray arr# :: MutableByteArray# (PrimState m)
arr#)
  = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\s# :: State# (PrimState m)
s# ->
      case MutableByteArray# (PrimState m)
-> State# (PrimState m) -> (# State# (PrimState m), Int# #)
forall d. MutableByteArray# d -> State# d -> (# State# d, Int# #)
getSizeofMutableByteArray# MutableByteArray# (PrimState m)
arr# State# (PrimState m)
s# of
        (# s'# :: State# (PrimState m)
s'#, sz# :: Int#
sz# #) -> (# State# (PrimState m)
s'#, Int# -> Int
I# (Int# -> Int# -> Int#
quotInt# Int#
sz# (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a))) #)
    )
#else
-- On older GHCs, it is not possible to resize a byte array, so
-- this provides behavior consistent with the implementation for
-- newer GHCs.
getSizeofMutablePrimArray arr
  = return (sizeofMutablePrimArray arr)
#endif

-- | Size of the mutable primitive array in elements. This function shall not
--   be used on primitive arrays that are an argument to or a result of
--   'resizeMutablePrimArray' or 'shrinkMutablePrimArray'.
sizeofMutablePrimArray :: forall s a. Prim a => MutablePrimArray s a -> Int
{-# INLINE sizeofMutablePrimArray #-}
sizeofMutablePrimArray :: MutablePrimArray s a -> Int
sizeofMutablePrimArray (MutablePrimArray arr# :: MutableByteArray# s
arr#) =
  Int# -> Int
I# (Int# -> Int# -> Int#
quotInt# (MutableByteArray# s -> Int#
forall d. MutableByteArray# d -> Int#
sizeofMutableByteArray# MutableByteArray# s
arr#) (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))

-- | Check if the two arrays refer to the same memory block.
sameMutablePrimArray :: MutablePrimArray s a -> MutablePrimArray s a -> Bool
{-# INLINE sameMutablePrimArray #-}
sameMutablePrimArray :: MutablePrimArray s a -> MutablePrimArray s a -> Bool
sameMutablePrimArray (MutablePrimArray arr# :: MutableByteArray# s
arr#) (MutablePrimArray brr# :: MutableByteArray# s
brr#)
  = Int# -> Bool
isTrue# (MutableByteArray# s -> MutableByteArray# s -> Int#
forall d. MutableByteArray# d -> MutableByteArray# d -> Int#
sameMutableByteArray# MutableByteArray# s
arr# MutableByteArray# s
brr#)

-- | Convert a mutable byte array to an immutable one without copying. The
-- array should not be modified after the conversion.
unsafeFreezePrimArray
  :: PrimMonad m => MutablePrimArray (PrimState m) a -> m (PrimArray a)
{-# INLINE unsafeFreezePrimArray #-}
unsafeFreezePrimArray :: MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray (MutablePrimArray arr# :: MutableByteArray# (PrimState m)
arr#)
  = (State# (PrimState m) -> (# State# (PrimState m), PrimArray a #))
-> m (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\s# :: State# (PrimState m)
s# -> case MutableByteArray# (PrimState m)
-> State# (PrimState m) -> (# State# (PrimState m), ByteArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, ByteArray# #)
unsafeFreezeByteArray# MutableByteArray# (PrimState m)
arr# State# (PrimState m)
s# of
                        (# s'# :: State# (PrimState m)
s'#, arr'# :: ByteArray#
arr'# #) -> (# State# (PrimState m)
s'#, ByteArray# -> PrimArray a
forall a. ByteArray# -> PrimArray a
PrimArray ByteArray#
arr'# #))

-- | Convert an immutable array to a mutable one without copying. The
-- original array should not be used after the conversion.
unsafeThawPrimArray
  :: PrimMonad m => PrimArray a -> m (MutablePrimArray (PrimState m) a)
{-# INLINE unsafeThawPrimArray #-}
unsafeThawPrimArray :: PrimArray a -> m (MutablePrimArray (PrimState m) a)
unsafeThawPrimArray (PrimArray arr# :: ByteArray#
arr#)
  = (State# (PrimState m)
 -> (# State# (PrimState m), MutablePrimArray (PrimState m) a #))
-> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive (\s# :: State# (PrimState m)
s# -> (# State# (PrimState m)
s#, MutableByteArray# (PrimState m) -> MutablePrimArray (PrimState m) a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray (ByteArray# -> MutableByteArray# (PrimState m)
unsafeCoerce# ByteArray#
arr#) #))

-- | Read a primitive value from the primitive array.
indexPrimArray :: forall a. Prim a => PrimArray a -> Int -> a
{-# INLINE indexPrimArray #-}
indexPrimArray :: PrimArray a -> Int -> a
indexPrimArray (PrimArray arr# :: ByteArray#
arr#) (I# i# :: Int#
i#) = ByteArray# -> Int# -> a
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# Int#
i#

-- | Get the size, in elements, of the primitive array.
sizeofPrimArray :: forall a. Prim a => PrimArray a -> Int
{-# INLINE sizeofPrimArray #-}
sizeofPrimArray :: PrimArray a -> Int
sizeofPrimArray (PrimArray arr# :: ByteArray#
arr#) = Int# -> Int
I# (Int# -> Int# -> Int#
quotInt# (ByteArray# -> Int#
sizeofByteArray# ByteArray#
arr#) (a -> Int#
forall a. Prim a => a -> Int#
sizeOf# (a
forall a. HasCallStack => a
undefined :: a)))

-- | Lazy right-associated fold over the elements of a 'PrimArray'.
{-# INLINE foldrPrimArray #-}
foldrPrimArray :: forall a b. Prim a => (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray :: (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray f :: a -> b -> b
f z :: b
z arr :: PrimArray a
arr = Int -> b
go 0
  where
    !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
    go :: Int -> b
go !Int
i
      | Int
sz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
i = a -> b -> b
f (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i) (Int -> b
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+1))
      | Bool
otherwise = b
z

-- | Strict right-associated fold over the elements of a 'PrimArray'.
{-# INLINE foldrPrimArray' #-}
foldrPrimArray' :: forall a b. Prim a => (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray' :: (a -> b -> b) -> b -> PrimArray a -> b
foldrPrimArray' f :: a -> b -> b
f z0 :: b
z0 arr :: PrimArray a
arr = Int -> b -> b
go (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) b
z0
  where
    go :: Int -> b -> b
go !Int
i !b
acc
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = b
acc
      | Bool
otherwise = Int -> b -> b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) (a -> b -> b
f (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i) b
acc)

-- | Lazy left-associated fold over the elements of a 'PrimArray'.
{-# INLINE foldlPrimArray #-}
foldlPrimArray :: forall a b. Prim a => (b -> a -> b) -> b -> PrimArray a -> b
foldlPrimArray :: (b -> a -> b) -> b -> PrimArray a -> b
foldlPrimArray f :: b -> a -> b
f z :: b
z arr :: PrimArray a
arr = Int -> b
go (PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)
  where
    go :: Int -> b
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = b
z
      | Bool
otherwise = b -> a -> b
f (Int -> b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1)) (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i)

-- | Strict left-associated fold over the elements of a 'PrimArray'.
{-# INLINE foldlPrimArray' #-}
foldlPrimArray' :: forall a b. Prim a => (b -> a -> b) -> b -> PrimArray a -> b
foldlPrimArray' :: (b -> a -> b) -> b -> PrimArray a -> b
foldlPrimArray' f :: b -> a -> b
f z0 :: b
z0 arr :: PrimArray a
arr = Int -> b -> b
go 0 b
z0
  where
    !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
    go :: Int -> b -> b
go !Int
i !b
acc
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = Int -> b -> b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (b -> a -> b
f b
acc (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i))
      | Bool
otherwise = b
acc

-- | Strict left-associated fold over the elements of a 'PrimArray'.
{-# INLINE foldlPrimArrayM' #-}
foldlPrimArrayM' :: (Prim a, Monad m) => (b -> a -> m b) -> b -> PrimArray a -> m b
foldlPrimArrayM' :: (b -> a -> m b) -> b -> PrimArray a -> m b
foldlPrimArrayM' f :: b -> a -> m b
f z0 :: b
z0 arr :: PrimArray a
arr = Int -> b -> m b
go 0 b
z0
  where
    !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
    go :: Int -> b -> m b
go !Int
i !b
acc1
      | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = do
          b
acc2 <- b -> a -> m b
f b
acc1 (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
i)
          Int -> b -> m b
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) b
acc2
      | Bool
otherwise = b -> m b
forall (m :: * -> *) a. Monad m => a -> m a
return b
acc1

-- | Traverse a primitive array. The traversal forces the resulting values and
-- writes them to the new primitive array as it performs the monadic effects.
-- Consequently:
--
-- >>> traversePrimArrayP (\x -> print x $> bool x undefined (x == 2)) (fromList [1, 2, 3 :: Int])
-- 1
-- 2
-- *** Exception: Prelude.undefined
--
-- In many situations, 'traversePrimArrayP' can replace 'traversePrimArray',
-- changing the strictness characteristics of the traversal but typically improving
-- the performance. Consider the following short-circuiting traversal:
--
-- > incrPositiveA :: PrimArray Int -> Maybe (PrimArray Int)
-- > incrPositiveA xs = traversePrimArray (\x -> bool Nothing (Just (x + 1)) (x > 0)) xs
--
-- This can be rewritten using 'traversePrimArrayP'. To do this, we must
-- change the traversal context to @MaybeT (ST s)@, which has a 'PrimMonad'
-- instance:
--
-- > incrPositiveB :: PrimArray Int -> Maybe (PrimArray Int)
-- > incrPositiveB xs = runST $ runMaybeT $ traversePrimArrayP
-- >   (\x -> bool (MaybeT (return Nothing)) (MaybeT (return (Just (x + 1)))) (x > 0))
-- >   xs
--
-- Benchmarks demonstrate that the second implementation runs 150 times
-- faster than the first. It also results in fewer allocations.
{-# INLINE traversePrimArrayP #-}
traversePrimArrayP :: (PrimMonad m, Prim a, Prim b)
  => (a -> m b)
  -> PrimArray a
  -> m (PrimArray b)
traversePrimArrayP :: (a -> m b) -> PrimArray a -> m (PrimArray b)
traversePrimArrayP f :: a -> m b
f arr :: PrimArray a
arr = do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray (PrimState m) b
marr <- Int -> m (MutablePrimArray (PrimState m) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> m ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          b
b <- a -> m b
f (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ix)
          MutablePrimArray (PrimState m) b -> Int -> b -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) b
marr Int
ix b
b
          Int -> m ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
        else () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> m ()
go 0
  MutablePrimArray (PrimState m) b -> m (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray (PrimState m) b
marr

-- | Filter the primitive array, keeping the elements for which the monadic
-- predicate evaluates true.
{-# INLINE filterPrimArrayP #-}
filterPrimArrayP :: (PrimMonad m, Prim a)
  => (a -> m Bool)
  -> PrimArray a
  -> m (PrimArray a)
filterPrimArrayP :: (a -> m Bool) -> PrimArray a -> m (PrimArray a)
filterPrimArrayP f :: a -> m Bool
f arr :: PrimArray a
arr = do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray (PrimState m) a
marr <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> Int -> m Int
go !Int
ixSrc !Int
ixDst = if Int
ixSrc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          let a :: a
a = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ixSrc
          Bool
b <- a -> m Bool
f a
a
          if Bool
b
            then do
              MutablePrimArray (PrimState m) a -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) a
marr Int
ixDst a
a
              Int -> Int -> m Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
            else Int -> Int -> m Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) Int
ixDst
        else Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
ixDst
  Int
lenDst <- Int -> Int -> m Int
go 0 0
  MutablePrimArray (PrimState m) a
marr' <- MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray MutablePrimArray (PrimState m) a
marr Int
lenDst
  MutablePrimArray (PrimState m) a -> m (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray (PrimState m) a
marr'

-- | Map over the primitive array, keeping the elements for which the monadic
-- predicate provides a 'Just'.
{-# INLINE mapMaybePrimArrayP #-}
mapMaybePrimArrayP :: (PrimMonad m, Prim a, Prim b)
  => (a -> m (Maybe b))
  -> PrimArray a
  -> m (PrimArray b)
mapMaybePrimArrayP :: (a -> m (Maybe b)) -> PrimArray a -> m (PrimArray b)
mapMaybePrimArrayP f :: a -> m (Maybe b)
f arr :: PrimArray a
arr = do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray (PrimState m) b
marr <- Int -> m (MutablePrimArray (PrimState m) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> Int -> m Int
go !Int
ixSrc !Int
ixDst = if Int
ixSrc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          let a :: a
a = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ixSrc
          Maybe b
mb <- a -> m (Maybe b)
f a
a
          case Maybe b
mb of
            Just b :: b
b -> do
              MutablePrimArray (PrimState m) b -> Int -> b -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) b
marr Int
ixDst b
b
              Int -> Int -> m Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
            Nothing -> Int -> Int -> m Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) Int
ixDst
        else Int -> m Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
ixDst
  Int
lenDst <- Int -> Int -> m Int
go 0 0
  MutablePrimArray (PrimState m) b
marr' <- MutablePrimArray (PrimState m) b
-> Int -> m (MutablePrimArray (PrimState m) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray MutablePrimArray (PrimState m) b
marr Int
lenDst
  MutablePrimArray (PrimState m) b -> m (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray (PrimState m) b
marr'

-- | Generate a primitive array by evaluating the monadic generator function
-- at each index.
{-# INLINE generatePrimArrayP #-}
generatePrimArrayP :: (PrimMonad m, Prim a)
  => Int -- ^ length
  -> (Int -> m a) -- ^ generator
  -> m (PrimArray a)
generatePrimArrayP :: Int -> (Int -> m a) -> m (PrimArray a)
generatePrimArrayP sz :: Int
sz f :: Int -> m a
f = do
  MutablePrimArray (PrimState m) a
marr <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> m ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          a
b <- Int -> m a
f Int
ix
          MutablePrimArray (PrimState m) a -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) a
marr Int
ix a
b
          Int -> m ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
        else () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> m ()
go 0
  MutablePrimArray (PrimState m) a -> m (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray (PrimState m) a
marr

-- | Execute the monadic action the given number of times and store the
-- results in a primitive array.
{-# INLINE replicatePrimArrayP #-}
replicatePrimArrayP :: (PrimMonad m, Prim a)
  => Int
  -> m a
  -> m (PrimArray a)
replicatePrimArrayP :: Int -> m a -> m (PrimArray a)
replicatePrimArrayP sz :: Int
sz f :: m a
f = do
  MutablePrimArray (PrimState m) a
marr <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> m ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          a
b <- m a
f
          MutablePrimArray (PrimState m) a -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) a
marr Int
ix a
b
          Int -> m ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
        else () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> m ()
go 0
  MutablePrimArray (PrimState m) a -> m (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray (PrimState m) a
marr


-- | Map over the elements of a primitive array.
{-# INLINE mapPrimArray #-}
mapPrimArray :: (Prim a, Prim b)
  => (a -> b)
  -> PrimArray a
  -> PrimArray b
mapPrimArray :: (a -> b) -> PrimArray a -> PrimArray b
mapPrimArray f :: a -> b
f arr :: PrimArray a
arr = (forall s. ST s (PrimArray b)) -> PrimArray b
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray b)) -> PrimArray b)
-> (forall s. ST s (PrimArray b)) -> PrimArray b
forall a b. (a -> b) -> a -> b
$ do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray s b
marr <- Int -> ST s (MutablePrimArray (PrimState (ST s)) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> ST s ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          let b :: b
b = a -> b
f (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ix)
          MutablePrimArray (PrimState (ST s)) b -> Int -> b -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray s b
MutablePrimArray (PrimState (ST s)) b
marr Int
ix b
b
          Int -> ST s ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
        else () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> ST s ()
go 0
  MutablePrimArray (PrimState (ST s)) b -> ST s (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s b
MutablePrimArray (PrimState (ST s)) b
marr

-- | Indexed map over the elements of a primitive array.
{-# INLINE imapPrimArray #-}
imapPrimArray :: (Prim a, Prim b)
  => (Int -> a -> b)
  -> PrimArray a
  -> PrimArray b
imapPrimArray :: (Int -> a -> b) -> PrimArray a -> PrimArray b
imapPrimArray f :: Int -> a -> b
f arr :: PrimArray a
arr = (forall s. ST s (PrimArray b)) -> PrimArray b
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray b)) -> PrimArray b)
-> (forall s. ST s (PrimArray b)) -> PrimArray b
forall a b. (a -> b) -> a -> b
$ do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray s b
marr <- Int -> ST s (MutablePrimArray (PrimState (ST s)) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> ST s ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          let b :: b
b = Int -> a -> b
f Int
ix (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ix)
          MutablePrimArray (PrimState (ST s)) b -> Int -> b -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray s b
MutablePrimArray (PrimState (ST s)) b
marr Int
ix b
b
          Int -> ST s ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
        else () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> ST s ()
go 0
  MutablePrimArray (PrimState (ST s)) b -> ST s (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s b
MutablePrimArray (PrimState (ST s)) b
marr

-- | Filter elements of a primitive array according to a predicate.
{-# INLINE filterPrimArray #-}
filterPrimArray :: Prim a
  => (a -> Bool)
  -> PrimArray a
  -> PrimArray a
filterPrimArray :: (a -> Bool) -> PrimArray a -> PrimArray a
filterPrimArray p :: a -> Bool
p arr :: PrimArray a
arr = (forall s. ST s (PrimArray a)) -> PrimArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray a)) -> PrimArray a)
-> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray s a
marr <- Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> Int -> ST s Int
go !Int
ixSrc !Int
ixDst = if Int
ixSrc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          let !a :: a
a = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ixSrc
          if a -> Bool
p a
a
            then do
              MutablePrimArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
marr Int
ixDst a
a
              Int -> Int -> ST s Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
            else Int -> Int -> ST s Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) Int
ixDst
        else Int -> ST s Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
ixDst
  Int
dstLen <- Int -> Int -> ST s Int
go 0 0
  MutablePrimArray s a
marr' <- MutablePrimArray (PrimState (ST s)) a
-> Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
marr Int
dstLen
  MutablePrimArray (PrimState (ST s)) a -> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
marr'

-- | Filter the primitive array, keeping the elements for which the monadic
-- predicate evaluates true.
filterPrimArrayA ::
     (Applicative f, Prim a)
  => (a -> f Bool) -- ^ mapping function
  -> PrimArray a -- ^ primitive array
  -> f (PrimArray a)
filterPrimArrayA :: (a -> f Bool) -> PrimArray a -> f (PrimArray a)
filterPrimArrayA f :: a -> f Bool
f = \ !PrimArray a
ary ->
  let
    !len :: Int
len = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
ary
    go :: Int -> f (IxSTA a)
go !Int
ixSrc
      | Int
ixSrc Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len = IxSTA a -> f (IxSTA a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IxSTA a -> f (IxSTA a)) -> IxSTA a -> f (IxSTA a)
forall a b. (a -> b) -> a -> b
$ (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
forall a.
(forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
IxSTA ((forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a)
-> (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
forall a b. (a -> b) -> a -> b
$ \ixDst :: Int
ixDst _ -> Int -> ST s Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
ixDst
      | Bool
otherwise = let x :: a
x = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
ary Int
ixSrc in
          (Bool -> IxSTA a -> IxSTA a)
-> f Bool -> f (IxSTA a) -> f (IxSTA a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
            (\keep :: Bool
keep (IxSTA m :: forall s. Int -> MutableByteArray# s -> ST s Int
m) -> (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
forall a.
(forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
IxSTA ((forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a)
-> (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
forall a b. (a -> b) -> a -> b
$ \ixDst :: Int
ixDst mary :: MutableByteArray# s
mary -> if Bool
keep
              then MutablePrimArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutableByteArray# s -> MutablePrimArray s a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary) Int
ixDst a
x ST s () -> ST s Int -> ST s Int
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> MutableByteArray# s -> ST s Int
forall s. Int -> MutableByteArray# s -> ST s Int
m (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) MutableByteArray# s
mary
              else Int -> MutableByteArray# s -> ST s Int
forall s. Int -> MutableByteArray# s -> ST s Int
m Int
ixDst MutableByteArray# s
mary
            )
            (a -> f Bool
f a
x)
            (Int -> f (IxSTA a)
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1))
  in if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
     then PrimArray a -> f (PrimArray a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimArray a
forall a. PrimArray a
emptyPrimArray
     else Int -> IxSTA a -> PrimArray a
forall a. Prim a => Int -> IxSTA a -> PrimArray a
runIxSTA Int
len (IxSTA a -> PrimArray a) -> f (IxSTA a) -> f (PrimArray a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f (IxSTA a)
go 0

-- | Map over the primitive array, keeping the elements for which the applicative
-- predicate provides a 'Just'.
mapMaybePrimArrayA ::
     (Applicative f, Prim a, Prim b)
  => (a -> f (Maybe b)) -- ^ mapping function
  -> PrimArray a -- ^ primitive array
  -> f (PrimArray b)
mapMaybePrimArrayA :: (a -> f (Maybe b)) -> PrimArray a -> f (PrimArray b)
mapMaybePrimArrayA f :: a -> f (Maybe b)
f = \ !PrimArray a
ary ->
  let
    !len :: Int
len = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
ary
    go :: Int -> f (IxSTA b)
go !Int
ixSrc
      | Int
ixSrc Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len = IxSTA b -> f (IxSTA b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (IxSTA b -> f (IxSTA b)) -> IxSTA b -> f (IxSTA b)
forall a b. (a -> b) -> a -> b
$ (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA b
forall a.
(forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
IxSTA ((forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA b)
-> (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA b
forall a b. (a -> b) -> a -> b
$ \ixDst :: Int
ixDst _ -> Int -> ST s Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
ixDst
      | Bool
otherwise = let x :: a
x = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
ary Int
ixSrc in
          (Maybe b -> IxSTA b -> IxSTA b)
-> f (Maybe b) -> f (IxSTA b) -> f (IxSTA b)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
            (\mb :: Maybe b
mb (IxSTA m :: forall s. Int -> MutableByteArray# s -> ST s Int
m) -> (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA b
forall a.
(forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA a
IxSTA ((forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA b)
-> (forall s. Int -> MutableByteArray# s -> ST s Int) -> IxSTA b
forall a b. (a -> b) -> a -> b
$ \ixDst :: Int
ixDst mary :: MutableByteArray# s
mary -> case Maybe b
mb of
              Just b -> MutablePrimArray (PrimState (ST s)) b -> Int -> b -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutableByteArray# s -> MutablePrimArray s b
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary) Int
ixDst b
b ST s () -> ST s Int -> ST s Int
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Int -> MutableByteArray# s -> ST s Int
forall s. Int -> MutableByteArray# s -> ST s Int
m (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) MutableByteArray# s
mary
              Nothing -> Int -> MutableByteArray# s -> ST s Int
forall s. Int -> MutableByteArray# s -> ST s Int
m Int
ixDst MutableByteArray# s
mary
            )
            (a -> f (Maybe b)
f a
x)
            (Int -> f (IxSTA b)
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1))
  in if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
     then PrimArray b -> f (PrimArray b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimArray b
forall a. PrimArray a
emptyPrimArray
     else Int -> IxSTA b -> PrimArray b
forall a. Prim a => Int -> IxSTA a -> PrimArray a
runIxSTA Int
len (IxSTA b -> PrimArray b) -> f (IxSTA b) -> f (PrimArray b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f (IxSTA b)
go 0

-- | Map over a primitive array, optionally discarding some elements. This
--   has the same behavior as @Data.Maybe.mapMaybe@.
{-# INLINE mapMaybePrimArray #-}
mapMaybePrimArray :: (Prim a, Prim b)
  => (a -> Maybe b)
  -> PrimArray a
  -> PrimArray b
mapMaybePrimArray :: (a -> Maybe b) -> PrimArray a -> PrimArray b
mapMaybePrimArray p :: a -> Maybe b
p arr :: PrimArray a
arr = (forall s. ST s (PrimArray b)) -> PrimArray b
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray b)) -> PrimArray b)
-> (forall s. ST s (PrimArray b)) -> PrimArray b
forall a b. (a -> b) -> a -> b
$ do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray s b
marr <- Int -> ST s (MutablePrimArray (PrimState (ST s)) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> Int -> ST s Int
go !Int
ixSrc !Int
ixDst = if Int
ixSrc Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
        then do
          let !a :: a
a = PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ixSrc
          case a -> Maybe b
p a
a of
            Just b :: b
b -> do
              MutablePrimArray (PrimState (ST s)) b -> Int -> b -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray s b
MutablePrimArray (PrimState (ST s)) b
marr Int
ixDst b
b
              Int -> Int -> ST s Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) (Int
ixDst Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
            Nothing -> Int -> Int -> ST s Int
go (Int
ixSrc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1) Int
ixDst
        else Int -> ST s Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
ixDst
  Int
dstLen <- Int -> Int -> ST s Int
go 0 0
  MutablePrimArray s b
marr' <- MutablePrimArray (PrimState (ST s)) b
-> Int -> ST s (MutablePrimArray (PrimState (ST s)) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray MutablePrimArray s b
MutablePrimArray (PrimState (ST s)) b
marr Int
dstLen
  MutablePrimArray (PrimState (ST s)) b -> ST s (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s b
MutablePrimArray (PrimState (ST s)) b
marr'


-- | Traverse a primitive array. The traversal performs all of the applicative
-- effects /before/ forcing the resulting values and writing them to the new
-- primitive array. Consequently:
--
-- >>> traversePrimArray (\x -> print x $> bool x undefined (x == 2)) (fromList [1, 2, 3 :: Int])
-- 1
-- 2
-- 3
-- *** Exception: Prelude.undefined
--
-- The function 'traversePrimArrayP' always outperforms this function, but it
-- requires a 'PrimMonad' constraint, and it forces the values as
-- it performs the effects.
traversePrimArray ::
     (Applicative f, Prim a, Prim b)
  => (a -> f b) -- ^ mapping function
  -> PrimArray a -- ^ primitive array
  -> f (PrimArray b)
traversePrimArray :: (a -> f b) -> PrimArray a -> f (PrimArray b)
traversePrimArray f :: a -> f b
f = \ !PrimArray a
ary ->
  let
    !len :: Int
len = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
ary
    go :: Int -> f (STA b)
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len = STA b -> f (STA b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STA b -> f (STA b)) -> STA b -> f (STA b)
forall a b. (a -> b) -> a -> b
$ (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b)
-> (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary -> MutablePrimArray (PrimState (ST s)) b -> ST s (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray (MutableByteArray# s -> MutablePrimArray s b
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary)
      | a
x <- PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
ary Int
i
      = (b -> STA b -> STA b) -> f b -> f (STA b) -> f (STA b)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\b :: b
b (STA m :: forall s. MutableByteArray# s -> ST s (PrimArray b)
m) -> (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b)
-> (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary ->
                  MutablePrimArray (PrimState (ST s)) b -> Int -> b -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutableByteArray# s -> MutablePrimArray s b
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary) Int
i b
b ST s () -> ST s (PrimArray b) -> ST s (PrimArray b)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MutableByteArray# s -> ST s (PrimArray b)
forall s. MutableByteArray# s -> ST s (PrimArray b)
m MutableByteArray# s
mary)
               (a -> f b
f a
x) (Int -> f (STA b)
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1))
  in if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
     then PrimArray b -> f (PrimArray b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimArray b
forall a. PrimArray a
emptyPrimArray
     else Int -> STA b -> PrimArray b
forall a. Prim a => Int -> STA a -> PrimArray a
runSTA Int
len (STA b -> PrimArray b) -> f (STA b) -> f (PrimArray b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f (STA b)
go 0

-- | Traverse a primitive array with the index of each element.
itraversePrimArray ::
     (Applicative f, Prim a, Prim b)
  => (Int -> a -> f b)
  -> PrimArray a
  -> f (PrimArray b)
itraversePrimArray :: (Int -> a -> f b) -> PrimArray a -> f (PrimArray b)
itraversePrimArray f :: Int -> a -> f b
f = \ !PrimArray a
ary ->
  let
    !len :: Int
len = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
ary
    go :: Int -> f (STA b)
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len = STA b -> f (STA b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STA b -> f (STA b)) -> STA b -> f (STA b)
forall a b. (a -> b) -> a -> b
$ (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b)
-> (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary -> MutablePrimArray (PrimState (ST s)) b -> ST s (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray (MutableByteArray# s -> MutablePrimArray s b
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary)
      | a
x <- PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
ary Int
i
      = (b -> STA b -> STA b) -> f b -> f (STA b) -> f (STA b)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\b :: b
b (STA m :: forall s. MutableByteArray# s -> ST s (PrimArray b)
m) -> (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b)
-> (forall s. MutableByteArray# s -> ST s (PrimArray b)) -> STA b
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary ->
                  MutablePrimArray (PrimState (ST s)) b -> Int -> b -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutableByteArray# s -> MutablePrimArray s b
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary) Int
i b
b ST s () -> ST s (PrimArray b) -> ST s (PrimArray b)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MutableByteArray# s -> ST s (PrimArray b)
forall s. MutableByteArray# s -> ST s (PrimArray b)
m MutableByteArray# s
mary)
               (Int -> a -> f b
f Int
i a
x) (Int -> f (STA b)
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1))
  in if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
     then PrimArray b -> f (PrimArray b)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimArray b
forall a. PrimArray a
emptyPrimArray
     else Int -> STA b -> PrimArray b
forall a. Prim a => Int -> STA a -> PrimArray a
runSTA Int
len (STA b -> PrimArray b) -> f (STA b) -> f (PrimArray b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f (STA b)
go 0

-- | Traverse a primitive array with the indices. The traversal forces the
-- resulting values and writes them to the new primitive array as it performs
-- the monadic effects.
{-# INLINE itraversePrimArrayP #-}
itraversePrimArrayP :: (Prim a, Prim b, PrimMonad m)
  => (Int -> a -> m b)
  -> PrimArray a
  -> m (PrimArray b)
itraversePrimArrayP :: (Int -> a -> m b) -> PrimArray a -> m (PrimArray b)
itraversePrimArrayP f :: Int -> a -> m b
f arr :: PrimArray a
arr = do
  let !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
arr
  MutablePrimArray (PrimState m) b
marr <- Int -> m (MutablePrimArray (PrimState m) b)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz
  let go :: Int -> m ()
go !Int
ix
        | Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz = do
            MutablePrimArray (PrimState m) b -> Int -> b -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) b
marr Int
ix (b -> m ()) -> m b -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> a -> m b
f Int
ix (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
arr Int
ix)
            Int -> m ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
        | Bool
otherwise = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> m ()
go 0
  MutablePrimArray (PrimState m) b -> m (PrimArray b)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray (PrimState m) b
marr

-- | Generate a primitive array.
{-# INLINE generatePrimArray #-}
generatePrimArray :: Prim a
  => Int -- ^ length
  -> (Int -> a) -- ^ element from index
  -> PrimArray a
generatePrimArray :: Int -> (Int -> a) -> PrimArray a
generatePrimArray len :: Int
len f :: Int -> a
f = (forall s. ST s (PrimArray a)) -> PrimArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray a)) -> PrimArray a)
-> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ do
  MutablePrimArray s a
marr <- Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
len
  let go :: Int -> ST s ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len
        then do
          MutablePrimArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
marr Int
ix (Int -> a
f Int
ix)
          Int -> ST s ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
        else () -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
  Int -> ST s ()
go 0
  MutablePrimArray (PrimState (ST s)) a -> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
marr

-- | Create a primitive array by copying the element the given
-- number of times.
{-# INLINE replicatePrimArray #-}
replicatePrimArray :: Prim a
  => Int -- ^ length
  -> a -- ^ element
  -> PrimArray a
replicatePrimArray :: Int -> a -> PrimArray a
replicatePrimArray len :: Int
len a :: a
a = (forall s. ST s (PrimArray a)) -> PrimArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray a)) -> PrimArray a)
-> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ do
  MutablePrimArray s a
marr <- Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
len
  MutablePrimArray (PrimState (ST s)) a -> Int -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> Int -> a -> m ()
setPrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
marr 0 Int
len a
a
  MutablePrimArray (PrimState (ST s)) a -> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
marr

-- | Generate a primitive array by evaluating the applicative generator
-- function at each index.
{-# INLINE generatePrimArrayA #-}
generatePrimArrayA ::
     (Applicative f, Prim a)
  => Int -- ^ length
  -> (Int -> f a) -- ^ element from index
  -> f (PrimArray a)
generatePrimArrayA :: Int -> (Int -> f a) -> f (PrimArray a)
generatePrimArrayA len :: Int
len f :: Int -> f a
f =
  let
    go :: Int -> f (STA a)
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len = STA a -> f (STA a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STA a -> f (STA a)) -> STA a -> f (STA a)
forall a b. (a -> b) -> a -> b
$ (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a)
-> (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary -> MutablePrimArray (PrimState (ST s)) a -> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray (MutableByteArray# s -> MutablePrimArray s a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary)
      | Bool
otherwise
      = (a -> STA a -> STA a) -> f a -> f (STA a) -> f (STA a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\b :: a
b (STA m :: forall s. MutableByteArray# s -> ST s (PrimArray a)
m) -> (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a)
-> (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary ->
                  MutablePrimArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutableByteArray# s -> MutablePrimArray s a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary) Int
i a
b ST s () -> ST s (PrimArray a) -> ST s (PrimArray a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MutableByteArray# s -> ST s (PrimArray a)
forall s. MutableByteArray# s -> ST s (PrimArray a)
m MutableByteArray# s
mary)
               (Int -> f a
f Int
i) (Int -> f (STA a)
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1))
  in if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
     then PrimArray a -> f (PrimArray a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimArray a
forall a. PrimArray a
emptyPrimArray
     else Int -> STA a -> PrimArray a
forall a. Prim a => Int -> STA a -> PrimArray a
runSTA Int
len (STA a -> PrimArray a) -> f (STA a) -> f (PrimArray a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f (STA a)
go 0

-- | Execute the applicative action the given number of times and store the
-- results in a vector.
{-# INLINE replicatePrimArrayA #-}
replicatePrimArrayA ::
     (Applicative f, Prim a)
  => Int -- ^ length
  -> f a -- ^ applicative element producer
  -> f (PrimArray a)
replicatePrimArrayA :: Int -> f a -> f (PrimArray a)
replicatePrimArrayA len :: Int
len f :: f a
f =
  let
    go :: Int -> f (STA a)
go !Int
i
      | Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
len = STA a -> f (STA a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (STA a -> f (STA a)) -> STA a -> f (STA a)
forall a b. (a -> b) -> a -> b
$ (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a)
-> (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary -> MutablePrimArray (PrimState (ST s)) a -> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray (MutableByteArray# s -> MutablePrimArray s a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary)
      | Bool
otherwise
      = (a -> STA a -> STA a) -> f a -> f (STA a) -> f (STA a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (\b :: a
b (STA m :: forall s. MutableByteArray# s -> ST s (PrimArray a)
m) -> (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a.
(forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
STA ((forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a)
-> (forall s. MutableByteArray# s -> ST s (PrimArray a)) -> STA a
forall a b. (a -> b) -> a -> b
$ \mary :: MutableByteArray# s
mary ->
                  MutablePrimArray (PrimState (ST s)) a -> Int -> a -> ST s ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray (MutableByteArray# s -> MutablePrimArray s a
forall s a. MutableByteArray# s -> MutablePrimArray s a
MutablePrimArray MutableByteArray# s
mary) Int
i a
b ST s () -> ST s (PrimArray a) -> ST s (PrimArray a)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MutableByteArray# s -> ST s (PrimArray a)
forall s. MutableByteArray# s -> ST s (PrimArray a)
m MutableByteArray# s
mary)
               f a
f (Int -> f (STA a)
go (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1))
  in if Int
len Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0
     then PrimArray a -> f (PrimArray a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimArray a
forall a. PrimArray a
emptyPrimArray
     else Int -> STA a -> PrimArray a
forall a. Prim a => Int -> STA a -> PrimArray a
runSTA Int
len (STA a -> PrimArray a) -> f (STA a) -> f (PrimArray a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> f (STA a)
go 0

-- | Traverse the primitive array, discarding the results. There
-- is no 'PrimMonad' variant of this function since it would not provide
-- any performance benefit.
traversePrimArray_ ::
     (Applicative f, Prim a)
  => (a -> f b)
  -> PrimArray a
  -> f ()
traversePrimArray_ :: (a -> f b) -> PrimArray a -> f ()
traversePrimArray_ f :: a -> f b
f a :: PrimArray a
a = Int -> f ()
go 0 where
  !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
a
  go :: Int -> f ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
    then a -> f b
f (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a Int
ix) f b -> f () -> f ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> f ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
    else () -> f ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- | Traverse the primitive array with the indices, discarding the results.
-- There is no 'PrimMonad' variant of this function since it would not
-- provide any performance benefit.
itraversePrimArray_ ::
     (Applicative f, Prim a)
  => (Int -> a -> f b)
  -> PrimArray a
  -> f ()
itraversePrimArray_ :: (Int -> a -> f b) -> PrimArray a -> f ()
itraversePrimArray_ f :: Int -> a -> f b
f a :: PrimArray a
a = Int -> f ()
go 0 where
  !sz :: Int
sz = PrimArray a -> Int
forall a. Prim a => PrimArray a -> Int
sizeofPrimArray PrimArray a
a
  go :: Int -> f ()
go !Int
ix = if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
sz
    then Int -> a -> f b
f Int
ix (PrimArray a -> Int -> a
forall a. Prim a => PrimArray a -> Int -> a
indexPrimArray PrimArray a
a Int
ix) f b -> f () -> f ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Int -> f ()
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
    else () -> f ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

newtype IxSTA a = IxSTA {IxSTA a -> forall s. Int -> MutableByteArray# s -> ST s Int
_runIxSTA :: forall s. Int -> MutableByteArray# s -> ST s Int}

runIxSTA :: forall a. Prim a
  => Int -- maximum possible size
  -> IxSTA a
  -> PrimArray a
runIxSTA :: Int -> IxSTA a -> PrimArray a
runIxSTA !Int
szUpper = \ (IxSTA m :: forall s. Int -> MutableByteArray# s -> ST s Int
m) -> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray a)) -> PrimArray a)
-> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ do
  MutablePrimArray s a
ar :: MutablePrimArray s a <- Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
szUpper
  Int
sz <- Int -> MutableByteArray# s -> ST s Int
forall s. Int -> MutableByteArray# s -> ST s Int
m 0 (MutablePrimArray s a -> MutableByteArray# s
forall s a. MutablePrimArray s a -> MutableByteArray# s
unMutablePrimArray MutablePrimArray s a
ar)
  MutablePrimArray s a
ar' <- MutablePrimArray (PrimState (ST s)) a
-> Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
MutablePrimArray (PrimState m) a
-> Int -> m (MutablePrimArray (PrimState m) a)
resizeMutablePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
ar Int
sz
  MutablePrimArray (PrimState (ST s)) a -> ST s (PrimArray a)
forall (m :: * -> *) a.
PrimMonad m =>
MutablePrimArray (PrimState m) a -> m (PrimArray a)
unsafeFreezePrimArray MutablePrimArray s a
MutablePrimArray (PrimState (ST s)) a
ar'
{-# INLINE runIxSTA #-}

newtype STA a = STA {STA a -> forall s. MutableByteArray# s -> ST s (PrimArray a)
_runSTA :: forall s. MutableByteArray# s -> ST s (PrimArray a)}

runSTA :: forall a. Prim a => Int -> STA a -> PrimArray a
runSTA :: Int -> STA a -> PrimArray a
runSTA !Int
sz = \ (STA m :: forall s. MutableByteArray# s -> ST s (PrimArray a)
m) -> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (PrimArray a)) -> PrimArray a)
-> (forall s. ST s (PrimArray a)) -> PrimArray a
forall a b. (a -> b) -> a -> b
$ Int -> ST s (MutablePrimArray (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
sz ST s (MutablePrimArray s a)
-> (MutablePrimArray s a -> ST s (PrimArray a))
-> ST s (PrimArray a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \ (MutablePrimArray s a
ar :: MutablePrimArray s a) -> MutableByteArray# s -> ST s (PrimArray a)
forall s. MutableByteArray# s -> ST s (PrimArray a)
m (MutablePrimArray s a -> MutableByteArray# s
forall s a. MutablePrimArray s a -> MutableByteArray# s
unMutablePrimArray MutablePrimArray s a
ar)
{-# INLINE runSTA #-}

unMutablePrimArray :: MutablePrimArray s a -> MutableByteArray# s
unMutablePrimArray :: MutablePrimArray s a -> MutableByteArray# s
unMutablePrimArray (MutablePrimArray m :: MutableByteArray# s
m) = MutableByteArray# s
m

{- $effectfulMapCreate
The naming conventions adopted in this section are explained in the
documentation of the @Data.Primitive@ module.
-}