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

import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable.Private (Array(Array))

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

import qualified Foreign.Marshal.Array.Guarded as Alloc
import Control.Monad.Primitive (PrimMonad, unsafeIOToPrim)
import Control.Monad (liftM)

import Data.Tuple.HT (mapFst)


unsafeCreate ::
   (PrimMonad m, Shape.C sh, Storable a) =>
   sh -> (Ptr a -> IO ()) -> m (Array sh a)
unsafeCreate :: forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> m (Array sh a)
unsafeCreate sh
sh Ptr a -> IO ()
f = sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)
forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)
unsafeCreateWithSize sh
sh ((Int -> Ptr a -> IO ()) -> m (Array sh a))
-> (Int -> Ptr a -> IO ()) -> m (Array sh a)
forall a b. (a -> b) -> a -> b
$ (Ptr a -> IO ()) -> Int -> Ptr a -> IO ()
forall a b. a -> b -> a
const Ptr a -> IO ()
f

unsafeCreateWithSize ::
   (PrimMonad m, Shape.C sh, Storable a) =>
   sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)
unsafeCreateWithSize :: forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a)
unsafeCreateWithSize sh
sh Int -> Ptr a -> IO ()
f = ((Array sh a, ()) -> Array sh a)
-> m (Array sh a, ()) -> m (Array sh a)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Array sh a, ()) -> Array sh a
forall a b. (a, b) -> a
fst (m (Array sh a, ()) -> m (Array sh a))
-> m (Array sh a, ()) -> m (Array sh a)
forall a b. (a -> b) -> a -> b
$ sh -> (Int -> Ptr a -> IO ()) -> m (Array sh a, ())
forall (m :: * -> *) sh a b.
(PrimMonad m, C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b)
unsafeCreateWithSizeAndResult sh
sh Int -> Ptr a -> IO ()
f

unsafeCreateWithSizeAndResult ::
   (PrimMonad m, Shape.C sh, Storable a) =>
   sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b)
unsafeCreateWithSizeAndResult :: forall (m :: * -> *) sh a b.
(PrimMonad m, C sh, Storable a) =>
sh -> (Int -> Ptr a -> IO b) -> m (Array sh a, b)
unsafeCreateWithSizeAndResult sh
sh Int -> Ptr a -> IO b
f = IO (Array sh a, b) -> m (Array sh a, b)
forall (m :: * -> *) a. PrimMonad m => IO a -> m a
unsafeIOToPrim (IO (Array sh a, b) -> m (Array sh a, b))
-> IO (Array sh a, b) -> m (Array sh a, b)
forall a b. (a -> b) -> a -> b
$
   let size :: Int
size = sh -> Int
forall sh. C sh => sh -> Int
Shape.size sh
sh
   in ((ForeignPtr a, b) -> (Array sh a, b))
-> IO (ForeignPtr a, b) -> IO (Array sh a, b)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((ForeignPtr a -> Array sh a)
-> (ForeignPtr a, b) -> (Array sh a, b)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (sh -> ForeignPtr a -> Array sh a
forall sh a. sh -> ForeignPtr a -> Array sh a
Array sh
sh)) (IO (ForeignPtr a, b) -> IO (Array sh a, b))
-> IO (ForeignPtr a, b) -> IO (Array sh a, b)
forall a b. (a -> b) -> a -> b
$ Int -> (Ptr a -> IO b) -> IO (ForeignPtr a, b)
forall a b.
Storable a =>
Int -> (Ptr a -> IO b) -> IO (ForeignPtr a, b)
Alloc.create Int
size ((Ptr a -> IO b) -> IO (ForeignPtr a, b))
-> (Ptr a -> IO b) -> IO (ForeignPtr a, b)
forall a b. (a -> b) -> a -> b
$ Int -> Ptr a -> IO b
f Int
size