module MonadVar.Instances.TMVar where

import           MonadVar.Prelude
import           MonadVar.Classes
import           MonadVar.Default
import           Control.Concurrent.STM

instance MonadNew   STM TMVar where
  new :: a -> STM (TMVar a)
new = a -> STM (TMVar a)
forall a. a -> STM (TMVar a)
newTMVar
  {-# INLINE new #-}

instance MonadLock  STM TMVar where
  hold :: TMVar a -> STM a
hold     = TMVar a -> STM a
forall a. TMVar a -> STM a
takeTMVar
  {-# INLINE hold #-}

  fill :: TMVar a -> a -> STM ()
fill     = TMVar a -> a -> STM ()
forall a. TMVar a -> a -> STM ()
putTMVar
  {-# INLINE fill #-}

  tryHold :: TMVar a -> STM (Maybe a)
tryHold  = TMVar a -> STM (Maybe a)
forall a. TMVar a -> STM (Maybe a)
tryTakeTMVar
  {-# INLINE tryHold #-}

  tryFill :: TMVar a -> a -> STM Bool
tryFill  = TMVar a -> a -> STM Bool
forall a. TMVar a -> a -> STM Bool
tryPutTMVar
  {-# INLINE tryFill #-}

  tryRead :: TMVar a -> STM (Maybe a)
tryRead  = TMVar a -> STM (Maybe a)
forall a. TMVar a -> STM (Maybe a)
tryReadTMVar
  {-# INLINE tryRead #-}

  newEmpty :: STM (TMVar a)
newEmpty = STM (TMVar a)
forall a. STM (TMVar a)
newEmptyTMVar
  {-# INLINE newEmpty #-}

  isEmpty :: TMVar a -> STM Bool
isEmpty  = TMVar a -> STM Bool
forall a. TMVar a -> STM Bool
isEmptyTMVar
  {-# INLINE isEmpty #-}

instance MonadRead  STM TMVar where
  read :: TMVar a -> STM a
read = TMVar a -> STM a
forall a. TMVar a -> STM a
readTMVar
  {-# INLINE read #-}

instance MonadWrite STM TMVar where
  write :: TMVar a -> a -> STM ()
write = TMVar a -> a -> STM ()
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> a -> m ()
defaultLockUnsafeWrite
  {-# INLINE write #-}

instance MonadSwap  STM TMVar where
  swap :: TMVar a -> a -> STM a
swap = TMVar a -> a -> STM a
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> a -> m a
defaultLockUnsafeSwap
  {-# INLINE swap #-}

instance MonadMutate_ STM TMVar where
  mutate_ :: TMVar a -> (a -> a) -> STM ()
mutate_ = TMVar a -> (a -> a) -> STM ()
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> (a -> a) -> m ()
defaultLockUnsafeMutate_
  {-# INLINE mutate_ #-}

instance MonadMutate  STM TMVar where
  mutate :: TMVar a -> (a -> (a, b)) -> STM b
mutate = TMVar a -> (a -> (a, b)) -> STM b
forall (m :: * -> *) (v :: * -> *) a b.
MonadLock m v =>
v a -> (a -> (a, b)) -> m b
defaultLockUnsafeMutate
  {-# INLINE mutate #-}

instance STM ~ stm => MonadMutateM_ stm STM TMVar where
  mutateM_ :: TMVar a -> (a -> stm a) -> STM ()
mutateM_ = TMVar a -> (a -> stm a) -> STM ()
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> (a -> m a) -> m ()
defaultLockUnsafeMutateM_
  {-# INLINE mutateM_ #-}

instance STM ~ stm => MonadMutateM  stm STM TMVar where
  mutateM :: TMVar a -> (a -> stm (a, b)) -> STM b
mutateM = TMVar a -> (a -> stm (a, b)) -> STM b
forall (m :: * -> *) (v :: * -> *) a b.
MonadLock m v =>
v a -> (a -> m (a, b)) -> m b
defaultLockUnsafeMutateM
  {-# INLINE mutateM #-}

instance MonadNew   IO TMVar where
  new :: a -> IO (TMVar a)
new = a -> IO (TMVar a)
forall a. a -> IO (TMVar a)
newTMVarIO
  {-# INLINE new #-}

instance MonadLock  IO TMVar where
  hold :: TMVar a -> IO a
hold     = STM a -> IO a
forall a. STM a -> IO a
atomically (STM a -> IO a) -> (TMVar a -> STM a) -> TMVar a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM a
forall (m :: * -> *) (v :: * -> *) a. MonadLock m v => v a -> m a
hold
  {-# INLINE hold #-}

  fill :: TMVar a -> a -> IO ()
fill     = STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ())
-> (TMVar a -> a -> STM ()) -> TMVar a -> a -> IO ()
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> a -> STM ()
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> a -> m ()
fill
  {-# INLINE fill #-}

  tryHold :: TMVar a -> IO (Maybe a)
tryHold  = STM (Maybe a) -> IO (Maybe a)
forall a. STM a -> IO a
atomically (STM (Maybe a) -> IO (Maybe a))
-> (TMVar a -> STM (Maybe a)) -> TMVar a -> IO (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM (Maybe a)
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> m (Maybe a)
tryHold
  {-# INLINE tryHold #-}

  tryFill :: TMVar a -> a -> IO Bool
tryFill  = STM Bool -> IO Bool
forall a. STM a -> IO a
atomically (STM Bool -> IO Bool)
-> (TMVar a -> a -> STM Bool) -> TMVar a -> a -> IO Bool
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> a -> STM Bool
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> a -> m Bool
tryFill
  {-# INLINE tryFill #-}

  tryRead :: TMVar a -> IO (Maybe a)
tryRead  = STM (Maybe a) -> IO (Maybe a)
forall a. STM a -> IO a
atomically (STM (Maybe a) -> IO (Maybe a))
-> (TMVar a -> STM (Maybe a)) -> TMVar a -> IO (Maybe a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM (Maybe a)
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> m (Maybe a)
tryRead
  {-# INLINE tryRead #-}

  newEmpty :: IO (TMVar a)
newEmpty = IO (TMVar a)
forall a. IO (TMVar a)
newEmptyTMVarIO
  {-# INLINE newEmpty #-}

  isEmpty :: TMVar a -> IO Bool
isEmpty  = STM Bool -> IO Bool
forall a. STM a -> IO a
atomically (STM Bool -> IO Bool)
-> (TMVar a -> STM Bool) -> TMVar a -> IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM Bool
forall (m :: * -> *) (v :: * -> *) a.
MonadLock m v =>
v a -> m Bool
isEmpty
  {-# INLINE isEmpty #-}

instance MonadRead  IO TMVar where
  read :: TMVar a -> IO a
read = STM a -> IO a
forall a. STM a -> IO a
atomically (STM a -> IO a) -> (TMVar a -> STM a) -> TMVar a -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TMVar a -> STM a
forall (m :: * -> *) (v :: * -> *) a. MonadRead m v => v a -> m a
read
  {-# INLINE read #-}

instance MonadWrite IO TMVar where
  write :: TMVar a -> a -> IO ()
write = STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ())
-> (TMVar a -> a -> STM ()) -> TMVar a -> a -> IO ()
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> a -> STM ()
forall (m :: * -> *) (v :: * -> *) a.
MonadWrite m v =>
v a -> a -> m ()
write
  {-# INLINE write #-}

instance MonadSwap  IO TMVar where
  swap :: TMVar a -> a -> IO a
swap = STM a -> IO a
forall a. STM a -> IO a
atomically (STM a -> IO a) -> (TMVar a -> a -> STM a) -> TMVar a -> a -> IO a
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> a -> STM a
forall (m :: * -> *) (v :: * -> *) a.
MonadSwap m v =>
v a -> a -> m a
swap
  {-# INLINE swap #-}

instance MonadMutate_ IO TMVar where
  mutate_ :: TMVar a -> (a -> a) -> IO ()
mutate_ = STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ())
-> (TMVar a -> (a -> a) -> STM ()) -> TMVar a -> (a -> a) -> IO ()
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> (a -> a) -> STM ()
forall (m :: * -> *) (v :: * -> *) a.
MonadMutate_ m v =>
v a -> (a -> a) -> m ()
mutate_
  {-# INLINE mutate_ #-}

instance MonadMutate  IO TMVar where
  mutate :: TMVar a -> (a -> (a, b)) -> IO b
mutate = STM b -> IO b
forall a. STM a -> IO a
atomically (STM b -> IO b)
-> (TMVar a -> (a -> (a, b)) -> STM b)
-> TMVar a
-> (a -> (a, b))
-> IO b
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> (a -> (a, b)) -> STM b
forall (m :: * -> *) (v :: * -> *) a b.
MonadMutate m v =>
v a -> (a -> (a, b)) -> m b
mutate
  {-# INLINE mutate #-}

instance MonadMutateM_ STM IO TMVar where
  mutateM_ :: TMVar a -> (a -> STM a) -> IO ()
mutateM_ = STM () -> IO ()
forall a. STM a -> IO a
atomically (STM () -> IO ())
-> (TMVar a -> (a -> STM a) -> STM ())
-> TMVar a
-> (a -> STM a)
-> IO ()
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> (a -> STM a) -> STM ()
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a.
MonadMutateM_ f m v =>
v a -> (a -> f a) -> m ()
mutateM_
  {-# INLINE mutateM_ #-}

instance MonadMutateM  STM IO TMVar where
  mutateM :: TMVar a -> (a -> STM (a, b)) -> IO b
mutateM = STM b -> IO b
forall a. STM a -> IO a
atomically (STM b -> IO b)
-> (TMVar a -> (a -> STM (a, b)) -> STM b)
-> TMVar a
-> (a -> STM (a, b))
-> IO b
forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d
.* TMVar a -> (a -> STM (a, b)) -> STM b
forall (f :: * -> *) (m :: * -> *) (v :: * -> *) a b.
MonadMutateM f m v =>
v a -> (a -> f (a, b)) -> m b
mutateM
  {-# INLINE mutateM #-}

instance MonadMutateM_ IO  IO TMVar where
  mutateM_ :: TMVar a -> (a -> IO a) -> IO ()
mutateM_ = TMVar a -> (a -> IO a) -> IO ()
forall (v :: * -> *) a.
MonadLock IO v =>
v a -> (a -> IO a) -> IO ()
defaultLockIOMutateM_
  {-# INLINE mutateM_ #-}

instance MonadMutateM  IO  IO TMVar where
  mutateM :: TMVar a -> (a -> IO (a, b)) -> IO b
mutateM = TMVar a -> (a -> IO (a, b)) -> IO b
forall (v :: * -> *) a b.
MonadLock IO v =>
v a -> (a -> IO (a, b)) -> IO b
defaultLockIOMutateM
  {-# INLINE mutateM #-}