    {-# LANGUAGE CPP #-}
    -- | Lifted version of "Control.Concurrent.STM"
    --
    -- @since 0.2.1.0
    module UnliftIO.STM
      ( -- * Core
        STM.STM
      , atomically
      , retrySTM
      , checkSTM
      , STM.orElse

        -- * TVar
      , STM.TVar
      , newTVarIO
      , readTVarIO
      , STM.newTVar
      , STM.readTVar
      , STM.writeTVar
      , STM.modifyTVar
      , STM.modifyTVar'
      , STM.stateTVar
      , STM.swapTVar
      , registerDelay
      , mkWeakTVar

        -- * TMVar
      , STM.TMVar
      , STM.newTMVar
      , STM.newEmptyTMVar
      , newTMVarIO
      , newEmptyTMVarIO
      , STM.takeTMVar
      , STM.putTMVar
      , STM.readTMVar
    #if MIN_VERSION_stm(2, 5, 1)
      , STM.writeTMVar
    #endif
      , STM.tryReadTMVar
      , STM.swapTMVar
      , STM.tryTakeTMVar
      , STM.tryPutTMVar
      , STM.isEmptyTMVar
      , mkWeakTMVar

        -- * TChan
      , STM.TChan
      , STM.newTChan
      , newTChanIO
      , STM.newBroadcastTChan
      , newBroadcastTChanIO
      , STM.dupTChan
      , STM.cloneTChan
      , STM.readTChan
      , STM.tryReadTChan
      , STM.peekTChan
      , STM.tryPeekTChan
      , STM.writeTChan
      , STM.unGetTChan
      , STM.isEmptyTChan

        -- * TQueue
      , STM.TQueue
      , STM.newTQueue
      , newTQueueIO
      , STM.readTQueue
      , STM.tryReadTQueue
      , STM.peekTQueue
      , STM.tryPeekTQueue
      , STM.writeTQueue
      , STM.unGetTQueue
      , STM.isEmptyTQueue

        -- * TBQueue
      , STM.TBQueue
      , STM.newTBQueue
      , newTBQueueIO
      , STM.readTBQueue
      , STM.tryReadTBQueue
      , STM.flushTBQueue
      , STM.peekTBQueue
      , STM.tryPeekTBQueue
      , STM.writeTBQueue
      , STM.unGetTBQueue
      , STM.lengthTBQueue
      , STM.isEmptyTBQueue
      , STM.isFullTBQueue
      ) where

    import Control.Concurrent.STM (STM, TVar, TMVar, TChan, TQueue, TBQueue)
    import qualified Control.Concurrent.STM as STM
    import Control.Monad.IO.Unlift
    import System.Mem.Weak (Weak)
    #if MIN_VERSION_base(4, 8, 0)
    import GHC.Natural (Natural)
    #else
    import Numeric.Natural (Natural)
    #endif

    -- | Lifted version of 'STM.atomically'
    --
    -- @since 0.2.1.0
    atomically :: MonadIO m => STM a -> m a
    atomically :: forall (m :: * -> *) a. MonadIO m => STM a -> m a
    atomically = IO a -> m a
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO a -> m a) -> (STM a -> IO a) -> STM a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . STM a -> IO a
    forall a. STM a -> IO a
    STM.atomically

    -- | Renamed 'STM.retry' for unqualified export
    --
    -- @since 0.2.1.0
    retrySTM :: STM a
    retrySTM :: forall a. STM a
    retrySTM = STM a
    forall a. STM a
    STM.retry

    -- | Renamed 'STM.check' for unqualified export
    --
    -- @since 0.2.1.0
    checkSTM :: Bool -> STM ()
    checkSTM :: Bool -> STM ()
    checkSTM = Bool -> STM ()
    STM.check

    -- | Lifted version of 'STM.newTVarIO'
    --
    -- @since 0.2.1.0
    newTVarIO :: MonadIO m => a -> m (TVar a)
    newTVarIO :: forall (m :: * -> *) a. MonadIO m => a -> m (TVar a)
    newTVarIO = IO (TVar a) -> m (TVar a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (TVar a) -> m (TVar a))
    -> (a -> IO (TVar a)) -> a -> m (TVar a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> IO (TVar a)
    forall a. a -> IO (TVar a)
    STM.newTVarIO

    -- | Lifted version of 'STM.readTVarIO'
    --
    -- @since 0.2.1.0
    readTVarIO :: MonadIO m => TVar a -> m a
    readTVarIO :: forall (m :: * -> *) a. MonadIO m => TVar a -> m a
    readTVarIO = IO a -> m a
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO a -> m a) -> (TVar a -> IO a) -> TVar a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TVar a -> IO a
    forall a. TVar a -> IO a
    STM.readTVarIO

    -- | Lifted version of 'STM.registerDelay'
    --
    -- @since 0.2.1.0
    registerDelay :: MonadIO m => Int -> m (TVar Bool)
    registerDelay :: forall (m :: * -> *). MonadIO m => Int -> m (TVar Bool)
    registerDelay = IO (TVar Bool) -> m (TVar Bool)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (TVar Bool) -> m (TVar Bool))
    -> (Int -> IO (TVar Bool)) -> Int -> m (TVar Bool)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> IO (TVar Bool)
    STM.registerDelay

    -- | Lifted version of 'STM.mkWeakTVar'
    --
    -- @since 0.2.1.0
    mkWeakTVar :: MonadUnliftIO m => TVar a -> m () -> m (Weak (TVar a))
    mkWeakTVar :: forall (m :: * -> *) a.
    MonadUnliftIO m =>
    TVar a -> m () -> m (Weak (TVar a))
    mkWeakTVar TVar a
    var m ()
    final = ((forall a. m a -> IO a) -> IO (Weak (TVar a)))
    -> m (Weak (TVar a))
    forall b. ((forall a. m a -> IO a) -> IO b) -> m b
    forall (m :: * -> *) b.
    MonadUnliftIO m =>
    ((forall a. m a -> IO a) -> IO b) -> m b
    withRunInIO (((forall a. m a -> IO a) -> IO (Weak (TVar a)))
     -> m (Weak (TVar a)))
    -> ((forall a. m a -> IO a) -> IO (Weak (TVar a)))
    -> m (Weak (TVar a))
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run -> TVar a -> IO () -> IO (Weak (TVar a))
    forall a. TVar a -> IO () -> IO (Weak (TVar a))
    STM.mkWeakTVar TVar a
    var (m () -> IO ()
    forall a. m a -> IO a
    run m ()
    final)

    -- | Lifted version of 'STM.newTMVarIO'
    --
    -- @since 0.2.1.0
    newTMVarIO :: MonadIO m => a -> m (TMVar a)
    newTMVarIO :: forall (m :: * -> *) a. MonadIO m => a -> m (TMVar a)
    newTMVarIO = IO (TMVar a) -> m (TMVar a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (TMVar a) -> m (TMVar a))
    -> (a -> IO (TMVar a)) -> a -> m (TMVar a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> IO (TMVar a)
    forall a. a -> IO (TMVar a)
    STM.newTMVarIO

    -- | Lifted version of 'STM.newEmptyTMVarIO'
    --
    -- @since 0.2.1.0
    newEmptyTMVarIO :: MonadIO m => m (TMVar a)
    newEmptyTMVarIO :: forall (m :: * -> *) a. MonadIO m => m (TMVar a)
    newEmptyTMVarIO = IO (TMVar a) -> m (TMVar a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO (TMVar a)
    forall a. IO (TMVar a)
    STM.newEmptyTMVarIO

    -- | Lifted version of 'STM.mkWeakTMVar'
    --
    -- @since 0.2.1.0
    mkWeakTMVar :: MonadUnliftIO m => TMVar a -> m () -> m (Weak (TMVar a))
    mkWeakTMVar :: forall (m :: * -> *) a.
    MonadUnliftIO m =>
    TMVar a -> m () -> m (Weak (TMVar a))
    mkWeakTMVar TMVar a
    var m ()
    final = ((forall a. m a -> IO a) -> IO (Weak (TMVar a)))
    -> m (Weak (TMVar a))
    forall b. ((forall a. m a -> IO a) -> IO b) -> m b
    forall (m :: * -> *) b.
    MonadUnliftIO m =>
    ((forall a. m a -> IO a) -> IO b) -> m b
    withRunInIO (((forall a. m a -> IO a) -> IO (Weak (TMVar a)))
     -> m (Weak (TMVar a)))
    -> ((forall a. m a -> IO a) -> IO (Weak (TMVar a)))
    -> m (Weak (TMVar a))
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run -> TMVar a -> IO () -> IO (Weak (TMVar a))
    forall a. TMVar a -> IO () -> IO (Weak (TMVar a))
    STM.mkWeakTMVar TMVar a
    var (m () -> IO ()
    forall a. m a -> IO a
    run m ()
    final)

    -- | Lifted version of 'STM.newTChanIO'
    --
    -- @since 0.2.1.0
    newTChanIO :: MonadIO m => m (TChan a)
    newTChanIO :: forall (m :: * -> *) a. MonadIO m => m (TChan a)
    newTChanIO = IO (TChan a) -> m (TChan a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO (TChan a)
    forall a. IO (TChan a)
    STM.newTChanIO

    -- | Lifted version of 'STM.newBroadcastTChanIO'
    --
    -- @since 0.2.1.0
    newBroadcastTChanIO :: MonadIO m => m (TChan a)
    newBroadcastTChanIO :: forall (m :: * -> *) a. MonadIO m => m (TChan a)
    newBroadcastTChanIO = IO (TChan a) -> m (TChan a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO (TChan a)
    forall a. IO (TChan a)
    STM.newBroadcastTChanIO

    -- | Lifted version of 'STM.newTQueueIO'
    --
    -- @since 0.2.1.0
    newTQueueIO :: MonadIO m => m (TQueue a)
    newTQueueIO :: forall (m :: * -> *) a. MonadIO m => m (TQueue a)
    newTQueueIO = IO (TQueue a) -> m (TQueue a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO IO (TQueue a)
    forall a. IO (TQueue a)
    STM.newTQueueIO

    -- | Lifted version of 'STM.newTBQueueIO'
    --
    -- @since 0.2.1.0
    #if MIN_VERSION_stm(2, 5, 0)
    newTBQueueIO :: MonadIO m => Natural -> m (TBQueue a)
    #else
    newTBQueueIO :: MonadIO m => Int -> m (TBQueue a)
    #endif
    newTBQueueIO :: forall (m :: * -> *) a. MonadIO m => Natural -> m (TBQueue a)
    newTBQueueIO = IO (TBQueue a) -> m (TBQueue a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (TBQueue a) -> m (TBQueue a))
    -> (Natural -> IO (TBQueue a)) -> Natural -> m (TBQueue a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Natural -> IO (TBQueue a)
    forall a. Natural -> IO (TBQueue a)
    STM.newTBQueueIO