    {-# LANGUAGE GeneralizedNewtypeDeriving #-}
    module Basement.MutableBuilder
        ( Builder(..)
        , BuildingState(..)
        ) where

    import           Basement.Compat.Base
    import           Basement.Compat.MonadTrans
    import           Basement.Types.OffsetSize
    import           Basement.Monad

    newtype Builder collection mutCollection step state err a = Builder
        { forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    Builder collection mutCollection step state err a
    -> State
         (Offset step,
          BuildingState collection mutCollection step (PrimState state),
          Maybe err)
         state
         a
    runBuilder :: State (Offset step, BuildingState collection mutCollection step (PrimState state), Maybe err) state a }
        deriving ((forall a b.
     (a -> b)
     -> Builder collection mutCollection step state err a
     -> Builder collection mutCollection step state err b)
    -> (forall a b.
        a
        -> Builder collection mutCollection step state err b
        -> Builder collection mutCollection step state err a)
    -> Functor (Builder collection mutCollection step state err)
    forall a b.
    a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    forall a b.
    (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    fmap :: forall a b.
    (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    $c<$ :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    <$ :: forall a b.
    a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    Functor, Functor (Builder collection mutCollection step state err)
    Functor (Builder collection mutCollection step state err)
    -> (forall a.
        a -> Builder collection mutCollection step state err a)
    -> (forall a b.
        Builder collection mutCollection step state err (a -> b)
        -> Builder collection mutCollection step state err a
        -> Builder collection mutCollection step state err b)
    -> (forall a b c.
        (a -> b -> c)
        -> Builder collection mutCollection step state err a
        -> Builder collection mutCollection step state err b
        -> Builder collection mutCollection step state err c)
    -> (forall a b.
        Builder collection mutCollection step state err a
        -> Builder collection mutCollection step state err b
        -> Builder collection mutCollection step state err b)
    -> (forall a b.
        Builder collection mutCollection step state err a
        -> Builder collection mutCollection step state err b
        -> Builder collection mutCollection step state err a)
    -> Applicative (Builder collection mutCollection step state err)
    forall a. a -> Builder collection mutCollection step state err a
    forall a b.
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    forall a b.
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    forall a b.
    Builder collection mutCollection step state err (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    forall a b c.
    (a -> b -> c)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err c
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err.
    Monad state =>
    Functor (Builder collection mutCollection step state err)
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    Monad state =>
    a -> Builder collection mutCollection step state err a
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b c.
    Monad state =>
    (a -> b -> c)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err c
    forall (f :: * -> *).
    Functor f
    -> (forall a. a -> f a)
    -> (forall a b. f (a -> b) -> f a -> f b)
    -> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
    -> (forall a b. f a -> f b -> f b)
    -> (forall a b. f a -> f b -> f a)
    -> Applicative f
    $cpure :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    Monad state =>
    a -> Builder collection mutCollection step state err a
    pure :: forall a. a -> Builder collection mutCollection step state err a
    $c<*> :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    <*> :: forall a b.
    Builder collection mutCollection step state err (a -> b)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    $cliftA2 :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b c.
    Monad state =>
    (a -> b -> c)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err c
    liftA2 :: forall a b c.
    (a -> b -> c)
    -> Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err c
    $c*> :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    *> :: forall a b.
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    $c<* :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    <* :: forall a b.
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err a
    Applicative, Applicative (Builder collection mutCollection step state err)
    Applicative (Builder collection mutCollection step state err)
    -> (forall a b.
        Builder collection mutCollection step state err a
        -> (a -> Builder collection mutCollection step state err b)
        -> Builder collection mutCollection step state err b)
    -> (forall a b.
        Builder collection mutCollection step state err a
        -> Builder collection mutCollection step state err b
        -> Builder collection mutCollection step state err b)
    -> (forall a.
        a -> Builder collection mutCollection step state err a)
    -> Monad (Builder collection mutCollection step state err)
    forall a. a -> Builder collection mutCollection step state err a
    forall a b.
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    forall a b.
    Builder collection mutCollection step state err a
    -> (a -> Builder collection mutCollection step state err b)
    -> Builder collection mutCollection step state err b
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err.
    Monad state =>
    Applicative (Builder collection mutCollection step state err)
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    Monad state =>
    a -> Builder collection mutCollection step state err a
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> (a -> Builder collection mutCollection step state err b)
    -> Builder collection mutCollection step state err b
    forall (m :: * -> *).
    Applicative m
    -> (forall a b. m a -> (a -> m b) -> m b)
    -> (forall a b. m a -> m b -> m b)
    -> (forall a. a -> m a)
    -> Monad m
    $c>>= :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> (a -> Builder collection mutCollection step state err b)
    -> Builder collection mutCollection step state err b
    >>= :: forall a b.
    Builder collection mutCollection step state err a
    -> (a -> Builder collection mutCollection step state err b)
    -> Builder collection mutCollection step state err b
    $c>> :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a b.
    Monad state =>
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    >> :: forall a b.
    Builder collection mutCollection step state err a
    -> Builder collection mutCollection step state err b
    -> Builder collection mutCollection step state err b
    $creturn :: forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    Monad state =>
    a -> Builder collection mutCollection step state err a
    return :: forall a. a -> Builder collection mutCollection step state err a
    Monad)

    -- | The in-progress state of a building operation.
    --
    -- The previous buffers are in reverse order, and
    -- this contains the current buffer and the state of
    -- progress packing the elements inside.
    data BuildingState collection mutCollection step state = BuildingState
        { forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> [collection]
    prevChunks     :: [collection]
        , forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> CountOf step
    prevChunksSize :: !(CountOf step)
        , forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state
    -> mutCollection state
    curChunk       :: mutCollection state
        , forall collection (mutCollection :: * -> *) step state.
    BuildingState collection mutCollection step state -> CountOf step
    chunkSize      :: !(CountOf step)
        }

    instance Monad state => MonadFailure (Builder collection mutCollection step state err) where
        type Failure (Builder collection mutCollection step state err) = err
        mFail :: Failure (Builder collection mutCollection step state err)
    -> Builder collection mutCollection step state err ()
    mFail Failure (Builder collection mutCollection step state err)
    builderError = State
      (Offset step,
       BuildingState collection mutCollection step (PrimState state),
       Maybe err)
      state
      ()
    -> Builder collection mutCollection step state err ()
    forall collection (mutCollection :: * -> *) step (state :: * -> *)
           err a.
    State
      (Offset step,
       BuildingState collection mutCollection step (PrimState state),
       Maybe err)
      state
      a
    -> Builder collection mutCollection step state err a
    Builder (State
       (Offset step,
        BuildingState collection mutCollection step (PrimState state),
        Maybe err)
       state
       ()
     -> Builder collection mutCollection step state err ())
    -> State
         (Offset step,
          BuildingState collection mutCollection step (PrimState state),
          Maybe err)
         state
         ()
    -> Builder collection mutCollection step state err ()
    forall a b. (a -> b) -> a -> b
    $ ((Offset step,
      BuildingState collection mutCollection step (PrimState state),
      Maybe err)
     -> state
          ((),
           (Offset step,
            BuildingState collection mutCollection step (PrimState state),
            Maybe err)))
    -> State
         (Offset step,
          BuildingState collection mutCollection step (PrimState state),
          Maybe err)
         state
         ()
    forall s (m :: * -> *) a. (s -> m (a, s)) -> State s m a
    State (((Offset step,
       BuildingState collection mutCollection step (PrimState state),
       Maybe err)
      -> state
           ((),
            (Offset step,
             BuildingState collection mutCollection step (PrimState state),
             Maybe err)))
     -> State
          (Offset step,
           BuildingState collection mutCollection step (PrimState state),
           Maybe err)
          state
          ())
    -> ((Offset step,
         BuildingState collection mutCollection step (PrimState state),
         Maybe err)
        -> state
             ((),
              (Offset step,
               BuildingState collection mutCollection step (PrimState state),
               Maybe err)))
    -> State
         (Offset step,
          BuildingState collection mutCollection step (PrimState state),
          Maybe err)
         state
         ()
    forall a b. (a -> b) -> a -> b
    $ \(Offset step
    offset, BuildingState collection mutCollection step (PrimState state)
    bs, Maybe err
    _)  ->
            ((),
     (Offset step,
      BuildingState collection mutCollection step (PrimState state),
      Maybe err))
    -> state
         ((),
          (Offset step,
           BuildingState collection mutCollection step (PrimState state),
           Maybe err))
    forall a. a -> state a
    forall (m :: * -> *) a. Monad m => a -> m a
    return ((), (Offset step
    offset, BuildingState collection mutCollection step (PrimState state)
    bs, err -> Maybe err
    forall a. a -> Maybe a
    Just err
    Failure (Builder collection mutCollection step state err)
    builderError))