{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
-- |
-- Module      : Data.Vector.Grow
-- Copyright   : (c) 2020 Gushcha Anton
-- License     : MIT
-- Maintainer  : ncrashed@protonmail.com
-- Stability   : unstable
-- Portability : non-portable
--
-- Module defines mutable vector that can grow in size automatically when an user
-- adds new elements at the end of vector.
--
-- We reallocate vector with 1.5x length to get amortized append.
module Data.Vector.Grow(
    GrowVector(..)
  , IOGrowVector
  -- * Quering info about vector
  , length
  , null
  , capacity
  -- * Creation
  , new
  , newSized
  -- * Quering subvectors
  , slice
  -- * Converting to immutable
  , thaw
  , freeze
  -- * Capacity maninuplation
  , ensure
  , ensureAppend
  -- * Accessing individual elements
  , read
  , write
  , unsafeRead
  , unsafeWrite
  -- * Appending to vector
  , pushBack
  , unsafePushBack
  ) where

import Control.Monad
import Control.Monad.Primitive
import Data.Primitive.MutVar
import Data.Vector.Mutable (MVector)
import GHC.Generics
import Prelude hiding (length, null, read)

import qualified Data.Vector as U
import qualified Data.Vector.Mutable as M

-- | Grow vector that is wrap around mutable vector. We allocate partially filled
-- vector and grow it when there is no more space for new element.
data GrowVector s a = GrowVector {
  GrowVector s a -> MutVar s (MVector s a)
growVector         :: !(MutVar s (MVector s a))
, GrowVector s a -> MutVar s Int
growVectorLength   :: !(MutVar s Int)
} deriving ((forall x. GrowVector s a -> Rep (GrowVector s a) x)
-> (forall x. Rep (GrowVector s a) x -> GrowVector s a)
-> Generic (GrowVector s a)
forall x. Rep (GrowVector s a) x -> GrowVector s a
forall x. GrowVector s a -> Rep (GrowVector s a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall s a x. Rep (GrowVector s a) x -> GrowVector s a
forall s a x. GrowVector s a -> Rep (GrowVector s a) x
$cto :: forall s a x. Rep (GrowVector s a) x -> GrowVector s a
$cfrom :: forall s a x. GrowVector s a -> Rep (GrowVector s a) x
Generic)

-- | Synonim for 'GrowVector' in 'IO' monad
type IOGrowVector a = GrowVector RealWorld a

-- | Return current capacity of the vector (amount of elements that it can fit without realloc)
capacity :: (PrimMonad m) => GrowVector (PrimState m) a -> m Int
capacity :: GrowVector (PrimState m) a -> m Int
capacity GrowVector (PrimState m) a
v = do
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  Int -> m Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> m Int) -> Int -> m Int
forall a b. (a -> b) -> a -> b
$ MVector (PrimState m) a -> Int
forall s a. MVector s a -> Int
M.length MVector (PrimState m) a
mv
{-# INLINE capacity #-}

-- | Return current amount of elements in the vector
length :: (PrimMonad m) => GrowVector (PrimState m) a -> m Int
length :: GrowVector (PrimState m) a -> m Int
length GrowVector (PrimState m) a
v = MutVar (PrimState m) Int -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) Int -> m Int)
-> MutVar (PrimState m) Int -> m Int
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a -> MutVar (PrimState m) Int
forall s a. GrowVector s a -> MutVar s Int
growVectorLength GrowVector (PrimState m) a
v
{-# INLINE length #-}

-- | Return 'True' if there is no elements inside the vector
null :: (PrimMonad m) => GrowVector (PrimState m) a -> m Bool
null :: GrowVector (PrimState m) a -> m Bool
null GrowVector (PrimState m) a
v = (Int -> Bool) -> m Int -> m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (m Int -> m Bool) -> m Int -> m Bool
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
GrowVector (PrimState m) a -> m Int
length GrowVector (PrimState m) a
v
{-# INLINE null #-}

-- | Allocation of new growable vector with given capacity.
new :: (PrimMonad m) => Int -> m (GrowVector (PrimState m) a)
new :: Int -> m (GrowVector (PrimState m) a)
new = Int -> Int -> m (GrowVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> Int -> m (GrowVector (PrimState m) a)
newSized Int
0
{-# INLINE new #-}

-- | Allocation of new growable vector with given filled size and capacity.
-- Elements is not initialized. Capacity must be greater than filled size.
newSized :: (PrimMonad m) => Int -> Int -> m (GrowVector (PrimState m) a)
newSized :: Int -> Int -> m (GrowVector (PrimState m) a)
newSized Int
n Int
cap = MutVar (PrimState m) (MVector (PrimState m) a)
-> MutVar (PrimState m) Int -> GrowVector (PrimState m) a
forall s a.
MutVar s (MVector s a) -> MutVar s Int -> GrowVector s a
GrowVector (MutVar (PrimState m) (MVector (PrimState m) a)
 -> MutVar (PrimState m) Int -> GrowVector (PrimState m) a)
-> m (MutVar (PrimState m) (MVector (PrimState m) a))
-> m (MutVar (PrimState m) Int -> GrowVector (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (MVector (PrimState m) a
-> m (MutVar (PrimState m) (MVector (PrimState m) a))
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar (MVector (PrimState m) a
 -> m (MutVar (PrimState m) (MVector (PrimState m) a)))
-> m (MVector (PrimState m) a)
-> m (MutVar (PrimState m) (MVector (PrimState m) a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
Int -> m (MVector (PrimState m) a)
M.new Int
cap) m (MutVar (PrimState m) Int -> GrowVector (PrimState m) a)
-> m (MutVar (PrimState m) Int) -> m (GrowVector (PrimState m) a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m (MutVar (PrimState m) Int)
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar Int
n
{-# INLINABLE newSized #-}

-- | Yield a part of mutable vector without copying it. The vector must contain at least i+n elements.
slice :: (PrimMonad m)
  => Int -- ^ i starting index
  -> Int -- ^ n number of elements
  -> GrowVector (PrimState m) a
  -> m (GrowVector (PrimState m) a)
slice :: Int
-> Int
-> GrowVector (PrimState m) a
-> m (GrowVector (PrimState m) a)
slice Int
i Int
n GrowVector (PrimState m) a
v = do
  MutVar (PrimState m) Int
newSize <- Int -> m (MutVar (PrimState m) Int)
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar Int
n
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  MutVar (PrimState m) (MVector (PrimState m) a)
newVec <- MVector (PrimState m) a
-> m (MutVar (PrimState m) (MVector (PrimState m) a))
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar (MVector (PrimState m) a
 -> m (MutVar (PrimState m) (MVector (PrimState m) a)))
-> MVector (PrimState m) a
-> m (MutVar (PrimState m) (MVector (PrimState m) a))
forall a b. (a -> b) -> a -> b
$! Int -> Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall s a. Int -> Int -> MVector s a -> MVector s a
M.slice Int
i Int
n MVector (PrimState m) a
mv
  GrowVector (PrimState m) a -> m (GrowVector (PrimState m) a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GrowVector (PrimState m) a -> m (GrowVector (PrimState m) a))
-> GrowVector (PrimState m) a -> m (GrowVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$! MutVar (PrimState m) (MVector (PrimState m) a)
-> MutVar (PrimState m) Int -> GrowVector (PrimState m) a
forall s a.
MutVar s (MVector s a) -> MutVar s Int -> GrowVector s a
GrowVector MutVar (PrimState m) (MVector (PrimState m) a)
newVec MutVar (PrimState m) Int
newSize
{-# INLINABLE slice #-}

-- | Convert immutable vector to grow mutable version. Doesn't allocate additonal memory for appending,
-- use 'ensure' to add capacity to the vector.
thaw :: (PrimMonad m)
  => U.Vector a
  -> m (GrowVector (PrimState m) a)
thaw :: Vector a -> m (GrowVector (PrimState m) a)
thaw Vector a
u = do
  MutVar (PrimState m) (MVector (PrimState m) a)
mv <- MVector (PrimState m) a
-> m (MutVar (PrimState m) (MVector (PrimState m) a))
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar (MVector (PrimState m) a
 -> m (MutVar (PrimState m) (MVector (PrimState m) a)))
-> m (MVector (PrimState m) a)
-> m (MutVar (PrimState m) (MVector (PrimState m) a))
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Vector a -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
Vector a -> m (MVector (PrimState m) a)
U.thaw Vector a
u
  MutVar (PrimState m) Int
lv <- Int -> m (MutVar (PrimState m) Int)
forall (m :: * -> *) a.
PrimMonad m =>
a -> m (MutVar (PrimState m) a)
newMutVar (Vector a -> Int
forall a. Vector a -> Int
U.length Vector a
u)
  GrowVector (PrimState m) a -> m (GrowVector (PrimState m) a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GrowVector (PrimState m) a -> m (GrowVector (PrimState m) a))
-> GrowVector (PrimState m) a -> m (GrowVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ MutVar (PrimState m) (MVector (PrimState m) a)
-> MutVar (PrimState m) Int -> GrowVector (PrimState m) a
forall s a.
MutVar s (MVector s a) -> MutVar s Int -> GrowVector s a
GrowVector MutVar (PrimState m) (MVector (PrimState m) a)
mv MutVar (PrimState m) Int
lv
{-# INLINABLE thaw #-}

-- | Freezing growable vector. It will contain only actual elements of the vector not including capacity
-- space, but you should call 'U.force' on resulting vector to not hold the allocated capacity of original
-- vector in memory.

freeze :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> m (U.Vector a)
freeze :: GrowVector (PrimState m) a -> m (Vector a)
freeze GrowVector (PrimState m) a
v = do
  Int
n <- GrowVector (PrimState m) a -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
GrowVector (PrimState m) a -> m Int
length GrowVector (PrimState m) a
v
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  MVector (PrimState m) a -> m (Vector a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> m (Vector a)
U.freeze (MVector (PrimState m) a -> m (Vector a))
-> MVector (PrimState m) a -> m (Vector a)
forall a b. (a -> b) -> a -> b
$ Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall s a. Int -> MVector s a -> MVector s a
M.take Int
n MVector (PrimState m) a
mv
{-# INLINABLE freeze #-}

-- | Ensure that grow vector has at least given capacity possibly with reallocation.
ensure :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> Int
  -> m ()
ensure :: GrowVector (PrimState m) a -> Int -> m ()
ensure GrowVector (PrimState m) a
v Int
n = do
  Int
c <- GrowVector (PrimState m) a -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
GrowVector (PrimState m) a -> m Int
capacity GrowVector (PrimState m) a
v
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
    MutVar (PrimState m) (MVector (PrimState m) a)
-> MVector (PrimState m) a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar (GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v) (MVector (PrimState m) a -> m ())
-> m (MVector (PrimState m) a) -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
M.grow MVector (PrimState m) a
mv (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
c)
{-# INLINABLE ensure #-}

-- | Ensure that grow vector has enough space for additonal n elements.
-- We grow vector by 1.5 factor or by required elements count * 1.5.
ensureAppend :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> Int -- ^ Additional n elements
  -> m ()
ensureAppend :: GrowVector (PrimState m) a -> Int -> m ()
ensureAppend GrowVector (PrimState m) a
v Int
i = do
  Int
n <- MutVar (PrimState m) Int -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) Int -> m Int)
-> MutVar (PrimState m) Int -> m Int
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a -> MutVar (PrimState m) Int
forall s a. GrowVector s a -> MutVar s Int
growVectorLength GrowVector (PrimState m) a
v
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  let c :: Int
c = MVector (PrimState m) a -> Int
forall s a. MVector s a -> Int
M.length MVector (PrimState m) a
mv
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    let growFactor :: Double
growFactor = Double
1.5
        newCap :: Int
newCap = Double -> Int
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double -> Int) -> Double -> Int
forall a b. (a -> b) -> a -> b
$ Double -> Double -> Double
forall a. Ord a => a -> a -> a
max (Double
growFactor Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
c) (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
c Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
growFactor Double -> Double -> Double
forall a. Num a => a -> a -> a
* Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
c))
    MutVar (PrimState m) (MVector (PrimState m) a)
-> MVector (PrimState m) a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar (GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v) (MVector (PrimState m) a -> m ())
-> m (MVector (PrimState m) a) -> m ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
M.grow MVector (PrimState m) a
mv (Int
newCap Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
c)
{-# INLINABLE ensureAppend #-}

-- | Read element from vector at given index.
read :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> Int -- ^ Index of element. Must be in [0 .. length) range
  -> m a
read :: GrowVector (PrimState m) a -> Int -> m a
read GrowVector (PrimState m) a
v Int
i = do
  Int
n <- MutVar (PrimState m) Int -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) Int -> m Int)
-> MutVar (PrimState m) Int -> m Int
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a -> MutVar (PrimState m) Int
forall s a. GrowVector s a -> MutVar s Int
growVectorLength GrowVector (PrimState m) a
v
#ifndef LIQUID
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ [Char] -> m ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> m ()) -> [Char] -> m ()
forall a b. (a -> b) -> a -> b
$ [Char]
"GrowVector.read: index " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
" is out bounds " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n
#endif
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  MVector (PrimState m) a -> Int -> m a
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
M.unsafeRead MVector (PrimState m) a
mv Int
i
{-# INLINABLE read #-}

-- | Read element from vector at given index.
unsafeRead :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> Int -- ^ Index of element. Must be in [0 .. length) range
  -> m a
unsafeRead :: GrowVector (PrimState m) a -> Int -> m a
unsafeRead GrowVector (PrimState m) a
v Int
i = do
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  MVector (PrimState m) a -> Int -> m a
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> m a
M.unsafeRead MVector (PrimState m) a
mv Int
i
{-# INLINABLE unsafeRead #-}

-- | Write down element in the vector at given index.
write :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> Int -- ^ Index of element. Must be in [0 .. length) range
  -> a
  -> m ()
write :: GrowVector (PrimState m) a -> Int -> a -> m ()
write GrowVector (PrimState m) a
v Int
i a
a = do
  Int
n <- MutVar (PrimState m) Int -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) Int -> m Int)
-> MutVar (PrimState m) Int -> m Int
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a -> MutVar (PrimState m) Int
forall s a. GrowVector s a -> MutVar s Int
growVectorLength GrowVector (PrimState m) a
v
#ifndef LIQUID
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ [Char] -> m ()
forall a. HasCallStack => [Char] -> a
error ([Char] -> m ()) -> [Char] -> m ()
forall a b. (a -> b) -> a -> b
$ [Char]
"GrowVector.write: index " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
i [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
" is out bounds " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n
#endif
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
M.unsafeWrite MVector (PrimState m) a
mv Int
i a
a
{-# INLINABLE write #-}

-- | Write down element in the vector at given index.
unsafeWrite :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> Int -- ^ Index of element. Must be in [0 .. length) range
  -> a
  -> m ()
unsafeWrite :: GrowVector (PrimState m) a -> Int -> a -> m ()
unsafeWrite GrowVector (PrimState m) a
v Int
i a
a = do
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
M.unsafeWrite MVector (PrimState m) a
mv Int
i a
a
{-# INLINABLE unsafeWrite #-}

-- | O(1) amortized appending to vector
pushBack :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> a
  -> m ()
pushBack :: GrowVector (PrimState m) a -> a -> m ()
pushBack GrowVector (PrimState m) a
v a
a = do
  GrowVector (PrimState m) a -> Int -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
GrowVector (PrimState m) a -> Int -> m ()
ensureAppend GrowVector (PrimState m) a
v Int
1
  GrowVector (PrimState m) a -> a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
GrowVector (PrimState m) a -> a -> m ()
unsafePushBack GrowVector (PrimState m) a
v a
a
{-# INLINABLE pushBack #-}

-- | O(1) amortized appending to vector. Doesn't reallocate vector, so
-- there must by capacity - length >= 1.
unsafePushBack :: (PrimMonad m)
  => GrowVector (PrimState m) a
  -> a
  -> m ()
unsafePushBack :: GrowVector (PrimState m) a -> a -> m ()
unsafePushBack GrowVector (PrimState m) a
v a
a = do
  Int
n <- MutVar (PrimState m) Int -> m Int
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) Int -> m Int)
-> MutVar (PrimState m) Int -> m Int
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a -> MutVar (PrimState m) Int
forall s a. GrowVector s a -> MutVar s Int
growVectorLength GrowVector (PrimState m) a
v
  MVector (PrimState m) a
mv <- MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> m a
readMutVar (MutVar (PrimState m) (MVector (PrimState m) a)
 -> m (MVector (PrimState m) a))
-> MutVar (PrimState m) (MVector (PrimState m) a)
-> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ GrowVector (PrimState m) a
-> MutVar (PrimState m) (MVector (PrimState m) a)
forall s a. GrowVector s a -> MutVar s (MVector s a)
growVector GrowVector (PrimState m) a
v
  MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MVector (PrimState m) a -> Int -> a -> m ()
M.write MVector (PrimState m) a
mv Int
n a
a
  MutVar (PrimState m) Int -> Int -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar (GrowVector (PrimState m) a -> MutVar (PrimState m) Int
forall s a. GrowVector s a -> MutVar s Int
growVectorLength GrowVector (PrimState m) a
v) (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1)
{-# INLINABLE unsafePushBack #-}