{-# LINE 1 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
{-|
module      :  Data.Number.Flint.Calcium.FFI
copyright   :  (c) 2023 Hartmut Monien
license     :  GNU GPL, version 2 or above (see LICENSE)
maintainer  :  hmonien@uni-bonn.de
-}
module Data.Number.Flint.Calcium.FFI (
  -- * Calcium
    CalciumStream (..)
  , CCalciumStream (..)
  , newCalciumStreamFile
  , newCalciumStreamStr
  , withCalciumStream
  , CCalciumFunctionCode (..)
  -- * Version
  , calcium_version
  -- * Triple-valued logic
  , t_true
  , t_false
  , t_unknown
  , CTruth (..)
  -- * Flint, Arb and Antic extras
  --, calcium_fmpz_hash
  , calcium_func_name
  -- * Input and output
  , calcium_stream_init_file
  , calcium_stream_init_str
  , calcium_write
  , calcium_write_free
  , calcium_write_si
  , calcium_write_fmpz
  , calcium_write_arb
  , calcium_write_acb
  -- * Function codes
  , ca_QQBar
  , ca_Neg
  , ca_Add
  , ca_Sub
  , ca_Mul
  , ca_Div
  , ca_Sqrt
  , ca_Cbrt
  , ca_Root
  , ca_Floor
  , ca_Ceil
  , ca_Abs
  , ca_Sign
  , ca_Re
  , ca_Im
  , ca_Arg
  , ca_Conjugate
  , ca_Pi
  , ca_Sin
  , ca_Cos
  , ca_Exp
  , ca_Log
  , ca_Pow
  , ca_Tan
  , ca_Cot
  , ca_Cosh
  , ca_Sinh
  , ca_Tanh
  , ca_Coth
  , ca_Atan
  , ca_Acos
  , ca_Asin
  , ca_Acot
  , ca_Atanh
  , ca_Acosh
  , ca_Asinh
  , ca_Acoth
  , ca_Euler
  , ca_Gamma
  , ca_LogGamma
  , ca_Psi
  , ca_Erf
  , ca_Erfc
  , ca_Erfi
  , ca_RiemannZeta
  , ca_HurwitzZeta
  , ca_FUNC_CODE_LENGTH
) where

-- Calcium ---------------------------------------------------------------------

import Foreign.C.Types
import Foreign.C.String
import Foreign.ForeignPtr
import Foreign.Ptr
import Foreign.Storable
import Foreign.Marshal.Alloc (free)

import Data.Number.Flint.Fmpz
import Data.Number.Flint.Arb.Types
import Data.Number.Flint.Acb.Types




-- calcium_stream_t ------------------------------------------------------------

data CalciumStream = CalciumStream {-# UNPACK #-} !(ForeignPtr CCalciumStream)
data CCalciumStream = CCalciumStream (Ptr CFile) CString CLong CLong

instance Storable CCalciumStream where
  {-# INLINE sizeOf #-}
  sizeOf :: CCalciumStream -> Int
sizeOf CCalciumStream
_ = (Int
32)
{-# LINE 108 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
  {-# INLINE alignment #-}
  alignment :: CCalciumStream -> Int
alignment CCalciumStream
_ = Int
8
{-# LINE 110 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
  peek ptr = CCalciumStream
    <$> (return $ castPtr ptr)
    <*> (\hsc_ptr -> peekByteOff hsc_ptr 8) ptr
{-# LINE 113 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
    <*> (\hsc_ptr -> peekByteOff hsc_ptr 16) ptr
{-# LINE 114 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
    <*> (\hsc_ptr -> peekByteOff hsc_ptr 24) ptr
{-# LINE 115 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
  poke ptr (CCalciumStream fp s len alloc) = do
    (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr fp
{-# LINE 117 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr s
{-# LINE 118 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 16) ptr len
{-# LINE 119 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
    (\hsc_ptr -> pokeByteOff hsc_ptr 24) ptr alloc
{-# LINE 120 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}
    
newCalciumStreamFile :: Ptr CFile -> IO CalciumStream
newCalciumStreamFile Ptr CFile
fp = do
  ForeignPtr CCalciumStream
p <- IO (ForeignPtr CCalciumStream)
forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr
  ForeignPtr CCalciumStream -> (Ptr CCalciumStream -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CCalciumStream
p ((Ptr CCalciumStream -> IO ()) -> IO ())
-> (Ptr CCalciumStream -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CCalciumStream
p -> do
    Ptr CCalciumStream -> Ptr CFile -> IO ()
calcium_stream_init_file Ptr CCalciumStream
p Ptr CFile
fp
  CalciumStream -> IO CalciumStream
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CalciumStream -> IO CalciumStream)
-> CalciumStream -> IO CalciumStream
forall a b. (a -> b) -> a -> b
$ ForeignPtr CCalciumStream -> CalciumStream
CalciumStream ForeignPtr CCalciumStream
p

newCalciumStreamStr :: p -> IO CalciumStream
newCalciumStreamStr p
s = do
  ForeignPtr CCalciumStream
p <- IO (ForeignPtr CCalciumStream)
forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr
  ForeignPtr CCalciumStream -> (Ptr CCalciumStream -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CCalciumStream
p ((Ptr CCalciumStream -> IO ()) -> IO ())
-> (Ptr CCalciumStream -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CCalciumStream
p -> do
    Ptr CCalciumStream -> IO ()
calcium_stream_init_str Ptr CCalciumStream
p
  CalciumStream -> IO CalciumStream
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CalciumStream -> IO CalciumStream)
-> CalciumStream -> IO CalciumStream
forall a b. (a -> b) -> a -> b
$ ForeignPtr CCalciumStream -> CalciumStream
CalciumStream ForeignPtr CCalciumStream
p
  
withCalciumStream :: CalciumStream
-> (Ptr CCalciumStream -> IO a) -> IO (CalciumStream, a)
withCalciumStream (CalciumStream ForeignPtr CCalciumStream
p) Ptr CCalciumStream -> IO a
f = do
  ForeignPtr CCalciumStream
-> (Ptr CCalciumStream -> IO (CalciumStream, a))
-> IO (CalciumStream, a)
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CCalciumStream
p ((Ptr CCalciumStream -> IO (CalciumStream, a))
 -> IO (CalciumStream, a))
-> (Ptr CCalciumStream -> IO (CalciumStream, a))
-> IO (CalciumStream, a)
forall a b. (a -> b) -> a -> b
$ \Ptr CCalciumStream
fp -> (ForeignPtr CCalciumStream -> CalciumStream
CalciumStream ForeignPtr CCalciumStream
p,) (a -> (CalciumStream, a)) -> IO a -> IO (CalciumStream, a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CCalciumStream -> IO a
f Ptr CCalciumStream
fp
  
-- Version ---------------------------------------------------------------------

-- | /calcium_version/ 
--
-- Returns a pointer to the version of the library as a string @X.Y.Z@.
foreign import ccall "calcium.h calcium_version"
  calcium_version :: IO CString

-- Triple-valued logic ---------------------------------------------------------

-- | Triple-valued logic
newtype CTruth = CTruth {CTruth -> CULong
_CTruth :: CULong} deriving CTruth -> CTruth -> Bool
(CTruth -> CTruth -> Bool)
-> (CTruth -> CTruth -> Bool) -> Eq CTruth
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CTruth -> CTruth -> Bool
== :: CTruth -> CTruth -> Bool
$c/= :: CTruth -> CTruth -> Bool
/= :: CTruth -> CTruth -> Bool
Eq

t_true     :: CTruth
t_true :: CTruth
t_true     = CULong -> CTruth
CTruth CULong
0
t_false    :: CTruth
t_false :: CTruth
t_false    = CULong -> CTruth
CTruth CULong
1
t_unknown  :: CTruth
t_unknown :: CTruth
t_unknown  = CULong -> CTruth
CTruth CULong
2

{-# LINE 154 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}

instance Show CTruth where
  show x
    | x == t_true    = "T_TRUE"
    | x == t_false   = "T_FALSE"
    | x == t_unknown = "T_UNKNOWN"
  
newtype CCalciumFunctionCode =
  CCalciumFunctionCode {CCalciumFunctionCode -> CULong
_CCalciumFunctionCode :: CULong} deriving (Int -> CCalciumFunctionCode -> ShowS
[CCalciumFunctionCode] -> ShowS
CCalciumFunctionCode -> String
(Int -> CCalciumFunctionCode -> ShowS)
-> (CCalciumFunctionCode -> String)
-> ([CCalciumFunctionCode] -> ShowS)
-> Show CCalciumFunctionCode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CCalciumFunctionCode -> ShowS
showsPrec :: Int -> CCalciumFunctionCode -> ShowS
$cshow :: CCalciumFunctionCode -> String
show :: CCalciumFunctionCode -> String
$cshowList :: [CCalciumFunctionCode] -> ShowS
showList :: [CCalciumFunctionCode] -> ShowS
Show, CCalciumFunctionCode -> CCalciumFunctionCode -> Bool
(CCalciumFunctionCode -> CCalciumFunctionCode -> Bool)
-> (CCalciumFunctionCode -> CCalciumFunctionCode -> Bool)
-> Eq CCalciumFunctionCode
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CCalciumFunctionCode -> CCalciumFunctionCode -> Bool
== :: CCalciumFunctionCode -> CCalciumFunctionCode -> Bool
$c/= :: CCalciumFunctionCode -> CCalciumFunctionCode -> Bool
/= :: CCalciumFunctionCode -> CCalciumFunctionCode -> Bool
Eq)

ca_QQBar  :: CCalciumFunctionCode
ca_QQBar :: CCalciumFunctionCode
ca_QQBar  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
0
ca_Neg  :: CCalciumFunctionCode
ca_Neg :: CCalciumFunctionCode
ca_Neg  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
1
ca_Add  :: CCalciumFunctionCode
ca_Add :: CCalciumFunctionCode
ca_Add  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
2
ca_Sub  :: CCalciumFunctionCode
ca_Sub :: CCalciumFunctionCode
ca_Sub  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
3
ca_Mul  :: CCalciumFunctionCode
ca_Mul :: CCalciumFunctionCode
ca_Mul  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
4
ca_Div  :: CCalciumFunctionCode
ca_Div :: CCalciumFunctionCode
ca_Div  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
5
ca_Sqrt  :: CCalciumFunctionCode
ca_Sqrt :: CCalciumFunctionCode
ca_Sqrt  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
6
ca_Cbrt  :: CCalciumFunctionCode
ca_Cbrt :: CCalciumFunctionCode
ca_Cbrt  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
7
ca_Root  :: CCalciumFunctionCode
ca_Root :: CCalciumFunctionCode
ca_Root  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
8
ca_Floor  :: CCalciumFunctionCode
ca_Floor :: CCalciumFunctionCode
ca_Floor  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
9
ca_Ceil  :: CCalciumFunctionCode
ca_Ceil :: CCalciumFunctionCode
ca_Ceil  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
10
ca_Abs  :: CCalciumFunctionCode
ca_Abs :: CCalciumFunctionCode
ca_Abs  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
11
ca_Sign  :: CCalciumFunctionCode
ca_Sign :: CCalciumFunctionCode
ca_Sign  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
12
ca_Re  :: CCalciumFunctionCode
ca_Re :: CCalciumFunctionCode
ca_Re  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
13
ca_Im  :: CCalciumFunctionCode
ca_Im :: CCalciumFunctionCode
ca_Im  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
14
ca_Arg  :: CCalciumFunctionCode
ca_Arg :: CCalciumFunctionCode
ca_Arg  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
15
ca_Conjugate  :: CCalciumFunctionCode
ca_Conjugate :: CCalciumFunctionCode
ca_Conjugate  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
16
ca_Pi  :: CCalciumFunctionCode
ca_Pi :: CCalciumFunctionCode
ca_Pi  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
17
ca_Sin  :: CCalciumFunctionCode
ca_Sin :: CCalciumFunctionCode
ca_Sin  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
18
ca_Cos  :: CCalciumFunctionCode
ca_Cos :: CCalciumFunctionCode
ca_Cos  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
19
ca_Exp  :: CCalciumFunctionCode
ca_Exp :: CCalciumFunctionCode
ca_Exp  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
20
ca_Log  :: CCalciumFunctionCode
ca_Log :: CCalciumFunctionCode
ca_Log  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
21
ca_Pow  :: CCalciumFunctionCode
ca_Pow :: CCalciumFunctionCode
ca_Pow  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
22
ca_Tan  :: CCalciumFunctionCode
ca_Tan :: CCalciumFunctionCode
ca_Tan  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
23
ca_Cot  :: CCalciumFunctionCode
ca_Cot :: CCalciumFunctionCode
ca_Cot  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
24
ca_Cosh  :: CCalciumFunctionCode
ca_Cosh :: CCalciumFunctionCode
ca_Cosh  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
25
ca_Sinh  :: CCalciumFunctionCode
ca_Sinh :: CCalciumFunctionCode
ca_Sinh  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
26
ca_Tanh  :: CCalciumFunctionCode
ca_Tanh :: CCalciumFunctionCode
ca_Tanh  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
27
ca_Coth  :: CCalciumFunctionCode
ca_Coth :: CCalciumFunctionCode
ca_Coth  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
28
ca_Atan  :: CCalciumFunctionCode
ca_Atan :: CCalciumFunctionCode
ca_Atan  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
29
ca_Acos  :: CCalciumFunctionCode
ca_Acos :: CCalciumFunctionCode
ca_Acos  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
30
ca_Asin  :: CCalciumFunctionCode
ca_Asin :: CCalciumFunctionCode
ca_Asin  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
31
ca_Acot  :: CCalciumFunctionCode
ca_Acot :: CCalciumFunctionCode
ca_Acot  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
32
ca_Atanh  :: CCalciumFunctionCode
ca_Atanh :: CCalciumFunctionCode
ca_Atanh  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
33
ca_Acosh  :: CCalciumFunctionCode
ca_Acosh :: CCalciumFunctionCode
ca_Acosh  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
34
ca_Asinh  :: CCalciumFunctionCode
ca_Asinh :: CCalciumFunctionCode
ca_Asinh  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
35
ca_Acoth  :: CCalciumFunctionCode
ca_Acoth :: CCalciumFunctionCode
ca_Acoth  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
36
ca_Euler  :: CCalciumFunctionCode
ca_Euler :: CCalciumFunctionCode
ca_Euler  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
37
ca_Gamma  :: CCalciumFunctionCode
ca_Gamma :: CCalciumFunctionCode
ca_Gamma  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
38
ca_LogGamma  :: CCalciumFunctionCode
ca_LogGamma :: CCalciumFunctionCode
ca_LogGamma  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
39
ca_Psi  :: CCalciumFunctionCode
ca_Psi :: CCalciumFunctionCode
ca_Psi  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
40
ca_Erf  :: CCalciumFunctionCode
ca_Erf :: CCalciumFunctionCode
ca_Erf  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
41
ca_Erfc  :: CCalciumFunctionCode
ca_Erfc :: CCalciumFunctionCode
ca_Erfc  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
42
ca_Erfi  :: CCalciumFunctionCode
ca_Erfi :: CCalciumFunctionCode
ca_Erfi  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
43
ca_RiemannZeta  :: CCalciumFunctionCode
ca_RiemannZeta :: CCalciumFunctionCode
ca_RiemannZeta  = CCalciumFunctionCode 44
ca_HurwitzZeta  :: CCalciumFunctionCode
ca_HurwitzZeta :: CCalciumFunctionCode
ca_HurwitzZeta  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
45
ca_FUNC_CODE_LENGTH  :: CCalciumFunctionCode
ca_FUNC_CODE_LENGTH :: CCalciumFunctionCode
ca_FUNC_CODE_LENGTH  = CULong -> CCalciumFunctionCode
CCalciumFunctionCode CULong
46

{-# LINE 213 "src/Data/Number/Flint/Calcium/FFI.hsc" #-}

-- Flint, Arb and Antic extras -------------------------------------------------

-- -- | /calcium_fmpz_hash/ /x/ 
--
-- -- Hash function for integers. The algorithm may change; presently, this
-- -- simply extracts the low word (with sign).
-- foreign import ccall "calcium.h calcium_fmpz_hash"
--   calcium_fmpz_hash :: Ptr CFmpz -> IO CULong

foreign import ccall "calcium.h calcium_stream_init_file"
  calcium_func_name :: CCalciumFunctionCode -> IO CString

-- Input and output ------------------------------------------------------------

-- | /calcium_stream_init_file/ /out/ /fp/ 
--
-- Initializes the stream /out/ for writing to the file /fp/. The file can
-- be /stdout/, /stderr/, or any file opened for writing by the user.
foreign import ccall "calcium.h calcium_stream_init_file"
  calcium_stream_init_file :: Ptr CCalciumStream -> Ptr CFile -> IO ()

-- | /calcium_stream_init_str/ /out/ 

-- Initializes the stream /out/ for writing to a string in memory. When
-- finished, the user should free the string (the /s/ member of /out/ with
-- @flint_free()@).
calcium_stream_init_str out = do
  cs <- newCString (replicate 16 '\0')
  poke out (CCalciumStream nullPtr cs 0 16)
  
-- | /calcium_write/ /out/ /s/ 
--
-- Writes the string /s/ to /out/.
foreign import ccall "calcium.h calcium_write"
  calcium_write :: Ptr CCalciumStream -> CString -> IO ()

-- | /calcium_write_free/ /out/ /s/ 
--
-- Writes /s/ to /out/ and then frees /s/ by calling @flint_free()@.
calcium_write_free :: Ptr CCalciumStream -> CString -> IO ()
calcium_write_free out s = do
  calcium_write out s
  free s
  
-- | /calcium_write_si/ /out/ /x/ 
foreign import ccall "calcium.h calcium_write_si"
  calcium_write_si :: Ptr CCalciumStream -> CLong -> IO ()
  
-- | /calcium_write_fmpz/ /out/ /x/ 
--
-- Writes the integer /x/ to /out/.
foreign import ccall "calcium.h calcium_write_fmpz"
  calcium_write_fmpz :: Ptr CCalciumStream
                     -> Ptr CFmpz -> IO ()

-- | /calcium_write_arb/ /out/ /z/ /digits/ /flags/ 
foreign import ccall "calcium.h calcium_write_arb"
  calcium_write_arb :: Ptr CCalciumStream
                    -> Ptr CArb -> CLong -> CULong -> IO ()
                    
-- | /calcium_write_acb/ /out/ /z/ /digits/ /flags/ 
--
-- Writes the Arb number /z/ to /out/, showing /digits/ digits and with the
-- display style specified by /flags/ (@ARB_STR_NO_RADIUS@, etc.).
foreign import ccall "calcium.h calcium_write_acb"
  calcium_write_acb :: Ptr CCalciumStream
  -> Ptr CAcb -> CLong -> CULong -> IO ()