@@ -0,0 +1,66 @@
1+{-# LANGUAGE BangPatterns #-}
2+{-# LANGUAGE ConstraintKinds #-}
4+{-# LANGUAGE ExistentialQuantification #-}
5+{-# LANGUAGE MagicHash #-}
6+{-# LANGUAGE RecordWildCards #-}
7+{-# LANGUAGE UnboxedTuples #-}
8+{-# LANGUAGE ScopedTypeVariables #-}
13+-- Module : Streamly.Internal.Mutable.Prim.Var
14+-- Copyright : (c) 2019 Composewell Technologies
17+-- Maintainer : streamly@composewell.com
18+-- Stability : experimental
21+-- A mutable variable in a mutable monad (IO/ST) holding a 'Prim' value. This
22+-- allows fast modification of a value.
24+module Streamly.Internal.Mutable.Prim.Var
40+import Control.Monad.Primitive (PrimMonad(..), primitive_)
41+import Data.Primitive.Types (Prim, sizeOf#, readByteArray#, writeByteArray#)
42+import GHC.Exts (MutableByteArray#, newByteArray#)
44+-- XXX use unlifted newtype?
46+-- | A 'Var' holds a single 'Prim' value.
47+data Var m a = Var (MutableByteArray# (PrimState m))
49+type MonadMut = PrimMonad
51+-- | Create a new mutable variable.
53+newVar :: forall m a. (MonadMut m, Prim a) => m (Var m a)
54+newVar = primitive (\s# ->
55+ case newByteArray# (sizeOf# (undefined :: a)) s# of
56+ (# s'#, arr# #) -> (# s'#, Var arr# #)
59+-- | Write a value to a mutable variable.
60+{-# INLINE writeVar #-}
61+writeVar :: (MonadMut m, Prim a) => Var m a -> a -> m ()
62+writeVar (Var arr#) x = primitive_ (writeByteArray# arr# 0# x)
64+{-# INLINE readVar #-}
65+readVar :: (MonadMut m, Prim a) => Var m a -> m a
66+readVar (Var arr#) = primitive (readByteArray# arr# 0#)