-----------------------------------------------------------------------------
-- |
-- Module      :  Control.Concurrent.AdvSTM.TArray
-- Copyright   :  (c) Peter Robinson 2009,  The University of Glasgow 2004
-- License     :  BSD-style (see the file LICENSE)
-- 
-- Maintainer  :  Peter Robinson <thaldyron@gmail.com>
-- Stability   :  experimental
-- Portability :  non-portable (requires STM)
--
-- Corresponds to "Control.Concurrent.STM.TArray" 
--
-----------------------------------------------------------------------------



module Control.Concurrent.AdvSTM.TArray( TArray )
where
import Control.Monad.AdvSTM( MonadAdvSTM )
import Control.Concurrent.AdvSTM.TVar


import Control.Monad (replicateM)
import Data.Array (Array, bounds)
import Data.Array.Base (listArray, arrEleBottom, unsafeAt, MArray(..), IArray(numElements))
import Data.Ix (rangeSize)


-- |TArray is a transactional array, supporting the usual 'MArray'
-- interface for mutable arrays.


newtype TArray i e = TArray (Array i (TVar e))

instance MonadAdvSTM m => MArray TArray e m where
    getBounds (TArray a) = return (bounds a)
    newArray b e = do
        a <- replicateM (rangeSize b) (newTVar e)
        return $ TArray (listArray b a)
    newArray_ b = do
        a <- replicateM (rangeSize b) (newTVar arrEleBottom)
        return $ TArray (listArray b a)
    unsafeRead (TArray a) i = readTVar $ unsafeAt a i
    unsafeWrite (TArray a) i e = writeTVar (unsafeAt a i) e
    getNumElements (TArray a) = return (numElements a)