module Ouroboros.Consensus.Util.MonadSTM.NormalForm (
    module Control.Monad.Class.MonadSTM.Strict
  , module Ouroboros.Consensus.Util.MonadSTM.StrictMVar
  , newEmptyMVar
  , newMVar
  , newTVar
  , newTVarIO
    -- * Temporary
  , uncheckedNewEmptyMVar
  , uncheckedNewMVar
  , uncheckedNewTVarM
  ) where

import           GHC.Stack
import           NoThunks.Class (NoThunks (..), unsafeNoThunks)

import           Control.Monad.Class.MonadSTM.Strict hiding (newEmptyTMVarIO,
                     newTMVar, newTMVarIO, newTVar, newTVarIO,
                     newTVarWithInvariantIO)
import           Ouroboros.Consensus.Util.MonadSTM.StrictMVar hiding
                     (newEmptyMVar, newEmptyMVarWithInvariant, newMVar,
                     newMVarWithInvariant)

import qualified Control.Monad.Class.MonadSTM.Strict as Strict
import qualified Ouroboros.Consensus.Util.MonadSTM.StrictMVar as Strict

{-------------------------------------------------------------------------------
  Wrappers that check for thunks
-------------------------------------------------------------------------------}

newTVarIO :: (MonadSTM m, HasCallStack, NoThunks a)
          => a -> m (StrictTVar m a)
newTVarIO :: a -> m (StrictTVar m a)
newTVarIO = (a -> Maybe String) -> a -> m (StrictTVar m a)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> m (StrictTVar m a)
Strict.newTVarWithInvariantIO ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

newTVar :: (MonadSTM m, HasCallStack, NoThunks a)
          => a -> STM m (StrictTVar m a)
newTVar :: a -> STM m (StrictTVar m a)
newTVar = (a -> Maybe String) -> a -> STM m (StrictTVar m a)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> STM m (StrictTVar m a)
Strict.newTVarWithInvariant ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

newMVar :: (MonadSTM m, HasCallStack, NoThunks a)
        => a -> m (StrictMVar m a)
newMVar :: a -> m (StrictMVar m a)
newMVar = (a -> Maybe String) -> a -> m (StrictMVar m a)
forall (m :: * -> *) a.
(MonadSTM m, HasCallStack) =>
(a -> Maybe String) -> a -> m (StrictMVar m a)
Strict.newMVarWithInvariant ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

newEmptyMVar :: (MonadSTM m, NoThunks a) => a -> m (StrictMVar m a)
newEmptyMVar :: a -> m (StrictMVar m a)
newEmptyMVar = (a -> Maybe String) -> a -> m (StrictMVar m a)
forall (m :: * -> *) a.
MonadSTM m =>
(a -> Maybe String) -> a -> m (StrictMVar m a)
Strict.newEmptyMVarWithInvariant ((ThunkInfo -> String) -> Maybe ThunkInfo -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ThunkInfo -> String
forall a. Show a => a -> String
show (Maybe ThunkInfo -> Maybe String)
-> (a -> Maybe ThunkInfo) -> a -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Maybe ThunkInfo
forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks)

{-------------------------------------------------------------------------------
  Unchecked wrappers (where we don't check for thunks)

  These will eventually be removed.
-------------------------------------------------------------------------------}

uncheckedNewTVarM :: MonadSTM m => a -> m (StrictTVar m a)
uncheckedNewTVarM :: a -> m (StrictTVar m a)
uncheckedNewTVarM = a -> m (StrictTVar m a)
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictTVar m a)
Strict.newTVarIO

uncheckedNewMVar :: MonadSTM m => a -> m (StrictMVar m a)
uncheckedNewMVar :: a -> m (StrictMVar m a)
uncheckedNewMVar = a -> m (StrictMVar m a)
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictMVar m a)
Strict.newMVar

uncheckedNewEmptyMVar :: MonadSTM m => a -> m (StrictMVar m a)
uncheckedNewEmptyMVar :: a -> m (StrictMVar m a)
uncheckedNewEmptyMVar = a -> m (StrictMVar m a)
forall (m :: * -> *) a. MonadSTM m => a -> m (StrictMVar m a)
Strict.newEmptyMVar