module Numeric.Netlib.ComfortArray.Utility (
   FortranIO,
   Util.run,
   Util.runChecked,
   Util.check,
   Util.assert,
   Util.ignore,
   Util.cint,
   Util.alloca,
   Util.allocaArray,
   Util.bool,
   Util.char,
   Util.string,
   Util.float,
   Util.double,
   Util.complexFloat,
   Util.complexDouble,
   Util.real,
   Util.complex,
   Util.number,

   ZeroInt,
   newArray,
   newArray1,
   newArray2,
   newArray3,
   freezeArray,
   sizes1,
   sizes2,
   sizes3,

   shapeSize,
   array,
   ioarray,
   (^!),
   ) where

import qualified Numeric.Netlib.Utility as Util
import Numeric.Netlib.Utility (FortranIO)

import qualified Data.Array.Comfort.Storable.Mutable.Unchecked as MutArray
import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable.Mutable (IOArray)
import Data.Array.Comfort.Storable (Array)

import qualified Foreign.C.Types as C
import Foreign.Storable (Storable)
import Foreign.ForeignPtr (withForeignPtr)
import Foreign.Ptr (Ptr)

import Control.Monad.Trans.Cont (ContT(ContT))



type ZeroInt = Shape.ZeroBased Int

newArray :: (Shape.C sh, Storable e) => sh -> IO (IOArray sh e)
newArray :: sh -> IO (IOArray sh e)
newArray sh
sh = sh -> (Ptr e -> IO ()) -> IO (IOArray sh e)
forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
sh -> (Ptr a -> IO ()) -> m (Array m sh a)
MutArray.unsafeCreate sh
sh (\Ptr e
_ -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

newArray1 :: (Storable e) => Int -> IO (IOArray ZeroInt e)
newArray1 :: Int -> IO (IOArray ZeroInt e)
newArray1 Int
m = ZeroInt -> IO (IOArray ZeroInt e)
forall sh e. (C sh, Storable e) => sh -> IO (IOArray sh e)
newArray (Int -> ZeroInt
forall n. n -> ZeroBased n
Shape.ZeroBased Int
m)

newArray2 :: (Storable e) => Int -> Int -> IO (IOArray (ZeroInt,ZeroInt) e)
newArray2 :: Int -> Int -> IO (IOArray (ZeroInt, ZeroInt) e)
newArray2 Int
m Int
n = (ZeroInt, ZeroInt) -> IO (IOArray (ZeroInt, ZeroInt) e)
forall sh e. (C sh, Storable e) => sh -> IO (IOArray sh e)
newArray (Int -> ZeroInt
forall n. n -> ZeroBased n
Shape.ZeroBased Int
m, Int -> ZeroInt
forall n. n -> ZeroBased n
Shape.ZeroBased Int
n)

newArray3 ::
   (Storable e) => Int -> Int -> Int -> IO (IOArray (ZeroInt,ZeroInt,ZeroInt) e)
newArray3 :: Int -> Int -> Int -> IO (IOArray (ZeroInt, ZeroInt, ZeroInt) e)
newArray3 Int
m Int
n Int
k =
   (ZeroInt, ZeroInt, ZeroInt)
-> IO (IOArray (ZeroInt, ZeroInt, ZeroInt) e)
forall sh e. (C sh, Storable e) => sh -> IO (IOArray sh e)
newArray (Int -> ZeroInt
forall n. n -> ZeroBased n
Shape.ZeroBased Int
m, Int -> ZeroInt
forall n. n -> ZeroBased n
Shape.ZeroBased Int
n, Int -> ZeroInt
forall n. n -> ZeroBased n
Shape.ZeroBased Int
k)


freezeArray :: (Shape.C sh, Storable e) => IOArray sh e -> IO (Array sh e)
freezeArray :: IOArray sh e -> IO (Array sh e)
freezeArray = IOArray sh e -> IO (Array sh e)
forall (m :: * -> *) sh a.
(PrimMonad m, C sh, Storable a) =>
Array m sh a -> m (Array sh a)
MutArray.unsafeFreeze


sizes1 :: (Shape.C sh0) => sh0 -> Int
sizes1 :: sh0 -> Int
sizes1 = sh0 -> Int
forall sh. C sh => sh -> Int
Shape.size

sizes2 :: (Shape.C sh0, Shape.C sh1) => (sh0,sh1) -> (Int,Int)
sizes2 :: (sh0, sh1) -> (Int, Int)
sizes2 (sh0
sh0,sh1
sh1) = (sh0 -> Int
forall sh. C sh => sh -> Int
Shape.size sh0
sh0, sh1 -> Int
forall sh. C sh => sh -> Int
Shape.size sh1
sh1)

sizes3 ::
   (Shape.C sh0, Shape.C sh1, Shape.C sh2) => (sh0,sh1,sh2) -> (Int,Int,Int)
sizes3 :: (sh0, sh1, sh2) -> (Int, Int, Int)
sizes3 (sh0
sh0,sh1
sh1,sh2
sh2) = (sh0 -> Int
forall sh. C sh => sh -> Int
Shape.size sh0
sh0, sh1 -> Int
forall sh. C sh => sh -> Int
Shape.size sh1
sh1, sh2 -> Int
forall sh. C sh => sh -> Int
Shape.size sh2
sh2)


shapeSize :: (Shape.C sh) => sh -> FortranIO r (Ptr C.CInt)
shapeSize :: sh -> FortranIO r (Ptr CInt)
shapeSize = Int -> FortranIO r (Ptr CInt)
forall r. Int -> FortranIO r (Ptr CInt)
Util.cint (Int -> FortranIO r (Ptr CInt))
-> (sh -> Int) -> sh -> FortranIO r (Ptr CInt)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sh -> Int
forall sh. C sh => sh -> Int
Shape.size

array :: (Storable a) => Array i a -> FortranIO r (Ptr a)
array :: Array i a -> FortranIO r (Ptr a)
array (Array.Array i
_sh ForeignPtr a
fptr) = ((Ptr a -> IO r) -> IO r) -> FortranIO r (Ptr a)
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr a -> IO r) -> IO r) -> FortranIO r (Ptr a))
-> ((Ptr a -> IO r) -> IO r) -> FortranIO r (Ptr a)
forall a b. (a -> b) -> a -> b
$ ForeignPtr a -> (Ptr a -> IO r) -> IO r
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr a
fptr

ioarray :: (Storable a) => IOArray i a -> FortranIO r (Ptr a)
ioarray :: IOArray i a -> FortranIO r (Ptr a)
ioarray = ((Ptr a -> IO r) -> IO r) -> FortranIO r (Ptr a)
forall k (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr a -> IO r) -> IO r) -> FortranIO r (Ptr a))
-> (IOArray i a -> (Ptr a -> IO r) -> IO r)
-> IOArray i a
-> FortranIO r (Ptr a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IOArray i a -> (Ptr a -> IO r) -> IO r
forall (m :: * -> *) sh a b.
PrimMonad m =>
Array m sh a -> (Ptr a -> IO b) -> m b
MutArray.withPtr


(^!) :: (Num a) => a -> Int -> a
a
x^! :: a -> Int -> a
^!Int
n = a
xa -> Int -> a
forall a b. (Num a, Integral b) => a -> b -> a
^Int
n