{-# LANGUAGE RecordWildCards #-}

-- | Fixed-sized queue. Internally it has an \([l, r)\) pair of valid element bounds.
--
-- ==== __Example__
-- >>> import AtCoder.Internal.Queue qualified as Q
-- >>> que <- Q.new @_ @Int 3
-- >>> Q.capacity que
-- 3
--
-- >>> Q.pushBack que 0 -- [0  _  _  _]
-- >>> Q.pushBack que 1 -- [0, 1  _  _]
-- >>> Q.pushBack que 2 -- [0, 1, 2  _]
-- >>> Q.length que
-- 3
--
-- >>> Q.popFront que   -- [_  1, 2  _]
-- Just 0
--
-- >>> Q.freeze que     -- [_  1, 2  _]
-- [1,2]
--
-- >>> Q.pushFront que 10   -- [10, 1, 2  _]
-- >>> Q.pushFront que 1000
-- *** Exception: AtCoder.Internal.Queue.pushFront: no empty front space
-- ...
--
-- >>> Q.unsafeFreeze que -- [10, 1, 2  _]
-- [10,1,2]
--
-- >>> Q.clear que      -- [_  _  _  _]
-- >>> Q.pushBack que 0 -- [0  _  _  _]
-- >>> Q.pushBack que 1 -- [0, 1  _  _]
-- >>> Q.pushBack que 2 -- [0, 1, 2  _]
-- >>> Q.freeze que
-- [0,1,2]
--
-- @since 1.0.0.0
module AtCoder.Internal.Queue
  ( -- * Queue
    Queue,

    -- * Constructor
    new,

    -- * Metadata
    capacity,
    length,
    null,

    -- * Modifications

    -- ** Push/pop
    pushBack,
    pushFront,
    popFront,
    popFront_,

    -- ** Reset
    clear,

    -- * Conversions
    freeze,
    unsafeFreeze,
  )
where

import Control.Monad.Primitive (PrimMonad, PrimState, stToPrim)
import Control.Monad.ST (ST)
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)

-- | Fixed-sized queue. Internally it has an \([l, r)\) pair of valid element bounds.
--
-- @since 1.0.0.0
data Queue s a = Queue
  { -- | Stores [l, r) range in the `vecQ`.
    forall s a. Queue s a -> MVector s Int
posQ :: !(VUM.MVector s Int),
    forall s a. Queue s a -> MVector s a
vecQ :: !(VUM.MVector s a)
  }

-- | \(O(n)\) Creates a `Queue` with capacity \(n\).
--
-- @since 1.0.0.0
{-# INLINE new #-}
new :: (PrimMonad m, VU.Unbox a) => Int -> m (Queue (PrimState m) a)
new :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (Queue (PrimState m) a)
new Int
n = ST (PrimState m) (Queue (PrimState m) a)
-> m (Queue (PrimState m) a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (Queue (PrimState m) a)
 -> m (Queue (PrimState m) a))
-> ST (PrimState m) (Queue (PrimState m) a)
-> m (Queue (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ Int -> ST (PrimState m) (Queue (PrimState m) a)
forall a s. Unbox a => Int -> ST s (Queue s a)
newST Int
n

-- | \(O(1)\) Returns the array size.
--
-- @since 1.0.0.0
{-# INLINE capacity #-}
capacity :: (VU.Unbox a) => Queue s a -> Int
capacity :: forall a s. Unbox a => Queue s a -> Int
capacity = MVector s a -> Int
forall a s. Unbox a => MVector s a -> Int
VUM.length (MVector s a -> Int)
-> (Queue s a -> MVector s a) -> Queue s a -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Queue s a -> MVector s a
forall s a. Queue s a -> MVector s a
vecQ

-- | \(O(1)\) Returns the number of elements in the queue.
--
-- @since 1.0.0.0
{-# INLINE length #-}
length :: (PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> m Int
length :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m Int
length Queue (PrimState m) a
que = ST (PrimState m) Int -> m Int
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) Int -> m Int) -> ST (PrimState m) Int -> m Int
forall a b. (a -> b) -> a -> b
$ Queue (PrimState m) a -> ST (PrimState m) Int
forall a s. Unbox a => Queue s a -> ST s Int
lengthST Queue (PrimState m) a
que

-- | \(O(1)\) Returns `True` if the buffer is empty.
--
-- @since 1.0.0.0
{-# INLINE null #-}
null :: (PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> m Bool
null :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (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)
-> (Queue (PrimState m) a -> m Int)
-> Queue (PrimState m) a
-> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Queue (PrimState m) a -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m Int
length

-- | \(O(1)\) Appends an element to the back. Will throw an exception if the index is out of range.
--
-- @since 1.0.0.0
{-# INLINE pushBack #-}
pushBack :: (HasCallStack, PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> a -> m ()
pushBack :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> a -> m ()
pushBack Queue (PrimState m) a
que a
e = ST (PrimState m) () -> m ()
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) () -> m ()) -> ST (PrimState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ Queue (PrimState m) a -> a -> ST (PrimState m) ()
forall a s. (HasCallStack, Unbox a) => Queue s a -> a -> ST s ()
pushBackST Queue (PrimState m) a
que a
e

-- | \(O(1)\) Appends an element to the back. Will throw an exception if the index is out of range.
--
-- @since 1.0.0.0
{-# INLINE pushFront #-}
pushFront :: (HasCallStack, PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> a -> m ()
pushFront :: forall (m :: * -> *) a.
(HasCallStack, PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> a -> m ()
pushFront Queue (PrimState m) a
que a
e = ST (PrimState m) () -> m ()
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) () -> m ()) -> ST (PrimState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ Queue (PrimState m) a -> a -> ST (PrimState m) ()
forall a s. (HasCallStack, Unbox a) => Queue s a -> a -> ST s ()
pushFrontST Queue (PrimState m) a
que a
e

-- | \(O(1)\) Removes the first element from the queue and returns it, or `Nothing` if it is empty.
--
-- @since 1.0.0.0
{-# INLINE popFront #-}
popFront :: (PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> m (Maybe a)
popFront :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m (Maybe a)
popFront Queue (PrimState m) a
que = ST (PrimState m) (Maybe a) -> m (Maybe a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (Maybe a) -> m (Maybe a))
-> ST (PrimState m) (Maybe a) -> m (Maybe a)
forall a b. (a -> b) -> a -> b
$ Queue (PrimState m) a -> ST (PrimState m) (Maybe a)
forall a s. Unbox a => Queue s a -> ST s (Maybe a)
popFrontST Queue (PrimState m) a
que

-- | \(O(1)\) `popFront` with the return value discarded.
--
-- @since 1.0.0.0
{-# INLINE popFront_ #-}
popFront_ :: (PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> m ()
popFront_ :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m ()
popFront_ Queue (PrimState m) a
que = ST (PrimState m) () -> m ()
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) () -> m ()) -> ST (PrimState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ Queue (PrimState m) a -> ST (PrimState m) ()
forall a s. Unbox a => Queue s a -> ST s ()
popFrontST_ Queue (PrimState m) a
que

-- | \(O(1)\) Sets the `length` to zero.
--
-- @since 1.0.0.0
{-# INLINE clear #-}
clear :: (PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> m ()
clear :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m ()
clear Queue {MVector (PrimState m) a
MVector (PrimState m) Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector (PrimState m) Int
vecQ :: MVector (PrimState m) a
..} = do
  MVector (PrimState m) Int -> Int -> m ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> a -> m ()
VGM.set MVector (PrimState m) Int
posQ Int
0

-- | \(O(n)\) Yields an immutable copy of the mutable vector.
--
-- @since 1.0.0.0
{-# INLINE freeze #-}
freeze :: (PrimMonad m, VU.Unbox a) => Queue (PrimState m) a -> m (VU.Vector a)
freeze :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m (Vector a)
freeze Queue (PrimState m) a
que = ST (PrimState m) (Vector a) -> m (Vector a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (Vector a) -> m (Vector a))
-> ST (PrimState m) (Vector a) -> m (Vector a)
forall a b. (a -> b) -> a -> b
$ Queue (PrimState m) a -> ST (PrimState m) (Vector a)
forall a s. Unbox a => Queue s a -> ST s (Vector a)
freezeST Queue (PrimState m) a
que

-- | \(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) => Queue (PrimState m) a -> m (VU.Vector a)
unsafeFreeze :: forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m (Vector a)
unsafeFreeze Queue (PrimState m) a
que = ST (PrimState m) (Vector a) -> m (Vector a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (Vector a) -> m (Vector a))
-> ST (PrimState m) (Vector a) -> m (Vector a)
forall a b. (a -> b) -> a -> b
$ Queue (PrimState m) a -> ST (PrimState m) (Vector a)
forall a s. Unbox a => Queue s a -> ST s (Vector a)
unsafeFreezeST Queue (PrimState m) a
que

-- -------------------------------------------------------------------------------------------------
-- Internal
-- -------------------------------------------------------------------------------------------------

{-# INLINEABLE newST #-}
newST :: (VU.Unbox a) => Int -> ST s (Queue s a)
newST :: forall a s. Unbox a => Int -> ST s (Queue s a)
newST Int
n = do
  MVector s Int
posQ <- Int -> Int -> ST s (MVector (PrimState (ST s)) Int)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
VUM.replicate Int
2 (Int
0 :: Int)
  MVector s a
vecQ <- Int -> ST s (MVector (PrimState (ST s)) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
VUM.unsafeNew Int
n
  Queue s a -> ST s (Queue s a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Queue {MVector s a
MVector s Int
vecQ :: MVector s a
posQ :: MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..}

{-# INLINEABLE lengthST #-}
lengthST :: (VU.Unbox a) => Queue s a -> ST s Int
lengthST :: forall a s. Unbox a => Queue s a -> ST s Int
lengthST Queue {MVector s a
MVector s Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..} = do
  Int
l <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
0
  Int
r <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
1
  Int -> ST s Int
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> ST s Int) -> Int -> ST s Int
forall a b. (a -> b) -> a -> b
$ Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l

{-# INLINEABLE pushBackST #-}
pushBackST :: (HasCallStack, VU.Unbox a) => Queue s a -> a -> ST s ()
pushBackST :: forall a s. (HasCallStack, Unbox a) => Queue s a -> a -> ST s ()
pushBackST Queue {MVector s a
MVector s Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..} a
e = do
  MVector (PrimState (ST s)) Int
-> (Int -> ST s Int) -> Int -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> (a -> m a) -> Int -> m ()
VGM.unsafeModifyM
    MVector s Int
MVector (PrimState (ST s)) Int
posQ
    ( \Int
r -> do
        MVector (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.write MVector s a
MVector (PrimState (ST s)) a
vecQ Int
r a
e
        Int -> ST s Int
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> ST s Int) -> Int -> ST s Int
forall a b. (a -> b) -> a -> b
$ Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
    )
    Int
1

{-# INLINEABLE pushFrontST #-}
pushFrontST :: (HasCallStack, VU.Unbox a) => Queue s a -> a -> ST s ()
pushFrontST :: forall a s. (HasCallStack, Unbox a) => Queue s a -> a -> ST s ()
pushFrontST Queue {MVector s a
MVector s Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..} a
e = do
  Int
l0 <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
0
  if Int
l0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0
    then [Char] -> ST s ()
forall a. HasCallStack => [Char] -> a
error [Char]
"AtCoder.Internal.Queue.pushFront: no empty front space"
    else do
      MVector (PrimState (ST s)) Int
-> (Int -> ST s Int) -> Int -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> (a -> m a) -> Int -> m ()
VGM.unsafeModifyM
        MVector s Int
MVector (PrimState (ST s)) Int
posQ
        ( \Int
l -> do
            MVector (PrimState (ST s)) a -> Int -> a -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.write MVector s a
MVector (PrimState (ST s)) a
vecQ (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
e
            Int -> ST s Int
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> ST s Int) -> Int -> ST s Int
forall a b. (a -> b) -> a -> b
$ Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
        )
        Int
0

{-# INLINEABLE popFrontST #-}
popFrontST :: (VU.Unbox a) => Queue s a -> ST s (Maybe a)
popFrontST :: forall a s. Unbox a => Queue s a -> ST s (Maybe a)
popFrontST Queue {MVector s a
MVector s Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..} = do
  Int
l <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
0
  Int
r <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
1
  if Int
l Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
r
    then Maybe a -> ST s (Maybe a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe a
forall a. Maybe a
Nothing
    else do
      a
x <- MVector (PrimState (ST s)) a -> Int -> ST s a
forall (m :: * -> *) (v :: * -> * -> *) a.
(HasCallStack, PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.read MVector s a
MVector (PrimState (ST s)) a
vecQ Int
l
      MVector (PrimState (ST s)) Int -> Int -> Int -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> a -> m ()
VGM.unsafeWrite MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
0 (Int
l Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
      Maybe a -> ST s (Maybe a)
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe a -> ST s (Maybe a)) -> Maybe a -> ST s (Maybe a)
forall a b. (a -> b) -> a -> b
$ a -> Maybe a
forall a. a -> Maybe a
Just a
x

{-# INLINEABLE popFrontST_ #-}
popFrontST_ :: (VU.Unbox a) => Queue s a -> ST s ()
popFrontST_ :: forall a s. Unbox a => Queue s a -> ST s ()
popFrontST_ Queue s a
que = do
  Maybe a
_ <- Queue (PrimState (ST s)) a -> ST s (Maybe a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Queue (PrimState m) a -> m (Maybe a)
popFront Queue s a
Queue (PrimState (ST s)) a
que
  () -> ST s ()
forall a. a -> ST s a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

{-# INLINEABLE clearST #-}
clearST :: (VU.Unbox a) => Queue s a -> ST s ()
clearST :: forall a s. Unbox a => Queue s a -> ST s ()
clearST Queue {MVector s a
MVector s Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..} = do
  MVector (PrimState (ST s)) Int -> Int -> ST s ()
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> a -> m ()
VGM.set MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
0

{-# INLINEABLE freezeST #-}
freezeST :: (VU.Unbox a) => Queue s a -> ST s (VU.Vector a)
freezeST :: forall a s. Unbox a => Queue s a -> ST s (Vector a)
freezeST Queue {MVector s a
MVector s Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..} = do
  Int
l <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
0
  Int
r <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
1
  MVector (PrimState (ST s)) a -> ST s (Vector a)
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
VU.freeze (MVector (PrimState (ST s)) a -> ST s (Vector a))
-> MVector (PrimState (ST s)) a -> ST s (Vector a)
forall a b. (a -> b) -> a -> b
$ Int -> MVector (PrimState (ST s)) a -> MVector (PrimState (ST s)) a
forall a s. Unbox a => Int -> MVector s a -> MVector s a
VUM.take (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l) (MVector (PrimState (ST s)) a -> MVector (PrimState (ST s)) a)
-> MVector (PrimState (ST s)) a -> MVector (PrimState (ST s)) a
forall a b. (a -> b) -> a -> b
$ Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> MVector s a -> MVector s a
VUM.drop Int
l MVector s a
vecQ

{-# INLINEABLE unsafeFreezeST #-}
unsafeFreezeST :: (VU.Unbox a) => Queue s a -> ST s (VU.Vector a)
unsafeFreezeST :: forall a s. Unbox a => Queue s a -> ST s (Vector a)
unsafeFreezeST Queue {MVector s a
MVector s Int
vecQ :: forall s a. Queue s a -> MVector s a
posQ :: forall s a. Queue s a -> MVector s Int
posQ :: MVector s Int
vecQ :: MVector s a
..} = do
  Int
l <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
0
  Int
r <- MVector (PrimState (ST s)) Int -> Int -> ST s Int
forall (m :: * -> *) (v :: * -> * -> *) a.
(PrimMonad m, MVector v a) =>
v (PrimState m) a -> Int -> m a
VGM.unsafeRead MVector s Int
MVector (PrimState (ST s)) Int
posQ Int
1
  MVector (PrimState (ST s)) a -> ST s (Vector a)
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
VU.unsafeFreeze (MVector (PrimState (ST s)) a -> ST s (Vector a))
-> MVector (PrimState (ST s)) a -> ST s (Vector a)
forall a b. (a -> b) -> a -> b
$ Int -> MVector (PrimState (ST s)) a -> MVector (PrimState (ST s)) a
forall a s. Unbox a => Int -> MVector s a -> MVector s a
VUM.take (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
l) (MVector (PrimState (ST s)) a -> MVector (PrimState (ST s)) a)
-> MVector (PrimState (ST s)) a -> MVector (PrimState (ST s)) a
forall a b. (a -> b) -> a -> b
$ Int -> MVector s a -> MVector s a
forall a s. Unbox a => Int -> MVector s a -> MVector s a
VUM.drop Int
l MVector s a
vecQ