{-# language RoleAnnotations #-}
{-# language ScopedTypeVariables #-}
{-# language MagicHash #-}
{-# language UnboxedTuples #-}
{-# language TypeFamilies #-}

module Data.Primitive.Unlifted.MutVar
  ( UnliftedMutVar_ (..)
  , UnliftedMutVar
  , newUnliftedMutVar
  , readUnliftedMutVar
  , writeUnliftedMutVar
  , modifyUnliftedMutVar
  , modifyUnliftedMutVar'
  , casUnliftedMutVar
  , atomicSwapUnliftedMutVar
  ) where
import Data.Primitive.Unlifted.Class (PrimUnlifted)
import Control.Monad.Primitive (PrimMonad (PrimState), stToPrim)
import qualified Data.Primitive.Unlifted.MutVar.ST as M
import Data.Primitive.Unlifted.MutVar.ST (UnliftedMutVar_ (..), UnliftedMutVar)

newUnliftedMutVar
  :: (PrimMonad m, PrimUnlifted a)
  => a -> m (UnliftedMutVar (PrimState m) a)
{-# INLINE newUnliftedMutVar #-}
newUnliftedMutVar :: a -> m (UnliftedMutVar (PrimState m) a)
newUnliftedMutVar a
a = ST (PrimState m) (UnliftedMutVar (PrimState m) a)
-> m (UnliftedMutVar (PrimState m) a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (UnliftedMutVar (PrimState m) a)
 -> m (UnliftedMutVar (PrimState m) a))
-> ST (PrimState m) (UnliftedMutVar (PrimState m) a)
-> m (UnliftedMutVar (PrimState m) a)
forall a b. (a -> b) -> a -> b
$ a -> ST (PrimState m) (UnliftedMutVar (PrimState m) a)
forall a s. PrimUnlifted a => a -> ST s (UnliftedMutVar s a)
M.newUnliftedMutVar a
a

readUnliftedMutVar
  :: (PrimMonad m, PrimUnlifted a)
  => UnliftedMutVar (PrimState m) a -> m a
{-# INLINE readUnliftedMutVar #-}
readUnliftedMutVar :: UnliftedMutVar (PrimState m) a -> m a
readUnliftedMutVar UnliftedMutVar (PrimState m) a
mv = ST (PrimState m) a -> m a
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) a -> m a) -> ST (PrimState m) a -> m a
forall a b. (a -> b) -> a -> b
$ UnliftedMutVar (PrimState m) a -> ST (PrimState m) a
forall a s. PrimUnlifted a => UnliftedMutVar s a -> ST s a
M.readUnliftedMutVar UnliftedMutVar (PrimState m) a
mv

writeUnliftedMutVar
  :: (PrimMonad m, PrimUnlifted a)
  => UnliftedMutVar (PrimState m) a -> a -> m ()
{-# INLINE writeUnliftedMutVar #-}
writeUnliftedMutVar :: UnliftedMutVar (PrimState m) a -> a -> m ()
writeUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a
a = ST (PrimState m) () -> m ()
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) () -> m ()) -> ST (PrimState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ UnliftedMutVar (PrimState m) a -> a -> ST (PrimState m) ()
forall a s. PrimUnlifted a => UnliftedMutVar s a -> a -> ST s ()
M.writeUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a
a

modifyUnliftedMutVar
  :: (PrimMonad m, PrimUnlifted a)
  => UnliftedMutVar (PrimState m) a -> (a -> a) -> m ()
{-# INLINE modifyUnliftedMutVar #-}
modifyUnliftedMutVar :: UnliftedMutVar (PrimState m) a -> (a -> a) -> m ()
modifyUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a -> a
f = ST (PrimState m) () -> m ()
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) () -> m ()) -> ST (PrimState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ UnliftedMutVar (PrimState m) a -> (a -> a) -> ST (PrimState m) ()
forall a s.
PrimUnlifted a =>
UnliftedMutVar s a -> (a -> a) -> ST s ()
M.modifyUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a -> a
f

modifyUnliftedMutVar'
  :: (PrimMonad m, PrimUnlifted a)
  => UnliftedMutVar (PrimState m) a -> (a -> a) -> m ()
{-# INLINE modifyUnliftedMutVar' #-}
modifyUnliftedMutVar' :: UnliftedMutVar (PrimState m) a -> (a -> a) -> m ()
modifyUnliftedMutVar' UnliftedMutVar (PrimState m) a
mv a -> a
f = ST (PrimState m) () -> m ()
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) () -> m ()) -> ST (PrimState m) () -> m ()
forall a b. (a -> b) -> a -> b
$ UnliftedMutVar (PrimState m) a -> (a -> a) -> ST (PrimState m) ()
forall a s.
PrimUnlifted a =>
UnliftedMutVar s a -> (a -> a) -> ST s ()
M.modifyUnliftedMutVar' UnliftedMutVar (PrimState m) a
mv a -> a
f

casUnliftedMutVar
  :: (PrimMonad m, PrimUnlifted a)
  => UnliftedMutVar (PrimState m) a   -- ^ The 'UnliftedMutVar' on which to operate
  -> a -- ^ The expected value
  -> a -- ^ The new value to install if the 'UnliftedMutVar contains the expected value
  -> m (Bool, a)
{-# INLINE casUnliftedMutVar #-}
casUnliftedMutVar :: UnliftedMutVar (PrimState m) a -> a -> a -> m (Bool, a)
casUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a
old a
new = ST (PrimState m) (Bool, a) -> m (Bool, a)
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) (Bool, a) -> m (Bool, a))
-> ST (PrimState m) (Bool, a) -> m (Bool, a)
forall a b. (a -> b) -> a -> b
$ UnliftedMutVar (PrimState m) a
-> a -> a -> ST (PrimState m) (Bool, a)
forall a s.
PrimUnlifted a =>
UnliftedMutVar s a -> a -> a -> ST s (Bool, a)
M.casUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a
old a
new

atomicSwapUnliftedMutVar
  :: (PrimMonad m, PrimUnlifted a)
  => UnliftedMutVar (PrimState m) a
  -> a
  -> m a
{-# INLINE atomicSwapUnliftedMutVar #-}
atomicSwapUnliftedMutVar :: UnliftedMutVar (PrimState m) a -> a -> m a
atomicSwapUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a
a = ST (PrimState m) a -> m a
forall (m :: * -> *) a. PrimMonad m => ST (PrimState m) a -> m a
stToPrim (ST (PrimState m) a -> m a) -> ST (PrimState m) a -> m a
forall a b. (a -> b) -> a -> b
$ UnliftedMutVar (PrimState m) a -> a -> ST (PrimState m) a
forall a s. PrimUnlifted a => UnliftedMutVar s a -> a -> ST s a
M.atomicSwapUnliftedMutVar UnliftedMutVar (PrimState m) a
mv a
a