{-# LANGUAGE MagicHash, UnboxedTuples #-}-- |-- Module : Data.Primitive.Array-- Copyright : (c) Roman Leshchinskiy 2009-- License : BSD-style---- Maintainer : Roman Leshchinskiy <rl@cse.unsw.edu.au>-- Portability : non-portable-- -- Primitive boxed arrays--moduleData.Primitive.Array(Array(..),MutableArray(..),newArray,readArray,writeArray,indexArray,indexArrayM,unsafeFreezeArray,unsafeThawArray,sameMutableArray)whereimportControl.Monad.PrimitiveimportGHC.Base(Int(..))importGHC.Prim-- | Boxed arraysdataArraya=Array(Array#a)-- | Mutable boxed arrays associated with a primitive state token.dataMutableArraysa=MutableArray(MutableArray#sa)-- | Create a new mutable array of the specified size and initialise all-- elements with the given value.newArray::PrimMonadm=>Int->a->m(MutableArray(PrimStatem)a){-# INLINE newArray #-}newArray(I#n#)x=primitive(\s#->casenewArray#n#xs#of(#s'#,arr##)->(#s'#,MutableArrayarr##))-- | Read a value from the array at the given index.readArray::PrimMonadm=>MutableArray(PrimStatem)a->Int->ma{-# INLINE readArray #-}readArray(MutableArrayarr#)(I#i#)=primitive(readArray#arr#i#)-- | Write a value to the array at the given index.writeArray::PrimMonadm=>MutableArray(PrimStatem)a->Int->a->m(){-# INLINE writeArray #-}writeArray(MutableArrayarr#)(I#i#)x=primitive_(writeArray#arr#i#x)-- | Read a value from the immutable array at the given index.indexArray::Arraya->Int->a{-# INLINE indexArray #-}indexArray(Arrayarr#)(I#i#)=caseindexArray#arr#i#of(#x#)->x-- | Monadically read a value from the immutable array at the given index.-- This allows us to be strict in the array while remaining lazy in the read-- element which is very useful for collective operations. Suppose we want to-- copy an array. We could do something like this:---- > copy marr arr ... = do ...-- > writeArray marr i (indexArray arr i) ...-- > ...---- But since primitive arrays are lazy, the calls to 'indexArray' will not be-- evaluated. Rather, @marr@ will be filled with thunks each of which would-- retain a reference to @arr@. This is definitely not what we want!---- With 'indexArrayM', we can instead write---- > copy marr arr ... = do ...-- > x <- indexArrayM arr i-- > writeArray marr i x-- > ...---- Now, indexing is executed immediately although the returned element is-- still not evaluated.--indexArrayM::Monadm=>Arraya->Int->ma{-# INLINE indexArrayM #-}indexArrayM(Arrayarr#)(I#i#)=caseindexArray#arr#i#of(#x#)->returnx-- | Convert a mutable array to an immutable one without copying. The-- array should not be modified after the conversion.unsafeFreezeArray::PrimMonadm=>MutableArray(PrimStatem)a->m(Arraya){-# INLINE unsafeFreezeArray #-}unsafeFreezeArray(MutableArrayarr#)=primitive(\s#->caseunsafeFreezeArray#arr#s#of(#s'#,arr'##)->(#s'#,Arrayarr'##))-- | Convert an immutable array to an mutable one without copying. The-- immutable array should not be used after the conversion.unsafeThawArray::PrimMonadm=>Arraya->m(MutableArray(PrimStatem)a){-# INLINE unsafeThawArray #-}unsafeThawArray(Arrayarr#)=primitive(\s#->caseunsafeThawArray#arr#s#of(#s'#,arr'##)->(#s'#,MutableArrayarr'##))-- | Check whether the two arrays refer to the same memory block.sameMutableArray::MutableArraysa->MutableArraysa->Bool{-# INLINE sameMutableArray #-}sameMutableArray(MutableArrayarr#)(MutableArraybrr#)=sameMutableArray#arr#brr#