{-# LANGUAGE UnboxedTuples #-}
module Streamly.Internal.Data.IORef.Prim
(
IORef
, Prim
, newIORef
, writeIORef
, modifyIORef'
, readIORef
, toStreamD
)
where
#include "inline.hs"
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Primitive (primitive_)
import Data.Primitive.Types (Prim, sizeOf#, readByteArray#, writeByteArray#)
import GHC.Exts (MutableByteArray#, newByteArray#, RealWorld)
import GHC.IO (IO(..))
import qualified Streamly.Internal.Data.Stream.StreamD.Type as D
data IORef a = IORef (MutableByteArray# RealWorld)
{-# INLINE newIORef #-}
newIORef :: forall a. Prim a => a -> IO (IORef a)
newIORef :: forall a. Prim a => a -> IO (IORef a)
newIORef a
x = forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO (\State# RealWorld
s# ->
case forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# (forall a. Prim a => a -> Int#
sizeOf# (forall a. HasCallStack => a
undefined :: a)) State# RealWorld
s# of
(# State# RealWorld
s1#, MutableByteArray# RealWorld
arr# #) ->
case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# RealWorld
arr# Int#
0# a
x State# RealWorld
s1# of
State# RealWorld
s2# -> (# State# RealWorld
s2#, forall a. MutableByteArray# RealWorld -> IORef a
IORef MutableByteArray# RealWorld
arr# #)
)
{-# INLINE writeIORef #-}
writeIORef :: Prim a => IORef a -> a -> IO ()
writeIORef :: forall a. Prim a => IORef a -> a -> IO ()
writeIORef (IORef MutableByteArray# RealWorld
arr#) a
x = forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ (forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# RealWorld
arr# Int#
0# a
x)
{-# INLINE readIORef #-}
readIORef :: Prim a => IORef a -> IO a
readIORef :: forall a. Prim a => IORef a -> IO a
readIORef (IORef MutableByteArray# RealWorld
arr#) = forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO (forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# RealWorld
arr# Int#
0#)
{-# INLINE modifyIORef' #-}
modifyIORef' :: Prim a => IORef a -> (a -> a) -> IO ()
modifyIORef' :: forall a. Prim a => IORef a -> (a -> a) -> IO ()
modifyIORef' (IORef MutableByteArray# RealWorld
arr#) a -> a
g = forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ forall a b. (a -> b) -> a -> b
$ \State# (PrimState IO)
s# ->
case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# RealWorld
arr# Int#
0# State# (PrimState IO)
s# of
(# State# RealWorld
s'#, a
a #) -> let a' :: a
a' = a -> a
g a
a in a
a' seq :: forall a b. a -> b -> b
`seq` forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# RealWorld
arr# Int#
0# a
a' State# RealWorld
s'#
{-# INLINE_NORMAL toStreamD #-}
toStreamD :: (MonadIO m, Prim a) => IORef a -> D.Stream m a
toStreamD :: forall (m :: * -> *) a.
(MonadIO m, Prim a) =>
IORef a -> Stream m a
toStreamD IORef a
var = forall (m :: * -> *) a s.
(State Stream m a -> s -> m (Step s a)) -> s -> Stream m a
D.Stream forall {m :: * -> *} {p}. MonadIO m => p -> () -> m (Step () a)
step ()
where
{-# INLINE_LATE step #-}
step :: p -> () -> m (Step () a)
step p
_ () = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (forall a. Prim a => IORef a -> IO a
readIORef IORef a
var) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \a
x -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall s a. a -> s -> Step s a
D.Yield a
x ()