-- | For full documentation please refer to "Data.IORef".
module Data.IORef.Strict
  ( IORef'

    -- * Operations
  , newIORef'
  , readIORef'
  , writeIORef'
  , modifyIORef'
  , atomicModifyIORef'
  , atomicWriteIORef'
  , mkWeakIORef'
  ) where

import Control.DeepSeq
import Control.Exception (evaluate)
import GHC.Exts (mkWeak#)
import GHC.IO (IO(..))
import GHC.IORef (IORef(..))
import GHC.STRef (STRef(..))
import GHC.Weak (Weak(..))
import qualified Data.IORef as Base

-- | A strict (WHNF) variant of 'IORef'.
newtype IORef' a = IORef' (Base.IORef a)
  deriving (IORef' a -> IORef' a -> Bool
(IORef' a -> IORef' a -> Bool)
-> (IORef' a -> IORef' a -> Bool) -> Eq (IORef' a)
forall a. IORef' a -> IORef' a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. IORef' a -> IORef' a -> Bool
== :: IORef' a -> IORef' a -> Bool
$c/= :: forall a. IORef' a -> IORef' a -> Bool
/= :: IORef' a -> IORef' a -> Bool
Eq, IORef' a -> ()
(IORef' a -> ()) -> NFData (IORef' a)
forall a. IORef' a -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall a. IORef' a -> ()
rnf :: IORef' a -> ()
NFData, (forall a. (a -> ()) -> IORef' a -> ()) -> NFData1 IORef'
forall a. (a -> ()) -> IORef' a -> ()
forall (f :: * -> *).
(forall a. (a -> ()) -> f a -> ()) -> NFData1 f
$cliftRnf :: forall a. (a -> ()) -> IORef' a -> ()
liftRnf :: forall a. (a -> ()) -> IORef' a -> ()
NFData1)

-- | 'Base.newIORef' for 'IORef''.
--
-- Evaluates the initial value to WHNF.
newIORef' :: a -> IO (IORef' a)
newIORef' :: forall a. a -> IO (IORef' a)
newIORef' a
a = (IORef a -> IORef' a) -> IO (IORef a) -> IO (IORef' a)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IORef a -> IORef' a
forall a. IORef a -> IORef' a
IORef' (IO (IORef a) -> IO (IORef' a))
-> (a -> IO (IORef a)) -> a -> IO (IORef' a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> IO (IORef a)
forall a. a -> IO (IORef a)
Base.newIORef (a -> IO (IORef' a)) -> IO a -> IO (IORef' a)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO a
forall a. a -> IO a
evaluate a
a

-- | 'Base.readIORef' for 'IORef''.
readIORef' :: IORef' a -> IO a
readIORef' :: forall a. IORef' a -> IO a
readIORef' (IORef' IORef a
var) = IORef a -> IO a
forall a. IORef a -> IO a
Base.readIORef IORef a
var

-- | 'Base.writeIORef' for 'IORef''.
--
-- Evaluates the new value to WHNF.
writeIORef' :: IORef' a -> a -> IO ()
writeIORef' :: forall a. IORef' a -> a -> IO ()
writeIORef' (IORef' IORef a
var) a
a = IORef a -> a -> IO ()
forall a. IORef a -> a -> IO ()
Base.writeIORef IORef a
var (a -> IO ()) -> IO a -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO a
forall a. a -> IO a
evaluate a
a

-- | 'Base.modifyIORef' for 'IORef''.
modifyIORef' :: IORef' a -> (a -> a) -> IO ()
modifyIORef' :: forall a. IORef' a -> (a -> a) -> IO ()
modifyIORef' (IORef' IORef a
var) a -> a
f = IORef a -> (a -> a) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
Base.modifyIORef' IORef a
var a -> a
f

-- | 'Base.atomicModifyIORef' for 'IORef''.
--
-- Evaluates the new value to WHNF.
atomicModifyIORef' :: IORef' a -> (a -> (a, b)) -> IO b
atomicModifyIORef' :: forall a b. IORef' a -> (a -> (a, b)) -> IO b
atomicModifyIORef' (IORef' IORef a
var) a -> (a, b)
f = IORef a -> (a -> (a, b)) -> IO b
forall a b. IORef a -> (a -> (a, b)) -> IO b
Base.atomicModifyIORef' IORef a
var a -> (a, b)
f

-- | 'Base.atomicWriteIORef' for 'IORef''.
--
-- Evaluates the new value to WHNF.
atomicWriteIORef' :: IORef' a -> a -> IO ()
atomicWriteIORef' :: forall a. IORef' a -> a -> IO ()
atomicWriteIORef' (IORef' IORef a
var) a
a = IORef a -> a -> IO ()
forall a. IORef a -> a -> IO ()
Base.atomicWriteIORef IORef a
var (a -> IO ()) -> IO a -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> IO a
forall a. a -> IO a
evaluate a
a

-- | 'Base.mkWeakIORef' for 'IORef''.
mkWeakIORef' :: IORef' a -> IO () -> IO (Weak (IORef' a))
mkWeakIORef' :: forall a. IORef' a -> IO () -> IO (Weak (IORef' a))
mkWeakIORef' var :: IORef' a
var@(IORef' (IORef (STRef MutVar# RealWorld a
var#))) (IO State# RealWorld -> (# State# RealWorld, () #)
finalizer) = (State# RealWorld -> (# State# RealWorld, Weak (IORef' a) #))
-> IO (Weak (IORef' a))
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO ((State# RealWorld -> (# State# RealWorld, Weak (IORef' a) #))
 -> IO (Weak (IORef' a)))
-> (State# RealWorld -> (# State# RealWorld, Weak (IORef' a) #))
-> IO (Weak (IORef' a))
forall a b. (a -> b) -> a -> b
$ \State# RealWorld
s0 ->
  case MutVar# RealWorld a
-> IORef' a
-> (State# RealWorld -> (# State# RealWorld, () #))
-> State# RealWorld
-> (# State# RealWorld, Weak# (IORef' a) #)
forall a b c.
a
-> b
-> (State# RealWorld -> (# State# RealWorld, c #))
-> State# RealWorld
-> (# State# RealWorld, Weak# b #)
mkWeak# MutVar# RealWorld a
var# IORef' a
var State# RealWorld -> (# State# RealWorld, () #)
finalizer State# RealWorld
s0 of
    (# State# RealWorld
s1, Weak# (IORef' a)
w #) -> (# State# RealWorld
s1, Weak# (IORef' a) -> Weak (IORef' a)
forall v. Weak# v -> Weak v
Weak Weak# (IORef' a)
w #)