module Data.Array.IO.Internals (
    IOArray(..),         
    IOUArray(..),        
    castIOUArray,        
    unsafeThawIOUArray,
    unsafeFreezeIOUArray
  ) where
import Data.Int
import Data.Word
import Control.Monad.ST         ( RealWorld, stToIO )
import Foreign.Ptr              ( Ptr, FunPtr )
import Foreign.StablePtr        ( StablePtr )
import Data.Array.Base
import GHC.IOArray (IOArray(..))
newtype IOUArray i e = IOUArray (STUArray RealWorld i e)
type role IOUArray nominal nominal
instance Eq (IOUArray i e) where
    IOUArray s1 == IOUArray s2  =  s1 == s2
instance MArray IOUArray Bool IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Char IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Int IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Word IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray (Ptr a) IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray (FunPtr a) IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Float IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Double IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray (StablePtr a) IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Int8 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Int16 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Int32 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Int64 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Word8 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Word16 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Word32 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
instance MArray IOUArray Word64 IO where
    
    getBounds (IOUArray arr) = stToIO $ getBounds arr
    
    getNumElements (IOUArray arr) = stToIO $ getNumElements arr
    
    newArray lu initialValue = stToIO $ do
        marr <- newArray lu initialValue; return (IOUArray marr)
    
    unsafeNewArray_ lu = stToIO $ do
        marr <- unsafeNewArray_ lu; return (IOUArray marr)
    
    newArray_ = unsafeNewArray_
    
    unsafeRead (IOUArray marr) i = stToIO (unsafeRead marr i)
    
    unsafeWrite (IOUArray marr) i e = stToIO (unsafeWrite marr i e)
castIOUArray :: IOUArray ix a -> IO (IOUArray ix b)
castIOUArray (IOUArray marr) = stToIO $ do
    marr' <- castSTUArray marr
    return (IOUArray marr')
unsafeThawIOUArray :: UArray ix e -> IO (IOUArray ix e)
unsafeThawIOUArray arr = stToIO $ do
    marr <- unsafeThawSTUArray arr
    return (IOUArray marr)
thawIOUArray :: UArray ix e -> IO (IOUArray ix e)
thawIOUArray arr = stToIO $ do
    marr <- thawSTUArray arr
    return (IOUArray marr)
unsafeFreezeIOUArray :: IOUArray ix e -> IO (UArray ix e)
unsafeFreezeIOUArray (IOUArray marr) = stToIO (unsafeFreezeSTUArray marr)
freezeIOUArray :: IOUArray ix e -> IO (UArray ix e)
freezeIOUArray (IOUArray marr) = stToIO (freezeSTUArray marr)