{- |
Module      :  Numeric.QD.QuadDouble.Raw.Safe
Copyright   :  (c) Claude Heiland-Allen 2011
License     :  BSD3

Maintainer  :  claude@mathr.co.uk
Stability   :  unstable
Portability :  portable

Safe bindings to libqd for quad-double numbers.

These bindings are to foreign wrappers around libqd, which set and
restore the FPU flags correctly.
-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Numeric.QD.QuadDouble.Raw.Safe
  ( c_qd_add
  , c_qd_add_dd_qd
  , c_qd_add_qd_dd
  , c_qd_add_d_qd
  , c_qd_add_qd_d
  , c_qd_selfadd
  , c_qd_selfadd_dd
  , c_qd_selfadd_d
  , c_qd_sub
  , c_qd_sub_dd_qd
  , c_qd_sub_qd_dd
  , c_qd_sub_d_qd
  , c_qd_sub_qd_d
  , c_qd_selfsub
  , c_qd_selfsub_dd
  , c_qd_selfsub_d
  , c_qd_mul
  , c_qd_mul_dd_qd
  , c_qd_mul_qd_dd
  , c_qd_mul_d_qd
  , c_qd_mul_qd_d
  , c_qd_selfmul
  , c_qd_selfmul_dd
  , c_qd_selfmul_d
  , c_qd_div
  , c_qd_div_dd_qd
  , c_qd_div_qd_dd
  , c_qd_div_d_qd
  , c_qd_div_qd_d
  , c_qd_selfdiv
  , c_qd_selfdiv_dd
  , c_qd_selfdiv_d
  , c_qd_copy
  , c_qd_copy_dd
  , c_qd_copy_d
  , c_qd_sqrt
  , c_qd_sqr
  , c_qd_abs
  , c_qd_npwr
  , c_qd_nroot
  , c_qd_nint
  , c_qd_aint
  , c_qd_floor
  , c_qd_ceil
  , c_qd_exp
  , c_qd_log
  , c_qd_log10
  , c_qd_sin
  , c_qd_cos
  , c_qd_tan
  , c_qd_asin
  , c_qd_acos
  , c_qd_atan
  , c_qd_atan2
  , c_qd_sinh
  , c_qd_cosh
  , c_qd_tanh
  , c_qd_asinh
  , c_qd_acosh
  , c_qd_atanh
  , c_qd_sincos
  , c_qd_sincosh
  , c_qd_read
  , c_qd_swrite
  , c_qd_neg
  , c_qd_comp
  , c_qd_comp_qd_d
  , c_qd_comp_d_qd
  , c_qd_pi
  , c_qd_write
  , c_qd_rand
  ) where

import Foreign (Ptr)
import Foreign.C (CChar(..), CDouble(..), CInt(..))

foreign import ccall unsafe "safe_qd.h safe_qd_add" c_qd_add :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_add_dd_qd" c_qd_add_dd_qd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_add_qd_dd" c_qd_add_qd_dd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_add_d_qd" c_qd_add_d_qd :: CDouble -> Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_add_qd_d" c_qd_add_qd_d :: Ptr CDouble -> CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfadd" c_qd_selfadd :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfadd_dd" c_qd_selfadd_dd :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfadd_d" c_qd_selfadd_d :: CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_sub" c_qd_sub :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_sub_dd_qd" c_qd_sub_dd_qd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_sub_qd_dd" c_qd_sub_qd_dd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_sub_d_qd" c_qd_sub_d_qd :: CDouble -> Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_sub_qd_d" c_qd_sub_qd_d :: Ptr CDouble -> CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfsub" c_qd_selfsub :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfsub_dd" c_qd_selfsub_dd :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfsub_d" c_qd_selfsub_d :: CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_mul" c_qd_mul :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_mul_dd_qd" c_qd_mul_dd_qd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_mul_qd_dd" c_qd_mul_qd_dd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_mul_d_qd" c_qd_mul_d_qd :: CDouble -> Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_mul_qd_d" c_qd_mul_qd_d :: Ptr CDouble -> CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfmul" c_qd_selfmul :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfmul_dd" c_qd_selfmul_dd :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfmul_d" c_qd_selfmul_d :: CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_div" c_qd_div :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_div_dd_qd" c_qd_div_dd_qd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_div_qd_dd" c_qd_div_qd_dd :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();
foreign import ccall unsafe "safe_qd.h safe_qd_div_d_qd" c_qd_div_d_qd :: CDouble -> Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_div_qd_d" c_qd_div_qd_d :: Ptr CDouble -> CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfdiv" c_qd_selfdiv :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfdiv_dd" c_qd_selfdiv_dd :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_selfdiv_d" c_qd_selfdiv_d :: CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_copy" c_qd_copy :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_copy_dd" c_qd_copy_dd :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_copy_d" c_qd_copy_d :: CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_sqrt" c_qd_sqrt :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_sqr" c_qd_sqr :: Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_abs" c_qd_abs :: Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_npwr" c_qd_npwr :: Ptr CDouble -> CInt -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_nroot" c_qd_nroot :: Ptr CDouble -> CInt -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_nint" c_qd_nint :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_aint" c_qd_aint :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_floor" c_qd_floor :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_ceil" c_qd_ceil :: Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_exp" c_qd_exp :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_log" c_qd_log :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_log10" c_qd_log10 :: Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_sin" c_qd_sin :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_cos" c_qd_cos :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_tan" c_qd_tan :: Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_asin" c_qd_asin :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_acos" c_qd_acos :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_atan" c_qd_atan :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_atan2" c_qd_atan2 :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ();

foreign import ccall unsafe "safe_qd.h safe_qd_sinh" c_qd_sinh :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_cosh" c_qd_cosh :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_tanh" c_qd_tanh :: Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_asinh" c_qd_asinh :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_acosh" c_qd_acosh :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_atanh" c_qd_atanh :: Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_sincos" c_qd_sincos :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_sincosh" c_qd_sincosh :: Ptr CDouble -> Ptr CDouble -> Ptr CDouble -> IO ()

foreign import ccall unsafe "safe_qd.h safe_qd_read" c_qd_read :: Ptr CChar -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_swrite" c_qd_swrite :: Ptr CDouble -> CInt -> Ptr CChar -> CInt -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_neg" c_qd_neg :: Ptr CDouble -> Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_comp" c_qd_comp :: Ptr CDouble -> Ptr CDouble -> Ptr CInt -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_comp_qd_d" c_qd_comp_qd_d :: Ptr CDouble -> CDouble -> Ptr CInt -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_comp_d_qd" c_qd_comp_d_qd :: CDouble -> Ptr CDouble -> Ptr CInt -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_pi" c_qd_pi :: Ptr CDouble -> IO ()

-- these two are almost certainly not referentially transparent
foreign import ccall unsafe "safe_qd.h safe_qd_write" c_qd_write :: Ptr CDouble -> IO ()
foreign import ccall unsafe "safe_qd.h safe_qd_rand" c_qd_rand :: Ptr CDouble -> IO ()