{-# LANGUAGE NamedFieldPuns #-}

module Data.Buffer where

import Control.Applicative (Applicative (..))
import Control.Exception (assert)
import Control.Monad.Primitive
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector.Unboxed.Mutable as UM
import Prelude hiding (Applicative (..))

data Buffer s a = Buffer
  { forall s a. Buffer s a -> MVector s Int
bufferVars :: !(UM.MVector s Int)
  , forall s a. Buffer s a -> MVector s a
internalBuffer :: !(UM.MVector s a)
  , forall s a. Buffer s a -> Int
internalBufferSize :: !Int
  }

_bufferFrontPos :: Int
_bufferFrontPos :: Int
_bufferFrontPos = Int
0

_bufferBackPos :: Int
_bufferBackPos :: Int
_bufferBackPos = Int
1

newBuffer :: (U.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a)
newBuffer :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Int -> m (Buffer (PrimState m) a)
newBuffer Int
n = MVector (PrimState m) Int
-> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a
forall s a. MVector s Int -> MVector s a -> Int -> Buffer s a
Buffer (MVector (PrimState m) Int
 -> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) Int)
-> m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> m (MVector (PrimState m) Int)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
UM.replicate Int
2 Int
0 m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) a) -> m (Int -> Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
UM.unsafeNew Int
n m (Int -> Buffer (PrimState m) a)
-> m Int -> m (Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m Int
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
n

type Stack s a = Buffer s a
newBufferAsStack :: (U.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a)
newBufferAsStack :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Int -> m (Buffer (PrimState m) a)
newBufferAsStack Int
n = MVector (PrimState m) Int
-> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a
forall s a. MVector s Int -> MVector s a -> Int -> Buffer s a
Buffer (MVector (PrimState m) Int
 -> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) Int)
-> m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> m (MVector (PrimState m) Int)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
UM.replicate Int
2 Int
0 m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) a) -> m (Int -> Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
UM.unsafeNew Int
n m (Int -> Buffer (PrimState m) a)
-> m Int -> m (Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m Int
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
n

type Queue s a = Buffer s a
newBufferAsQueue :: (U.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a)
newBufferAsQueue :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Int -> m (Buffer (PrimState m) a)
newBufferAsQueue Int
n = MVector (PrimState m) Int
-> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a
forall s a. MVector s Int -> MVector s a -> Int -> Buffer s a
Buffer (MVector (PrimState m) Int
 -> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) Int)
-> m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> m (MVector (PrimState m) Int)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
UM.replicate Int
2 Int
0 m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) a) -> m (Int -> Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
UM.unsafeNew Int
n m (Int -> Buffer (PrimState m) a)
-> m Int -> m (Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m Int
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
n

type Deque s a = Buffer s a
newBufferAsDeque :: (U.Unbox a, PrimMonad m) => Int -> m (Buffer (PrimState m) a)
newBufferAsDeque :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Int -> m (Buffer (PrimState m) a)
newBufferAsDeque Int
n =
  MVector (PrimState m) Int
-> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a
forall s a. MVector s Int -> MVector s a -> Int -> Buffer s a
Buffer (MVector (PrimState m) Int
 -> MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) Int)
-> m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int -> Int -> m (MVector (PrimState m) Int)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> a -> m (MVector (PrimState m) a)
UM.replicate Int
2 Int
n
    m (MVector (PrimState m) a -> Int -> Buffer (PrimState m) a)
-> m (MVector (PrimState m) a) -> m (Int -> Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m (MVector (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
Int -> m (MVector (PrimState m) a)
UM.unsafeNew (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n)
    m (Int -> Buffer (PrimState m) a)
-> m Int -> m (Buffer (PrimState m) a)
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Int -> m Int
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
n)

lengthBuffer :: (PrimMonad m) => Buffer (PrimState m) a -> m Int
lengthBuffer :: forall (m :: * -> *) a.
PrimMonad m =>
Buffer (PrimState m) a -> m Int
lengthBuffer Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars} =
  (Int -> Int -> Int) -> m Int -> m Int -> m Int
forall a b c. (a -> b -> c) -> m a -> m b -> m c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2
    (-)
    (MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos)
    (MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos)
{-# INLINE lengthBuffer #-}

clearBuffer :: (PrimMonad m) => Buffer (PrimState m) a -> m ()
clearBuffer :: forall (m :: * -> *) a.
PrimMonad m =>
Buffer (PrimState m) a -> m ()
clearBuffer Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars} = do
  MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos Int
0
  MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferBackPos Int
0

freezeBuffer ::
  (U.Unbox a, PrimMonad m) =>
  Buffer (PrimState m) a ->
  m (U.Vector a)
freezeBuffer :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Vector a)
freezeBuffer Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  MVector (PrimState m) a -> m (Vector a)
forall a (m :: * -> *).
(Unbox 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 -> Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
UM.unsafeSlice Int
f (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
f) MVector (PrimState m) a
internalBuffer

unsafeFreezeBuffer ::
  (U.Unbox a, PrimMonad m) =>
  Buffer (PrimState m) a ->
  m (U.Vector a)
unsafeFreezeBuffer :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Vector a)
unsafeFreezeBuffer Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  MVector (PrimState m) a -> m (Vector a)
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
U.unsafeFreeze (MVector (PrimState m) a -> m (Vector a))
-> MVector (PrimState m) a -> m (Vector a)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
UM.unsafeSlice Int
f (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
f) MVector (PrimState m) a
internalBuffer

freezeInternalBuffer ::
  (U.Unbox a, PrimMonad m) =>
  Buffer (PrimState m) a ->
  m (U.Vector a)
freezeInternalBuffer :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Vector a)
freezeInternalBuffer Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  MVector (PrimState m) a -> m (Vector a)
forall a (m :: * -> *).
(Unbox 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 -> Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
UM.unsafeSlice Int
0 Int
b MVector (PrimState m) a
internalBuffer

unsafeFreezeInternalBuffer ::
  (U.Unbox a, PrimMonad m) =>
  Buffer (PrimState m) a ->
  m (U.Vector a)
unsafeFreezeInternalBuffer :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Vector a)
unsafeFreezeInternalBuffer Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  MVector (PrimState m) a -> m (Vector a)
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> m (Vector a)
U.unsafeFreeze (MVector (PrimState m) a -> m (Vector a))
-> MVector (PrimState m) a -> m (Vector a)
forall a b. (a -> b) -> a -> b
$ Int -> Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
UM.unsafeSlice Int
0 Int
b MVector (PrimState m) a
internalBuffer

popFront :: (U.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a)
popFront :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Maybe a)
popFront Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  if Int
f Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
b
    then do
      MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos (Int
f Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
      a -> Maybe a
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (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 :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) a
internalBuffer Int
f
    else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
{-# INLINE popFront #-}

viewFront :: (U.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a)
viewFront :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Maybe a)
viewFront Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  if Int
f Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
b
    then a -> Maybe a
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (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 :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) a
internalBuffer Int
f
    else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
{-# INLINE viewFront #-}

popBack :: (U.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a)
popBack :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Maybe a)
popBack Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  if Int
f Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
b
    then do
      MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferBackPos (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
      a -> Maybe a
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (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 :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) a
internalBuffer (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
    else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
{-# INLINE popBack #-}

viewBack :: (U.Unbox a, PrimMonad m) => Buffer (PrimState m) a -> m (Maybe a)
viewBack :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Buffer (PrimState m) a -> m (Maybe a)
viewBack Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  if Int
f Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
b
    then a -> Maybe a
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (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 :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) a
internalBuffer (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
    else Maybe a -> m (Maybe a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
{-# INLINE viewBack #-}

pushFront :: (U.Unbox a, PrimMonad m) => a -> Buffer (PrimState m) a -> m ()
pushFront :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
a -> Buffer (PrimState m) a -> m ()
pushFront a
x Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos (Int
f Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
  Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
f Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) a
internalBuffer (Int
f Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) a
x
{-# INLINE pushFront #-}

pushBack :: (U.Unbox a, PrimMonad m) => a -> Buffer (PrimState m) a -> m ()
pushBack :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
a -> Buffer (PrimState m) a -> m ()
pushBack a
x Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer, Int
internalBufferSize :: forall s a. Buffer s a -> Int
internalBufferSize :: Int
internalBufferSize} = do
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferBackPos (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
  Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
b Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
internalBufferSize) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a -> Int -> a -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) a
internalBuffer Int
b a
x
{-# INLINE pushBack #-}

pushFronts ::
  (U.Unbox a, PrimMonad m) =>
  U.Vector a ->
  Buffer (PrimState m) a ->
  m ()
pushFronts :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Vector a -> Buffer (PrimState m) a -> m ()
pushFronts Vector a
vec Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer} = do
  let n :: Int
n = Vector a -> Int
forall a. Unbox a => Vector a -> Int
U.length Vector a
vec
  Int
f <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos
  MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferFrontPos (Int
f Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n)
  Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
f) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a -> Vector a -> m ()
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> Vector a -> m ()
U.unsafeCopy (Int -> Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
UM.unsafeSlice (Int
f Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) Int
n MVector (PrimState m) a
internalBuffer) Vector a
vec
{-# INLINE pushFronts #-}

pushBacks ::
  (U.Unbox a, PrimMonad m) =>
  U.Vector a ->
  Buffer (PrimState m) a ->
  m ()
pushBacks :: forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
Vector a -> Buffer (PrimState m) a -> m ()
pushBacks Vector a
vec Buffer{MVector (PrimState m) Int
bufferVars :: forall s a. Buffer s a -> MVector s Int
bufferVars :: MVector (PrimState m) Int
bufferVars, MVector (PrimState m) a
internalBuffer :: forall s a. Buffer s a -> MVector s a
internalBuffer :: MVector (PrimState m) a
internalBuffer, Int
internalBufferSize :: forall s a. Buffer s a -> Int
internalBufferSize :: Int
internalBufferSize} = do
  let n :: Int
n = Vector a -> Int
forall a. Unbox a => Vector a -> Int
U.length Vector a
vec
  Int
b <- MVector (PrimState m) Int -> Int -> m Int
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> m a
UM.unsafeRead MVector (PrimState m) Int
bufferVars Int
_bufferBackPos
  MVector (PrimState m) Int -> Int -> Int -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Unbox a) =>
MVector (PrimState m) a -> Int -> a -> m ()
UM.unsafeWrite MVector (PrimState m) Int
bufferVars Int
_bufferBackPos (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
  Bool -> m () -> m ()
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Int
b Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
internalBufferSize) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    MVector (PrimState m) a -> Vector a -> m ()
forall a (m :: * -> *).
(Unbox a, PrimMonad m) =>
MVector (PrimState m) a -> Vector a -> m ()
U.unsafeCopy (Int -> Int -> MVector (PrimState m) a -> MVector (PrimState m) a
forall a s. Unbox a => Int -> Int -> MVector s a -> MVector s a
UM.unsafeSlice Int
b Int
n MVector (PrimState m) a
internalBuffer) Vector a
vec
{-# INLINE pushBacks #-}