    -- | Unlifted "System.IO".
    --
    -- @since 0.1.0.0
    module UnliftIO.IO
      ( IOMode (..)
      , Handle
      , IO.stdin
      , IO.stdout
      , IO.stderr
      , withFile
      , withBinaryFile
      , openFile
      , hClose
      , hFlush
      , hFileSize
      , hSetFileSize
      , hIsEOF
      , IO.BufferMode (..)
      , hSetBuffering
      , hGetBuffering
      , hSeek
      , IO.SeekMode (..)
      , hTell
      , hIsOpen
      , hIsClosed
      , hIsReadable
      , hIsWritable
      , hIsSeekable
      , hIsTerminalDevice
      , hSetEcho
      , hGetEcho
      , hWaitForInput
      , hReady
      , getMonotonicTime
      ) where

    import qualified System.IO as IO
    import System.IO (Handle, IOMode (..))
    import Control.Monad.IO.Unlift

    import System.IO.Unsafe (unsafePerformIO)

    -- | Unlifted version of 'IO.withFile'.
    --
    -- @since 0.1.0.0
    withFile :: MonadUnliftIO m => FilePath -> IOMode -> (Handle -> m a) -> m a
    withFile :: forall (m :: * -> *) a.
    MonadUnliftIO m =>
    FilePath -> IOMode -> (Handle -> m a) -> m a
    withFile FilePath
    fp IOMode
    mode Handle -> m a
    inner = ((forall a. m a -> IO a) -> IO a) -> m 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 a) -> m a)
    -> ((forall a. m a -> IO a) -> IO a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run -> FilePath -> IOMode -> (Handle -> IO a) -> IO a
    forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
    IO.withFile FilePath
    fp IOMode
    mode ((Handle -> IO a) -> IO a) -> (Handle -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ m a -> IO a
    forall a. m a -> IO a
    run (m a -> IO a) -> (Handle -> m a) -> Handle -> IO a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Handle -> m a
    inner

    -- | Unlifted version of 'IO.withBinaryFile'.
    --
    -- @since 0.1.0.0
    withBinaryFile :: MonadUnliftIO m => FilePath -> IOMode -> (Handle -> m a) -> m a
    withBinaryFile :: forall (m :: * -> *) a.
    MonadUnliftIO m =>
    FilePath -> IOMode -> (Handle -> m a) -> m a
    withBinaryFile FilePath
    fp IOMode
    mode Handle -> m a
    inner = ((forall a. m a -> IO a) -> IO a) -> m 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 a) -> m a)
    -> ((forall a. m a -> IO a) -> IO a) -> m a
    forall a b. (a -> b) -> a -> b
    $ \forall a. m a -> IO a
    run -> FilePath -> IOMode -> (Handle -> IO a) -> IO a
    forall r. FilePath -> IOMode -> (Handle -> IO r) -> IO r
    IO.withBinaryFile FilePath
    fp IOMode
    mode ((Handle -> IO a) -> IO a) -> (Handle -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ m a -> IO a
    forall a. m a -> IO a
    run (m a -> IO a) -> (Handle -> m a) -> Handle -> IO a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Handle -> m a
    inner

    -- | Lifted version of 'IO.openFile'
    --
    -- @since 0.2.20
    openFile :: MonadIO m => FilePath -> IOMode -> m Handle
    openFile :: forall (m :: * -> *). MonadIO m => FilePath -> IOMode -> m Handle
    openFile FilePath
    fp = IO Handle -> m Handle
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Handle -> m Handle)
    -> (IOMode -> IO Handle) -> IOMode -> m Handle
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FilePath -> IOMode -> IO Handle
    IO.openFile FilePath
    fp

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

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

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

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

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

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

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

    -- | Lifted version of 'IO.hSeek'
    --
    -- @since 0.2.1.0
    hSeek :: MonadIO m => Handle -> IO.SeekMode -> Integer -> m ()
    hSeek :: forall (m :: * -> *).
    MonadIO m =>
    Handle -> SeekMode -> Integer -> m ()
    hSeek Handle
    h SeekMode
    s = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> (Integer -> IO ()) -> Integer -> m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Handle -> SeekMode -> Integer -> IO ()
    IO.hSeek Handle
    h SeekMode
    s

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

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

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

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

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

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

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

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

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

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

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

    -- | Get the number of seconds which have passed since an arbitrary starting
    -- time, useful for calculating runtime in a program.
    --
    -- @since 0.2.3.0
    getMonotonicTime :: MonadIO m => m Double
    getMonotonicTime :: forall (m :: * -> *). MonadIO m => m Double
    getMonotonicTime = IO Double -> m Double
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Double -> m Double) -> IO Double -> m Double
    forall a b. (a -> b) -> a -> b
    $ ()
    initted () -> IO Double -> IO Double
    forall a b. a -> b -> b
    `seq` IO Double
    getMonotonicTime'

    -- | Set up time measurement.
    foreign import ccall unsafe "unliftio_inittime" initializeTime :: IO ()

    initted :: ()
    initted :: ()
    initted = IO () -> ()
    forall a. IO a -> a
    unsafePerformIO IO ()
    initializeTime
    {-# NOINLINE initted #-}

    foreign import ccall unsafe "unliftio_gettime" getMonotonicTime' :: IO Double