{-# language
    BangPatterns
  , CPP
  , FlexibleInstances
  , ImportQualifiedPost
  , MagicHash
  , MultiParamTypeClasses
  , MultiWayIf
  , NamedFieldPuns
  , PackageImports
  , PolyKinds
  , RecordWildCards
  , ScopedTypeVariables
  , TypeApplications
  , TypeFamilies
  , TypeOperators
  , UnboxedSums
  , UnboxedTuples
#-}

-- |
--   = Purpose
--   A contiguous growable array type with heap-allocated contents, written @'Vec' arr s a@.
--
--   'Vec' has /O(1)/ indexing, amortised /O(1)/ 'push' (to the end), and /O(1)/ 'pop' (from the end).
--
--   == A note about representation
--   The type exposed by this module is polymorphic in the type of array backing the data structure, functionality
--   which is provided by the [contiguous](https://hackage.haskell.org/package/contiguous-0.6.3.0) library. There are
--   modules providing monomorphised variants for better type inference. They are:
--
--   * "GrowableVector.Lifted": backed by 'Data.Primitive.Array'; for storing lifted
--     elements. This suits most Haskell types.
--   * "GrowableVector.Lifted.Small": backed by 'Data.Primitive.SmallArray'; also for
--     storing lifted elements, but more efficient for <= 128 elements.
--   * "GrowableVector.Unlifted": backed by 'Data.Primitive.Unlifted.Array.UnliftedArray'; for storing elements which can be unlifted (i.e.,
--     non-thunk pointers; e.g., 'ByteArray', 'Control.Concurrent.MVar', 'Data.IORef.IORef'). See the
--     'Data.Primitive.Unlifted.Class.PrimUnlifted' typeclass for more details.
--   * "GrowableVector.Unboxed": backed by 'Data.Primitive.PrimArray'; for storing elements which can be completely unboxed
--     (i.e., non-thunk, non-pointers; e.g., 'Int', 'Word', 'Char'). See
--     the 'Prim' typeclass for more details.
--
--   == A note about type variable ordering
--   The type variables in this module will be ordered according to the following precedence list (with higher precedence meaning left-most in the forall-quantified type variables):
--
--     1. The 'PrimMonad' type variable, @m@
--     2. The array type, @arr@
--     3. The 'PrimState' token, @s@
--     4. The element type, @a@
--     5. Everything else is unspecified (look at the forall)
--
--   This structuring is intended to document and ensure a uniform experience for users of @-XTypeApplications@.
--
--   == A note about ordering of arguments
--   The arguments of functions in this module will generally be ordered as follows:
--
--     1. The vector
--     2. The index (e.g. when reading/writing)
--     3. The element
--
--   As an example, 'write', which has all three of these, takes the vector, then the index, then the element.
--
--   As another example, 'push', which does not take an index, takes the vector, then the element.
--
--   Any function which accepts more than one of the types in the list, or accepts a type which is not in the list, has no guarantee about its argument order.
module GrowableVector
  ( Vec

  , new
  , withCapacity

  , length
  , capacity

  , reserve
  , reserveExact

  , shrinkToFit
  , shrinkTo

  , unsafeRead
  , read
  , unsafeWrite
  , write
  , push
  , pop
  -- , insert
  , extend
  , fromFoldable

  , toList
  , toLiftedVector, toLiftedVectorWith
  , toPrimitiveVector, toPrimitiveVectorWith
  , toStorableVector, toStorableVectorWith

  , map, map', imap, imap'
  ) where

import Control.Monad
import Control.Monad.Primitive
import Data.Foldable (traverse_)
import Data.Foldable qualified as F
import Data.Primitive
import Data.Primitive.Contiguous (Contiguous, Element, Mutable)
import Data.Primitive.Contiguous qualified as C
import GHC.Float (int2Double)
import Foreign.Storable (Storable)
import Prelude hiding (length, read, map)
import Data.Vector qualified as LiftedVector
import Data.Vector.Primitive qualified as PrimitiveVector
import Data.Vector.Storable qualified as StorableVector

-- |
--   = Indexing
--   The 'Vec' type allows access to values by (0-based) index. An example will be more explicit:
--
--   >>> vec <- fromFoldable @_ @Array @_ @Int [0, 2, 4, 6]
--   >>> two <- unsafeRead vec 1
--   >>> unsafeWrite vec 1 7
--   >>> seven <- unsafeRead vec 1
--   >>> two + seven
--   9
--
--   However, be careful: if you try to access an index which isn't in the 'Vec', your program will exhibit undefined behaviour (\"UB\"), either returning garbage or segfaulting. You cannot do this:
--
--   @
--   v <- fromFoldable [0, 2, 4, 6]
--   unsafeRead v 6 -- this is UB
--   @
--
--   If you want safe access, use 'read':
--
--   >>> vec <- fromFoldable @_ @Array @_ @Int [0, 2, 4, 6]
--   >>> read vec 1
--   Just 2
--   >>> read vec 6
--   Nothing
--
--   = Capacity and reallocation
--   The capacity of a vector is the amount of space allocated for any future elements that will be added onto the vector. This is not to be confused with the /length/ of a vector, which specifies the number of actual elements within the vector. If a vector's length exceeds its capacity, its capacity will automatically be increased, but its elements will have to be reallocated.
--
--   For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10 more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or cause reallocation to occur. However, if the vector's length is increased to 11, it will have to reallocate, which can be slow. For this reason, it is recommended to use 'withCapacity' whenever possible to specify how big the vector is expected to get.
--
--   = Guarantees
--   'Vec' is a (pointer, capacity, length) triplet. The pointer
--   will never be null.
--
--   Because of the semantics of the GHC runtime, creating a new vector will always allocate. In particular, if you construct a 'MutablePrimArray'-backed 'Vec' with capacity 0 via @'new' 0@, @'fromFoldable' []@, or @'shrinkToFit'@ on an empty 'Vec', the 16-byte header to GHC 'ByteArray#' will be allocated, but nothing else (for the curious: this is needed for 'GHC.Exts.sameMutableByteArray#' to work). Similarly, if you store zero-sized types inside such a 'Vec', it will not allocate space for them. /Note that in this case the 'Vec' may not report a 'capacity' of 0/. 'Vec' will allocate if and only if @'sizeOf (undefined :: a) '*' 'capacity' '>' 0@.
--
--   If a 'Vec' /has/ allocated memory, then the memory it points to is on the heap (as defined by GHC's allocator), and its pointer points to 'length' initialised, contiguous elements in order (i.e. what you would see if you turned it into a list), followed by @'capacity' '-' 'length'@ logically uninitialised, contiguous elements.
--
--   'Vec' will never automatically shrink itself, even if completely empty. This ensures no unnecessary allocations or deallocations occur. Emptying a 'Vec' and then filling it back up to the same 'length' should incur no calls to the allocator. If you wish to free up unused memory, use 'shrinkToFit'.
--
--   'push' will never (re)allocate if the reported capacity is sufficient. 'push' /will/ (re)allocate if @'length' '==' 'capacity'@. That is, the reported capacity is completely accurate, and can be relied on. Bulk insertion methods /may/ reallocate, even when not necessary.
--
--   'Vec' does not guarantee any particular growth strategy when reallocating when full, nor when 'reserve' is called. The strategy is basic and may prove desirable to use a non-constant growth factor. Whatever strategy is used will of course guarantee /O(1)/ amortised push.
--
--   'fromFoldable' and 'withCapacity' will produce a 'Vec' with exactly the requested capacity.
--
--   'Vec' will not specifically overwrite any data that is removed from it, but also won't specifically preserve it. Its uninitialised memory is scratch space that it may use however it wants. It will generally just do whatever is most efficient or otherwise easy to implement. Do not rely on removed data to be erased for security purposes. Even if a 'Vec' drops out of scope, its buffer may simply be reused by another 'Vec'. Even if you zero a 'Vec's memory first, this may not actually happen when you think it does because of Garbage Collection.
data Vec arr s a = Vec
  { forall (arr :: * -> *) s a. Vec arr s a -> MutVar s Word
len :: {-# unpack #-} !(MutVar s Word)
  , forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf :: {-# unpack #-} !(MutVar s (Mutable arr s a))
  }

-- | \(O(1)\). Constructs a new, empty @'Vec' arr s a@.
--
-- >>> vec <- new @_ @Array @_ @Int
-- >>> assertM (== 0) (length vec)
-- >>> assertM (== 0) (capacity vec)
new :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => m (Vec arr s a)
new :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
m (Vec arr s a)
new = Word -> m (Vec arr s a)
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Word -> m (Vec arr s a)
withCapacity Word
0

-- | \(O(1)\). Constructs a new, empty @'Vec' arr s a@.
--
--   The vector will be able to hold exactly @capacity@
--   elements without reallocating. It is important to
--   note that althrough the returned vector has the
--   /capacity/ specified, with vector will have a zero
--   /length/.
--
-- >>> vec <- withCapacity @_ @SmallArray @_ @Int 10
-- -- The vector contains no items, even though it has capacity for more
-- >>> assertM (== 0) (length vec)
-- >>> assertM (== 10) (capacity vec)
-- -- These are all done without reallocating...
-- >>> forM_ [1..10] $ \i -> push vec i
-- >>> assertM (== 10) (length vec)
-- >>> assertM (== 10) (capacity vec)
-- -- ..but this may make the vector reallocate
-- >>> push vec 11
-- >>> assertM (== 11) (length vec)
-- >>> assertM (>= 11) (capacity vec)
withCapacity :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Word -- ^ capacity
  -> m (Vec arr s a)
withCapacity :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Word -> m (Vec arr s a)
withCapacity Word
sz = MutVar s Word -> MutVar s (Mutable arr s a) -> Vec arr s a
forall (arr :: * -> *) s a.
MutVar s Word -> MutVar s (Mutable arr s a) -> Vec arr s a
Vec
  (MutVar s Word -> MutVar s (Mutable arr s a) -> Vec arr s a)
-> m (MutVar s Word)
-> m (MutVar s (Mutable arr s a) -> Vec arr s a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word -> m (MutVar (PrimState m) Word)
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar Word
0
  m (MutVar s (Mutable arr s a) -> Vec arr s a)
-> m (MutVar s (Mutable arr s a)) -> m (Vec arr s a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (Mutable arr s a -> m (MutVar s (Mutable arr s a))
Mutable arr s a -> m (MutVar (PrimState m) (Mutable arr s a))
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar (Mutable arr s a -> m (MutVar s (Mutable arr s a)))
-> m (Mutable arr s a) -> m (MutVar s (Mutable arr s a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Word -> m (Mutable arr s a)
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Word -> m (Mutable arr s a)
cNew Word
sz)

-- | \(O(1)\). Returns the number of elements in the vector.
--
length :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m Word
length :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec = MutVar (PrimState m) Word -> m Word
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (Vec arr s a -> MutVar s Word
forall (arr :: * -> *) s a. Vec arr s a -> MutVar s Word
len Vec arr s a
vec)

-- | \(O(1)\). Returns the maximum number of elements the vector
--   can hold without reallocating.
--
-- >>> vec <- withCapacity @_ @PrimArray @_ @Word 10
-- >>> push vec 42
-- >>> assertM (== 10) (capacity vec)
capacity :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m Word
capacity :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
capacity Vec arr s a
vec = do
  Vec arr s a -> m Word
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
internal_max_capacity Vec arr s a
vec

-- | \(O(n)\). Reserves the minimum capacity for exactly @additional@
--   more elements to be inserted in the given @'Vec' arr s a@.
--   After calling 'reserveExact', capacity will be greater
--   than or equal to @length + additional@. Does nothing if
--   the capacity is already sufficient.
--
--   Capacity cannot be relied upon to be precisely minimal. Prefer 'reserve'
--   if future insertions are expected.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int @_ [1]
-- >>> reserveExact vec 10
-- >>> assertM (>= 11) (capacity vec)
reserveExact :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> m ()
reserveExact :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m ()
reserveExact Vec arr s a
vec Word
additional = do
  Word
cap <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
capacity Vec arr s a
vec
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word
additional Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
> Word
cap) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Mutable arr s a
oldBuf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
    Word
oldSize <- Mutable arr s a -> m Word
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> m Word
cSizeMut Mutable arr s a
oldBuf

    Word
usedCap <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
    let newSize :: Word
newSize = Word
oldSize Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
additional

    Mutable arr s a
newBuf <- Word -> m (Mutable arr s a)
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Word -> m (Mutable arr s a)
cNew Word
newSize
    Mutable arr s a -> Word -> Mutable arr s a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> Mutable arr s a -> m ()
internalCopyOverN Mutable arr s a
newBuf Word
usedCap Mutable arr s a
oldBuf

    MutVar (PrimState m) (Mutable arr s a) -> Mutable arr s a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar (Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf Vec arr s a
vec) Mutable arr s a
newBuf

-- | \(O(n)\). Reserves capacity for at least @additional@ more elements
--   to be inserted in the given @'Vec' arr s a@. The collection
--   may reserve more space to avoid frequent reallocations.
--   After calling 'reserve', capacity will be greater than or
--   equal to @length + additional@. Does nothing if capacity
--   is already sufficient.
--
-- >>> vec <- fromFoldable @_ @PrimArray @_ @Int @_ [1]
-- >>> reserve vec 10
-- >>> assertM (>= 11) (capacity vec)
reserve :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> m ()
reserve :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m ()
reserve Vec arr s a
vec Word
additional = do
  Bool
needsMore <- (\Word
len Word
cap -> Word
len Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
additional Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
> Word
cap)
               (Word -> Word -> Bool) -> m Word -> m (Word -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
               m (Word -> Bool) -> m Word -> m Bool
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
capacity Vec arr s a
vec
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
needsMore (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Mutable arr s a
oldBuf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
    Word
oldSize <- Mutable arr s a -> m Word
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> m Word
cSizeMut Mutable arr s a
oldBuf

    Word
usedCap <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
    let c :: Double
c = Word -> Double
uw2d Word
usedCap
    let newSize :: Word
newSize = Double -> Word
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (Double
_GROWTH_FACTOR Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
c) (Double
c Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
_GROWTH_FACTOR Double -> Double -> Double
forall a. Num a => a -> a -> a
* Word -> Double
uw2d (Word
oldSize Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
additional Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
usedCap)))

    Mutable arr s a
newBuf <- Word -> m (Mutable arr s a)
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Word -> m (Mutable arr s a)
cNew Word
newSize
    Mutable arr s a -> Word -> Mutable arr s a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> Mutable arr s a -> m ()
internalCopyOverN Mutable arr s a
newBuf Word
usedCap Mutable arr s a
oldBuf

    MutVar (PrimState m) (Mutable arr s a) -> Mutable arr s a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar (Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf Vec arr s a
vec) Mutable arr s a
newBuf

-- | \(O(n)\). Shrinks the capacity of the vector as much as possible.
--
-- >>> vec <- withCapacity @_ @Array @_ @Int 10
-- >>> extend vec [1, 2, 3]
-- >>> assertM (== 10) (capacity vec)
-- >>> shrinkToFit vec
-- >>> assertM (== 3) (capacity vec)
shrinkToFit :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m ()
shrinkToFit :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m ()
shrinkToFit Vec arr s a
vec = do
  Bool
shrinkable <- (\Word
len Word
cap -> Word
cap Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
> Word
len)
                (Word -> Word -> Bool) -> m Word -> m (Word -> Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
                m (Word -> Bool) -> m Word -> m Bool
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
capacity Vec arr s a
vec
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
shrinkable (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Word
usedCap <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
    Mutable arr s a
oldBuf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
    Mutable arr s a
newBuf <- Word -> m (Mutable arr s a)
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Word -> m (Mutable arr s a)
cNew Word
usedCap
    Mutable arr s a -> Word -> Mutable arr s a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> Mutable arr s a -> m ()
internalCopyOverN Mutable arr s a
newBuf Word
usedCap Mutable arr s a
oldBuf
    MutVar (PrimState m) (Mutable arr s a) -> Mutable arr s a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar (Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf Vec arr s a
vec) Mutable arr s a
newBuf

-- | \(O(n)\). Shrinks the capacity of the vector with a lower bound.
--
--   The capacity will remain at least as large as both the length and the
--   supplied value.
--
--   If the current capacity is less than the lower limit, this is a no-op.
--
-- >>> vec <- withCapacity @_ @Array @_ @Int 10
-- >>> extend vec [1, 2, 3]
-- >>> assertM (== 10) (capacity vec)
-- >>> shrinkTo vec 4
-- >>> assertM (>= 4) (capacity vec)
-- >>> shrinkTo vec 0
-- >>> assertM (>= 3) (capacity vec)
shrinkTo :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> m ()
shrinkTo :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m ()
shrinkTo Vec arr s a
vec Word
minCap = do
  Word
cap <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
capacity Vec arr s a
vec
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word
cap Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
> Word
minCap) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
    let newLen :: Word
newLen = Word -> Word -> Word
forall a. Ord a => a -> a -> a
max Word
len Word
minCap
    Mutable arr s a
oldBuf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
    Mutable arr s a
newBuf <- Word -> m (Mutable arr s a)
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Word -> m (Mutable arr s a)
cNew Word
newLen
    Mutable arr s a -> Word -> Mutable arr s a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> Mutable arr s a -> m ()
internalCopyOverN Mutable arr s a
newBuf Word
newLen Mutable arr s a
oldBuf
    MutVar (PrimState m) (Mutable arr s a) -> Mutable arr s a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar (Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf Vec arr s a
vec) Mutable arr s a
newBuf

-- | \(O(1)\). Return the element at the given position.
--
--   If the element index is out of bounds, this function will segfault.
--
--   The bounds are defined as [0, length).
--
--   This function is intended to be used in situations where you have
--   manually proved that your indices are within bounds, and you don't want to
--   repeatedly pay for bounds checking.
--
--   Consider using 'read' instead.
unsafeRead :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> m a
unsafeRead :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m a
unsafeRead Vec arr s a
vec Word
n = do
  Mutable arr s a
v <- MutVar (PrimState m) (Mutable arr s a) -> m (Mutable arr s a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf Vec arr s a
vec)
  Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
v Word
n

-- | \(O(1)\). Return the element at the given position, or 'Nothing' if the index is out
--   of bounds.
--
--   The bounds are defined as [0, length).
read :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> m (Maybe a)
read :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m (Maybe a)
read Vec arr s a
vec Word
n = do
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  if (Word
n Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
>= Word
0 Bool -> Bool -> Bool
&& Word
n Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
len)
    then a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> m a -> m (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vec arr s a -> Word -> m a
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m a
unsafeRead Vec arr s a
vec Word
n
    else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing

-- | \(O(1)\). Write a value to the vector at the given position.
--
--   If the index is out of bounds, this function will segfault.
--
--   The bounds are defined as [0, length).
--   If you want to add an element past @length - 1@, use `push` or `extend`, which can
--   intelligently handle resizes.
--
--   This function is intended to be used in situations where you have
--   manually proved that your indices are within bounds, and you don't want to
--   repeatedly pay for bounds checking.
--
--   Consider using 'write' instead.
unsafeWrite :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> a
  -> m ()
unsafeWrite :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> a -> m ()
unsafeWrite Vec arr s a
vec Word
n a
x = do
  Mutable arr s a
v <- MutVar (PrimState m) (Mutable arr s a) -> m (Mutable arr s a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf Vec arr s a
vec)
  Mutable arr s a -> Word -> a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> a -> m ()
cWrite Mutable arr s a
v Word
n a
x

-- | \(O(1)\). Write a value to the vector at the given position.
--
--   If the index is in bounds, this returns @'Just' ()@.
--   If the index is out of bounds, this returns 'Nothing'.
--
--   The bounds are defined as [0, length).
--   If you want to add an element past @length - 1@, use `push` or `extend`, which can
--   intelligently handle resizes.
write :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> a
  -> m (Maybe ())
write :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> a -> m (Maybe ())
write Vec arr s a
vec Word
n a
x = do
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  if (Word
n Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
>= Word
0 Bool -> Bool -> Bool
&& Word
n Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
len)
    then () -> Maybe ()
forall a. a -> Maybe a
Just (() -> Maybe ()) -> m () -> m (Maybe ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vec arr s a -> Word -> a -> m ()
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> a -> m ()
unsafeWrite Vec arr s a
vec Word
n a
x
    else Maybe () -> m (Maybe ())
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ()
forall a. Maybe a
Nothing

-- | Amortised \(O(1)\). Appends an element to the vector.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1, 2]
-- >>> push vec 3
-- >>> assertM (== [1, 2, 3]) (toList vec)
push :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> a
  -> m ()
push :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> a -> m ()
push Vec arr s a
vec a
x = do
  -- reserve (not reserveExact) will take care of
  -- intelligent resizing.
  Vec arr s a -> Word -> m ()
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m ()
reserve Vec arr s a
vec Word
1

  Word
index <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  Vec arr s a -> Word -> a -> m ()
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> a -> m ()
internal_write Vec arr s a
vec Word
index a
x

  Vec arr s a -> (Word -> Word) -> m ()
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> (Word -> Word) -> m ()
internal_modify_len Vec arr s a
vec (Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1)

{-
-- | \(O(n)\). Inserts an element at the given position, shifting all elements
--   after it to the right. Returns 'Nothing' if the given index is greater than
--   the length of the vector, otherwise returns 'Just' ().
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1, 2, 3]
-- >>> insert vec 1 4
-- >>> assertM (== [1, 4, 2, 3]) (toList vec)
-- >>> insert vec 4 5
-- >>> assertM (== [1, 4, 2, 3, 5]) (toList vec)
insert :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> a
  -> m (Maybe ())
insert vec ix x = do
  buf <- internal_vector vec
  len <- length vec
  cap <- capacity vec

  when (len == cap) $ do
    reserve vec 1

  if | ix < len -> do
         C.copyMut buf (uw2i (ix + 1)) (C.sliceMut buf (uw2i ix) (uw2i (len - ix)))
         --(uw2i (len - ix)) (C.sliceMut buf 0 (uw2i (ix + 1)))
         cWrite buf ix x
         internal_set_len vec (len + 1)
         pure (Just ())
     | ix == len -> do
         cWrite buf ix x
         internal_set_len vec (len + 1)
         pure (Just ())
     | otherwise -> do
         pure Nothing
-}

-- | \(O(1)\). Removes the last element from a vector and returns it, or 'Nothing' if it
--   is empty.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1, 2, 3]
-- >>> assertM (== Just 3) (pop vec)
-- >>> assertM (== [1, 2]) (toList vec)
pop :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m (Maybe a)
pop :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Maybe a)
pop Vec arr s a
vec = do
  Word
lastIndex <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  if Word
lastIndex Word -> Word -> Bool
forall a. Eq a => a -> a -> Bool
== Word
0
    then Maybe a -> m (Maybe a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
    else do
      Vec arr s a -> (Word -> Word) -> m ()
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> (Word -> Word) -> m ()
internal_modify_len Vec arr s a
vec (Word -> Word -> Word
forall a. Num a => a -> a -> a
subtract Word
1)
      a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> m a -> m (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Vec arr s a -> Word -> m a
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> m a
unsafeRead Vec arr s a
vec (Word
lastIndex Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1)

-- | \(O(m)\). Extend the vector with the elements of some 'Foldable' structure.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Char ['a', 'b', 'c']
-- >>> extend vec ['d', 'e', 'f']
-- >>> assertM (== "abcdef") (toList vec)
extend :: forall m arr s a t. (MonadPrim s m, Contiguous arr, Element arr a, Foldable t)
  => Vec arr s a
  -> t a
  -> m ()
extend :: forall (m :: * -> *) (arr :: * -> *) s a (t :: * -> *).
(MonadPrim s m, Contiguous arr, Element arr a, Foldable t) =>
Vec arr s a -> t a -> m ()
extend Vec arr s a
vec t a
xs = do
  -- TODO: inline some of this stuff
  -- to reduce redundant reads/writes
  (a -> m ()) -> t a -> m ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Vec arr s a -> a -> m ()
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> a -> m ()
push Vec arr s a
vec) t a
xs

-- | \(O(n)\). Create a vector with the elements of some 'Foldable' structure.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1..10]
-- >>> assertM (== [1..10]) (toList vec)
fromFoldable :: forall m arr s a t. (MonadPrim s m, Contiguous arr, Element arr a, Foldable t)
  => t a
  -> m (Vec arr s a)
fromFoldable :: forall (m :: * -> *) (arr :: * -> *) s a (t :: * -> *).
(MonadPrim s m, Contiguous arr, Element arr a, Foldable t) =>
t a -> m (Vec arr s a)
fromFoldable t a
xs = do
  Vec arr s a
vec <- Word -> m (Vec arr s a)
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Word -> m (Vec arr s a)
withCapacity (Int -> Word
ui2w (t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
F.length t a
xs))
  Vec arr s a -> t a -> m ()
forall (m :: * -> *) (arr :: * -> *) s a (t :: * -> *).
(MonadPrim s m, Contiguous arr, Element arr a, Foldable t) =>
Vec arr s a -> t a -> m ()
extend Vec arr s a
vec t a
xs
  Vec arr s a -> m (Vec arr s a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Vec arr s a
vec

-- | \(O(n)\). Create a list with the elements of the vector.
--
-- >>> vec <- new @_ @PrimArray @_ @Int
-- >>> extend vec [1..5]
-- >>> toList vec
-- [1,2,3,4,5]
toList :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m [a]
toList :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m [a]
toList Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
sz <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  let go :: Int -> [a] -> m [a]
      go :: Int -> [a] -> m [a]
go !Int
ix ![a]
acc =
        if Int
ix Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
0
        then do
          a
x <- Mutable arr (PrimState m) a -> Int -> m a
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> m b
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> m b
C.read Mutable arr s a
Mutable arr (PrimState m) a
buf Int
ix
          Int -> [a] -> m [a]
go (Int
ix Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
acc)
        else do
          [a] -> m [a]
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [a]
acc
  Int -> [a] -> m [a]
go (Word -> Int
uw2i (Word
sz Word -> Word -> Word
forall a. Num a => a -> a -> a
- Word
1)) []

{-
toList' :: forall arr a. (Contiguous arr, Element arr a, Show a)
  => Vec arr RealWorld a
  -> IO [a]
toList' vec = do
  buf <- internal_vector vec
  sz <- length vec
  putStrLn $ "sz=" ++ show sz
  let go :: Int -> [a] -> IO [a]
      go !ix !acc =
        if ix >= 0
        then do
          putStrLn $ "ix=" ++ show ix
          x <- C.read buf ix
          putStrLn $ "elem=" ++ show x
          go (ix - 1) (x : acc)
        else do
          pure acc
  go (uw2i (sz - 1)) []
-}

-- | \(O(n)\). Create a Primitive 'PrimitiveVector.Vector' copy of a vector.
toPrimitiveVector :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a, Prim a)
  => Vec arr s a
  -> m (PrimitiveVector.Vector a)
toPrimitiveVector :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a, Prim a) =>
Vec arr s a -> m (Vector a)
toPrimitiveVector Vec arr s a
vec = do
  (Word -> a -> m a) -> Vec arr s a -> m (Vector a)
forall (m :: * -> *) (arr :: * -> *) s a b.
(MonadPrim s m, Contiguous arr, Element arr a, Prim b) =>
(Word -> a -> m b) -> Vec arr s a -> m (Vector b)
toPrimitiveVectorWith (\Word
_ a
a -> a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a) Vec arr s a
vec

-- | \(O(n)\). Create a Storable 'StorableVector.Vector' copy of a vector.
toStorableVector :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a, Storable a)
  => Vec arr s a
  -> m (StorableVector.Vector a)
toStorableVector :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a, Storable a) =>
Vec arr s a -> m (Vector a)
toStorableVector Vec arr s a
vec = do
  (Word -> a -> m a) -> Vec arr s a -> m (Vector a)
forall (m :: * -> *) (arr :: * -> *) s a b.
(MonadPrim s m, Contiguous arr, Element arr a, Storable b) =>
(Word -> a -> m b) -> Vec arr s a -> m (Vector b)
toStorableVectorWith (\Word
_ a
a -> a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a) Vec arr s a
vec

-- | \(O(n)\). Create a lifted 'LiftedVector.Vector' copy of a vector.
toLiftedVector :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m (LiftedVector.Vector a)
toLiftedVector :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Vector a)
toLiftedVector Vec arr s a
vec = do
  (Word -> a -> m a) -> Vec arr s a -> m (Vector a)
forall (m :: * -> *) (arr :: * -> *) s a b.
(MonadPrim s m, Contiguous arr, Element arr a) =>
(Word -> a -> m b) -> Vec arr s a -> m (Vector b)
toLiftedVectorWith (\Word
_ a
a -> a -> m a
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a) Vec arr s a
vec

-- | \(O(n)\). Create a Primitive 'PrimitiveVector.Vector' copy of a vector by
-- applying a function to each element and its corresponding index.
toPrimitiveVectorWith :: forall m arr s a b. (MonadPrim s m, Contiguous arr, Element arr a, Prim b)
  => (Word -> a -> m b)
  -> Vec arr s a
  -> m (PrimitiveVector.Vector b)
toPrimitiveVectorWith :: forall (m :: * -> *) (arr :: * -> *) s a b.
(MonadPrim s m, Contiguous arr, Element arr a, Prim b) =>
(Word -> a -> m b) -> Vec arr s a -> m (Vector b)
toPrimitiveVectorWith Word -> a -> m b
f Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  Int -> (Int -> m b) -> m (Vector b)
forall (m :: * -> *) a.
(Monad m, Prim a) =>
Int -> (Int -> m a) -> m (Vector a)
PrimitiveVector.generateM (Word -> Int
uw2i Word
len) ((Int -> m b) -> m (Vector b)) -> (Int -> m b) -> m (Vector b)
forall a b. (a -> b) -> a -> b
$ \Int
ix -> do
    let wix :: Word
wix = Int -> Word
ui2w Int
ix
    a
x <- Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
buf Word
wix
    Word -> a -> m b
f Word
wix a
x

-- | \(O(n)\). Create a Storable 'StorableVector.Vector' copy of a vector by
-- applying a function to each element and its corresponding index.
toStorableVectorWith :: forall m arr s a b. (MonadPrim s m, Contiguous arr, Element arr a, Storable b)
  => (Word -> a -> m b)
  -> Vec arr s a
  -> m (StorableVector.Vector b)
toStorableVectorWith :: forall (m :: * -> *) (arr :: * -> *) s a b.
(MonadPrim s m, Contiguous arr, Element arr a, Storable b) =>
(Word -> a -> m b) -> Vec arr s a -> m (Vector b)
toStorableVectorWith Word -> a -> m b
f Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  Int -> (Int -> m b) -> m (Vector b)
forall (m :: * -> *) a.
(Monad m, Storable a) =>
Int -> (Int -> m a) -> m (Vector a)
StorableVector.generateM (Word -> Int
uw2i Word
len) ((Int -> m b) -> m (Vector b)) -> (Int -> m b) -> m (Vector b)
forall a b. (a -> b) -> a -> b
$ \Int
ix -> do
    let wix :: Word
wix = Int -> Word
ui2w Int
ix
    a
x <- Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
buf Word
wix
    Word -> a -> m b
f Word
wix a
x

-- | \(O(n)\). Create a lifted 'LiftedVector.Vector' copy of a vector by
-- applying a function to each element and its corresponding index.
toLiftedVectorWith :: forall m arr s a b. (MonadPrim s m, Contiguous arr, Element arr a)
  => (Word -> a -> m b)
  -> Vec arr s a
  -> m (LiftedVector.Vector b)
toLiftedVectorWith :: forall (m :: * -> *) (arr :: * -> *) s a b.
(MonadPrim s m, Contiguous arr, Element arr a) =>
(Word -> a -> m b) -> Vec arr s a -> m (Vector b)
toLiftedVectorWith Word -> a -> m b
f Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  Int -> (Int -> m b) -> m (Vector b)
forall (m :: * -> *) a.
Monad m =>
Int -> (Int -> m a) -> m (Vector a)
LiftedVector.generateM (Word -> Int
uw2i Word
len) ((Int -> m b) -> m (Vector b)) -> (Int -> m b) -> m (Vector b)
forall a b. (a -> b) -> a -> b
$ \Int
ix -> do
    let wix :: Word
wix = Int -> Word
ui2w Int
ix
    a
x <- Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
buf Word
wix
    Word -> a -> m b
f Word
wix a
x

-- | \(O(n)\). Map over an array, modifying the elements in place.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1..10]
-- >>> map (+ 1) vec
-- >>> assertM (== [2, 3 .. 11]) (toList vec)
map :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => (a -> a)
  -> Vec arr s a
  -> m ()
map :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
(a -> a) -> Vec arr s a -> m ()
map a -> a
f Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  let go :: Word -> m ()
go !Word
ix = Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word
ix Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
len) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
        a
a <- Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
buf Word
ix
        Mutable arr s a -> Word -> a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> a -> m ()
cWrite Mutable arr s a
buf Word
ix (a -> a
f a
a)
        Word -> m ()
go (Word
ix Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1)
  Word -> m ()
go Word
0

-- | \(O(n)\). Map strictly over an array, modifying the elements in place.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1..10]
-- >>> map' (* 2) vec
-- >>> assertM (== [2, 4 .. 20]) (toList vec)
map' :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => (a -> a)
  -> Vec arr s a
  -> m ()
map' :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
(a -> a) -> Vec arr s a -> m ()
map' a -> a
f Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  let go :: Word -> m ()
go !Word
ix = Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word
ix Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
len) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
        a
a <- Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
buf Word
ix
        let !a' :: a
a' = a -> a
f a
a
        Mutable arr s a -> Word -> a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> a -> m ()
cWrite Mutable arr s a
buf Word
ix a
a'
        Word -> m ()
go (Word
ix Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1)
  Word -> m ()
go Word
0

-- | \(O(n)\). Map over an array with a function that takes the index and its
--   corresponding element as input, modifying the elements in place.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1..10]
-- >>> imap (\ix el -> ix + 1) vec
-- >>> assertM (== zipWith (+) [0..] [1..10]) (toList vec)
imap :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => (Word -> a -> a)
  -> Vec arr s a
  -> m ()
imap :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
(Word -> a -> a) -> Vec arr s a -> m ()
imap Word -> a -> a
f Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  let go :: Word -> m ()
go !Word
ix = Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word
ix Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
len) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
        a
a <- Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
buf Word
ix
        Mutable arr s a -> Word -> a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> a -> m ()
cWrite Mutable arr s a
buf Word
ix (Word -> a -> a
f Word
ix a
a)
        Word -> m ()
go (Word
ix Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1)
  Word -> m ()
go Word
0

-- | \(O(n)\). Map strictly over an array with a function that takes
--   the index and its corresponding element as input, modifying the
--   elements in place.
--
-- >>> vec <- fromFoldable @_ @Array @_ @Int [1..10]
-- >>> imap' (\ix el -> ix + 1) vec
-- >>> assertM (== zipWith (+) [0..] [1..10]) (toList vec)
imap' :: forall m arr s a. (MonadPrim s m, Contiguous arr, Element arr a)
  => (Word -> a -> a)
  -> Vec arr s a
  -> m ()
imap' :: forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
(Word -> a -> a) -> Vec arr s a -> m ()
imap' Word -> a -> a
f Vec arr s a
vec = do
  Mutable arr s a
buf <- Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec
  Word
len <- Vec arr s a -> m Word
forall (m :: * -> *) (arr :: * -> *) s a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
length Vec arr s a
vec
  let go :: Word -> m ()
go !Word
ix = Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Word
ix Word -> Word -> Bool
forall a. Ord a => a -> a -> Bool
< Word
len) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
        a
a <- Mutable arr s a -> Word -> m a
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
buf Word
ix
        let !a' :: a
a' = Word -> a -> a
f Word
ix a
a
        Mutable arr s a -> Word -> a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> a -> m ()
cWrite Mutable arr s a
buf Word
ix a
a'
        Word -> m ()
go (Word
ix Word -> Word -> Word
forall a. Num a => a -> a -> a
+ Word
1)
  Word -> m ()
go Word
0

--------- INTERNALS -------------

internal_vector :: (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m (Mutable arr s a)
internal_vector :: forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector = MutVar s (Mutable arr s a) -> m (Mutable arr s a)
MutVar (PrimState m) (Mutable arr s a) -> m (Mutable arr s a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar s (Mutable arr s a) -> m (Mutable arr s a))
-> (Vec arr s a -> MutVar s (Mutable arr s a))
-> Vec arr s a
-> m (Mutable arr s a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf

internal_write :: (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> a
  -> m ()
internal_write :: forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> Word -> a -> m ()
internal_write Vec arr s a
vec Word
i a
x = Vec arr s a -> m (Mutable arr s a)
forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m (Mutable arr s a)
internal_vector Vec arr s a
vec m (Mutable arr s a) -> (Mutable arr s a -> m ()) -> m ()
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Mutable arr s a
v -> Mutable arr s a -> Word -> a -> m ()
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> a -> m ()
cWrite Mutable arr s a
v Word
i a
x

internal_max_capacity :: (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> m Word
internal_max_capacity :: forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> m Word
internal_max_capacity Vec arr s a
vec = do
  Mutable arr s a -> m Word
forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> m Word
cSizeMut (Mutable arr s a -> m Word) -> m (Mutable arr s a) -> m Word
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MutVar (PrimState m) (Mutable arr s a) -> m (Mutable arr s a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (Vec arr s a -> MutVar s (Mutable arr s a)
forall (arr :: * -> *) s a.
Vec arr s a -> MutVar s (Mutable arr s a)
buf Vec arr s a
vec)

{-
internal_set_len :: (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> Word
  -> m ()
internal_set_len vec newLen = do
  writeMutVar (len vec) newLen
-}

internal_modify_len :: (MonadPrim s m, Contiguous arr, Element arr a)
  => Vec arr s a
  -> (Word -> Word)
  -> m ()
internal_modify_len :: forall s (m :: * -> *) (arr :: * -> *) a.
(MonadPrim s m, Contiguous arr, Element arr a) =>
Vec arr s a -> (Word -> Word) -> m ()
internal_modify_len Vec arr s a
vec Word -> Word
f = do
  MutVar (PrimState m) Word -> (Word -> Word) -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> (a -> a) -> m ()
modifyMutVar' (Vec arr s a -> MutVar s Word
forall (arr :: * -> *) s a. Vec arr s a -> MutVar s Word
len Vec arr s a
vec) Word -> Word
f

ui2w :: Int -> Word
ui2w :: Int -> Word
ui2w = Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral

uw2i :: Word -> Int
uw2i :: Word -> Int
uw2i = Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral

uw2d :: Word -> Double
uw2d :: Word -> Double
uw2d Word
w = Int -> Double
int2Double (Word -> Int
uw2i Word
w)

cNew :: (Contiguous arr, Element arr a, MonadPrim s m) => Word -> m (Mutable arr s a)
cNew :: forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Word -> m (Mutable arr s a)
cNew Word
w = Int -> m (Mutable arr (PrimState m) a)
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Int -> m (Mutable arr (PrimState m) b)
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Int -> m (Mutable arr (PrimState m) b)
C.new (Word -> Int
uw2i Word
w)

cRead :: (Contiguous arr, Element arr a, MonadPrim s m) => Mutable arr s a -> Word -> m a
cRead :: forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> m a
cRead Mutable arr s a
m Word
w = Mutable arr (PrimState m) a -> Int -> m a
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> m b
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> m b
C.read Mutable arr s a
Mutable arr (PrimState m) a
m (Word -> Int
uw2i Word
w)

cWrite :: (Contiguous arr, Element arr a, MonadPrim s m) => Mutable arr s a -> Word -> a -> m ()
cWrite :: forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> a -> m ()
cWrite Mutable arr s a
m Word
w a
a = Mutable arr (PrimState m) a -> Int -> a -> m ()
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> b -> m ()
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> Int -> b -> m ()
C.write Mutable arr s a
Mutable arr (PrimState m) a
m (Word -> Int
uw2i Word
w) a
a

cSizeMut :: (Contiguous arr, Element arr a, MonadPrim s m) => Mutable arr s a -> m Word
cSizeMut :: forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> m Word
cSizeMut Mutable arr s a
m = Int -> Word
ui2w (Int -> Word) -> m Int -> m Word
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Mutable arr (PrimState m) a -> m Int
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> m Int
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b -> m Int
C.sizeMut Mutable arr s a
Mutable arr (PrimState m) a
m

internalCopyOverN :: (Contiguous arr, Element arr a, MonadPrim s m) => Mutable arr s a -> Word -> Mutable arr s a -> m ()
internalCopyOverN :: forall (arr :: * -> *) a s (m :: * -> *).
(Contiguous arr, Element arr a, MonadPrim s m) =>
Mutable arr s a -> Word -> Mutable arr s a -> m ()
internalCopyOverN Mutable arr s a
destination Word
sourceLen Mutable arr s a
source = do
  Mutable arr (PrimState m) a
-> Int -> MutableSliced arr (PrimState m) a -> m ()
forall (arr :: * -> *) (m :: * -> *) b.
(Contiguous arr, PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b
-> Int -> MutableSliced arr (PrimState m) b -> m ()
forall (m :: * -> *) b.
(PrimMonad m, Element arr b) =>
Mutable arr (PrimState m) b
-> Int -> MutableSliced arr (PrimState m) b -> m ()
C.copyMut Mutable arr s a
Mutable arr (PrimState m) a
destination Int
0 (Mutable arr s a -> Int -> Int -> MutableSliced arr s a
forall a s.
Element arr a =>
Mutable arr s a -> Int -> Int -> MutableSliced arr s a
forall (arr :: * -> *) a s.
(Contiguous arr, Element arr a) =>
Mutable arr s a -> Int -> Int -> MutableSliced arr s a
C.sliceMut Mutable arr s a
source Int
0 (Word -> Int
uw2i Word
sourceLen))

_GROWTH_FACTOR :: Double
_GROWTH_FACTOR :: Double
_GROWTH_FACTOR = Double
1.5
{-# inline _GROWTH_FACTOR #-}