ArrayRef-0.1.2: Data/Ref/Unboxed.hs
{-# LANGUAGE CPP #-}
{- |
Module : Data.Ref.Unboxed
Copyright : Copyright (C) 2006 Bulat Ziganshin
License : BSD3
Maintainer : Bulat Ziganshin <Bulat.Ziganshin@gmail.com>
Stability : experimental
Portability: GHC/Hugs
Unboxed references
Based on the idea of Oleg Kiselyov
(see http://www.haskell.org/pipermail/haskell-cafe/2004-July/006400.html)
-}
module Data.Ref.Unboxed where
import Control.Monad.ST (ST)
import Data.Typeable
#include "Typeable.h"
import Control.Monad.STorIO
import Data.Unboxed
-- -----------------------------------------------------------------------------
-- | Unboxed references in IO monad
newtype IOURef a = IOURef (IOSpecific2 MUVec a)
ioURefTc :: TyCon
INSTANCE_TYPEABLE1(IOURef,ioURefTc,"IOURef")
-- | Create new unboxed reference in IO monad
newIOURef :: (Unboxed a) => a -> IO (IOURef a)
newIOURef initial = do var <- allocUnboxed (1::Int)
writeUnboxed var (0::Int) initial
return (IOURef var)
-- | Read current value of unboxed reference in IO monad
{-# INLINE readIOURef #-}
readIOURef :: (Unboxed a) => IOURef a -> IO a
readIOURef (IOURef ref) = readUnboxed ref (0::Int)
-- | Change value of unboxed reference in IO monad
{-# INLINE writeIOURef #-}
writeIOURef :: (Unboxed a) => IOURef a -> a -> IO ()
writeIOURef (IOURef ref) = writeUnboxed ref (0::Int)
-- |Modify contents of an 'IOURef' by applying pure function to it
{-# INLINE modifyIOURef #-}
modifyIOURef :: (Unboxed a) => IOURef a -> (a -> a) -> IO ()
modifyIOURef ref f = readIOURef ref >>= writeIOURef ref . f
-- -----------------------------------------------------------------------------
-- | Unboxed references in ST monad
newtype STURef s a = STURef (MUVec s a)
stURefTc :: TyCon
INSTANCE_TYPEABLE2(STURef,stURefTc,"STURef")
-- | Create new unboxed reference in ST monad
newSTURef :: (Unboxed a) => a -> ST s (STURef s a)
newSTURef initial = do var <- allocUnboxed (1::Int)
writeUnboxed var (0::Int) initial
return (STURef var)
-- | Read current value of unboxed reference in ST monad
{-# INLINE readSTURef #-}
readSTURef :: (Unboxed a) => STURef s a -> ST s a
readSTURef (STURef ref) = readUnboxed ref (0::Int)
-- | Change value of unboxed reference in ST monad
{-# INLINE writeSTURef #-}
writeSTURef :: (Unboxed a) => STURef s a -> a -> ST s ()
writeSTURef (STURef ref) = writeUnboxed ref (0::Int)
-- |Modify contents of an 'STURef' by applying pure function to it
{-# INLINE modifySTURef #-}
modifySTURef :: (Unboxed a) => STURef s a -> (a -> a) -> ST s ()
modifySTURef ref f = readSTURef ref >>= writeSTURef ref . f