{-# LANGUAGE CPP #-} {- | Module : Data.Ref.Unboxed Copyright : Copyright (C) 2006 Bulat Ziganshin License : BSD3 Maintainer : Bulat Ziganshin 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) INSTANCE_TYPEABLE1(IOURef,ioURefTc,"IOURef") -- | Create new unboxed reference in IO monad newIOURef :: (Unboxed a) => a -> IO (IOURef a) newIOURef init = do var <- allocUnboxed 1 writeUnboxed var 0 init 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 -- | Change value of unboxed reference in IO monad {-# INLINE writeIOURef #-} writeIOURef :: (Unboxed a) => IOURef a -> a -> IO () writeIOURef (IOURef ref) = writeUnboxed ref 0 -- |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) INSTANCE_TYPEABLE2(STURef,stURefTc,"STURef") -- | Create new unboxed reference in ST monad newSTURef :: (Unboxed a) => a -> ST s (STURef s a) newSTURef init = do var <- allocUnboxed 1 writeUnboxed var 0 init 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 -- | 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 -- |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