{-# LANGUAGE RecordWildCards #-}

-- | Growable vector with some runtime overhead (by `MutVar`).
--
-- ==== __Example__
-- >>> import AtCoder.Internal.GrowVec qualified as GV
-- >>> growVec <- GV.new @_ @Int 0
-- >>> GV.null growVec
-- True
--
-- >>> GV.pushBack growVec 10
-- >>> GV.pushBack growVec 11
-- >>> GV.pushBack growVec 12
-- >>> GV.freeze growVec
-- [10,11,12]
--
-- >>> GV.length growVec
-- 3
--
-- >>> GV.capacity growVec
-- 4
--
-- >>> GV.write growVec 1 20
-- >>> GV.read growVec 1
-- 20
--
-- >>> GV.popBack growVec
-- Just 12
--
-- >>> GV.popBack growVec
-- Just 20
--
-- >>> GV.reserve growVec 20
-- >>> GV.capacity growVec
-- 20
--
-- >>> GV.unsafeFreeze growVec
-- [10]
--
-- @since 1.0.0.0
module AtCoder.Internal.GrowVec
  ( -- * GrowVec
    GrowVec (vecGV),

    -- * Constructors
    new,
    build,
    reserve,

    -- * Metadata
    length,
    capacity,
    null,

    -- * Readings
    read,

    -- * Modifications

    -- ** Writing
    write,

    -- ** Push/pop
    pushBack,
    popBack,
    popBack_,

    -- * Conversion
    freeze,
    unsafeFreeze,
  )
where

import AtCoder.Internal.Assert qualified as ACIA
import Control.Monad (when)
import Control.Monad.Primitive (PrimMonad, PrimState)
import Data.Primitive.MutVar (MutVar, newMutVar, readMutVar, writeMutVar)
import Data.Vector.Generic.Mutable qualified as VGM
import Data.Vector.Unboxed qualified as VU
import Data.Vector.Unboxed.Mutable qualified as VUM
import GHC.Stack (HasCallStack)
import Prelude hiding (length, null, read)

-- | Growable vector with some runtime overhead.
--
-- @since 1.0.0.0
data GrowVec s a = GrowVec
  { -- | Stores [l, r) range in the `vecGV`.
    forall s a. GrowVec s a -> MVector s Int
posGV :: !(VUM.MVector s Int),
    -- | @since 1.0.0.0
    forall s a. GrowVec s a -> MutVar s (MVector s a)
vecGV :: !(MutVar s (VUM.MVector s a))
  }

-- | \(O(n)\) Creates a `GrowVec` with initial capacity \(n\).
--
-- @since 1.0.0.0
{-# INLINE new #-}
new :: (PrimMonad m, VU.Unbox a) => Int -> m (GrowVec (PrimState m) a)
new :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (GrowVec (PrimState m) a)
new Int
n = do
  MVector (PrimState m) Int
posGV <- Int -> Int -> m (MVector (PrimState m) Int)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
VUM.replicate Int
1 (Int
0 :: Int)
  MutVar (PrimState m) (MVector (PrimState m) a)
vecGV <- 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, Unbox a) =>
Int -> m (MVector (PrimState m) a)
VUM.unsafeNew Int
n
  GrowVec (PrimState m) a -> m (GrowVec (PrimState m) a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
posGV :: MVector (PrimState m) Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..}

-- | \(O(n)\) Creates a `GrowVec` with initial values.
--
-- @since 1.0.0.0
{-# INLINE build #-}
build :: (PrimMonad m, VU.Unbox a) => VU.Vector a -> m (GrowVec (PrimState m) a)
build :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Vector a -> m (GrowVec (PrimState m) a)
build Vector a
xs = do
  MVector (PrimState m) Int
posGV <- Int -> Int -> m (MVector (PrimState m) Int)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
VUM.replicate Int
1 (Int -> m (MVector (PrimState m) Int))
-> Int -> m (MVector (PrimState m) Int)
forall a b. (a -> b) -> a -> b
$ Vector a -> Int
forall a. Unbox a => Vector a -> Int
VU.length Vector a
xs
  MutVar (PrimState m) (MVector (PrimState m) a)
vecGV <- 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 a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Vector a -> m (MVector (PrimState m) a)
VU.thaw Vector a
xs
  GrowVec (PrimState m) a -> m (GrowVec (PrimState m) a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
posGV :: MVector (PrimState m) Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..}

-- | \(O(n)\) Reserves the internal storage capacity.
--
-- @since 1.0.0.0
{-# INLINE reserve #-}
reserve :: (HasCallStack, PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> Int -> m ()
reserve :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> Int -> m ()
reserve GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} Int
len = do
  MVector (PrimState m) a
vec <- 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)
vecGV
  Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (MVector (PrimState m) a -> Int
forall a s. Unbox a => MVector s a -> Int
VUM.length MVector (PrimState m) a
vec Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
len) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a
newVec <- MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
VUM.unsafeGrow MVector (PrimState m) a
vec (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- MVector (PrimState m) a -> Int
forall a s. Unbox a => MVector s a -> Int
VUM.length MVector (PrimState m) a
vec)
    MutVar (PrimState m) (MVector (PrimState m) a)
-> MVector (PrimState m) a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) (MVector (PrimState m) a)
vecGV MVector (PrimState m) a
newVec

-- | \(O(1)\) Returns the number of elements in the vector.
--
-- @since 1.0.0.0
{-# INLINE length #-}
length :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> m Int
length :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m Int
length GrowVec {MVector (PrimState m) Int
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
posGV} = do
  MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector (PrimState m) Int
posGV Int
0

-- | \(O(1)\) Returns the capacity of the internal the vector.
--
-- @since 1.0.0.0
{-# INLINE capacity #-}
capacity :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> m Int
capacity :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m Int
capacity GrowVec {MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
vecGV} = do
  MVector (PrimState m) a
vec <- 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)
vecGV
  Int -> m Int
forall a. a -> m a
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 a s. Unbox a => MVector s a -> Int
VUM.length MVector (PrimState m) a
vec

-- | \(O(1)\) Returns `True` if the vector is empty.
--
-- @since 1.0.0.0
{-# INLINE null #-}
null :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> m Bool
null :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m Bool
null = (Int -> Bool) -> m Int -> m Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
(<$>) (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0) (m Int -> m Bool)
-> (GrowVec (PrimState m) a -> m Int)
-> GrowVec (PrimState m) a
-> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GrowVec (PrimState m) a -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m Int
length

-- | \(O(1)\) Yields the element at the given position. Will throw an exception if the index is out
-- of range.
--
-- @since 1.0.0.0
{-# INLINE read #-}
read :: (HasCallStack, PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> Int -> m a
read :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> Int -> m a
read GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} Int
i = do
  MVector (PrimState m) a
vec <- 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)
vecGV
  let len :: Int
len = MVector (PrimState m) a -> Int
forall a s. Unbox a => MVector s a -> Int
VUM.length MVector (PrimState m) a
vec
  let !()
_ = HasCallStack => String -> Int -> Int -> ()
String -> Int -> Int -> ()
ACIA.checkIndex String
"AtCoder.Internal.GrowVec.read" Int
i Int
len
  MVector (PrimState m) a -> Int -> m a
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.read MVector (PrimState m) a
vec Int
i

-- | \(O(1)\) Writes to the element at the given position. Will throw an exception if the index is
-- out of range.
--
-- @since 1.0.0.0
{-# INLINE write #-}
write :: (HasCallStack, PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> Int -> a -> m ()
write :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> Int -> a -> m ()
write GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} Int
i a
x = do
  MVector (PrimState m) a
vec <- 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)
vecGV
  let len :: Int
len = MVector (PrimState m) a -> Int
forall a s. Unbox a => MVector s a -> Int
VUM.length MVector (PrimState m) a
vec
  let !()
_ = HasCallStack => String -> Int -> Int -> ()
String -> Int -> Int -> ()
ACIA.checkIndex String
"AtCoder.Internal.GrowVec.write" Int
i Int
len
  MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.write MVector (PrimState m) a
vec Int
i a
x

-- | Amortized \(O(1)\). Grow the capacity twice
--
-- @since 1.0.0.0
{-# INLINE pushBack #-}
pushBack :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> a -> m ()
pushBack :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> a -> m ()
pushBack GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} a
e = do
  Int
len <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector (PrimState m) Int
posGV Int
0
  MVector (PrimState m) a
vec <- do
    MVector (PrimState m) a
vec <- 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)
vecGV
    if MVector (PrimState m) a -> Int
forall a s. Unbox a => MVector s a -> Int
VUM.length MVector (PrimState m) a
vec Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
len
      then MVector (PrimState m) a -> m (MVector (PrimState m) a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure MVector (PrimState m) a
vec
      else do
        -- double the internal vector length
        MVector (PrimState m) a
newVec <- MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m (MVector (PrimState m) a)
VUM.unsafeGrow MVector (PrimState m) a
vec (Int -> m (MVector (PrimState m) a))
-> Int -> m (MVector (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
1 Int
len
        MutVar (PrimState m) (MVector (PrimState m) a)
-> MVector (PrimState m) a -> m ()
forall (m :: * -> *) a.
PrimMonad m =>
MutVar (PrimState m) a -> a -> m ()
writeMutVar MutVar (PrimState m) (MVector (PrimState m) a)
vecGV MVector (PrimState m) a
newVec
        MVector (PrimState m) a -> m (MVector (PrimState m) a)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure MVector (PrimState m) a
newVec

  MVector (PrimState m) Int -> (Int -> m Int) -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> (a -> m a) -> Int -> m ()
VGM.unsafeModifyM
    MVector (PrimState m) Int
posGV
    ( \Int
r -> do
        MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.write MVector (PrimState m) a
vec Int
r a
e
        Int -> m Int
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> m Int) -> Int -> m Int
forall a b. (a -> b) -> a -> b
$ Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
    )
    Int
0

-- | \(O(1)\) Removes the last element from the buffer and returns it, or `Nothing` if it is empty.
--
-- @since 1.0.0.0
{-# INLINE popBack #-}
popBack :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> m (Maybe a)
popBack :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m (Maybe a)
popBack GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} = do
  Int
pos <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector (PrimState m) Int
posGV Int
0
  if Int
pos Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
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
      MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.unsafeWrite MVector (PrimState m) Int
posGV Int
0 (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
      MVector (PrimState m) a
vec <- 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)
vecGV
      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
<$> MVector (PrimState m) a -> Int -> m a
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.read MVector (PrimState m) a
vec (Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

-- | \(O(1)\) `popBack` with the return value discarded.
--
-- @since 1.0.0.0
{-# INLINE popBack_ #-}
popBack_ :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> m ()
popBack_ :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m ()
popBack_ GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} = do
  Int
pos <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector (PrimState m) Int
posGV Int
0
  MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.unsafeWrite MVector (PrimState m) Int
posGV Int
0 (Int -> m ()) -> Int -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ Int
pos Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1

-- | \(O(n)\) Yields an immutable copy of the mutable vector.
--
-- @since 1.0.0.0
{-# INLINE freeze #-}
freeze :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> m (VU.Vector a)
freeze :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m (Vector a)
freeze GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} = do
  Int
len <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector (PrimState m) Int
posGV Int
0
  MVector (PrimState m) a
vec <- 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)
vecGV
  MVector (PrimState m) a -> m (Vector a)
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
VU.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 a s. Unbox a => Int -> MVector s a -> MVector s a
VUM.take Int
len MVector (PrimState m) a
vec

-- | \(O(1)\) Unsafely converts a mutable vector to an immutable one without copying. The mutable
-- vector may not be used after this operation.
--
-- @since 1.0.0.0
{-# INLINE unsafeFreeze #-}
unsafeFreeze :: (PrimMonad m, VU.Unbox a) => GrowVec (PrimState m) a -> m (VU.Vector a)
unsafeFreeze :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
GrowVec (PrimState m) a -> m (Vector a)
unsafeFreeze GrowVec {MVector (PrimState m) Int
MutVar (PrimState m) (MVector (PrimState m) a)
vecGV :: forall s a. GrowVec s a -> MutVar s (MVector s a)
posGV :: forall s a. GrowVec s a -> MVector s Int
posGV :: MVector (PrimState m) Int
vecGV :: MutVar (PrimState m) (MVector (PrimState m) a)
..} = do
  Int
len <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector (PrimState m) Int
posGV Int
0
  MVector (PrimState m) a
vec <- 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)
vecGV
  MVector (PrimState m) a -> m (Vector a)
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
VU.unsafeFreeze (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 a s. Unbox a => Int -> MVector s a -> MVector s a
VUM.take Int
len MVector (PrimState m) a
vec