module Data.Array.Comfort.Storable.Internal.Monadic where

import qualified Data.Array.Comfort.Storable.Mutable.Private as MutArray
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable.Private (Array, unsafeFreeze)

import Foreign.Storable (Storable, )
import Foreign.Ptr (Ptr, )

import Control.Monad.Primitive (PrimMonad)
import Control.Monad.HT ((<=<))


unsafeCreate ::
   (PrimMonad m, Shape.C sh, Storable a) =>
   sh -> (Ptr a -> IO ()) -> m (Array sh a)
unsafeCreate sh = unsafeFreeze <=< MutArray.unsafeCreate sh

unsafeCreateWithSize ::
   (PrimMonad m, Shape.C sh, Storable a) =>
   sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)
unsafeCreateWithSize sh = unsafeFreeze <=< MutArray.unsafeCreateWithSize sh

unsafeCreateWithSizeAndResult ::
   (PrimMonad m, Shape.C sh, Storable a) =>
   sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b)
unsafeCreateWithSizeAndResult sh f = do
   (arr, b) <- MutArray.unsafeCreateWithSizeAndResult sh f
   marr <- unsafeFreeze arr
   return (marr, b)