module Data.Graph.Inductive.Internal.Queue(
    -- * Type
    Queue(..),
    -- * Operations
    mkQueue, queuePut, queuePutList, queueGet, queueEmpty
) where

import Data.List (foldl')

data Queue a = MkQueue [a] [a]

mkQueue :: Queue a
mkQueue :: forall a. Queue a
mkQueue = forall a. [a] -> [a] -> Queue a
MkQueue [] []

queuePut :: a -> Queue a -> Queue a
queuePut :: forall a. a -> Queue a -> Queue a
queuePut a
item (MkQueue [a]
ins [a]
outs) = forall a. [a] -> [a] -> Queue a
MkQueue (a
itemforall a. a -> [a] -> [a]
:[a]
ins) [a]
outs

queuePutList :: [a] -> Queue a -> Queue a
queuePutList :: forall a. [a] -> Queue a -> Queue a
queuePutList [a]
xs Queue a
q = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. a -> Queue a -> Queue a
queuePut) Queue a
q [a]
xs

queueGet :: Queue a -> (a, Queue a)
queueGet :: forall a. Queue a -> (a, Queue a)
queueGet (MkQueue [a]
ins (a
item:[a]
rest)) = (a
item, forall a. [a] -> [a] -> Queue a
MkQueue [a]
ins [a]
rest)
queueGet (MkQueue [a]
ins []) = forall a. Queue a -> (a, Queue a)
queueGet (forall a. [a] -> [a] -> Queue a
MkQueue [] (forall a. [a] -> [a]
reverse [a]
ins))

queueEmpty :: Queue a -> Bool
queueEmpty :: forall a. Queue a -> Bool
queueEmpty (MkQueue [a]
ins [a]
outs) = forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
ins Bool -> Bool -> Bool
&& forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
outs