-- |
-- Module      : Basement.UArray
-- License     : BSD-style
-- Maintainer  : Vincent Hanquez <vincent@snarc.org>
-- Stability   : experimental
-- Portability : portable
--
-- An unboxed array of primitive types
--
-- All the cells in the array are in one chunk of contiguous
-- memory.
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
module Basement.UArray
    ( UArray(..)
    , PrimType(..)
    -- * methods
    , copy
    , unsafeCopyAtRO
    -- * internal methods
    -- , copyAddr
    , recast
    , unsafeRecast
    , length
    , freeze
    , unsafeFreeze
    , thaw
    , unsafeThaw
    -- * Creation
    , vFromListN
    , new
    , create
    , createFromIO
    , createFromPtr
    , sub
    , copyToPtr
    , withPtr
    , withMutablePtr
    , unsafeFreezeShrink
    , freezeShrink
    , fromBlock
    , toBlock
    -- * accessors
    , update
    , unsafeUpdate
    , unsafeIndex
    , unsafeIndexer
    , unsafeDewrap
    , unsafeRead
    , unsafeWrite
    -- * Functions
    , equalMemcmp
    , singleton
    , replicate
    , map
    , mapIndex
    , findIndex
    , revFindIndex
    , index
    , null
    , take
    , unsafeTake
    , drop
    , unsafeDrop
    , splitAt
    , revDrop
    , revTake
    , revSplitAt
    , splitOn
    , break
    , breakEnd
    , breakElem
    , breakLine
    , elem
    , indices
    , intersperse
    , span
    , spanEnd
    , cons
    , snoc
    , uncons
    , unsnoc
    , find
    , sortBy
    , filter
    , reverse
    , replace
    , foldr
    , foldl'
    , foldr1
    , foldl1'
    , all
    , any
    , isPrefixOf
    , isSuffixOf
    , foreignMem
    , fromForeignPtr
    , builderAppend
    , builderBuild
    , builderBuild_
    , toHexadecimal
    , toBase64Internal
    ) where

import           GHC.Prim
import           GHC.Types
import           GHC.Word
import           GHC.ST
import           GHC.Ptr
import           GHC.ForeignPtr (ForeignPtr)
import           Foreign.Marshal.Utils (copyBytes)
import           Basement.Compat.Base
import           Basement.Compat.Primitive
import           Data.Proxy
import           Basement.Types.OffsetSize
import           Basement.Compat.MonadTrans
import           Basement.NonEmpty
import           Basement.Monad
import           Basement.PrimType
import           Basement.FinalPtr
import           Basement.Exception
import           Basement.UArray.Base
import           Basement.Bits
import           Basement.Block (Block(..), MutableBlock(..))
import qualified Basement.Block as BLK
import qualified Basement.Block.Base as BLK (withPtr, unsafeWrite)
import           Basement.UArray.Mutable hiding (sub, copyToPtr)
import           Basement.Numerical.Additive
import           Basement.Numerical.Subtractive
import           Basement.Numerical.Multiplicative
import           Basement.MutableBuilder
import           Basement.Bindings.Memory (sysHsMemFindByteBa, sysHsMemFindByteAddr)
import qualified Basement.Compat.ExtList as List
import qualified Basement.Base16 as Base16
import qualified Basement.Alg.Mutable as Alg
import qualified Basement.Alg.Class as Alg
import qualified Basement.Alg.PrimArray as Alg

-- | Return the element at a specific index from an array.
--
-- If the index @n is out of bounds, an error is raised.
index :: PrimType ty => UArray ty -> Offset ty -> ty
index :: forall ty. PrimType ty => UArray ty -> Offset ty -> ty
index UArray ty
array Offset ty
n
    | Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
isOutOfBound Offset ty
n CountOf ty
len = OutOfBoundOperation -> Offset ty -> CountOf ty -> ty
forall ty a. OutOfBoundOperation -> Offset ty -> CountOf ty -> a
outOfBound OutOfBoundOperation
OOB_Index Offset ty
n CountOf ty
len
    | Bool
otherwise          = UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
array Offset ty
n
  where
    !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
array
{-# INLINE index #-}

foreignMem :: PrimType ty
           => FinalPtr ty -- ^ the start pointer with a finalizer
           -> CountOf ty  -- ^ the number of elements (in elements, not bytes)
           -> UArray ty
foreignMem :: forall ty. PrimType ty => FinalPtr ty -> CountOf ty -> UArray ty
foreignMem FinalPtr ty
fptr CountOf ty
nb = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) CountOf ty
nb (FinalPtr ty -> UArrayBackend ty
forall ty. FinalPtr ty -> UArrayBackend ty
UArrayAddr FinalPtr ty
fptr)

-- | Create a foreign UArray from foreign memory and given offset/size
--
-- No check are performed to make sure this is valid, so this is unsafe.
--
-- This is particularly useful when dealing with foreign memory and
-- 'ByteString'
fromForeignPtr :: PrimType ty
               => (ForeignPtr ty, Int, Int) -- ForeignPtr, an offset in prim elements, a size in prim elements
               -> UArray ty
fromForeignPtr :: forall ty. PrimType ty => (ForeignPtr ty, Int, Int) -> UArray ty
fromForeignPtr (ForeignPtr ty
fptr, Int
ofs, Int
len) = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
ofs) (Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
len) (FinalPtr ty -> UArrayBackend ty
forall ty. FinalPtr ty -> UArrayBackend ty
UArrayAddr (FinalPtr ty -> UArrayBackend ty)
-> FinalPtr ty -> UArrayBackend ty
forall a b. (a -> b) -> a -> b
$ ForeignPtr ty -> FinalPtr ty
forall a. ForeignPtr a -> FinalPtr a
toFinalPtrForeign ForeignPtr ty
fptr)


-- | Create a UArray from a Block
--
-- The block is still used by the uarray
fromBlock :: PrimType ty
          => Block ty
          -> UArray ty
fromBlock :: forall ty. PrimType ty => Block ty -> UArray ty
fromBlock Block ty
blk = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
0 (Block ty -> CountOf ty
forall ty. PrimType ty => Block ty -> CountOf ty
BLK.length Block ty
blk) (Block ty -> UArrayBackend ty
forall ty. Block ty -> UArrayBackend ty
UArrayBA Block ty
blk)

-- | Allocate a new array with a fill function that has access to the elements of
--   the source array.
unsafeCopyFrom :: (PrimType a, PrimType b)
               => UArray a -- ^ Source array
               -> CountOf b -- ^ Length of the destination array
               -> (UArray a -> Offset a -> MUArray b s -> ST s ())
               -- ^ Function called for each element in the source array
               -> ST s (UArray b) -- ^ Returns the filled new array
unsafeCopyFrom :: forall a b s.
(PrimType a, PrimType b) =>
UArray a
-> CountOf b
-> (UArray a -> Offset a -> MUArray b s -> ST s ())
-> ST s (UArray b)
unsafeCopyFrom UArray a
v' CountOf b
newLen UArray a -> Offset a -> MUArray b s -> ST s ()
f = CountOf b -> ST s (MUArray b (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf b
newLen ST s (MUArray b s)
-> (MUArray b s -> ST s (MUArray b s)) -> ST s (MUArray b s)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Offset a -> MUArray b s -> ST s (MUArray b s)
fill Offset a
0 ST s (MUArray b s)
-> (MUArray b s -> ST s (UArray b)) -> ST s (UArray b)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= MUArray b s -> ST s (UArray b)
MUArray b (PrimState (ST s)) -> ST s (UArray b)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze
  where len :: CountOf a
len = UArray a -> CountOf a
forall ty. UArray ty -> CountOf ty
length UArray a
v'
        fill :: Offset a -> MUArray b s -> ST s (MUArray b s)
fill Offset a
i MUArray b s
r'
            | Offset a
i Offset a -> CountOf a -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf a
len = MUArray b s -> ST s (MUArray b s)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure MUArray b s
r'
            | Bool
otherwise  = do UArray a -> Offset a -> MUArray b s -> ST s ()
f UArray a
v' Offset a
i MUArray b s
r'
                              Offset a -> MUArray b s -> ST s (MUArray b s)
fill (Offset a
i Offset a -> Offset a -> Offset a
forall a. Additive a => a -> a -> a
+ Offset a
1) MUArray b s
r'

-- | Freeze a MUArray into a UArray by copying all the content is a pristine new buffer
--
-- The MUArray in parameter can be still be used after the call without
-- changing the resulting frozen data.
freeze :: (PrimType ty, PrimMonad prim) => MUArray ty (PrimState prim) -> prim (UArray ty)
freeze :: forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> prim (UArray ty)
freeze MUArray ty (PrimState prim)
ma = do
    MUArray ty (PrimState prim)
ma' <- CountOf ty -> prim (MUArray ty (PrimState prim))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
len
    MUArray ty (PrimState prim)
-> Offset ty
-> MUArray ty (PrimState prim)
-> Offset ty
-> CountOf ty
-> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty
-> MUArray ty (PrimState prim)
-> Offset ty
-> CountOf ty
-> prim ()
copyAt MUArray ty (PrimState prim)
ma' (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) MUArray ty (PrimState prim)
ma (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) CountOf ty
len
    MUArray ty (PrimState prim) -> prim (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty (PrimState prim)
ma'
  where len :: CountOf ty
len = MUArray ty (PrimState prim) -> CountOf ty
forall ty st. PrimType ty => MUArray ty st -> CountOf ty
mutableLength MUArray ty (PrimState prim)
ma

-- | Just like 'freeze' but copy only the first n bytes
--
-- The size requested need to be smaller or equal to the length
-- of the MUArray, otherwise a Out of Bounds exception is raised
freezeShrink :: (PrimType ty, PrimMonad prim) => MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
freezeShrink :: forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
freezeShrink MUArray ty (PrimState prim)
ma CountOf ty
n = do
    Bool -> prim () -> prim ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
> MUArray ty (PrimState prim) -> CountOf ty
forall ty st. PrimType ty => MUArray ty st -> CountOf ty
mutableLength MUArray ty (PrimState prim)
ma) (prim () -> prim ()) -> prim () -> prim ()
forall a b. (a -> b) -> a -> b
$ OutOfBoundOperation -> Offset ty -> CountOf ty -> prim ()
forall (prim :: * -> *) ty a.
PrimMonad prim =>
OutOfBoundOperation -> Offset ty -> CountOf ty -> prim a
primOutOfBound OutOfBoundOperation
OOB_MemCopy (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
n) (MUArray ty (PrimState prim) -> CountOf ty
forall ty st. PrimType ty => MUArray ty st -> CountOf ty
mutableLength MUArray ty (PrimState prim)
ma)
    MUArray ty (PrimState prim)
ma' <- CountOf ty -> prim (MUArray ty (PrimState prim))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
n
    MUArray ty (PrimState prim)
-> Offset ty
-> MUArray ty (PrimState prim)
-> Offset ty
-> CountOf ty
-> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty
-> MUArray ty (PrimState prim)
-> Offset ty
-> CountOf ty
-> prim ()
copyAt MUArray ty (PrimState prim)
ma' (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) MUArray ty (PrimState prim)
ma (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) CountOf ty
n
    MUArray ty (PrimState prim) -> prim (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty (PrimState prim)
ma'

-- | Create a new array of size @n by settings each cells through the
-- function @f.
create :: forall ty . PrimType ty
       => CountOf ty           -- ^ the size of the array
       -> (Offset ty -> ty) -- ^ the function that set the value at the index
       -> UArray ty         -- ^ the array created
create :: forall ty.
PrimType ty =>
CountOf ty -> (Offset ty -> ty) -> UArray ty
create CountOf ty
n Offset ty -> ty
initializer
    | CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
0    = UArray ty
forall a. Monoid a => a
mempty
    | Bool
otherwise = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST (CountOf ty -> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
n ST s (MUArray ty s)
-> (MUArray ty s -> ST s (UArray ty)) -> ST s (UArray ty)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Offset ty -> ty)
-> MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
forall (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
(Offset ty -> ty)
-> MUArray ty (PrimState prim) -> prim (UArray ty)
iter Offset ty -> ty
initializer)
  where
    iter :: (PrimType ty, PrimMonad prim) => (Offset ty -> ty) -> MUArray ty (PrimState prim) -> prim (UArray ty)
    iter :: forall (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
(Offset ty -> ty)
-> MUArray ty (PrimState prim) -> prim (UArray ty)
iter Offset ty -> ty
f MUArray ty (PrimState prim)
ma = Offset ty -> prim (UArray ty)
loop Offset ty
0
      where
        loop :: Offset ty -> prim (UArray ty)
loop Offset ty
i
            | Offset ty
i Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
n  = MUArray ty (PrimState prim) -> prim (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty (PrimState prim)
ma
            | Bool
otherwise = MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty (PrimState prim)
ma Offset ty
i (Offset ty -> ty
f Offset ty
i) prim () -> prim (UArray ty) -> prim (UArray ty)
forall a b. prim a -> prim b -> prim b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> prim (UArray ty)
loop (Offset ty
iOffset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+Offset ty
1)
        {-# INLINE loop #-}
    {-# INLINE iter #-}

-- | Create a pinned array that is filled by a 'filler' function (typically an IO call like hGetBuf)
createFromIO :: PrimType ty
             => CountOf ty                  -- ^ the size of the array
             -> (Ptr ty -> IO (CountOf ty)) -- ^ filling function that
             -> IO (UArray ty)
createFromIO :: forall ty.
PrimType ty =>
CountOf ty -> (Ptr ty -> IO (CountOf ty)) -> IO (UArray ty)
createFromIO CountOf ty
size Ptr ty -> IO (CountOf ty)
filler
    | CountOf ty
size CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
0 = UArray ty -> IO (UArray ty)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure UArray ty
forall a. Monoid a => a
mempty
    | Bool
otherwise = do
        MUArray ty RealWorld
mba <- CountOf ty -> IO (MUArray ty (PrimState IO))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
newPinned CountOf ty
size
        CountOf ty
r   <- MUArray ty (PrimState IO)
-> (Ptr ty -> IO (CountOf ty)) -> IO (CountOf ty)
forall (prim :: * -> *) ty a.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> (Ptr ty -> prim a) -> prim a
withMutablePtr MUArray ty RealWorld
MUArray ty (PrimState IO)
mba ((Ptr ty -> IO (CountOf ty)) -> IO (CountOf ty))
-> (Ptr ty -> IO (CountOf ty)) -> IO (CountOf ty)
forall a b. (a -> b) -> a -> b
$ \Ptr ty
p -> Ptr ty -> IO (CountOf ty)
filler Ptr ty
p
        case CountOf ty
r of
            CountOf ty
0             -> UArray ty -> IO (UArray ty)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure UArray ty
forall a. Monoid a => a
mempty -- make sure we don't keep our array referenced by using empty
            CountOf ty
_ | CountOf ty
r CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
< CountOf ty
0     -> [Char] -> IO (UArray ty)
forall a. HasCallStack => [Char] -> a
error [Char]
"filler returned negative number"
              | Bool
otherwise -> MUArray ty (PrimState IO) -> CountOf ty -> IO (UArray ty)
forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
unsafeFreezeShrink MUArray ty RealWorld
MUArray ty (PrimState IO)
mba CountOf ty
r

-- | Freeze a chunk of memory pointed, of specific size into a new unboxed array
createFromPtr :: PrimType ty
              => Ptr ty
              -> CountOf ty
              -> IO (UArray ty)
createFromPtr :: forall ty. PrimType ty => Ptr ty -> CountOf ty -> IO (UArray ty)
createFromPtr Ptr ty
p CountOf ty
s = do
    MUArray ty RealWorld
ma <- CountOf ty -> IO (MUArray ty (PrimState IO))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
s
    Ptr ty -> CountOf ty -> MUArray ty (PrimState IO) -> IO ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
Ptr ty -> CountOf ty -> MUArray ty (PrimState prim) -> prim ()
copyFromPtr Ptr ty
p CountOf ty
s MUArray ty RealWorld
MUArray ty (PrimState IO)
ma
    MUArray ty (PrimState IO) -> IO (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty RealWorld
MUArray ty (PrimState IO)
ma

-----------------------------------------------------------------------
-- higher level collection implementation
-----------------------------------------------------------------------

singleton :: PrimType ty => ty -> UArray ty
singleton :: forall ty. PrimType ty => ty -> UArray ty
singleton ty
ty = CountOf ty -> (Offset ty -> ty) -> UArray ty
forall ty.
PrimType ty =>
CountOf ty -> (Offset ty -> ty) -> UArray ty
create CountOf ty
1 (ty -> Offset ty -> ty
forall a b. a -> b -> a
const ty
ty)

replicate :: PrimType ty => CountOf ty -> ty -> UArray ty
replicate :: forall ty. PrimType ty => CountOf ty -> ty -> UArray ty
replicate CountOf ty
sz ty
ty = CountOf ty -> (Offset ty -> ty) -> UArray ty
forall ty.
PrimType ty =>
CountOf ty -> (Offset ty -> ty) -> UArray ty
create CountOf ty
sz (ty -> Offset ty -> ty
forall a b. a -> b -> a
const ty
ty)

-- | update an array by creating a new array with the updates.
--
-- the operation copy the previous array, modify it in place, then freeze it.
update :: PrimType ty
       => UArray ty
       -> [(Offset ty, ty)]
       -> UArray ty
update :: forall ty.
PrimType ty =>
UArray ty -> [(Offset ty, ty)] -> UArray ty
update UArray ty
array [(Offset ty, ty)]
modifiers = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST (UArray ty -> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
UArray ty -> prim (MUArray ty (PrimState prim))
thaw UArray ty
array ST s (MUArray ty s)
-> (MUArray ty s -> ST s (UArray ty)) -> ST s (UArray ty)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(Offset ty, ty)]
-> MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
forall {prim :: * -> *} {ty}.
(PrimMonad prim, PrimType ty) =>
[(Offset ty, ty)]
-> MUArray ty (PrimState prim) -> prim (UArray ty)
doUpdate [(Offset ty, ty)]
modifiers)
  where doUpdate :: [(Offset ty, ty)]
-> MUArray ty (PrimState prim) -> prim (UArray ty)
doUpdate [(Offset ty, ty)]
l MUArray ty (PrimState prim)
ma = [(Offset ty, ty)] -> prim (UArray ty)
loop [(Offset ty, ty)]
l
          where loop :: [(Offset ty, ty)] -> prim (UArray ty)
loop []         = MUArray ty (PrimState prim) -> prim (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty (PrimState prim)
ma
                loop ((Offset ty
i,ty
v):[(Offset ty, ty)]
xs) = MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
write MUArray ty (PrimState prim)
ma Offset ty
i ty
v prim () -> prim (UArray ty) -> prim (UArray ty)
forall a b. prim a -> prim b -> prim b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [(Offset ty, ty)] -> prim (UArray ty)
loop [(Offset ty, ty)]
xs
                {-# INLINE loop #-}
        {-# INLINE doUpdate #-}

unsafeUpdate :: PrimType ty
             => UArray ty
             -> [(Offset ty, ty)]
             -> UArray ty
unsafeUpdate :: forall ty.
PrimType ty =>
UArray ty -> [(Offset ty, ty)] -> UArray ty
unsafeUpdate UArray ty
array [(Offset ty, ty)]
modifiers = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST (UArray ty -> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
UArray ty -> prim (MUArray ty (PrimState prim))
thaw UArray ty
array ST s (MUArray ty s)
-> (MUArray ty s -> ST s (UArray ty)) -> ST s (UArray ty)
forall a b. ST s a -> (a -> ST s b) -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [(Offset ty, ty)]
-> MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
forall {prim :: * -> *} {ty}.
(PrimMonad prim, PrimType ty) =>
[(Offset ty, ty)]
-> MUArray ty (PrimState prim) -> prim (UArray ty)
doUpdate [(Offset ty, ty)]
modifiers)
  where doUpdate :: [(Offset ty, ty)]
-> MUArray ty (PrimState prim) -> prim (UArray ty)
doUpdate [(Offset ty, ty)]
l MUArray ty (PrimState prim)
ma = [(Offset ty, ty)] -> prim (UArray ty)
loop [(Offset ty, ty)]
l
          where loop :: [(Offset ty, ty)] -> prim (UArray ty)
loop []         = MUArray ty (PrimState prim) -> prim (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty (PrimState prim)
ma
                loop ((Offset ty
i,ty
v):[(Offset ty, ty)]
xs) = MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty (PrimState prim)
ma Offset ty
i ty
v prim () -> prim (UArray ty) -> prim (UArray ty)
forall a b. prim a -> prim b -> prim b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> [(Offset ty, ty)] -> prim (UArray ty)
loop [(Offset ty, ty)]
xs
                {-# INLINE loop #-}
        {-# INLINE doUpdate #-}

-- | Copy all the block content to the memory starting at the destination address
copyToPtr :: forall ty prim . (PrimType ty, PrimMonad prim)
          => UArray ty -- ^ the source array to copy
          -> Ptr ty    -- ^ The destination address where the copy is going to start
          -> prim ()
copyToPtr :: forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
UArray ty -> Ptr ty -> prim ()
copyToPtr UArray ty
arr dst :: Ptr ty
dst@(Ptr Addr#
dst#) = (Block ty -> prim ())
-> (FinalPtr ty -> prim ()) -> UArray ty -> prim ()
forall (prim :: * -> *) ty a.
PrimMonad prim =>
(Block ty -> prim a)
-> (FinalPtr ty -> prim a) -> UArray ty -> prim a
onBackendPrim Block ty -> prim ()
copyBa FinalPtr ty -> prim ()
copyPtr UArray ty
arr
  where
    !(Offset os :: Int
os@(I# Int#
os#)) = Offset ty -> Offset Word8
forall a. PrimType a => Offset a -> Offset Word8
offsetInBytes (Offset ty -> Offset Word8) -> Offset ty -> Offset Word8
forall a b. (a -> b) -> a -> b
$ UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
arr
    !(CountOf szBytes :: Int
szBytes@(I# Int#
szBytes#)) = CountOf ty -> CountOf Word8
forall a. PrimType a => CountOf a -> CountOf Word8
sizeInBytes (CountOf ty -> CountOf Word8) -> CountOf ty -> CountOf Word8
forall a b. (a -> b) -> a -> b
$ UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
arr
    copyBa :: Block ty -> prim ()
copyBa (Block ByteArray#
ba) = (State# (PrimState prim) -> (# State# (PrimState prim), () #))
-> prim ()
forall a.
(State# (PrimState prim) -> (# State# (PrimState prim), a #))
-> prim a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState prim) -> (# State# (PrimState prim), () #))
 -> prim ())
-> (State# (PrimState prim) -> (# State# (PrimState prim), () #))
-> prim ()
forall a b. (a -> b) -> a -> b
$ \State# (PrimState prim)
s1 -> (# ByteArray#
-> Int#
-> Addr#
-> Int#
-> State# (PrimState prim)
-> State# (PrimState prim)
forall d.
ByteArray# -> Int# -> Addr# -> Int# -> State# d -> State# d
copyByteArrayToAddr# ByteArray#
ba Int#
os# Addr#
dst# Int#
szBytes# State# (PrimState prim)
s1, () #)
    copyPtr :: FinalPtr ty -> prim ()
copyPtr FinalPtr ty
fptr = IO () -> prim ()
forall (prim :: * -> *) a. PrimMonad prim => IO a -> prim a
unsafePrimFromIO (IO () -> prim ()) -> IO () -> prim ()
forall a b. (a -> b) -> a -> b
$ FinalPtr ty -> (Ptr ty -> IO ()) -> IO ()
forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr ((Ptr ty -> IO ()) -> IO ()) -> (Ptr ty -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr -> Ptr ty -> Ptr ty -> Int -> IO ()
forall a. Ptr a -> Ptr a -> Int -> IO ()
copyBytes Ptr ty
dst (Ptr ty
ptr Ptr ty -> Int -> Ptr ty
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os) Int
szBytes

-- | Get a Ptr pointing to the data in the UArray.
--
-- Since a UArray is immutable, this Ptr shouldn't be
-- to use to modify the contents
--
-- If the UArray is pinned, then its address is returned as is,
-- however if it's unpinned, a pinned copy of the UArray is made
-- before getting the address.
withPtr :: forall ty prim a . (PrimMonad prim, PrimType ty)
        => UArray ty
        -> (Ptr ty -> prim a)
        -> prim a
withPtr :: forall ty (prim :: * -> *) a.
(PrimMonad prim, PrimType ty) =>
UArray ty -> (Ptr ty -> prim a) -> prim a
withPtr UArray ty
a Ptr ty -> prim a
f =
    (Block ty -> prim a)
-> (FinalPtr ty -> prim a) -> UArray ty -> prim a
forall (prim :: * -> *) ty a.
PrimMonad prim =>
(Block ty -> prim a)
-> (FinalPtr ty -> prim a) -> UArray ty -> prim a
onBackendPrim (\Block ty
blk  -> Block ty -> (Ptr ty -> prim a) -> prim a
forall (prim :: * -> *) ty a.
PrimMonad prim =>
Block ty -> (Ptr ty -> prim a) -> prim a
BLK.withPtr  Block ty
blk  ((Ptr ty -> prim a) -> prim a) -> (Ptr ty -> prim a) -> prim a
forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr -> Ptr ty -> prim a
f (Ptr ty
ptr Ptr ty -> Int -> Ptr ty
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os))
                  (\FinalPtr ty
fptr -> FinalPtr ty -> (Ptr ty -> prim a) -> prim a
forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr ((Ptr ty -> prim a) -> prim a) -> (Ptr ty -> prim a) -> prim a
forall a b. (a -> b) -> a -> b
$ \Ptr ty
ptr -> Ptr ty -> prim a
f (Ptr ty
ptr Ptr ty -> Int -> Ptr ty
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
os))
                  UArray ty
a
  where
    !sz :: CountOf Word8
sz          = Proxy ty -> CountOf Word8
forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (Proxy ty
forall {k} (t :: k). Proxy t
Proxy :: Proxy ty)
    !(Offset Int
os) = CountOf Word8 -> Offset ty -> Offset Word8
forall ty. CountOf Word8 -> Offset ty -> Offset Word8
offsetOfE CountOf Word8
sz (Offset ty -> Offset Word8) -> Offset ty -> Offset Word8
forall a b. (a -> b) -> a -> b
$ UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
a
{-# INLINE withPtr #-}

-- | Recast an array of type a to an array of b
--
-- a and b need to have the same size otherwise this
-- raise an async exception
recast :: forall a b . (PrimType a, PrimType b) => UArray a -> UArray b
recast :: forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
recast UArray a
array
    | CountOf Word8
aTypeSize CountOf Word8 -> CountOf Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf Word8
bTypeSize = UArray a -> UArray b
forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
unsafeRecast UArray a
array
    | Int
missing   Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0         = UArray a -> UArray b
forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
unsafeRecast UArray a
array
    | Bool
otherwise = InvalidRecast -> UArray b
forall a e. Exception e => e -> a
throw (InvalidRecast -> UArray b) -> InvalidRecast -> UArray b
forall a b. (a -> b) -> a -> b
$ RecastSourceSize -> RecastDestinationSize -> InvalidRecast
InvalidRecast
                      (Int -> RecastSourceSize
RecastSourceSize      Int
alen)
                      (Int -> RecastDestinationSize
RecastDestinationSize (Int -> RecastDestinationSize) -> Int -> RecastDestinationSize
forall a b. (a -> b) -> a -> b
$ Int
alen Int -> Int -> Int
forall a. Additive a => a -> a -> a
+ Int
missing)
  where
    aTypeSize :: CountOf Word8
aTypeSize = Proxy a -> CountOf Word8
forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (Proxy a
forall {k} (t :: k). Proxy t
Proxy :: Proxy a)
    bTypeSize :: CountOf Word8
bTypeSize@(CountOf Int
bs) = Proxy b -> CountOf Word8
forall ty. PrimType ty => Proxy ty -> CountOf Word8
primSizeInBytes (Proxy b
forall {k} (t :: k). Proxy t
Proxy :: Proxy b)
    (CountOf Int
alen) = CountOf a -> CountOf Word8
forall a. PrimType a => CountOf a -> CountOf Word8
sizeInBytes (UArray a -> CountOf a
forall ty. UArray ty -> CountOf ty
length UArray a
array)
    missing :: Int
missing = Int
alen Int -> Int -> Int
forall a. IDivisible a => a -> a -> a
`mod` Int
bs

-- | Unsafely recast an UArray containing 'a' to an UArray containing 'b'
--
-- The offset and size are converted from units of 'a' to units of 'b',
-- but no check are performed to make sure this is compatible.
--
-- use 'recast' if unsure.
unsafeRecast :: (PrimType a, PrimType b) => UArray a -> UArray b
unsafeRecast :: forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
unsafeRecast (UArray Offset a
start CountOf a
len UArrayBackend a
backend) = Offset b -> CountOf b -> UArrayBackend b -> UArray b
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray (Offset a -> Offset b
forall a b. (PrimType a, PrimType b) => Offset a -> Offset b
primOffsetRecast Offset a
start) (CountOf a -> CountOf b
forall a b. (PrimType a, PrimType b) => CountOf a -> CountOf b
sizeRecast CountOf a
len) (UArrayBackend b -> UArray b) -> UArrayBackend b -> UArray b
forall a b. (a -> b) -> a -> b
$
    case UArrayBackend a
backend of
        UArrayAddr FinalPtr a
fptr     -> FinalPtr b -> UArrayBackend b
forall ty. FinalPtr ty -> UArrayBackend ty
UArrayAddr (FinalPtr a -> FinalPtr b
forall a b. FinalPtr a -> FinalPtr b
castFinalPtr FinalPtr a
fptr)
        UArrayBA (Block ByteArray#
ba) -> Block b -> UArrayBackend b
forall ty. Block ty -> UArrayBackend ty
UArrayBA (ByteArray# -> Block b
forall ty. ByteArray# -> Block ty
Block ByteArray#
ba)
{-# INLINE [1] unsafeRecast #-}
{-# SPECIALIZE [3] unsafeRecast :: PrimType a => UArray Word8 -> UArray a #-}

null :: UArray ty -> Bool
null :: forall ty. UArray ty -> Bool
null UArray ty
arr = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
arr CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
0

-- | Take a count of elements from the array and create an array with just those elements
take :: CountOf ty -> UArray ty -> UArray ty
take :: forall ty. CountOf ty -> UArray ty -> UArray ty
take CountOf ty
n arr :: UArray ty
arr@(UArray Offset ty
start CountOf ty
len UArrayBackend ty
backend)
    | CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
<= CountOf ty
0    = UArray ty
forall ty. UArray ty
empty
    | CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
>= CountOf ty
len  = UArray ty
arr
    | Bool
otherwise = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
start CountOf ty
n UArrayBackend ty
backend

unsafeTake :: CountOf ty -> UArray ty -> UArray ty
unsafeTake :: forall ty. CountOf ty -> UArray ty -> UArray ty
unsafeTake CountOf ty
sz (UArray Offset ty
start CountOf ty
_ UArrayBackend ty
ba) = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
start CountOf ty
sz UArrayBackend ty
ba

-- | Drop a count of elements from the array and return the new array minus those dropped elements
drop :: CountOf ty -> UArray ty -> UArray ty
drop :: forall ty. CountOf ty -> UArray ty -> UArray ty
drop CountOf ty
n arr :: UArray ty
arr@(UArray Offset ty
start CountOf ty
len UArrayBackend ty
backend)
    | CountOf ty
n CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
<= CountOf ty
0                             = UArray ty
arr
    | Just CountOf ty
newLen <- CountOf ty
len CountOf ty -> CountOf ty -> Difference (CountOf ty)
forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
n, CountOf ty
newLen CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf ty
0 = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray (Offset ty
start Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
n) CountOf ty
newLen UArrayBackend ty
backend
    | Bool
otherwise                          = UArray ty
forall ty. UArray ty
empty

unsafeDrop :: CountOf ty -> UArray ty -> UArray ty
unsafeDrop :: forall ty. CountOf ty -> UArray ty -> UArray ty
unsafeDrop CountOf ty
n (UArray Offset ty
start CountOf ty
sz UArrayBackend ty
backend) = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray (Offset ty
start Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
n) (CountOf ty
sz CountOf ty -> CountOf ty -> CountOf ty
forall a. CountOf a -> CountOf a -> CountOf a
`sizeSub` CountOf ty
n) UArrayBackend ty
backend

-- | Split an array into two, with a count of at most N elements in the first one
-- and the remaining in the other.
splitAt :: CountOf ty -> UArray ty -> (UArray ty, UArray ty)
splitAt :: forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
splitAt CountOf ty
nbElems arr :: UArray ty
arr@(UArray Offset ty
start CountOf ty
len UArrayBackend ty
backend)
    | CountOf ty
nbElems CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
<= CountOf ty
0                               = (UArray ty
forall ty. UArray ty
empty, UArray ty
arr)
    | Just CountOf ty
nbTails <- CountOf ty
len CountOf ty -> CountOf ty -> Difference (CountOf ty)
forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
nbElems, CountOf ty
nbTails CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf ty
0 = (Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
start                         CountOf ty
nbElems UArrayBackend ty
backend
                                                   ,Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray (Offset ty
start Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
nbElems) CountOf ty
nbTails UArrayBackend ty
backend)
    | Bool
otherwise                                  = (UArray ty
arr, UArray ty
forall ty. UArray ty
empty)


breakElem :: PrimType ty => ty -> UArray ty -> (UArray ty, UArray ty)
breakElem :: forall ty. PrimType ty => ty -> UArray ty -> (UArray ty, UArray ty)
breakElem !ty
ty arr :: UArray ty
arr@(UArray Offset ty
start CountOf ty
len UArrayBackend ty
backend)
    | Offset ty
k Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
forall {ty}. Offset ty
sentinel = (UArray ty
arr, UArray ty
forall ty. UArray ty
empty)
    | Offset ty
k Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
start    = (UArray ty
forall ty. UArray ty
empty, UArray ty
arr)
    | Bool
otherwise     = (Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
start (Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize Offset ty
l1)       UArrayBackend ty
backend
                     , Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset ty
k     (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
len Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- Offset ty
l1) UArrayBackend ty
backend)
  where
    !k :: Offset ty
k = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((forall container.
  Indexable container ty =>
  container -> Offset ty -> Offset ty -> Offset ty)
 -> Offset ty)
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall a b. (a -> b) -> a -> b
$ ty -> container -> Offset ty -> Offset ty -> Offset ty
forall container ty.
(Indexable container ty, Eq ty) =>
ty -> container -> Offset ty -> Offset ty -> Offset ty
Alg.findIndexElem ty
ty
    l1 :: Offset ty
l1 = Offset ty
k Offset ty -> Offset ty -> Offset ty
forall a. Offset a -> Offset a -> Offset a
`offsetSub` Offset ty
start
{-# NOINLINE [3] breakElem #-}
{-# RULES "breakElem Word8" [4] breakElem = breakElemByte #-}
{-# SPECIALIZE [3] breakElem :: Word32 -> UArray Word32 -> (UArray Word32, UArray Word32) #-}

breakElemByte :: Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
breakElemByte :: Word8 -> UArray Word8 -> (UArray Word8, UArray Word8)
breakElemByte !Word8
ty arr :: UArray Word8
arr@(UArray Offset Word8
start CountOf Word8
len UArrayBackend Word8
backend)
    | Offset Word8
k Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Offset Word8
end   = (UArray Word8
arr, UArray Word8
forall ty. UArray ty
empty)
    | Offset Word8
k Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Offset Word8
start = (UArray Word8
forall ty. UArray ty
empty, UArray Word8
arr)
    | Bool
otherwise  = ( Offset Word8
-> CountOf Word8 -> UArrayBackend Word8 -> UArray Word8
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset Word8
start (Offset Word8 -> CountOf Word8
forall a. Offset a -> CountOf a
offsetAsSize Offset Word8
k CountOf Word8 -> CountOf Word8 -> CountOf Word8
forall a. CountOf a -> CountOf a -> CountOf a
`sizeSub` Offset Word8 -> CountOf Word8
forall a. Offset a -> CountOf a
offsetAsSize Offset Word8
start) UArrayBackend Word8
backend
                   , Offset Word8
-> CountOf Word8 -> UArrayBackend Word8 -> UArray Word8
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset Word8
k     (CountOf Word8
len CountOf Word8 -> CountOf Word8 -> CountOf Word8
forall a. CountOf a -> CountOf a -> CountOf a
`sizeSub` (Offset Word8 -> CountOf Word8
forall a. Offset a -> CountOf a
offsetAsSize Offset Word8
k CountOf Word8 -> CountOf Word8 -> CountOf Word8
forall a. CountOf a -> CountOf a -> CountOf a
`sizeSub` Offset Word8 -> CountOf Word8
forall a. Offset a -> CountOf a
offsetAsSize Offset Word8
start)) UArrayBackend Word8
backend)
  where
    !end :: Offset Word8
end = Offset Word8
start Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf Word8
len
    !k :: Offset Word8
k = (Block Word8 -> Offset Word8)
-> (Ptr Word8 -> Offset Word8) -> UArray Word8 -> Offset Word8
forall ty a. (Block ty -> a) -> (Ptr ty -> a) -> UArray ty -> a
onBackendPure Block Word8 -> Offset Word8
goBa Ptr Word8 -> Offset Word8
goAddr UArray Word8
arr
    goBa :: Block Word8 -> Offset Word8
goBa (Block ByteArray#
ba) = ByteArray# -> Offset Word8 -> Offset Word8 -> Word8 -> Offset Word8
sysHsMemFindByteBa ByteArray#
ba Offset Word8
start Offset Word8
end Word8
ty
    goAddr :: Ptr Word8 -> Offset Word8
goAddr (Ptr Addr#
addr) = Addr# -> Offset Word8 -> Offset Word8 -> Word8 -> Offset Word8
sysHsMemFindByteAddr Addr#
addr Offset Word8
start Offset Word8
end Word8
ty

-- | Similar to breakElem specialized to split on linefeed
--
-- it either returns:
-- * Left. no line has been found, and whether the last character is a CR
-- * Right, a line has been found with an optional CR, and it returns
--   the array of bytes on the left of the CR/LF, and the
--   the array of bytes on the right of the LF.
--
breakLine :: UArray Word8 -> Either Bool (UArray Word8, UArray Word8)
breakLine :: UArray Word8 -> Either Bool (UArray Word8, UArray Word8)
breakLine arr :: UArray Word8
arr@(UArray Offset Word8
start CountOf Word8
len UArrayBackend Word8
backend)
    | Offset Word8
end Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Offset Word8
start = Bool -> Either Bool (UArray Word8, UArray Word8)
forall a b. a -> Either a b
Left Bool
False
    | Offset Word8
k2 Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Offset Word8
end    = Bool -> Either Bool (UArray Word8, UArray Word8)
forall a b. a -> Either a b
Left (Offset Word8
k1 Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
/= Offset Word8
k2)
    | Bool
otherwise    = let newArray :: Offset Word8 -> CountOf Word8 -> UArray Word8
newArray Offset Word8
start' CountOf Word8
len' = if CountOf Word8
len' CountOf Word8 -> CountOf Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf Word8
0 then UArray Word8
forall ty. UArray ty
empty else Offset Word8
-> CountOf Word8 -> UArrayBackend Word8 -> UArray Word8
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray Offset Word8
start' CountOf Word8
len' UArrayBackend Word8
backend
                      in (UArray Word8, UArray Word8)
-> Either Bool (UArray Word8, UArray Word8)
forall a b. b -> Either a b
Right (Offset Word8 -> CountOf Word8 -> UArray Word8
newArray Offset Word8
start (Offset Word8
k1Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
forall a. Subtractive a => a -> a -> Difference a
-Offset Word8
start), Offset Word8 -> CountOf Word8 -> UArray Word8
newArray (Offset Word8
k2Offset Word8 -> Offset Word8 -> Offset Word8
forall a. Additive a => a -> a -> a
+Offset Word8
1) (Offset Word8
end Offset Word8 -> Offset Word8 -> Difference (Offset Word8)
forall a. Subtractive a => a -> a -> Difference a
- (Offset Word8
k2Offset Word8 -> Offset Word8 -> Offset Word8
forall a. Additive a => a -> a -> a
+Offset Word8
1)))
  where
    !end :: Offset Word8
end = Offset Word8
start Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf Word8
len
    -- return (offset of CR, offset of LF, whether the last element was a carriage return
    !(Offset Word8
k1, Offset Word8
k2) = (Block Word8 -> (Offset Word8, Offset Word8))
-> (Ptr Word8 -> (Offset Word8, Offset Word8))
-> UArray Word8
-> (Offset Word8, Offset Word8)
forall ty a. (Block ty -> a) -> (Ptr ty -> a) -> UArray ty -> a
onBackendPure Block Word8 -> (Offset Word8, Offset Word8)
goBa Ptr Word8 -> (Offset Word8, Offset Word8)
goAddr UArray Word8
arr
    lineFeed :: Word8
lineFeed = Word8
0xa
    carriageReturn :: Word8
carriageReturn = Word8
0xd
    goBa :: Block Word8 -> (Offset Word8, Offset Word8)
goBa (Block ByteArray#
ba) =
        let k :: Offset Word8
k = ByteArray# -> Offset Word8 -> Offset Word8 -> Word8 -> Offset Word8
sysHsMemFindByteBa ByteArray#
ba Offset Word8
start Offset Word8
end Word8
lineFeed
            cr :: Bool
cr = Offset Word8
k Offset Word8 -> Offset Word8 -> Bool
forall a. Ord a => a -> a -> Bool
> Offset Word8
start Bool -> Bool -> Bool
&& ByteArray# -> Offset Word8 -> Word8
forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
primBaIndex ByteArray#
ba (Offset Word8
k Offset Word8 -> Offset Word8 -> Offset Word8
forall a. Offset a -> Offset a -> Offset a
`offsetSub` Offset Word8
1) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
carriageReturn
         in (if Bool
cr then Offset Word8
k Offset Word8 -> Offset Word8 -> Offset Word8
forall a. Offset a -> Offset a -> Offset a
`offsetSub` Offset Word8
1 else Offset Word8
k, Offset Word8
k)
    goAddr :: Ptr Word8 -> (Offset Word8, Offset Word8)
goAddr (Ptr Addr#
addr) =
        let k :: Offset Word8
k = Addr# -> Offset Word8 -> Offset Word8 -> Word8 -> Offset Word8
sysHsMemFindByteAddr Addr#
addr Offset Word8
start Offset Word8
end Word8
lineFeed
            cr :: Bool
cr = Offset Word8
k Offset Word8 -> Offset Word8 -> Bool
forall a. Ord a => a -> a -> Bool
> Offset Word8
start Bool -> Bool -> Bool
&& Addr# -> Offset Word8 -> Word8
forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr (Offset Word8
k Offset Word8 -> Offset Word8 -> Offset Word8
forall a. Offset a -> Offset a -> Offset a
`offsetSub` Offset Word8
1) Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
carriageReturn
         in (if Bool
cr then Offset Word8
k Offset Word8 -> Offset Word8 -> Offset Word8
forall a. Offset a -> Offset a -> Offset a
`offsetSub` Offset Word8
1 else Offset Word8
k, Offset Word8
k)

-- inverse a CountOf that is specified from the end (e.g. take n elements from the end)
countFromStart :: UArray ty -> CountOf ty -> CountOf ty
countFromStart :: forall ty. UArray ty -> CountOf ty -> CountOf ty
countFromStart UArray ty
v sz :: CountOf ty
sz@(CountOf Int
sz')
    | CountOf ty
sz CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
>= CountOf ty
len = Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
0
    | Bool
otherwise = Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf (Int
len' Int -> Int -> Difference Int
forall a. Subtractive a => a -> a -> Difference a
- Int
sz')
  where len :: CountOf ty
len@(CountOf Int
len') = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
v

-- | Take the N elements from the end of the array
revTake :: CountOf ty -> UArray ty -> UArray ty
revTake :: forall ty. CountOf ty -> UArray ty -> UArray ty
revTake CountOf ty
n UArray ty
v = CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
drop (UArray ty -> CountOf ty -> CountOf ty
forall ty. UArray ty -> CountOf ty -> CountOf ty
countFromStart UArray ty
v CountOf ty
n) UArray ty
v

-- | Drop the N elements from the end of the array
revDrop :: CountOf ty -> UArray ty -> UArray ty
revDrop :: forall ty. CountOf ty -> UArray ty -> UArray ty
revDrop CountOf ty
n UArray ty
v = CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
take (UArray ty -> CountOf ty -> CountOf ty
forall ty. UArray ty -> CountOf ty -> CountOf ty
countFromStart UArray ty
v CountOf ty
n) UArray ty
v

-- | Split an array at the N element from the end, and return
-- the last N elements in the first part of the tuple, and whatever first
-- elements remaining in the second
revSplitAt :: CountOf ty -> UArray ty -> (UArray ty, UArray ty)
revSplitAt :: forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
revSplitAt CountOf ty
n UArray ty
v = (CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
drop CountOf ty
sz UArray ty
v, CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
take CountOf ty
sz UArray ty
v) where sz :: CountOf ty
sz = UArray ty -> CountOf ty -> CountOf ty
forall ty. UArray ty -> CountOf ty -> CountOf ty
countFromStart UArray ty
v CountOf ty
n

splitOn :: PrimType ty => (ty -> Bool) -> UArray ty -> [UArray ty]
splitOn :: forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> [UArray ty]
splitOn ty -> Bool
xpredicate UArray ty
ivec
    | CountOf ty
len CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
0  = [UArray ty
forall a. Monoid a => a
mempty]
    | Bool
otherwise = (forall s. ST s [UArray ty]) -> [UArray ty]
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s [UArray ty]) -> [UArray ty])
-> (forall s. ST s [UArray ty]) -> [UArray ty]
forall a b. (a -> b) -> a -> b
$ UArray ty
-> ((Offset ty -> ty) -> ST s [UArray ty]) -> ST s [UArray ty]
forall (prim :: * -> *) ty a.
(PrimMonad prim, PrimType ty) =>
UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
unsafeIndexer UArray ty
ivec ([UArray ty] -> ST s [UArray ty]
forall a s. a -> ST s a
pureST ([UArray ty] -> ST s [UArray ty])
-> ((Offset ty -> ty) -> [UArray ty])
-> (Offset ty -> ty)
-> ST s [UArray ty]
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. UArray ty -> (ty -> Bool) -> (Offset ty -> ty) -> [UArray ty]
go UArray ty
ivec ty -> Bool
xpredicate)
  where
    !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
ivec
    go :: UArray ty -> (ty -> Bool) -> (Offset ty -> ty) -> [UArray ty]
go UArray ty
v ty -> Bool
predicate Offset ty -> ty
getIdx = Offset ty -> Offset ty -> [UArray ty]
loop Offset ty
0 Offset ty
0
      where
        loop :: Offset ty -> Offset ty -> [UArray ty]
loop !Offset ty
prevIdx !Offset ty
idx
            | Offset ty
idx Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = [UArray ty -> Offset ty -> Offset ty -> UArray ty
forall ty.
PrimType ty =>
UArray ty -> Offset ty -> Offset ty -> UArray ty
sub UArray ty
v Offset ty
prevIdx Offset ty
idx]
            | Bool
otherwise    =
                let e :: ty
e = Offset ty -> ty
getIdx Offset ty
idx
                    idx' :: Offset ty
idx' = Offset ty
idx Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
1
                 in if ty -> Bool
predicate ty
e
                        then UArray ty -> Offset ty -> Offset ty -> UArray ty
forall ty.
PrimType ty =>
UArray ty -> Offset ty -> Offset ty -> UArray ty
sub UArray ty
v Offset ty
prevIdx Offset ty
idx UArray ty -> [UArray ty] -> [UArray ty]
forall a. a -> [a] -> [a]
: Offset ty -> Offset ty -> [UArray ty]
loop Offset ty
idx' Offset ty
idx'
                        else Offset ty -> Offset ty -> [UArray ty]
loop Offset ty
prevIdx Offset ty
idx'
    {-# INLINE go #-}

sub :: PrimType ty => UArray ty -> Offset ty -> Offset ty -> UArray ty
sub :: forall ty.
PrimType ty =>
UArray ty -> Offset ty -> Offset ty -> UArray ty
sub (UArray Offset ty
start CountOf ty
len UArrayBackend ty
backend) Offset ty
startIdx Offset ty
expectedEndIdx
    | Offset ty
startIdx Offset ty -> Offset ty -> Bool
forall a. Ord a => a -> a -> Bool
>= Offset ty
endIdx = UArray ty
forall a. Monoid a => a
mempty
    | Bool
otherwise          = Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
forall ty. Offset ty -> CountOf ty -> UArrayBackend ty -> UArray ty
UArray (Offset ty
start Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
startIdx) Difference (Offset ty)
CountOf ty
newLen UArrayBackend ty
backend
  where
    newLen :: Difference (Offset ty)
newLen = Offset ty
endIdx Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- Offset ty
startIdx
    endIdx :: Offset ty
endIdx = Offset ty -> Offset ty -> Offset ty
forall a. Ord a => a -> a -> a
min Offset ty
expectedEndIdx (Offset ty
0 Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
len)

findIndex :: PrimType ty => ty -> UArray ty -> Maybe (Offset ty)
findIndex :: forall ty. PrimType ty => ty -> UArray ty -> Maybe (Offset ty)
findIndex ty
ty UArray ty
arr
    | Offset ty
k Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
forall {ty}. Offset ty
sentinel  = Maybe (Offset ty)
forall a. Maybe a
Nothing
    | Bool
otherwise      = Offset ty -> Maybe (Offset ty)
forall a. a -> Maybe a
Just (Offset ty
k Offset ty -> Offset ty -> Offset ty
forall a. Offset a -> Offset a -> Offset a
`offsetSub` UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
arr)
  where
    !k :: Offset ty
k = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((forall container.
  Indexable container ty =>
  container -> Offset ty -> Offset ty -> Offset ty)
 -> Offset ty)
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall a b. (a -> b) -> a -> b
$ ty -> container -> Offset ty -> Offset ty -> Offset ty
forall container ty.
(Indexable container ty, Eq ty) =>
ty -> container -> Offset ty -> Offset ty -> Offset ty
Alg.findIndexElem ty
ty
{-# SPECIALIZE [3] findIndex :: Word8 -> UArray Word8 -> Maybe (Offset Word8) #-}

revFindIndex :: PrimType ty => ty -> UArray ty -> Maybe (Offset ty)
revFindIndex :: forall ty. PrimType ty => ty -> UArray ty -> Maybe (Offset ty)
revFindIndex ty
ty UArray ty
arr
    | Offset ty
k Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
forall {ty}. Offset ty
sentinel = Maybe (Offset ty)
forall a. Maybe a
Nothing
    | Bool
otherwise     = Offset ty -> Maybe (Offset ty)
forall a. a -> Maybe a
Just (Offset ty
k Offset ty -> Offset ty -> Offset ty
forall a. Offset a -> Offset a -> Offset a
`offsetSub` UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
arr)
  where
    !k :: Offset ty
k = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((forall container.
  Indexable container ty =>
  container -> Offset ty -> Offset ty -> Offset ty)
 -> Offset ty)
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall a b. (a -> b) -> a -> b
$ ty -> container -> Offset ty -> Offset ty -> Offset ty
forall container ty.
(Indexable container ty, Eq ty) =>
ty -> container -> Offset ty -> Offset ty -> Offset ty
Alg.revFindIndexElem ty
ty
{-# SPECIALIZE [3] revFindIndex :: Word8 -> UArray Word8 -> Maybe (Offset Word8) #-}

break :: forall ty . PrimType ty => (ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
break :: forall ty.
PrimType ty =>
(ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
break ty -> Bool
predicate UArray ty
arr
    | Offset ty
k Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
forall {ty}. Offset ty
sentinel = (UArray ty
arr, UArray ty
forall a. Monoid a => a
mempty)
    | Bool
otherwise     = CountOf ty -> UArray ty -> (UArray ty, UArray ty)
forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
splitAt (Offset ty
k Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
arr) UArray ty
arr
  where
    !k :: Offset ty
k = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((forall container.
  Indexable container ty =>
  container -> Offset ty -> Offset ty -> Offset ty)
 -> Offset ty)
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall a b. (a -> b) -> a -> b
$ (ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty
forall container ty.
Indexable container ty =>
(ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty
Alg.findIndexPredicate ty -> Bool
predicate

{-
{-# SPECIALIZE [3] findIndex :: Word8 -> UArray Word8 -> Maybe (Offset Word8) #-}
    | len == 0  = (mempty, mempty)
    | otherwise = runST $ unsafeIndexer xv (go xv xpredicate)
  where
    !len = length xv
    go :: PrimType ty => UArray ty -> (ty -> Bool) -> (Offset ty -> ty) -> ST s (UArray ty, UArray ty)
    go v predicate getIdx = pure (findBreak $ Offset 0)
      where
        findBreak !i
            | i .==# len           = (v, mempty)
            | predicate (getIdx i) = splitAt (offsetAsSize i) v
            | otherwise            = findBreak (i + Offset 1)
        {-# INLINE findBreak #-}
    {-# INLINE go #-}
    -}
{-# NOINLINE [2] break #-}
{-# SPECIALIZE [2] break :: (Word8 -> Bool) -> UArray Word8 -> (UArray Word8, UArray Word8) #-}

{-
{-# RULES "break (== ty)" [3] forall (x :: forall ty . PrimType ty => ty) . break (== x) = breakElem x #-}
{-# RULES "break (ty ==)" [3] forall (x :: forall ty . PrimType ty => ty) . break (x ==) = breakElem x #-}
{-# RULES "break (== ty)" [3] forall (x :: Word8) . break (== x) = breakElem x #-}
-}

-- | Similar to break but start the search of the breakpoint from the end
--
-- > breakEnd (> 0) [1,2,3,0,0,0]
-- ([1,2,3], [0,0,0])
breakEnd :: forall ty . PrimType ty => (ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
breakEnd :: forall ty.
PrimType ty =>
(ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
breakEnd ty -> Bool
predicate UArray ty
arr
    | Offset ty
k Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
forall {ty}. Offset ty
sentinel = (UArray ty
arr, UArray ty
forall a. Monoid a => a
mempty)
    | Bool
otherwise     = CountOf ty -> UArray ty -> (UArray ty, UArray ty)
forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
splitAt ((Offset ty
kOffset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+Offset ty
1) Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
arr) UArray ty
arr
  where
    !k :: Offset ty
k = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((forall container.
  Indexable container ty =>
  container -> Offset ty -> Offset ty -> Offset ty)
 -> Offset ty)
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall a b. (a -> b) -> a -> b
$ (ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty
forall container ty.
Indexable container ty =>
(ty -> Bool) -> container -> Offset ty -> Offset ty -> Offset ty
Alg.revFindIndexPredicate ty -> Bool
predicate
{-# SPECIALIZE [3] breakEnd :: (Word8 -> Bool) -> UArray Word8 -> (UArray Word8, UArray Word8) #-}

elem :: PrimType ty => ty -> UArray ty -> Bool
elem :: forall ty. PrimType ty => ty -> UArray ty -> Bool
elem !ty
ty UArray ty
arr = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Offset ty)
-> Offset ty
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr (ty -> container -> Offset ty -> Offset ty -> Offset ty
forall container ty.
(Indexable container ty, Eq ty) =>
ty -> container -> Offset ty -> Offset ty -> Offset ty
Alg.findIndexElem ty
ty) Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
/= Offset ty
forall {ty}. Offset ty
sentinel
{-# SPECIALIZE [2] elem :: Word8 -> UArray Word8 -> Bool #-}

intersperse :: forall ty . PrimType ty => ty -> UArray ty -> UArray ty
intersperse :: forall ty. PrimType ty => ty -> UArray ty -> UArray ty
intersperse ty
sep UArray ty
v = case CountOf ty
len CountOf ty -> CountOf ty -> Difference (CountOf ty)
forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
1 of
    Maybe (CountOf ty)
Difference (CountOf ty)
Nothing -> UArray ty
v
    Just CountOf ty
0 -> UArray ty
v
    Just CountOf ty
gaps -> (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ UArray ty
-> CountOf ty
-> (UArray ty -> Offset ty -> MUArray ty s -> ST s ())
-> ST s (UArray ty)
forall a b s.
(PrimType a, PrimType b) =>
UArray a
-> CountOf b
-> (UArray a -> Offset a -> MUArray b s -> ST s ())
-> ST s (UArray b)
unsafeCopyFrom UArray ty
v (CountOf ty
len CountOf ty -> CountOf ty -> CountOf ty
forall a. Additive a => a -> a -> a
+ CountOf ty
gaps) UArray ty -> Offset ty -> MUArray ty s -> ST s ()
forall s.
PrimType ty =>
UArray ty -> Offset ty -> MUArray ty s -> ST s ()
go
  where
    len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
v

    go :: PrimType ty => UArray ty -> Offset ty -> MUArray ty s -> ST s ()
    go :: forall s.
PrimType ty =>
UArray ty -> Offset ty -> MUArray ty s -> ST s ()
go UArray ty
oldV Offset ty
oldI MUArray ty s
newV
        | (Offset ty
oldI Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
1) Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = MUArray ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty s
MUArray ty (PrimState (ST s))
newV Offset ty
newI ty
e
        | Bool
otherwise           = do
            MUArray ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty s
MUArray ty (PrimState (ST s))
newV Offset ty
newI ty
e
            MUArray ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty s
MUArray ty (PrimState (ST s))
newV (Offset ty
newI Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
1) ty
sep
      where
        e :: ty
e = UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
oldV Offset ty
oldI
        newI :: Offset ty
newI = Word -> Offset ty -> Offset ty
forall n. IsNatural n => n -> Offset ty -> Offset ty
forall a n. (Additive a, IsNatural n) => n -> a -> a
scale (Word
2 :: Word) Offset ty
oldI

span :: PrimType ty => (ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
span :: forall ty.
PrimType ty =>
(ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
span ty -> Bool
p = (ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
forall ty.
PrimType ty =>
(ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
break (Bool -> Bool
not (Bool -> Bool) -> (ty -> Bool) -> ty -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ty -> Bool
p)

spanEnd :: PrimType ty => (ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
spanEnd :: forall ty.
PrimType ty =>
(ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
spanEnd ty -> Bool
p = (ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
forall ty.
PrimType ty =>
(ty -> Bool) -> UArray ty -> (UArray ty, UArray ty)
breakEnd (Bool -> Bool
not (Bool -> Bool) -> (ty -> Bool) -> ty -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ty -> Bool
p)

map :: (PrimType a, PrimType b) => (a -> b) -> UArray a -> UArray b
map :: forall a b.
(PrimType a, PrimType b) =>
(a -> b) -> UArray a -> UArray b
map a -> b
f UArray a
a = CountOf b -> (Offset b -> b) -> UArray b
forall ty.
PrimType ty =>
CountOf ty -> (Offset ty -> ty) -> UArray ty
create CountOf b
lenB (\Offset b
i -> a -> b
f (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ UArray a -> Offset a -> a
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray a
a (Proxy (b -> a) -> Offset b -> Offset a
forall a b. Proxy (a -> b) -> Offset a -> Offset b
offsetCast Proxy (b -> a)
forall {k} (t :: k). Proxy t
Proxy Offset b
i))
  where !lenB :: CountOf b
lenB = Proxy (a -> b) -> CountOf a -> CountOf b
forall a b. Proxy (a -> b) -> CountOf a -> CountOf b
sizeCast (Proxy (a -> b)
forall {k} (t :: k). Proxy t
forall {a} {b}. Proxy (a -> b)
Proxy :: Proxy (a -> b)) (UArray a -> CountOf a
forall ty. UArray ty -> CountOf ty
length UArray a
a)

mapIndex :: (PrimType a, PrimType b) => (Offset b -> a -> b) -> UArray a -> UArray b
mapIndex :: forall a b.
(PrimType a, PrimType b) =>
(Offset b -> a -> b) -> UArray a -> UArray b
mapIndex Offset b -> a -> b
f UArray a
a = CountOf b -> (Offset b -> b) -> UArray b
forall ty.
PrimType ty =>
CountOf ty -> (Offset ty -> ty) -> UArray ty
create (Proxy (a -> b) -> CountOf a -> CountOf b
forall a b. Proxy (a -> b) -> CountOf a -> CountOf b
sizeCast Proxy (a -> b)
forall {k} (t :: k). Proxy t
Proxy (CountOf a -> CountOf b) -> CountOf a -> CountOf b
forall a b. (a -> b) -> a -> b
$ UArray a -> CountOf a
forall ty. UArray ty -> CountOf ty
length UArray a
a) (\Offset b
i -> Offset b -> a -> b
f Offset b
i (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ UArray a -> Offset a -> a
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray a
a (Proxy (b -> a) -> Offset b -> Offset a
forall a b. Proxy (a -> b) -> Offset a -> Offset b
offsetCast Proxy (b -> a)
forall {k} (t :: k). Proxy t
Proxy Offset b
i))

cons :: PrimType ty => ty -> UArray ty -> UArray ty
cons :: forall ty. PrimType ty => ty -> UArray ty -> UArray ty
cons ty
e UArray ty
vec
    | CountOf ty
len CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
0 = ty -> UArray ty
forall ty. PrimType ty => ty -> UArray ty
singleton ty
e
    | Bool
otherwise     = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ do
        MUArray ty s
muv <- CountOf ty -> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new (CountOf ty
len CountOf ty -> CountOf ty -> CountOf ty
forall a. Additive a => a -> a -> a
+ CountOf ty
1)
        MUArray ty (PrimState (ST s))
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
unsafeCopyAtRO MUArray ty s
MUArray ty (PrimState (ST s))
muv Offset ty
1 UArray ty
vec Offset ty
0 CountOf ty
len
        MUArray ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty s
MUArray ty (PrimState (ST s))
muv Offset ty
0 ty
e
        MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty s
MUArray ty (PrimState (ST s))
muv
  where
    !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec

snoc :: PrimType ty => UArray ty -> ty -> UArray ty
snoc :: forall ty. PrimType ty => UArray ty -> ty -> UArray ty
snoc UArray ty
vec ty
e
    | CountOf ty
len CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
0 = ty -> UArray ty
forall ty. PrimType ty => ty -> UArray ty
singleton ty
e
    | Bool
otherwise     = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ do
        MUArray ty s
muv <- CountOf ty -> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new (CountOf ty
len CountOf ty -> CountOf ty -> CountOf ty
forall a. Additive a => a -> a -> a
+ Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
1)
        MUArray ty (PrimState (ST s))
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
unsafeCopyAtRO MUArray ty s
MUArray ty (PrimState (ST s))
muv (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) UArray ty
vec (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) CountOf ty
len
        MUArray ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty s
MUArray ty (PrimState (ST s))
muv (Offset ty
0 Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec) ty
e
        MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty s
MUArray ty (PrimState (ST s))
muv
  where
     !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec

uncons :: PrimType ty => UArray ty -> Maybe (ty, UArray ty)
uncons :: forall ty. PrimType ty => UArray ty -> Maybe (ty, UArray ty)
uncons UArray ty
vec
    | CountOf ty
nbElems CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
0 = Maybe (ty, UArray ty)
forall a. Maybe a
Nothing
    | Bool
otherwise    = (ty, UArray ty) -> Maybe (ty, UArray ty)
forall a. a -> Maybe a
Just (UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
vec Offset ty
0, UArray ty -> Offset ty -> Offset ty -> UArray ty
forall ty.
PrimType ty =>
UArray ty -> Offset ty -> Offset ty -> UArray ty
sub UArray ty
vec Offset ty
1 (Offset ty
0 Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
nbElems))
  where
    !nbElems :: CountOf ty
nbElems = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec

unsnoc :: PrimType ty => UArray ty -> Maybe (UArray ty, ty)
unsnoc :: forall ty. PrimType ty => UArray ty -> Maybe (UArray ty, ty)
unsnoc UArray ty
vec = case UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec CountOf ty -> CountOf ty -> Difference (CountOf ty)
forall a. Subtractive a => a -> a -> Difference a
- CountOf ty
1 of
    Maybe (CountOf ty)
Difference (CountOf ty)
Nothing -> Maybe (UArray ty, ty)
forall a. Maybe a
Nothing
    Just CountOf ty
newLen -> (UArray ty, ty) -> Maybe (UArray ty, ty)
forall a. a -> Maybe a
Just (UArray ty -> Offset ty -> Offset ty -> UArray ty
forall ty.
PrimType ty =>
UArray ty -> Offset ty -> Offset ty -> UArray ty
sub UArray ty
vec Offset ty
0 Offset ty
lastElem, UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
vec Offset ty
lastElem)
                     where !lastElem :: Offset ty
lastElem = Offset ty
0 Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
newLen

find :: PrimType ty => (ty -> Bool) -> UArray ty -> Maybe ty
find :: forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Maybe ty
find ty -> Bool
predicate UArray ty
vec = Offset ty -> Maybe ty
loop Offset ty
0
  where
    !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec
    loop :: Offset ty -> Maybe ty
loop Offset ty
i
        | Offset ty
i Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = Maybe ty
forall a. Maybe a
Nothing
        | Bool
otherwise  =
            let e :: ty
e = UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
vec Offset ty
i
             in if ty -> Bool
predicate ty
e then ty -> Maybe ty
forall a. a -> Maybe a
Just ty
e else Offset ty -> Maybe ty
loop (Offset ty
iOffset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+Offset ty
1)

sortBy :: forall ty . PrimType ty => (ty -> ty -> Ordering) -> UArray ty -> UArray ty
sortBy :: forall ty.
PrimType ty =>
(ty -> ty -> Ordering) -> UArray ty -> UArray ty
sortBy ty -> ty -> Ordering
ford UArray ty
vec = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ do
    MUArray ty s
mvec <- UArray ty -> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
UArray ty -> prim (MUArray ty (PrimState prim))
thaw UArray ty
vec
    (MutableBlock ty (PrimState (ST s)) -> ST s ())
-> (FinalPtr ty -> ST s ())
-> MUArray ty (PrimState (ST s))
-> ST s ()
forall (prim :: * -> *) ty a.
PrimMonad prim =>
(MutableBlock ty (PrimState prim) -> prim a)
-> (FinalPtr ty -> prim a) -> MUArray ty (PrimState prim) -> prim a
onMutableBackend MutableBlock ty s -> ST s ()
MutableBlock ty (PrimState (ST s)) -> ST s ()
forall s. MutableBlock ty s -> ST s ()
goNative (\FinalPtr ty
fptr -> FinalPtr ty -> (Ptr ty -> ST s ()) -> ST s ()
forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr Ptr ty -> ST s ()
forall s. Ptr ty -> ST s ()
goAddr) MUArray ty s
MUArray ty (PrimState (ST s))
mvec
    MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty s
MUArray ty (PrimState (ST s))
mvec
  where
    !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec
    !start :: Offset ty
start = UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
vec

    goNative :: MutableBlock ty s -> ST s ()
    goNative :: forall s. MutableBlock ty s -> ST s ()
goNative MutableBlock ty s
mb = (ty -> ty -> Ordering)
-> Offset ty -> CountOf ty -> MutableBlock ty s -> ST s ()
forall (prim :: * -> *) container ty.
(PrimMonad prim, RandomAccess container prim ty) =>
(ty -> ty -> Ordering)
-> Offset ty -> CountOf ty -> container -> prim ()
Alg.inplaceSortBy ty -> ty -> Ordering
ford Offset ty
start CountOf ty
len MutableBlock ty s
mb
    goAddr :: Ptr ty -> ST s ()
    goAddr :: forall s. Ptr ty -> ST s ()
goAddr (Ptr Addr#
addr) = (ty -> ty -> Ordering)
-> Offset ty -> CountOf ty -> Ptr ty -> ST s ()
forall (prim :: * -> *) container ty.
(PrimMonad prim, RandomAccess container prim ty) =>
(ty -> ty -> Ordering)
-> Offset ty -> CountOf ty -> container -> prim ()
Alg.inplaceSortBy ty -> ty -> Ordering
ford Offset ty
start CountOf ty
len (Addr# -> Ptr ty
forall a. Addr# -> Ptr a
Ptr Addr#
addr :: Ptr ty)
{-# SPECIALIZE [3] sortBy :: (Word8 -> Word8 -> Ordering) -> UArray Word8 -> UArray Word8 #-}

filter :: forall ty . PrimType ty => (ty -> Bool) -> UArray ty -> UArray ty
filter :: forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> UArray ty
filter ty -> Bool
predicate UArray ty
arr = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ do
    (CountOf ty
newLen, MUArray ty s
ma) <- CountOf ty
-> (MutableBlock ty (PrimState (ST s)) -> ST s (CountOf ty))
-> ST s (CountOf ty, MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty a.
(PrimMonad prim, PrimType ty) =>
CountOf ty
-> (MutableBlock ty (PrimState prim) -> prim a)
-> prim (a, MUArray ty (PrimState prim))
newNative (UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
arr) ((MutableBlock ty (PrimState (ST s)) -> ST s (CountOf ty))
 -> ST s (CountOf ty, MUArray ty (PrimState (ST s))))
-> (MutableBlock ty (PrimState (ST s)) -> ST s (CountOf ty))
-> ST s (CountOf ty, MUArray ty (PrimState (ST s)))
forall a b. (a -> b) -> a -> b
$ \(MutableBlock MutableByteArray# (PrimState (ST s))
mba) ->
            (Block ty -> ST s (CountOf ty))
-> (FinalPtr ty -> ST s (CountOf ty))
-> UArray ty
-> ST s (CountOf ty)
forall (prim :: * -> *) ty a.
PrimMonad prim =>
(Block ty -> prim a)
-> (FinalPtr ty -> prim a) -> UArray ty -> prim a
onBackendPrim (\Block ty
block -> (ty -> Bool)
-> MutableByteArray# (PrimState (ST s))
-> Block ty
-> Offset ty
-> Offset ty
-> ST s (CountOf ty)
forall (prim :: * -> *) ty container.
(PrimMonad prim, PrimType ty, Indexable container ty) =>
(ty -> Bool)
-> MutableByteArray# (PrimState prim)
-> container
-> Offset ty
-> Offset ty
-> prim (CountOf ty)
Alg.filter ty -> Bool
predicate MutableByteArray# (PrimState (ST s))
mba Block ty
block Offset ty
start Offset ty
end)
                          (\FinalPtr ty
fptr -> FinalPtr ty -> (Ptr ty -> ST s (CountOf ty)) -> ST s (CountOf ty)
forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr ((Ptr ty -> ST s (CountOf ty)) -> ST s (CountOf ty))
-> (Ptr ty -> ST s (CountOf ty)) -> ST s (CountOf ty)
forall a b. (a -> b) -> a -> b
$ \ptr :: Ptr ty
ptr@(Ptr !Addr#
_) ->
                                        (ty -> Bool)
-> MutableByteArray# (PrimState (ST s))
-> Ptr ty
-> Offset ty
-> Offset ty
-> ST s (CountOf ty)
forall (prim :: * -> *) ty container.
(PrimMonad prim, PrimType ty, Indexable container ty) =>
(ty -> Bool)
-> MutableByteArray# (PrimState prim)
-> container
-> Offset ty
-> Offset ty
-> prim (CountOf ty)
Alg.filter ty -> Bool
predicate MutableByteArray# (PrimState (ST s))
mba Ptr ty
ptr Offset ty
start Offset ty
end)
                          UArray ty
arr
    MUArray ty (PrimState (ST s)) -> CountOf ty -> ST s (UArray ty)
forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
unsafeFreezeShrink MUArray ty s
MUArray ty (PrimState (ST s))
ma CountOf ty
newLen
  where
    !len :: CountOf ty
len   = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
arr
    !start :: Offset ty
start = UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
arr
    !end :: Offset ty
end   = Offset ty
start Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
len

reverse :: forall ty . PrimType ty => UArray ty -> UArray ty
reverse :: forall ty. PrimType ty => UArray ty -> UArray ty
reverse UArray ty
a
    | CountOf ty
len CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty
0  = UArray ty
forall a. Monoid a => a
mempty
    | Bool
otherwise = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ do
        MUArray ty s
a <- CountOf ty
-> (MutableBlock ty (PrimState (ST s)) -> ST s ())
-> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty
-> (MutableBlock ty (PrimState prim) -> prim ())
-> prim (MUArray ty (PrimState prim))
newNative_ CountOf ty
len ((MutableBlock ty (PrimState (ST s)) -> ST s ())
 -> ST s (MUArray ty (PrimState (ST s))))
-> (MutableBlock ty (PrimState (ST s)) -> ST s ())
-> ST s (MUArray ty (PrimState (ST s)))
forall a b. (a -> b) -> a -> b
$ \MutableBlock ty (PrimState (ST s))
mba -> (Block ty -> ST s ())
-> (FinalPtr ty -> ST s ()) -> UArray ty -> ST s ()
forall (prim :: * -> *) ty a.
PrimMonad prim =>
(Block ty -> prim a)
-> (FinalPtr ty -> prim a) -> UArray ty -> prim a
onBackendPrim (MutableBlock ty s -> Block ty -> ST s ()
forall s. MutableBlock ty s -> Block ty -> ST s ()
goNative MutableBlock ty s
MutableBlock ty (PrimState (ST s))
mba)
                                                    (\FinalPtr ty
fptr -> FinalPtr ty -> (Ptr ty -> ST s ()) -> ST s ()
forall (prim :: * -> *) p a.
PrimMonad prim =>
FinalPtr p -> (Ptr p -> prim a) -> prim a
withFinalPtr FinalPtr ty
fptr ((Ptr ty -> ST s ()) -> ST s ()) -> (Ptr ty -> ST s ()) -> ST s ()
forall a b. (a -> b) -> a -> b
$ MutableBlock ty s -> Ptr ty -> ST s ()
forall s. MutableBlock ty s -> Ptr ty -> ST s ()
goAddr MutableBlock ty s
MutableBlock ty (PrimState (ST s))
mba)
                                                    UArray ty
a
        MUArray ty (PrimState (ST s)) -> ST s (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray ty s
MUArray ty (PrimState (ST s))
a
  where
    !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
a
    !end :: Offset ty
end = Offset ty
0 Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
len
    !start :: Offset ty
start = UArray ty -> Offset ty
forall ty. UArray ty -> Offset ty
offset UArray ty
a
    !endI :: Offset ty
endI = CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset ((Offset ty
start Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
end) Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
1)

    goNative :: MutableBlock ty s -> Block ty -> ST s ()
    goNative :: forall s. MutableBlock ty s -> Block ty -> ST s ()
goNative !MutableBlock ty s
ma (Block !ByteArray#
ba) = Offset ty -> ST s ()
loop Offset ty
0
      where
        loop :: Offset ty -> ST s ()
loop !Offset ty
i
            | Offset ty
i Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
end  = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
            | Bool
otherwise = MutableBlock ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
BLK.unsafeWrite MutableBlock ty s
MutableBlock ty (PrimState (ST s))
ma Offset ty
i (ByteArray# -> Offset ty -> ty
forall ty. PrimType ty => ByteArray# -> Offset ty -> ty
primBaIndex ByteArray#
ba (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset (Offset ty
endI Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- Offset ty
i))) ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> ST s ()
loop (Offset ty
iOffset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+Offset ty
1)
    goAddr :: MutableBlock ty s -> Ptr ty -> ST s ()
    goAddr :: forall s. MutableBlock ty s -> Ptr ty -> ST s ()
goAddr !MutableBlock ty s
ma (Ptr Addr#
addr) = Offset ty -> ST s ()
loop Offset ty
0
      where
        loop :: Offset ty -> ST s ()
loop !Offset ty
i
            | Offset ty
i Offset ty -> Offset ty -> Bool
forall a. Eq a => a -> a -> Bool
== Offset ty
end  = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
            | Bool
otherwise = MutableBlock ty (PrimState (ST s)) -> Offset ty -> ty -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MutableBlock ty (PrimState prim) -> Offset ty -> ty -> prim ()
BLK.unsafeWrite MutableBlock ty s
MutableBlock ty (PrimState (ST s))
ma Offset ty
i (Addr# -> Offset ty -> ty
forall ty. PrimType ty => Addr# -> Offset ty -> ty
primAddrIndex Addr#
addr (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset (Offset ty
endI Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- Offset ty
i))) ST s () -> ST s () -> ST s ()
forall a b. ST s a -> ST s b -> ST s b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Offset ty -> ST s ()
loop (Offset ty
iOffset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+Offset ty
1)
{-# SPECIALIZE [3] reverse :: UArray Word8 -> UArray Word8 #-}
{-# SPECIALIZE [3] reverse :: UArray Word32 -> UArray Word32 #-}
{-# SPECIALIZE [3] reverse :: UArray Char -> UArray Char #-}

-- Finds where are the insertion points when we search for a `needle`
-- within an `haystack`.
-- Throws an error in case `needle` is empty.
indices :: PrimType ty => UArray ty -> UArray ty -> [Offset ty]
indices :: forall ty. PrimType ty => UArray ty -> UArray ty -> [Offset ty]
indices UArray ty
needle UArray ty
hy
  | CountOf ty
needleLen CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
<= CountOf ty
0 = [Char] -> [Offset ty]
forall a. HasCallStack => [Char] -> a
error [Char]
"Basement.UArray.indices: needle is empty."
  | Bool
otherwise = case CountOf ty
haystackLen CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
< CountOf ty
needleLen of
                  Bool
True  -> []
                  Bool
False -> Offset ty -> [Offset ty] -> [Offset ty]
go (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) []
  where
    !haystackLen :: CountOf ty
haystackLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
hy

    !needleLen :: CountOf ty
needleLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
needle

    go :: Offset ty -> [Offset ty] -> [Offset ty]
go Offset ty
currentOffset [Offset ty]
ipoints
      | (Offset ty
currentOffset Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
needleLen) Offset ty -> Offset ty -> Bool
forall a. Ord a => a -> a -> Bool
> (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
haystackLen) = [Offset ty]
ipoints
      | Bool
otherwise =
        let matcher :: UArray ty
matcher = CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
take CountOf ty
needleLen (UArray ty -> UArray ty)
-> (UArray ty -> UArray ty) -> UArray ty -> UArray ty
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
drop (Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize Offset ty
currentOffset) (UArray ty -> UArray ty) -> UArray ty -> UArray ty
forall a b. (a -> b) -> a -> b
$ UArray ty
hy
        in case UArray ty
matcher UArray ty -> UArray ty -> Bool
forall a. Eq a => a -> a -> Bool
== UArray ty
needle of
             -- TODO: Move away from right-appending as it's gonna be slow.
             Bool
True  -> Offset ty -> [Offset ty] -> [Offset ty]
go (Offset ty
currentOffset Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
needleLen) ([Offset ty]
ipoints [Offset ty] -> [Offset ty] -> [Offset ty]
forall a. Semigroup a => a -> a -> a
<> [Offset ty
currentOffset])
             Bool
False -> Offset ty -> [Offset ty] -> [Offset ty]
go (Offset ty
currentOffset Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
1) [Offset ty]
ipoints

-- | Replace all the occurrencies of `needle` with `replacement` in
-- the `haystack` string.
replace :: PrimType ty => UArray ty -> UArray ty -> UArray ty -> UArray ty
replace :: forall ty.
PrimType ty =>
UArray ty -> UArray ty -> UArray ty -> UArray ty
replace (UArray ty
needle :: UArray ty) UArray ty
replacement UArray ty
haystack = (forall s. ST s (UArray ty)) -> UArray ty
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray ty)) -> UArray ty)
-> (forall s. ST s (UArray ty)) -> UArray ty
forall a b. (a -> b) -> a -> b
$ do
    case UArray ty -> Bool
forall ty. UArray ty -> Bool
null UArray ty
needle of
      Bool
True -> [Char] -> ST s (UArray ty)
forall a. HasCallStack => [Char] -> a
error [Char]
"Basement.UArray.replace: empty needle"
      Bool
False -> do
        let insertionPoints :: [Offset ty]
insertionPoints = UArray ty -> UArray ty -> [Offset ty]
forall ty. PrimType ty => UArray ty -> UArray ty -> [Offset ty]
indices UArray ty
needle UArray ty
haystack
        let !(CountOf Int
occs) = [Offset ty] -> CountOf (Offset ty)
forall a. [a] -> CountOf a
List.length [Offset ty]
insertionPoints
        let !newLen :: CountOf ty
newLen         = CountOf ty
haystackLen CountOf ty -> CountOf ty -> CountOf ty
forall a. CountOf a -> CountOf a -> CountOf a
`sizeSub` (CountOf ty -> Int -> CountOf ty
forall {ty} {ty}. CountOf ty -> Int -> CountOf ty
multBy CountOf ty
needleLen Int
occs) CountOf ty -> CountOf ty -> CountOf ty
forall a. Additive a => a -> a -> a
+ (CountOf ty -> Int -> CountOf ty
forall {ty} {ty}. CountOf ty -> Int -> CountOf ty
multBy CountOf ty
replacementLen Int
occs)
        MUArray ty s
ms <- CountOf ty -> ST s (MUArray ty (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
newLen
        MUArray ty (PrimState (ST s))
-> Offset ty -> Offset ty -> [Offset ty] -> ST s (UArray ty)
forall (prim :: * -> *).
PrimMonad prim =>
MUArray ty (PrimState prim)
-> Offset ty -> Offset ty -> [Offset ty] -> prim (UArray ty)
loop MUArray ty s
MUArray ty (PrimState (ST s))
ms (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) [Offset ty]
insertionPoints
  where

    multBy :: CountOf ty -> Int -> CountOf ty
multBy (CountOf Int
x) Int
y = Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf (Int
x Int -> Int -> Int
forall a. Multiplicative a => a -> a -> a
* Int
y)

    !needleLen :: CountOf ty
needleLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
needle

    !replacementLen :: CountOf ty
replacementLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
replacement

    !haystackLen :: CountOf ty
haystackLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
haystack

    -- Go through each insertion point and copy things over.
    -- We keep around the offset to the original string to
    -- be able to copy bytes which didn't change.
    loop :: PrimMonad prim
         => MUArray ty (PrimState prim)
         -> Offset ty
         -> Offset ty
         -> [Offset ty]
         -> prim (UArray ty)
    loop :: forall (prim :: * -> *).
PrimMonad prim =>
MUArray ty (PrimState prim)
-> Offset ty -> Offset ty -> [Offset ty] -> prim (UArray ty)
loop MUArray ty (PrimState prim)
mba Offset ty
currentOffset Offset ty
offsetInOriginalString [] = do
      -- Finalise the string
      let !unchangedDataLen :: Difference (Offset ty)
unchangedDataLen = CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
haystackLen Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- Offset ty
offsetInOriginalString
      MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
unsafeCopyAtRO MUArray ty (PrimState prim)
mba Offset ty
currentOffset UArray ty
haystack Offset ty
offsetInOriginalString Difference (Offset ty)
CountOf ty
unchangedDataLen
      MUArray ty (PrimState prim) -> prim (UArray ty)
forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> prim (UArray ty)
freeze MUArray ty (PrimState prim)
mba
    loop MUArray ty (PrimState prim)
mba Offset ty
currentOffset Offset ty
offsetInOriginalString (Offset ty
x:[Offset ty]
xs) = do
        -- 1. Copy from the old string.
        let !unchangedDataLen :: Difference (Offset ty)
unchangedDataLen = (Offset ty
x Offset ty -> Offset ty -> Difference (Offset ty)
forall a. Subtractive a => a -> a -> Difference a
- Offset ty
offsetInOriginalString)
        MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
unsafeCopyAtRO MUArray ty (PrimState prim)
mba Offset ty
currentOffset UArray ty
haystack Offset ty
offsetInOriginalString Difference (Offset ty)
CountOf ty
unchangedDataLen
        let !newOffset :: Offset ty
newOffset = Offset ty
currentOffset Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Difference (Offset ty)
CountOf ty
unchangedDataLen
        -- 2. Copy the replacement.
        MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
unsafeCopyAtRO MUArray ty (PrimState prim)
mba Offset ty
newOffset UArray ty
replacement (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) CountOf ty
replacementLen
        let !offsetInOriginalString' :: Offset ty
offsetInOriginalString' = Offset ty
offsetInOriginalString Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Difference (Offset ty)
CountOf ty
unchangedDataLen Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
needleLen
        MUArray ty (PrimState prim)
-> Offset ty -> Offset ty -> [Offset ty] -> prim (UArray ty)
forall (prim :: * -> *).
PrimMonad prim =>
MUArray ty (PrimState prim)
-> Offset ty -> Offset ty -> [Offset ty] -> prim (UArray ty)
loop MUArray ty (PrimState prim)
mba (Offset ty
newOffset Offset ty -> CountOf ty -> Offset ty
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf ty
replacementLen) Offset ty
offsetInOriginalString' [Offset ty]
xs
{-# SPECIALIZE [3] replace :: UArray Word8 -> UArray Word8 -> UArray Word8 -> UArray Word8 #-}

foldr :: PrimType ty => (ty -> a -> a) -> a -> UArray ty -> a
foldr :: forall ty a. PrimType ty => (ty -> a -> a) -> a -> UArray ty -> a
foldr ty -> a -> a
f a
initialAcc UArray ty
vec = Offset ty -> a
loop Offset ty
0
  where
    !len :: CountOf ty
len = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
vec
    loop :: Offset ty -> a
loop Offset ty
i
        | Offset ty
i Offset ty -> CountOf ty -> Bool
forall ty. Offset ty -> CountOf ty -> Bool
.==# CountOf ty
len = a
initialAcc
        | Bool
otherwise  = UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
vec Offset ty
i ty -> a -> a
`f` Offset ty -> a
loop (Offset ty
iOffset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+Offset ty
1)

foldl' :: PrimType ty => (a -> ty -> a) -> a -> UArray ty -> a
foldl' :: forall ty a. PrimType ty => (a -> ty -> a) -> a -> UArray ty -> a
foldl' a -> ty -> a
f a
initialAcc UArray ty
arr = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((a -> ty -> a) -> a -> container -> Offset ty -> Offset ty -> a
forall container ty a.
Indexable container ty =>
(a -> ty -> a) -> a -> container -> Offset ty -> Offset ty -> a
Alg.foldl a -> ty -> a
f a
initialAcc)
{-# SPECIALIZE [3] foldl' :: (a -> Word8 -> a) -> a -> UArray Word8 -> a #-}

foldl1' :: PrimType ty => (ty -> ty -> ty) -> NonEmpty (UArray ty) -> ty
foldl1' :: forall ty.
PrimType ty =>
(ty -> ty -> ty) -> NonEmpty (UArray ty) -> ty
foldl1' ty -> ty -> ty
f (NonEmpty UArray ty
arr) = UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> ty)
-> ty
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((ty -> ty -> ty) -> container -> Offset ty -> Offset ty -> ty
forall container ty.
Indexable container ty =>
(ty -> ty -> ty) -> container -> Offset ty -> Offset ty -> ty
Alg.foldl1 ty -> ty -> ty
f)
{-# SPECIALIZE [3] foldl1' :: (Word8 -> Word8 -> Word8) -> NonEmpty (UArray Word8) -> Word8 #-}

foldr1 :: PrimType ty => (ty -> ty -> ty) -> NonEmpty (UArray ty) -> ty
foldr1 :: forall ty.
PrimType ty =>
(ty -> ty -> ty) -> NonEmpty (UArray ty) -> ty
foldr1 ty -> ty -> ty
f NonEmpty (UArray ty)
arr = let (UArray ty
initialAcc, UArray ty
rest) = CountOf ty -> UArray ty -> (UArray ty, UArray ty)
forall ty. CountOf ty -> UArray ty -> (UArray ty, UArray ty)
revSplitAt CountOf ty
1 (UArray ty -> (UArray ty, UArray ty))
-> UArray ty -> (UArray ty, UArray ty)
forall a b. (a -> b) -> a -> b
$ NonEmpty (UArray ty) -> UArray ty
forall a. NonEmpty a -> a
getNonEmpty NonEmpty (UArray ty)
arr
               in (ty -> ty -> ty) -> ty -> UArray ty -> ty
forall ty a. PrimType ty => (ty -> a -> a) -> a -> UArray ty -> a
foldr ty -> ty -> ty
f (UArray ty -> Offset ty -> ty
forall ty. PrimType ty => UArray ty -> Offset ty -> ty
unsafeIndex UArray ty
initialAcc Offset ty
0) UArray ty
rest

all :: PrimType ty => (ty -> Bool) -> UArray ty -> Bool
all :: forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
all ty -> Bool
predicate UArray ty
arr = UArray ty
-> (forall {container}.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Bool)
-> Bool
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((forall {container}.
  Indexable container ty =>
  container -> Offset ty -> Offset ty -> Bool)
 -> Bool)
-> (forall {container}.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Bool)
-> Bool
forall a b. (a -> b) -> a -> b
$ (ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool
forall container ty.
Indexable container ty =>
(ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool
Alg.all ty -> Bool
predicate
{-# SPECIALIZE [3] all :: (Word8 -> Bool) -> UArray Word8 -> Bool #-}

any :: PrimType ty => (ty -> Bool) -> UArray ty -> Bool
any :: forall ty. PrimType ty => (ty -> Bool) -> UArray ty -> Bool
any ty -> Bool
predicate UArray ty
arr = UArray ty
-> (forall {container}.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Bool)
-> Bool
forall ty a.
PrimType ty =>
UArray ty
-> (forall container.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> a)
-> a
onBackendPure' UArray ty
arr ((forall {container}.
  Indexable container ty =>
  container -> Offset ty -> Offset ty -> Bool)
 -> Bool)
-> (forall {container}.
    Indexable container ty =>
    container -> Offset ty -> Offset ty -> Bool)
-> Bool
forall a b. (a -> b) -> a -> b
$ (ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool
forall container ty.
Indexable container ty =>
(ty -> Bool) -> container -> Offset ty -> Offset ty -> Bool
Alg.any ty -> Bool
predicate
{-# SPECIALIZE [3] any :: (Word8 -> Bool) -> UArray Word8 -> Bool #-}

builderAppend :: (PrimType ty, PrimMonad state) => ty -> Builder (UArray ty) (MUArray ty) ty state err ()
builderAppend :: forall ty (state :: * -> *) err.
(PrimType ty, PrimMonad state) =>
ty -> Builder (UArray ty) (MUArray ty) ty state err ()
builderAppend ty
v = State
  (Offset ty,
   BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
   Maybe err)
  state
  ()
-> Builder (UArray ty) (MUArray ty) ty state err ()
forall collection (mutCollection :: * -> *) step (state :: * -> *)
       err a.
State
  (Offset step,
   BuildingState collection mutCollection step (PrimState state),
   Maybe err)
  state
  a
-> Builder collection mutCollection step state err a
Builder (State
   (Offset ty,
    BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
    Maybe err)
   state
   ()
 -> Builder (UArray ty) (MUArray ty) ty state err ())
-> State
     (Offset ty,
      BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
      Maybe err)
     state
     ()
-> Builder (UArray ty) (MUArray ty) ty state err ()
forall a b. (a -> b) -> a -> b
$ ((Offset ty,
  BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
  Maybe err)
 -> state
      ((),
       (Offset ty,
        BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
        Maybe err)))
-> State
     (Offset ty,
      BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
      Maybe err)
     state
     ()
forall s (m :: * -> *) a. (s -> m (a, s)) -> State s m a
State (((Offset ty,
   BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
   Maybe err)
  -> state
       ((),
        (Offset ty,
         BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
         Maybe err)))
 -> State
      (Offset ty,
       BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
       Maybe err)
      state
      ())
-> ((Offset ty,
     BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
     Maybe err)
    -> state
         ((),
          (Offset ty,
           BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
           Maybe err)))
-> State
     (Offset ty,
      BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
      Maybe err)
     state
     ()
forall a b. (a -> b) -> a -> b
$ \(Offset ty
i, BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
st, Maybe err
e) ->
    if Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize Offset ty
i CountOf ty -> CountOf ty -> Bool
forall a. Eq a => a -> a -> Bool
== BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
-> CountOf ty
forall collection (mutCollection :: * -> *) step state.
BuildingState collection mutCollection step state -> CountOf step
chunkSize BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
st
        then do
            UArray ty
cur      <- MUArray ty (PrimState state) -> state (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze (BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
-> MUArray ty (PrimState state)
forall collection (mutCollection :: * -> *) step state.
BuildingState collection mutCollection step state
-> mutCollection state
curChunk BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
st)
            MUArray ty (PrimState state)
newChunk <- CountOf ty -> state (MUArray ty (PrimState state))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new (BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
-> CountOf ty
forall collection (mutCollection :: * -> *) step state.
BuildingState collection mutCollection step state -> CountOf step
chunkSize BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
st)
            MUArray ty (PrimState state) -> Offset ty -> ty -> state ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray ty (PrimState state)
newChunk Offset ty
0 ty
v
            ((),
 (Offset ty,
  BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
  Maybe err))
-> state
     ((),
      (Offset ty,
       BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
       Maybe err))
forall a. a -> state a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((), (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
1, BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
st { prevChunks     = cur : prevChunks st
                                    , prevChunksSize = chunkSize st + prevChunksSize st
                                    , curChunk       = newChunk
                                    }, Maybe err
e))
        else do
            MUArray ty (PrimState state) -> Offset ty -> ty -> state ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite (BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
-> MUArray ty (PrimState state)
forall collection (mutCollection :: * -> *) step state.
BuildingState collection mutCollection step state
-> mutCollection state
curChunk BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
st) Offset ty
i ty
v
            ((),
 (Offset ty,
  BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
  Maybe err))
-> state
     ((),
      (Offset ty,
       BuildingState (UArray ty) (MUArray ty) ty (PrimState state),
       Maybe err))
forall a. a -> state a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((), (Offset ty
i Offset ty -> Offset ty -> Offset ty
forall a. Additive a => a -> a -> a
+ Offset ty
1, BuildingState (UArray ty) (MUArray ty) ty (PrimState state)
st, Maybe err
e))

builderBuild :: (PrimType ty, PrimMonad m) => Int -> Builder (UArray ty) (MUArray ty) ty m err () -> m (Either err (UArray ty))
builderBuild :: forall ty (m :: * -> *) err.
(PrimType ty, PrimMonad m) =>
Int
-> Builder (UArray ty) (MUArray ty) ty m err ()
-> m (Either err (UArray ty))
builderBuild Int
sizeChunksI Builder (UArray ty) (MUArray ty) ty m err ()
ab
    | Int
sizeChunksI Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = Int
-> Builder (UArray ty) (MUArray ty) ty m err ()
-> m (Either err (UArray ty))
forall ty (m :: * -> *) err.
(PrimType ty, PrimMonad m) =>
Int
-> Builder (UArray ty) (MUArray ty) ty m err ()
-> m (Either err (UArray ty))
builderBuild Int
64 Builder (UArray ty) (MUArray ty) ty m err ()
ab
    | Bool
otherwise        = do
        MUArray ty (PrimState m)
first      <- CountOf ty -> m (MUArray ty (PrimState m))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
sizeChunks
        (Offset ty
i, BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
st, Maybe err
e) <- ((),
 (Offset ty,
  BuildingState (UArray ty) (MUArray ty) ty (PrimState m),
  Maybe err))
-> (Offset ty,
    BuildingState (UArray ty) (MUArray ty) ty (PrimState m), Maybe err)
forall a b. (a, b) -> b
snd (((),
  (Offset ty,
   BuildingState (UArray ty) (MUArray ty) ty (PrimState m),
   Maybe err))
 -> (Offset ty,
     BuildingState (UArray ty) (MUArray ty) ty (PrimState m),
     Maybe err))
-> m ((),
      (Offset ty,
       BuildingState (UArray ty) (MUArray ty) ty (PrimState m),
       Maybe err))
-> m (Offset ty,
      BuildingState (UArray ty) (MUArray ty) ty (PrimState m), Maybe err)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> State
  (Offset ty,
   BuildingState (UArray ty) (MUArray ty) ty (PrimState m), Maybe err)
  m
  ()
-> (Offset ty,
    BuildingState (UArray ty) (MUArray ty) ty (PrimState m), Maybe err)
-> m ((),
      (Offset ty,
       BuildingState (UArray ty) (MUArray ty) ty (PrimState m),
       Maybe err))
forall s (m :: * -> *) a. State s m a -> s -> m (a, s)
runState (Builder (UArray ty) (MUArray ty) ty m err ()
-> State
     (Offset ty,
      BuildingState (UArray ty) (MUArray ty) ty (PrimState m), Maybe err)
     m
     ()
forall collection (mutCollection :: * -> *) step (state :: * -> *)
       err a.
Builder collection mutCollection step state err a
-> State
     (Offset step,
      BuildingState collection mutCollection step (PrimState state),
      Maybe err)
     state
     a
runBuilder Builder (UArray ty) (MUArray ty) ty m err ()
ab) (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0, [UArray ty]
-> CountOf ty
-> MUArray ty (PrimState m)
-> CountOf ty
-> BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
forall collection (mutCollection :: * -> *) step state.
[collection]
-> CountOf step
-> mutCollection state
-> CountOf step
-> BuildingState collection mutCollection step state
BuildingState [] (Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
0) MUArray ty (PrimState m)
first CountOf ty
sizeChunks, Maybe err
forall a. Maybe a
Nothing)
        case Maybe err
e of
          Just err
err -> Either err (UArray ty) -> m (Either err (UArray ty))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (err -> Either err (UArray ty)
forall a b. a -> Either a b
Left err
err)
          Maybe err
Nothing -> do
            UArray ty
cur <- MUArray ty (PrimState m) -> CountOf ty -> m (UArray ty)
forall ty (prim :: * -> *).
(PrimType ty, PrimMonad prim) =>
MUArray ty (PrimState prim) -> CountOf ty -> prim (UArray ty)
unsafeFreezeShrink (BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
-> MUArray ty (PrimState m)
forall collection (mutCollection :: * -> *) step state.
BuildingState collection mutCollection step state
-> mutCollection state
curChunk BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
st) (Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize Offset ty
i)
            -- Build final array
            let totalSize :: CountOf ty
totalSize = BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
-> CountOf ty
forall collection (mutCollection :: * -> *) step state.
BuildingState collection mutCollection step state -> CountOf step
prevChunksSize BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
st CountOf ty -> CountOf ty -> CountOf ty
forall a. Additive a => a -> a -> a
+ Offset ty -> CountOf ty
forall a. Offset a -> CountOf a
offsetAsSize Offset ty
i
            UArray ty
bytes <- CountOf ty -> m (MUArray ty (PrimState m))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf ty
totalSize m (MUArray ty (PrimState m))
-> (MUArray ty (PrimState m) -> m (MUArray ty (PrimState m)))
-> m (MUArray ty (PrimState m))
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CountOf ty
-> [UArray ty]
-> MUArray ty (PrimState m)
-> m (MUArray ty (PrimState m))
forall {f :: * -> *} {ty}.
(PrimMonad f, PrimType ty) =>
CountOf ty
-> [UArray ty]
-> MUArray ty (PrimState f)
-> f (MUArray ty (PrimState f))
fillFromEnd CountOf ty
totalSize (UArray ty
cur UArray ty -> [UArray ty] -> [UArray ty]
forall a. a -> [a] -> [a]
: BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
-> [UArray ty]
forall collection (mutCollection :: * -> *) step state.
BuildingState collection mutCollection step state -> [collection]
prevChunks BuildingState (UArray ty) (MUArray ty) ty (PrimState m)
st) m (MUArray ty (PrimState m))
-> (MUArray ty (PrimState m) -> m (UArray ty)) -> m (UArray ty)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= MUArray ty (PrimState m) -> m (UArray ty)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze
            Either err (UArray ty) -> m (Either err (UArray ty))
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (UArray ty -> Either err (UArray ty)
forall a b. b -> Either a b
Right UArray ty
bytes)
  where
      sizeChunks :: CountOf ty
sizeChunks = Int -> CountOf ty
forall ty. Int -> CountOf ty
CountOf Int
sizeChunksI

      fillFromEnd :: CountOf ty
-> [UArray ty]
-> MUArray ty (PrimState f)
-> f (MUArray ty (PrimState f))
fillFromEnd CountOf ty
_    []     MUArray ty (PrimState f)
mua = MUArray ty (PrimState f) -> f (MUArray ty (PrimState f))
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure MUArray ty (PrimState f)
mua
      fillFromEnd !CountOf ty
end (UArray ty
x:[UArray ty]
xs) MUArray ty (PrimState f)
mua = do
          let sz :: CountOf ty
sz = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
x
          let start :: CountOf ty
start = CountOf ty
end CountOf ty -> CountOf ty -> CountOf ty
forall a. CountOf a -> CountOf a -> CountOf a
`sizeSub` CountOf ty
sz
          MUArray ty (PrimState f)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> f ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim)
-> Offset ty -> UArray ty -> Offset ty -> CountOf ty -> prim ()
unsafeCopyAtRO MUArray ty (PrimState f)
mua (CountOf ty -> Offset ty
forall a. CountOf a -> Offset a
sizeAsOffset CountOf ty
start) UArray ty
x (Int -> Offset ty
forall ty. Int -> Offset ty
Offset Int
0) CountOf ty
sz
          CountOf ty
-> [UArray ty]
-> MUArray ty (PrimState f)
-> f (MUArray ty (PrimState f))
fillFromEnd CountOf ty
start [UArray ty]
xs MUArray ty (PrimState f)
mua

builderBuild_ :: (PrimType ty, PrimMonad m) => Int -> Builder (UArray ty) (MUArray ty) ty m () () -> m (UArray ty)
builderBuild_ :: forall ty (m :: * -> *).
(PrimType ty, PrimMonad m) =>
Int -> Builder (UArray ty) (MUArray ty) ty m () () -> m (UArray ty)
builderBuild_ Int
sizeChunksI Builder (UArray ty) (MUArray ty) ty m () ()
ab = (() -> UArray ty)
-> (UArray ty -> UArray ty) -> Either () (UArray ty) -> UArray ty
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\() -> [Char] -> UArray ty
forall a. [Char] -> a
internalError [Char]
"impossible output") UArray ty -> UArray ty
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id (Either () (UArray ty) -> UArray ty)
-> m (Either () (UArray ty)) -> m (UArray ty)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int
-> Builder (UArray ty) (MUArray ty) ty m () ()
-> m (Either () (UArray ty))
forall ty (m :: * -> *) err.
(PrimType ty, PrimMonad m) =>
Int
-> Builder (UArray ty) (MUArray ty) ty m err ()
-> m (Either err (UArray ty))
builderBuild Int
sizeChunksI Builder (UArray ty) (MUArray ty) ty m () ()
ab

toHexadecimal :: PrimType ty => UArray ty -> UArray Word8
toHexadecimal :: forall ty. PrimType ty => UArray ty -> UArray Word8
toHexadecimal UArray ty
ba
    | CountOf Word8
len CountOf Word8 -> CountOf Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
0 = UArray Word8
forall a. Monoid a => a
mempty
    | Bool
otherwise     = (forall s. ST s (UArray Word8)) -> UArray Word8
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray Word8)) -> UArray Word8)
-> (forall s. ST s (UArray Word8)) -> UArray Word8
forall a b. (a -> b) -> a -> b
$ do
        MUArray Word8 s
ma <- CountOf Word8 -> ST s (MUArray Word8 (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new (CountOf Word8
len CountOf Word8 -> CountOf Word8 -> CountOf Word8
forall n. IsNatural n => n -> CountOf Word8 -> CountOf Word8
forall a n. (Additive a, IsNatural n) => n -> a -> a
`scale` CountOf Word8
2)
        UArray Word8 -> ((Offset Word8 -> Word8) -> ST s ()) -> ST s ()
forall (prim :: * -> *) ty a.
(PrimMonad prim, PrimType ty) =>
UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
unsafeIndexer UArray Word8
b8 (MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
forall s. MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
go MUArray Word8 s
ma)
        MUArray Word8 (PrimState (ST s)) -> ST s (UArray Word8)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma
  where
    b8 :: UArray Word8
b8 = UArray ty -> UArray Word8
forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
unsafeRecast UArray ty
ba
    !len :: CountOf Word8
len = UArray Word8 -> CountOf Word8
forall ty. UArray ty -> CountOf ty
length UArray Word8
b8
    !endOfs :: Offset Word8
endOfs = Int -> Offset Word8
forall ty. Int -> Offset ty
Offset Int
0 Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf Word8
len

    go :: MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
    go :: forall s. MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
go !MUArray Word8 s
ma !Offset Word8 -> Word8
getAt = Offset Word8 -> Offset Word8 -> ST s ()
loop Offset Word8
0 Offset Word8
0
      where
        loop :: Offset Word8 -> Offset Word8 -> ST s ()
loop !Offset Word8
dIdx !Offset Word8
sIdx
            | Offset Word8
sIdx Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Offset Word8
endOfs = () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
            | Bool
otherwise      = do
                let !(W8# !Word8#
w)       = Offset Word8 -> Word8
getAt Offset Word8
sIdx
                    !(# Word8#
wHi, Word8#
wLo #) = Word8# -> (# Word8#, Word8# #)
Base16.unsafeConvertByte Word8#
w
                MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma Offset Word8
dIdx     (Word8# -> Word8
W8# Word8#
wHi)
                MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma (Offset Word8
dIdxOffset Word8 -> Offset Word8 -> Offset Word8
forall a. Additive a => a -> a -> a
+Offset Word8
1) (Word8# -> Word8
W8# Word8#
wLo)
                Offset Word8 -> Offset Word8 -> ST s ()
loop (Offset Word8
dIdx Offset Word8 -> Offset Word8 -> Offset Word8
forall a. Additive a => a -> a -> a
+ Offset Word8
2) (Offset Word8
sIdxOffset Word8 -> Offset Word8 -> Offset Word8
forall a. Additive a => a -> a -> a
+Offset Word8
1)

toBase64Internal :: PrimType ty => Addr# -> UArray ty -> Bool -> UArray Word8
toBase64Internal :: forall ty.
PrimType ty =>
Addr# -> UArray ty -> Bool -> UArray Word8
toBase64Internal Addr#
table UArray ty
src Bool
padded
    | CountOf Word8
len CountOf Word8 -> CountOf Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
0 = UArray Word8
forall a. Monoid a => a
mempty
    | Bool
otherwise = (forall s. ST s (UArray Word8)) -> UArray Word8
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (UArray Word8)) -> UArray Word8)
-> (forall s. ST s (UArray Word8)) -> UArray Word8
forall a b. (a -> b) -> a -> b
$ do
        MUArray Word8 s
ma <- CountOf Word8 -> ST s (MUArray Word8 (PrimState (ST s)))
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
CountOf ty -> prim (MUArray ty (PrimState prim))
new CountOf Word8
dstLen
        UArray Word8 -> ((Offset Word8 -> Word8) -> ST s ()) -> ST s ()
forall (prim :: * -> *) ty a.
(PrimMonad prim, PrimType ty) =>
UArray ty -> ((Offset ty -> ty) -> prim a) -> prim a
unsafeIndexer UArray Word8
b8 (MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
forall s. MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
go MUArray Word8 s
ma)
        MUArray Word8 (PrimState (ST s)) -> ST s (UArray Word8)
forall (prim :: * -> *) ty.
PrimMonad prim =>
MUArray ty (PrimState prim) -> prim (UArray ty)
unsafeFreeze MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma
  where
    b8 :: UArray Word8
b8 = UArray ty -> UArray Word8
forall a b. (PrimType a, PrimType b) => UArray a -> UArray b
unsafeRecast UArray ty
src
    !len :: CountOf Word8
len = UArray Word8 -> CountOf Word8
forall ty. UArray ty -> CountOf ty
length UArray Word8
b8
    !dstLen :: CountOf Word8
dstLen = Bool -> CountOf Word8 -> CountOf Word8
outputLengthBase64 Bool
padded CountOf Word8
len
    !endOfs :: Offset Word8
endOfs = Int -> Offset Word8
forall ty. Int -> Offset ty
Offset Int
0 Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf Word8
len
    !dstEndOfs :: Offset Word8
dstEndOfs = Int -> Offset Word8
forall ty. Int -> Offset ty
Offset Int
0 Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` CountOf Word8
dstLen

    go :: MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
    go :: forall s. MUArray Word8 s -> (Offset Word8 -> Word8) -> ST s ()
go !MUArray Word8 s
ma !Offset Word8 -> Word8
getAt = Offset Word8 -> Offset Word8 -> ST s ()
loop Offset Word8
0 Offset Word8
0
      where
        eqChar :: Word8
eqChar = Word8
0x3d :: Word8

        loop :: Offset Word8 -> Offset Word8 -> ST s ()
loop !Offset Word8
sIdx !Offset Word8
dIdx
            | Offset Word8
sIdx Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Offset Word8
endOfs = Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
padded (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ do
                Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Offset Word8
dIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
1 Offset Word8 -> Offset Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= Offset Word8
dstEndOfs) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma Offset Word8
dIdx Word8
eqChar
                Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Offset Word8
dIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
2 Offset Word8 -> Offset Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Offset Word8
dstEndOfs) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma (Offset Word8
dIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
1) Word8
eqChar
            | Bool
otherwise = do
                let !b2Idx :: Offset Word8
b2Idx = Offset Word8
sIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
1
                    !b3Idx :: Offset Word8
b3Idx = Offset Word8
sIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
2

                    !b2Available :: Bool
b2Available = Offset Word8
b2Idx Offset Word8 -> Offset Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Offset Word8
endOfs
                    !b3Available :: Bool
b3Available = Offset Word8
b3Idx Offset Word8 -> Offset Word8 -> Bool
forall a. Ord a => a -> a -> Bool
< Offset Word8
endOfs

                    !b1 :: Word8
b1 = Offset Word8 -> Word8
getAt Offset Word8
sIdx
                    !b2 :: Word8
b2 = if Bool
b2Available then Offset Word8 -> Word8
getAt Offset Word8
b2Idx else Word8
0
                    !b3 :: Word8
b3 = if Bool
b3Available then Offset Word8 -> Word8
getAt Offset Word8
b3Idx else Word8
0

                    (Word8
w,Word8
x,Word8
y,Word8
z) = Addr# -> Word8 -> Word8 -> Word8 -> (Word8, Word8, Word8, Word8)
convert3 Addr#
table Word8
b1 Word8
b2 Word8
b3

                    sNextIncr :: Int
sNextIncr = Int
1 Int -> Int -> Int
forall a. Additive a => a -> a -> a
+ Bool -> Int
forall a. Enum a => a -> Int
fromEnum Bool
b2Available Int -> Int -> Int
forall a. Additive a => a -> a -> a
+ Bool -> Int
forall a. Enum a => a -> Int
fromEnum Bool
b3Available
                    dNextIncr :: Int
dNextIncr = Int
1 Int -> Int -> Int
forall a. Additive a => a -> a -> a
+ Int
sNextIncr

                MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma Offset Word8
dIdx Word8
w
                MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma (Offset Word8
dIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
1) Word8
x

                Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
b2Available (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma (Offset Word8
dIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
2) Word8
y
                Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
b3Available (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ MUArray Word8 (PrimState (ST s))
-> Offset Word8 -> Word8 -> ST s ()
forall (prim :: * -> *) ty.
(PrimMonad prim, PrimType ty) =>
MUArray ty (PrimState prim) -> Offset ty -> ty -> prim ()
unsafeWrite MUArray Word8 s
MUArray Word8 (PrimState (ST s))
ma (Offset Word8
dIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
3) Word8
z

                Offset Word8 -> Offset Word8 -> ST s ()
loop (Offset Word8
sIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
sNextIncr) (Offset Word8
dIdx Offset Word8 -> CountOf Word8 -> Offset Word8
forall ty. Offset ty -> CountOf ty -> Offset ty
`offsetPlusE` Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
dNextIncr)

outputLengthBase64 :: Bool -> CountOf Word8 -> CountOf Word8
outputLengthBase64 :: Bool -> CountOf Word8 -> CountOf Word8
outputLengthBase64 Bool
padding (CountOf Int
inputLenInt) = CountOf Word8
outputLength
  where
    outputLength :: CountOf Word8
outputLength = if Bool
padding then Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
lenWithPadding else Int -> CountOf Word8
forall ty. Int -> CountOf ty
CountOf Int
lenWithoutPadding
    lenWithPadding :: Int
lenWithPadding
        | Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0    = Int
4 Int -> Int -> Int
forall a. Multiplicative a => a -> a -> a
* Int
d
        | Bool
otherwise = Int
4 Int -> Int -> Int
forall a. Multiplicative a => a -> a -> a
* (Int
d Int -> Int -> Int
forall a. Additive a => a -> a -> a
+ Int
1)
    lenWithoutPadding :: Int
lenWithoutPadding
        | Int
m Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0    = Int
4 Int -> Int -> Int
forall a. Multiplicative a => a -> a -> a
* Int
d
        | Bool
otherwise = Int
4 Int -> Int -> Int
forall a. Multiplicative a => a -> a -> a
* Int
d Int -> Int -> Int
forall a. Additive a => a -> a -> a
+ Int
m Int -> Int -> Int
forall a. Additive a => a -> a -> a
+ Int
1
    (Int
d,Int
m) = Int
inputLenInt Int -> Int -> (Int, Int)
forall a. IDivisible a => a -> a -> (a, a)
`divMod` Int
3

convert3 :: Addr# -> Word8 -> Word8 -> Word8 -> (Word8, Word8, Word8, Word8)
convert3 :: Addr# -> Word8 -> Word8 -> Word8 -> (Word8, Word8, Word8, Word8)
convert3 Addr#
table Word8
a Word8
b Word8
c =
    let !w :: Word8
w = Word8
a Word8 -> CountOf Bool -> Word8
forall bits. BitOps bits => bits -> CountOf Bool -> bits
.>>. CountOf Bool
2
        !x :: Word8
x = ((Word8
a Word8 -> CountOf Bool -> Word8
forall bits. BitOps bits => bits -> CountOf Bool -> bits
.<<. CountOf Bool
4) Word8 -> Word8 -> Word8
forall bits. BitOps bits => bits -> bits -> bits
.&. Word8
0x30) Word8 -> Word8 -> Word8
forall bits. BitOps bits => bits -> bits -> bits
.|. (Word8
b Word8 -> CountOf Bool -> Word8
forall bits. BitOps bits => bits -> CountOf Bool -> bits
.>>. CountOf Bool
4)
        !y :: Word8
y = ((Word8
b Word8 -> CountOf Bool -> Word8
forall bits. BitOps bits => bits -> CountOf Bool -> bits
.<<. CountOf Bool
2) Word8 -> Word8 -> Word8
forall bits. BitOps bits => bits -> bits -> bits
.&. Word8
0x3c) Word8 -> Word8 -> Word8
forall bits. BitOps bits => bits -> bits -> bits
.|. (Word8
c Word8 -> CountOf Bool -> Word8
forall bits. BitOps bits => bits -> CountOf Bool -> bits
.>>. CountOf Bool
6)
        !z :: Word8
z = Word8
c Word8 -> Word8 -> Word8
forall bits. BitOps bits => bits -> bits -> bits
.&. Word8
0x3f
     in (Word8 -> Word8
idx Word8
w, Word8 -> Word8
idx Word8
x, Word8 -> Word8
idx Word8
y, Word8 -> Word8
idx Word8
z)
  where
    idx :: Word8 -> Word8
    idx :: Word8 -> Word8
idx (W8# Word8#
i) = Word8# -> Word8
W8# (Addr# -> Int# -> Word8#
indexWord8OffAddr# Addr#
table (Word# -> Int#
word2Int# (Word8# -> Word#
word8ToWord# Word8#
i)))

isPrefixOf :: PrimType ty => UArray ty -> UArray ty -> Bool
isPrefixOf :: forall ty. PrimType ty => UArray ty -> UArray ty -> Bool
isPrefixOf UArray ty
pre UArray ty
arr
    | CountOf ty
pLen CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf ty
pArr = Bool
False
    | Bool
otherwise   = UArray ty
pre UArray ty -> UArray ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
unsafeTake CountOf ty
pLen UArray ty
arr
  where
    !pLen :: CountOf ty
pLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
pre
    !pArr :: CountOf ty
pArr = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
arr
{-# SPECIALIZE [3] isPrefixOf :: UArray Word8 -> UArray Word8 -> Bool #-}

isSuffixOf :: PrimType ty => UArray ty -> UArray ty -> Bool
isSuffixOf :: forall ty. PrimType ty => UArray ty -> UArray ty -> Bool
isSuffixOf UArray ty
suffix UArray ty
arr
    | CountOf ty
pLen CountOf ty -> CountOf ty -> Bool
forall a. Ord a => a -> a -> Bool
> CountOf ty
pArr = Bool
False
    | Bool
otherwise   = UArray ty
suffix UArray ty -> UArray ty -> Bool
forall a. Eq a => a -> a -> Bool
== CountOf ty -> UArray ty -> UArray ty
forall ty. CountOf ty -> UArray ty -> UArray ty
revTake CountOf ty
pLen UArray ty
arr
  where
    !pLen :: CountOf ty
pLen = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
suffix
    !pArr :: CountOf ty
pArr = UArray ty -> CountOf ty
forall ty. UArray ty -> CountOf ty
length UArray ty
arr
{-# SPECIALIZE [3] isSuffixOf :: UArray Word8 -> UArray Word8 -> Bool #-}