{-|
Module:             STM.Base
Description:        Lifted STM operations.
Copyright:          © 2017 All rights reserved.
License:            GPL-3
Maintainer:         Evan Cofsky <evan@theunixman.com>
Stability:          experimental
Portability:        POSIX
-}

module STM.Base (
    module IO.Base,
    module Control.Concurrent.STM.TVar,
    module Control.Concurrent.STM.TMVar,
    module Control.Concurrent.STM.TBChan,
    STM,
    atomically,
    newTVarIO,
    newTMVarIO,
    newEmptyTMVarIO,
    newTBChanIO,
    newTBChan
    ) where

import Lawless
import IO.Base
import Control.Concurrent.STM (STM)
import qualified Control.Concurrent.STM as STM
import qualified Control.Concurrent.STM.TVar as TVar
import Control.Concurrent.STM.TVar (TVar, readTVar, writeTVar,  modifyTVar)
import qualified Control.Concurrent.STM.TMVar as TMVar
import Control.Concurrent.STM.TMVar (TMVar, readTMVar)
import qualified Control.Concurrent.STM.TBChan as TBChan
import Control.Concurrent.STM.TBChan (
    TBChan, readTBChan, writeTBChan, isEmptyTBChan
    )

-- | 'STM.atomically' lifted to 'MonadBase' 'IO'.
atomically :: MonadBase IO m => STM α -> m α
atomically = liftBase  STM.atomically

-- | 'newTVarIO' at the top level, lifted.
newTVarIO  MonadBase IO m  a  m (TVar a)
newTVarIO = liftBase  TVar.newTVarIO

-- | 'newTMVarIO' at the top level, lifted.
newTMVarIO  MonadBase IO m  a  m (TMVar a)
newTMVarIO = liftBase  TMVar.newTMVarIO

-- | 'newTMVarIO' at the top level, lifted.
newEmptyTMVarIO  MonadBase IO m  m (TMVar a)
newEmptyTMVarIO = liftBase TMVar.newEmptyTMVarIO

newtype BoundedLength = BoundedLength Word64
    deriving (Eq, Ord, Show, Bounded, Enum, Num, Integral, Real)

-- | 'newTBChanIO' at the top level, lifted, only with a saturated length.
newTBChanIO  (MonadBase IO m, Integral l)  l  m (TBChan a)
newTBChanIO =
    liftBase  TBChan.newTBChanIO  max 0  fromIntegral

newTBChan  Integral l  l  STM (TBChan a)
newTBChan = TBChan.newTBChan  max 0  fromIntegral