{-# LINE 1 "src/Data/Number/Flint/NF/FFI.hsc" #-}
{-|
module      :  Data.Number.Flint.NF.FFI
copyright   :  (c) 2022 Hartmut Monien
license     :  GNU GPL, version 2 or above (see LICENSE)
maintainer  :  hmonien@uni-bonn.de
-}
module Data.Number.Flint.NF.FFI (
  -- Number fields
    NF (..)
  , CNF (..)
  , newNF
  , withNF
  , nf_init
  , nf_clear
) where

-- Number fields ---------------------------------------------------------------

import Foreign.ForeignPtr
import Foreign.Ptr
import Foreign.Storable

import Data.Number.Flint.Fmpq.Poly



-- nf_t ------------------------------------------------------------------------

data NF = NF {-# UNPACK #-} !(ForeignPtr CNF)
data CNF = CNF

instance Storable CNF where
  {-# INLINE sizeOf #-}
  sizeOf :: CNF -> Int
sizeOf CNF
_ = (Int
112)
{-# LINE 35 "src/Data/Number/Flint/NF/FFI.hsc" #-}
  {-# INLINE alignment #-}
  alignment :: CNF -> Int
alignment CNF
_ = Int
8
{-# LINE 37 "src/Data/Number/Flint/NF/FFI.hsc" #-}
  peek = error "CNF.peek is not defined."
  poke :: Ptr CNF -> CNF -> IO ()
poke = forall a. HasCallStack => [Char] -> a
error [Char]
"CNF.poke is not defined."

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

-- | Create a new number field
newNF :: FmpqPoly -> IO NF
newNF FmpqPoly
poly = do
  ForeignPtr CNF
nf <- forall a. Storable a => IO (ForeignPtr a)
mallocForeignPtr
  forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CNF
nf forall a b. (a -> b) -> a -> b
$ \Ptr CNF
nf ->
    forall {a}. FmpqPoly -> (Ptr CFmpqPoly -> IO a) -> IO (FmpqPoly, a)
withFmpqPoly FmpqPoly
poly forall a b. (a -> b) -> a -> b
$ \Ptr CFmpqPoly
poly ->
      Ptr CNF -> Ptr CFmpqPoly -> IO ()
nf_init Ptr CNF
nf Ptr CFmpqPoly
poly
  forall a. FinalizerPtr a -> ForeignPtr a -> IO ()
addForeignPtrFinalizer FunPtr (Ptr CNF -> IO ())
p_nf_clear ForeignPtr CNF
nf 
  forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ ForeignPtr CNF -> NF
NF ForeignPtr CNF
nf

-- | Use number field
withNF :: NF -> (Ptr CNF -> IO a) -> IO (NF, a)
withNF (NF ForeignPtr CNF
nf) Ptr CNF -> IO a
f = do
  forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr CNF
nf forall a b. (a -> b) -> a -> b
$ \Ptr CNF
fp -> (ForeignPtr CNF -> NF
NF ForeignPtr CNF
nf,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CNF -> IO a
f Ptr CNF
fp

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

-- | /nf_init/ /nf/ /pol/ 
-- 
-- Perform basic initialisation of a number field (for element arithmetic)
-- given a defining polynomial over \(\mathbb{Q}\).
foreign import ccall "nf.h nf_init"
  nf_init :: Ptr CNF -> Ptr CFmpqPoly -> IO ()

-- | /nf_clear/ /nf/ 
-- 
-- Release resources used by a number field object. The object will need
-- initialisation again before it can be used.
foreign import ccall "nf.h nf_clear"
  nf_clear :: Ptr CNF -> IO ()

foreign import ccall "nf.h &nf_clear"
  p_nf_clear :: FunPtr (Ptr CNF -> IO ())