{-# INCLUDE <chsmpfr.h> #-}
{-# INCLUDE <mpfr.h> #-}
{-# LINE 1 "Data/Number/MPFR/FFIhelper.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable #-}
{-# LINE 2 "Data/Number/MPFR/FFIhelper.hsc" #-}

{-# LINE 3 "Data/Number/MPFR/FFIhelper.hsc" #-}

{-# LINE 4 "Data/Number/MPFR/FFIhelper.hsc" #-}

module Data.Number.MPFR.FFIhelper where

import Data.Word

import Data.Int

import Foreign.C.String(CString)
import Foreign.C.Types(CULong, CLong, CInt, CUInt, CDouble, CChar)
import Foreign.Ptr(FunPtr, Ptr)
import Foreign.Marshal(alloca)
import Foreign.Storable
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr, mallocForeignPtrBytes)

import Data.Typeable(Typeable)

data RoundMode = Near | Zero | Up | Down | GMP_RND_MAX | GMP_RNDNA 

instance Enum RoundMode where
    fromEnum Near        = 0 
{-# LINE 24 "Data/Number/MPFR/FFIhelper.hsc" #-}
    fromEnum Zero        = 1 
{-# LINE 25 "Data/Number/MPFR/FFIhelper.hsc" #-}
    fromEnum Up          = 2 
{-# LINE 26 "Data/Number/MPFR/FFIhelper.hsc" #-}
    fromEnum Down        = 3 
{-# LINE 27 "Data/Number/MPFR/FFIhelper.hsc" #-}
    fromEnum GMP_RND_MAX = 4
{-# LINE 28 "Data/Number/MPFR/FFIhelper.hsc" #-}
    fromEnum GMP_RNDNA   = -1
{-# LINE 29 "Data/Number/MPFR/FFIhelper.hsc" #-}
    
    toEnum 0    = Near
{-# LINE 31 "Data/Number/MPFR/FFIhelper.hsc" #-}
    toEnum 1    = Zero
{-# LINE 32 "Data/Number/MPFR/FFIhelper.hsc" #-}
    toEnum 2    = Up
{-# LINE 33 "Data/Number/MPFR/FFIhelper.hsc" #-}
    toEnum 3    = Down
{-# LINE 34 "Data/Number/MPFR/FFIhelper.hsc" #-}
    toEnum 4 = GMP_RND_MAX
{-# LINE 35 "Data/Number/MPFR/FFIhelper.hsc" #-}
    toEnum (-1) = GMP_RNDNA
{-# LINE 36 "Data/Number/MPFR/FFIhelper.hsc" #-}
    toEnum i                    = error $ "RoundMode.toEnum called with illegal argument :" ++ show i 


data MPFR = MP { precision :: {-# UNPACK #-} !CPrecision,
                 sign :: {-# UNPACK #-} !Sign,
                 exponent :: {-# UNPACK #-} !Exp,
                 limbs :: {-# UNPACK #-} !(ForeignPtr Limb)
} deriving (Typeable)

instance Storable MPFR where
    sizeOf _ = (16)
{-# LINE 47 "Data/Number/MPFR/FFIhelper.hsc" #-}
    alignment _ = alignment (undefined :: Word32)
{-# LINE 48 "Data/Number/MPFR/FFIhelper.hsc" #-}
    peek = error "MPFR.peek: Not needed and not applicable"
    poke p (MP prec s e fp) = do (\hsc_ptr -> pokeByteOff hsc_ptr 0) p prec
{-# LINE 50 "Data/Number/MPFR/FFIhelper.hsc" #-}
                                 (\hsc_ptr -> pokeByteOff hsc_ptr 4) p s 
{-# LINE 51 "Data/Number/MPFR/FFIhelper.hsc" #-}
                                 (\hsc_ptr -> pokeByteOff hsc_ptr 8) p e
{-# LINE 52 "Data/Number/MPFR/FFIhelper.hsc" #-}
                                 withForeignPtr fp $ \p1 -> (\hsc_ptr -> pokeByteOff hsc_ptr 12) p p1
{-# LINE 53 "Data/Number/MPFR/FFIhelper.hsc" #-}

{-# INLINE peekP #-}
peekP      :: Ptr MPFR -> ForeignPtr Limb -> IO MPFR
peekP p fp = do r11 <- (\hsc_ptr -> peekByteOff hsc_ptr 0) p
{-# LINE 57 "Data/Number/MPFR/FFIhelper.hsc" #-}
                r21 <- (\hsc_ptr -> peekByteOff hsc_ptr 4) p
{-# LINE 58 "Data/Number/MPFR/FFIhelper.hsc" #-}
                r22 <- (\hsc_ptr -> peekByteOff hsc_ptr 8) p
{-# LINE 59 "Data/Number/MPFR/FFIhelper.hsc" #-}
                return (MP r11 r21 r22 fp)
{-# INLINE withDummy #-}
withDummy     :: Word -> (Ptr MPFR -> IO CInt) -> IO (MPFR, Int)
withDummy w f = do alloca $ \ptr -> do
                      ls <- mpfr_custom_get_size (fromIntegral w)
                      fp <- mallocForeignPtrBytes (fromIntegral ls)
                      (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr (fromIntegral w :: CPrecision)
{-# LINE 66 "Data/Number/MPFR/FFIhelper.hsc" #-}
                      (\hsc_ptr -> pokeByteOff hsc_ptr 4) ptr (1 :: Sign) 
{-# LINE 67 "Data/Number/MPFR/FFIhelper.hsc" #-}
                      (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr (0 :: Exp)
{-# LINE 68 "Data/Number/MPFR/FFIhelper.hsc" #-}
                      withForeignPtr fp $ \p1 -> (\hsc_ptr -> pokeByteOff hsc_ptr 12) ptr p1
{-# LINE 69 "Data/Number/MPFR/FFIhelper.hsc" #-}
                      r2 <- f ptr
                      r1 <- peekP ptr fp
                      return (r1, fromIntegral r2)

{-# INLINE pokeDummy #-}
pokeDummy          :: Ptr MPFR -> ForeignPtr Limb -> Word -> IO ()
pokeDummy ptr fp p = do (\hsc_ptr -> pokeByteOff hsc_ptr 0) ptr (fromIntegral p :: CPrecision)
{-# LINE 76 "Data/Number/MPFR/FFIhelper.hsc" #-}
                        (\hsc_ptr -> pokeByteOff hsc_ptr 4) ptr (0 :: Sign) 
{-# LINE 77 "Data/Number/MPFR/FFIhelper.hsc" #-}
                        (\hsc_ptr -> pokeByteOff hsc_ptr 8) ptr (0 :: Exp)
{-# LINE 78 "Data/Number/MPFR/FFIhelper.hsc" #-}
                        withForeignPtr fp $ \p1 -> (\hsc_ptr -> pokeByteOff hsc_ptr 12) ptr p1
{-# LINE 79 "Data/Number/MPFR/FFIhelper.hsc" #-}

bitsPerMPLimb :: Int 
bitsPerMPLimb = 8 * (4)
{-# LINE 82 "Data/Number/MPFR/FFIhelper.hsc" #-}

bitsPerIntegerLimb :: Int
bitsPerIntegerLimb = bitsPerMPLimb

expZero :: Exp
expZero = -2147483647
{-# LINE 88 "Data/Number/MPFR/FFIhelper.hsc" #-}

expNaN :: Exp
expNaN = -2147483646
{-# LINE 91 "Data/Number/MPFR/FFIhelper.hsc" #-}

expInf :: Exp
expInf = -2147483645
{-# LINE 94 "Data/Number/MPFR/FFIhelper.hsc" #-}


type CRoundMode = CInt

type Limb = Word32
{-# LINE 99 "Data/Number/MPFR/FFIhelper.hsc" #-}

type Sign = Int32
{-# LINE 101 "Data/Number/MPFR/FFIhelper.hsc" #-}

type CPrecision = Word32
{-# LINE 103 "Data/Number/MPFR/FFIhelper.hsc" #-}

type Exp = Int32
{-# LINE 105 "Data/Number/MPFR/FFIhelper.hsc" #-}

type MpSize = Int32
{-# LINE 107 "Data/Number/MPFR/FFIhelper.hsc" #-}

-- utility functions from chsmpfr.h
foreign import ccall unsafe "initS"
        initS :: CPrecision -> IO (Ptr MPFR)

foreign import ccall unsafe "&clear"
        clear :: FunPtr (Ptr MPFR -> IO ())

--------------------
foreign import ccall unsafe "mpfr_get_prec_wrap"
        mpfr_get_prec :: Ptr MPFR -> IO CPrecision 

----------------------------------------------------------------

-- assignment functions
foreign import ccall unsafe "mpfr_set_wrap"
        mpfr_set :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_set_ui_wrap"
        mpfr_set_ui :: Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_set_si_wrap"
        mpfr_set_si :: Ptr MPFR -> CLong -> CRoundMode -> IO CInt

--TODO set_uj, set_sj

foreign import ccall unsafe "mpfr_set_d"
        mpfr_set_d :: Ptr MPFR -> CDouble -> CRoundMode -> IO CInt

--foreign import ccall unsafe "mfpr_set_ld"
  --      mpfr_set_ld :: Ptr MPFR -> #{type long double} -> CRoundMode -> IO CInt
--long double does not seem to be supported

--TODO set_decimal64, set_z, set_q, set_f

foreign import ccall unsafe "mpfr_set_ui_2exp"
        mpfr_set_ui_2exp :: Ptr MPFR -> CULong -> Exp -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_set_si_2exp"
        mpfr_set_si_2exp :: Ptr MPFR -> CLong -> Exp -> CRoundMode -> IO CInt

--TODO set_uj_2exp, set_sj_2exp

foreign import ccall unsafe "mpfr_set_str"
        mpfr_set_str :: Ptr MPFR -> CString -> CInt -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_strtofr"
        mpfr_strtofr :: Ptr MPFR  ->  CString -> Ptr (Ptr CChar) -> CInt -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_set_inf"
        mpfr_set_inf :: Ptr MPFR -> CInt -> IO ()

foreign import ccall unsafe "mpfr_set_nan"
        mpfr_set_nan :: Ptr MPFR -> IO ()

foreign import ccall unsafe "mpfr_swap"
        mpfr_swap :: Ptr MPFR -> Ptr MPFR -> IO ()

-- THINK combined initialization and assignment functions are non-applicable
-- with custom interface?

--------------------------------------------------------------------------------


-- conversion functions
foreign import ccall unsafe "mpfr_get_d"
        mpfr_get_d :: Ptr MPFR -> CRoundMode -> IO CDouble

-- TODO get_decimal64

foreign import ccall unsafe "mpfr_get_d_2exp"
        mpfr_get_d_2exp :: Ptr CLong -> Ptr MPFR -> CRoundMode -> IO CDouble

-- TODO get_ld_2exp
-- !!!!!!! next 4 set erange flags
foreign import ccall unsafe "mpfr_get_si" 
        mpfr_get_si :: Ptr MPFR -> CRoundMode -> IO CLong

foreign import ccall unsafe "mpfr_get_ui" 
        mpfr_get_ui :: Ptr MPFR -> CRoundMode -> IO CULong

{-
foreign import ccall unsafe "mpfr_get_sj_wrap"
        mpfr_get_sj :: Ptr MPFR -> CRoundMode -> IO #type intmax_t

foreign import ccall unsafe "mpfr_get_uj_wrap"
        mpft_get_uj :: Ptr MPFR -> CRoundMode -> IO #type uintmax_t
-}
--TODO get_z_exp, get_z, get_f, 

foreign import ccall unsafe "mpfr_get_str"
        mpfr_get_str :: CString -> Ptr Exp -> CInt -> CUInt -> Ptr MPFR ->  CRoundMode -> IO CString

foreign import ccall unsafe "mpfr_free_str"
        mpfr_free_str :: CString -> IO ()

foreign import ccall unsafe "mpfr_fits_ulong_p"
        mpfr_fits_ulong_p :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fits_slong_p"
        mpfr_fits_slong_p :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fits_uint_p"
        mpfr_fits_uint_p :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fits_sint_p"
        mpfr_fits_sint_p :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fits_ushort_p"
        mpfr_fits_ushort_p :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fits_sshort_p"
        mpfr_fits_sshort_p :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fits_intmax_p"
        mpfr_fits_intmax_p :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fits_uintmax_p"
        mpfr_fits_uintmax_p :: Ptr MPFR -> CRoundMode -> IO CInt


-------------------------------------------------------------------------------

-- basic arithmetic functions

foreign import ccall unsafe "mpfr_add"
        mpfr_add :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_add_ui"
        mpfr_add_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_add_si"
        mpfr_add_si :: Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_add_d"
        mpfr_add_d :: Ptr MPFR -> Ptr MPFR -> CDouble -> CRoundMode -> IO CInt

-- TODO add_z, add_q

foreign import ccall unsafe "mpfr_sub"
        mpfr_sub :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_ui_sub" 
        mpfr_ui_sub :: Ptr MPFR -> CULong -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sub_ui"
        mpfr_sub_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_si_sub" 
        mpfr_si_sub :: Ptr MPFR -> CLong -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sub_si"
        mpfr_sub_si :: Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sub_d"
        mpfr_sub_d :: Ptr MPFR -> Ptr MPFR -> CDouble -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_d_sub"
        mpfr_d_sub :: Ptr MPFR -> CDouble -> Ptr MPFR -> CRoundMode -> IO CInt

--TODO sub_z, sub_q

foreign import ccall unsafe "mpfr_mul"
        mpfr_mul :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 

foreign import ccall unsafe "mpfr_mul_ui"
        mpfr_mul_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_mul_si"
        mpfr_mul_si :: Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_mul_d"
        mpfr_mul_d:: Ptr MPFR -> Ptr MPFR -> CDouble -> CRoundMode -> IO CInt

--TODO mul_z, mul_q

foreign import ccall unsafe "mpfr_sqr"
        mpfr_sqr :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_div"
        mpfr_div :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_ui_div"
        mpfr_ui_div :: Ptr MPFR -> CULong -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_div_ui"
        mpfr_div_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_si_div"
        mpfr_si_div :: Ptr MPFR -> CLong -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_div_si"
        mpfr_div_si :: Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_div_d"
        mpfr_div_d :: Ptr MPFR -> Ptr MPFR -> CDouble -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_d_div"
        mpfr_d_div :: Ptr MPFR -> CDouble -> Ptr MPFR -> CRoundMode -> IO CInt


-- TODO div_z, div_q

foreign import ccall unsafe "mpfr_sqrt"
        mpfr_sqrt :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sqrt_ui"
        mpfr_sqrt_ui :: Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_rec_sqrt"
        mpfr_rec_sqrt :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_cbrt"
        mpfr_cbrt :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_root"
        mpfr_root :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt 

foreign import ccall unsafe "mpfr_pow"
        mpfr_pow :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 

foreign import ccall unsafe "mpfr_pow_ui"
        mpfr_pow_ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_pow_si"
        mpfr_pow_si :: Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt

--TODO pow_z

foreign import ccall unsafe "mpfr_ui_pow_ui"
        mpfr_ui_pow_ui :: Ptr MPFR -> CULong -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_ui_pow"
        mpfr_ui_pow :: Ptr MPFR -> CULong -> Ptr MPFR -> CRoundMode -> IO CInt


foreign import ccall unsafe "mpfr_neg"
        mpfr_neg :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 

foreign import ccall unsafe "mpfr_abs_wrap"
        mpfr_abs :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 

foreign import ccall unsafe "mpfr_dim"
        mpfr_dim :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_mul_2ui"
        mpfr_mul_2ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_mul_2si"
        mpfr_mul_2si :: Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_div_2ui"
        mpfr_div_2ui :: Ptr MPFR -> Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_div_2si"
        mpfr_div_2si :: Ptr MPFR -> Ptr MPFR -> CLong -> CRoundMode -> IO CInt



--------------------------------------------------------------------------------
-- comparison functions
-- !!!!!!!! these set erange flags
foreign import ccall unsafe "mpfr_cmp_wrap"
        mpfr_cmp :: Ptr MPFR -> Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_cmp_ui_wrap"
        mpfr_cmp_ui :: Ptr MPFR -> CULong -> IO CInt

foreign import ccall unsafe "mpfr_cmp_si_wrap"
        mpfr_cmp_si :: Ptr MPFR -> CLong -> IO CInt

foreign import ccall unsafe "mpfr_cmp_d"
        mpfr_cmp_d :: Ptr MPFR -> CDouble -> IO CInt

--TODO cmp_ld, cmp_z, cmp_q, cmp_f

foreign import ccall unsafe "mpfr_cmp_ui_2exp"
        mpfr_cmp_ui_2exp :: Ptr MPFR -> CULong -> Exp -> IO CInt

foreign import ccall unsafe "mpfr_cmp_si_2exp"
        mpfr_cmp_si_2exp :: Ptr MPFR -> CLong -> Exp -> IO CInt

foreign import ccall unsafe "mpfr_cmpabs"
        mpfr_cmpabs :: Ptr MPFR -> Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_nan_p_wrap"
        mpfr_nan_p :: Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_inf_p_wrap"
        mpfr_inf_p :: Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_number_p"
        mpfr_number_p :: Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_zero_p_wrap"
        mpfr_zero_p :: Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_sgn_wrap"
        mpfr_sgn :: Ptr MPFR -> IO CInt 

foreign import ccall unsafe "mpfr_greater_p"
        mpfr_greater_p :: Ptr MPFR ->  Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_greaterequal_p"
        mpfr_greaterequal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 

foreign import ccall unsafe "mpfr_less_p"
        mpfr_less_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 

foreign import ccall unsafe "mpfr_lessequal_p"
        mpfr_lessequal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 

foreign import ccall unsafe "mpfr_lessgreater_p"
        mpfr_lessgreater_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 

foreign import ccall unsafe "mpfr_equal_p"
        mpfr_equal_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 

foreign import ccall unsafe "mpfr_unordered_p"
        mpfr_unordered_p :: Ptr MPFR -> Ptr MPFR -> IO CInt 

-- special functions 

foreign import ccall unsafe "mpfr_log"
        mpfr_log :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_log2"
        mpfr_log2 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_log10"
        mpfr_log10 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_exp"
        mpfr_exp :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_exp2"
        mpfr_exp2 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_exp10"
        mpfr_exp10 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sin"
        mpfr_sin :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_cos"
        mpfr_cos :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_tan"
        mpfr_tan :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sec"
        mpfr_sec :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_csc"
        mpfr_csc :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_cot"
        mpfr_cot :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sin_cos"
        mpfr_sin_cos :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt


foreign import ccall unsafe "mpfr_asin"
        mpfr_asin :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_acos"
        mpfr_acos :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_atan"
        mpfr_atan :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_atan2"
        mpfr_atan2 :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt


foreign import ccall unsafe "mpfr_cosh"
        mpfr_cosh :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sinh"
        mpfr_sinh :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_tanh"
        mpfr_tanh :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sinh_cosh"
        mpfr_sinh_cosh :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_sech"
        mpfr_sech :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_csch"
        mpfr_csch :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_coth"
        mpfr_coth :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_asinh"
        mpfr_asinh :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_acosh"
        mpfr_acosh :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_atanh"
        mpfr_atanh :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fac_ui"
        mpfr_fac_ui :: Ptr MPFR -> CULong -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_log1p"
        mpfr_log1p :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_expm1"
        mpfr_expm1 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_li2"
        mpfr_li2 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_eint"
        mpfr_eint :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_gamma"
        mpfr_gamma :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_lngamma"
        mpfr_lngamma :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_lgamma"
        mpfr_lgamma :: Ptr MPFR -> Ptr CInt -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_zeta"
        mpfr_zeta :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_zeta_ui"
        mpfr_zeta_ui :: Ptr MPFR -> CULong ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_erf"
        mpfr_erf :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_erfc"
        mpfr_erfc :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_j0"
        mpfr_j0 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_j1"
        mpfr_j1 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_jn"
        mpfr_jn :: Ptr MPFR -> CLong -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_y0"
        mpfr_y0 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_y1"
        mpfr_y1 :: Ptr MPFR -> Ptr MPFR ->  CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_yn"
        mpfr_yn :: Ptr MPFR -> CLong -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fma"
        mpfr_fma :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt  

foreign import ccall unsafe "mpfr_fms"
        mpfr_fms :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt


foreign import ccall unsafe "mpfr_agm"
        mpfr_agm :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt  

foreign import ccall unsafe "mpfr_hypot"
        mpfr_hypot :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt  

-- constants
foreign import ccall unsafe "mpfr_const_log2"
        mpfr_const_log2 :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_const_pi"
        mpfr_const_pi :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_const_euler"
        mpfr_const_euler :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_const_catalan"
        mpfr_const_catalan :: Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_free_cache"
        mpfr_free_cache :: IO ()

foreign import ccall unsafe "mpfr_sum"
        mpfr_sum :: Ptr MPFR -> Ptr (Ptr MPFR) -> CULong -> CRoundMode -> IO CInt

-- TODO input and output functions

-- integer related functions

foreign import ccall unsafe "mpfr_rint"
        mpfr_rint :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_ceil_wrap"
        mpfr_ceil :: Ptr MPFR -> Ptr MPFR  -> IO CInt

foreign import ccall unsafe "mpfr_floor_wrap"
        mpfr_floor :: Ptr MPFR -> Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_round_wrap"
        mpfr_round :: Ptr MPFR -> Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_trunc_wrap"
        mpfr_trunc :: Ptr MPFR -> Ptr MPFR -> IO CInt
 
foreign import ccall unsafe "mpfr_rint_ceil"
        mpfr_rint_ceil :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_rint_floor"
        mpfr_rint_floor :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_rint_round"
        mpfr_rint_round :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_rint_trunc"
        mpfr_rint_trunc :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_frac"
        mpfr_frac :: Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_modf"
        mpfr_modf :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_fmod"
        mpfr_fmod :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_remainder" 
        mpfr_remainder :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_remquo" 
        mpfr_remquo :: Ptr MPFR -> Ptr CLong -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_integer_p"
        mpfr_integer_p :: Ptr MPFR -> IO CInt

--------------------
-- miscellaneus functions

foreign import ccall unsafe "mpfr_nexttoward"
        mpfr_nexttoward ::  Ptr MPFR -> Ptr MPFR -> IO ()

foreign import ccall unsafe "mpfr_nextabove"
        mpfr_nextabove ::  Ptr MPFR -> IO ()

foreign import ccall unsafe "mpfr_nextbelow"
        mpfr_nextbelow ::  Ptr MPFR -> IO ()

foreign import ccall unsafe "mpfr_min"
        mpfr_min :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_max"
        mpfr_max :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt

-- TODO urandomb

foreign import ccall unsafe "mpfr_random2"
        mpfr_random2 :: Ptr MPFR -> MpSize -> Exp -> IO ()


foreign import ccall unsafe "mpfr_get_exp_wrap"
        mpfr_get_exp :: Ptr MPFR -> IO Exp

foreign import ccall unsafe "mpfr_set_exp"
        mpfr_set_exp :: Ptr MPFR -> Exp -> IO CInt

foreign import ccall unsafe "mpfr_signbit_wrap"
        mpfr_signbit :: Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_setsign_wrap"
        mpfr_setsign :: Ptr MPFR -> Ptr MPFR -> CInt -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_copysign_wrap"
        mpfr_copysign :: Ptr MPFR -> Ptr MPFR -> Ptr MPFR -> CRoundMode -> IO CInt 

---------------------------------------------------------------
-- rounding mode related functions

foreign import ccall unsafe "mpfr_get_emin"
        mpfr_get_emin :: IO Exp

foreign import ccall unsafe "mpfr_get_emax"
        mpfr_get_emax :: IO Exp

foreign import ccall unsafe "mpfr_set_emin"
        mpfr_set_emin :: Exp -> IO CInt

foreign import ccall unsafe "mpfr_set_emax"
        mpfr_set_emax :: Exp -> IO CInt

foreign import ccall unsafe "mpfr_get_emin_min"
        mpfr_get_emin_min :: IO Exp

foreign import ccall unsafe "mpfr_get_emin_max"
        mpfr_get_emin_max :: IO Exp

foreign import ccall unsafe "mpfr_get_emax_min"
        mpfr_get_emax_min :: IO Exp

foreign import ccall unsafe "mpfr_get_emax_max"
        mpfr_get_emax_max :: IO Exp

foreign import ccall unsafe "mpfr_check_range"
        mpfr_check_range :: Ptr MPFR -> CInt -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_subnormalize"
        mpfr_subnormalize :: Ptr MPFR -> CInt -> CRoundMode -> IO CInt

foreign import ccall unsafe "mpfr_clear_underflow"
        mpfr_clear_underflow :: IO ()

foreign import ccall unsafe "mpfr_clear_overflow"
        mpfr_clear_overflow :: IO ()

foreign import ccall unsafe "mpfr_clear_nanflag"
        mpfr_clear_nanflag :: IO ()

foreign import ccall unsafe "mpfr_clear_inexflag"
        mpfr_clear_inexflag :: IO ()

foreign import ccall unsafe "mpfr_clear_erangeflag"
        mpfr_clear_erangeflag :: IO ()

foreign import ccall unsafe "mpfr_set_underflow"
        mpfr_set_underflow :: IO ()

foreign import ccall unsafe "mpfr_set_overflow"
        mpfr_set_overflow :: IO ()

foreign import ccall unsafe "mpfr_set_nanflag"
        mpfr_set_nanflag :: IO ()

foreign import ccall unsafe "mpfr_set_inexflag"
        mpfr_set_inexflag :: IO ()

foreign import ccall unsafe "mpfr_set_erangeflag"
        mpfr_set_erangeflag :: IO ()

foreign import ccall unsafe "mpfr_clear_flags"
        mpfr_clear_flags :: IO ()


foreign import ccall unsafe "mpfr_underflow_p"
        mpfr_underflow_p :: IO CInt

foreign import ccall unsafe "mpfr_overflow_p"
        mpfr_overflow_p :: IO CInt

foreign import ccall unsafe "mpfr_nanflag_p"
        mpfr_nanflag_p :: IO CInt

foreign import ccall unsafe "mpfr_inexflag_p"
        mpfr_inexflag_p :: IO CInt

foreign import ccall unsafe "mpfr_erangeflag_p"
        mpfr_erangeflag_p :: IO CInt

---------------------------------------------------------------
-- custom interface
foreign import ccall unsafe "mpfr_custom_get_size_wrap" 
        mpfr_custom_get_size :: CPrecision -> IO Word32
{-# LINE 773 "Data/Number/MPFR/FFIhelper.hsc" #-}

foreign import ccall unsafe "mpfr_custom_init_wrap"
        mpfr_custom_init :: Ptr Word32 -> CPrecision -> IO ()
{-# LINE 776 "Data/Number/MPFR/FFIhelper.hsc" #-}

foreign import ccall unsafe "mpfr_custom_init_set_wrap"
        mpfr_custom_init_set :: Ptr MPFR -> CInt -> Exp -> CPrecision -> Ptr Limb -> IO ()

foreign import ccall unsafe "mpfr_custom_get_kind_wrap"
        mpfr_custom_get_kind :: Ptr MPFR -> IO CInt

foreign import ccall unsafe "mpfr_custom_get_mantissa_wrap"
        mpfr_custom_get_mantissa :: Ptr MPFR -> IO (Ptr Limb)

foreign import ccall unsafe "mpfr_custom_get_exp_wrap"
        mpfr_custom_get_exp :: Ptr MPFR -> IO Exp

foreign import ccall unsafe "mpfr_custom_move_wrap"
        mpfr_custom_move :: Ptr MPFR -> Ptr Word32 -> IO ()
{-# LINE 791 "Data/Number/MPFR/FFIhelper.hsc" #-}

-------------------------------------------------