-- GENERATED by C->Haskell Compiler, version 0.28.8 Switcheroo, 25 November 2017 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "./QuantLib/Context.chs" #-}
-- |process-global evaluation context: run-time library settings and the exception type
-- raised across the FFI boundary
module QuantLib.Context
  (
    -- * Types
    Error(..)

    -- * Mutators
  , setEvaluationDate
  , setEnforceTodaysHistoricFixings
  , setIncludeTodaysCashFlows
  , setIncludeReferenceDateEvents
  , disableUpdates
  , enableUpdates
  , keepingSettings
  , keepingSettingsGc
  , collectGarbage
  , setExtendedPrecision

    -- * Inspectors
  , evaluationDate
  , enforceTodaysHistoricFixings
  , includeTodaysCashFlows
  , includeReferenceDateEvents
  , updatesEnabled
  , updatesDeferred
  , version
  , boostVersion
  , epsilon
  ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Marshal.Utils as C2HSImp
import qualified Foreign.Ptr as C2HSImp


import Foreign.C.Types(CDouble)
import Foreign.C.String(CString, peekCString)
import System.IO.Unsafe(unsafePerformIO)
import System.Mem(performGC)
import Control.Exception(bracket)

import QuantLib.Time.Date
import QuantLib.Internal




-- |Sets the x87 floating-point unit to 64-bit extended precision. On Windows, call on
-- each OS thread before it prices, since the control word is per-thread; a no-op elsewhere.
setExtendedPrecision :: IO ()
setExtendedPrecision :: IO ()
setExtendedPrecision =
  IO ()
setExtendedPrecision'_ IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

{-# LINE 45 "./QuantLib/Context.chs" #-}


-- Padding: being the file's first {#fun#}, this entry absorbs c2hs's module-header
-- line-count drift; without enough real distance to the next entry, Haddock
-- misattaches this doc to that one (see c2hs-shim-patterns's LINE-pragma note).




-- |returns the current value of the Evaluation Date: the date at which pricing is to be performed
evaluationDate :: IO ((Day))
evaluationDate :: IO Day
evaluationDate =
  IO CInt
evaluationDate'_ IO CInt -> (CInt -> IO Day) -> IO Day
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \CInt
res ->
  let {res' :: Day
res' = CInt -> Day
toDay CInt
res} in
  Day -> IO Day
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Day
res')

{-# LINE 55 "./QuantLib/Context.chs" #-}


-- |sets the value of the Evaluation Date.
-- Nothing sets the evaluation date to Date::todaysDate() and allow it to change at midnight.
-- This comes at the price of losing some performance, since the evaluation date is re-evaluated each time it is read.
setEvaluationDate :: (Maybe Day) -> IO ()
setEvaluationDate :: Maybe Day -> IO ()
setEvaluationDate Maybe Day
a1 =
  Maybe Day -> (CInt -> IO ()) -> IO ()
forall a. Maybe Day -> (CInt -> IO a) -> IO a
withMaybeDay Maybe Day
a1 ((CInt -> IO ()) -> IO ()) -> (CInt -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \CInt
a1' -> 
  (Ptr (Ptr CChar) -> IO ()) -> IO ()
forall a b. (Ptr (Ptr a) -> IO b) -> IO b
preErrorCheck ((Ptr (Ptr CChar) -> IO ()) -> IO ())
-> (Ptr (Ptr CChar) -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CChar)
a2' -> 
  CInt -> Ptr (Ptr CChar) -> IO ()
setEvaluationDate'_ CInt
a1' Ptr (Ptr CChar)
a2' IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  Ptr (Ptr CChar) -> IO ()
errorCheck  Ptr (Ptr CChar)
a2'IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

{-# LINE 60 "./QuantLib/Context.chs" #-}


-- |returns the current value of the boolean which enforce the usage of historic
-- fixings for today's date
enforceTodaysHistoricFixings :: IO ((Bool))
enforceTodaysHistoricFixings =
  enforceTodaysHistoricFixings'_ >>= \res ->
  let {res' = C2HSImp.toBool res} in
  return (res')

{-# LINE 64 "./QuantLib/Context.chs" #-}


-- |sets the value of the boolean which enforce the usage of historic fixings for today's date
setEnforceTodaysHistoricFixings :: (Bool) -> IO ()
setEnforceTodaysHistoricFixings a1 =
  let {a1' = C2HSImp.fromBool a1} in 
  setEnforceTodaysHistoricFixings'_ a1' >>
  return ()

{-# LINE 67 "./QuantLib/Context.chs" #-}


-- |if set, whether CashFlows occurring on today's date should enter the NPV; when the NPV date
-- equals today's date this overrides includeReferenceDateEvents and cannot be overridden locally
includeTodaysCashFlows :: IO ((Maybe Bool))
includeTodaysCashFlows =
  includeTodaysCashFlows'_ >>= \res ->
  let {res' = toMaybeBool res} in
  return (res')

{-# LINE 71 "./QuantLib/Context.chs" #-}


-- |sets whether CashFlows occurring on today's date should enter the NPV
setIncludeTodaysCashFlows :: (Maybe Bool) -> IO ()
setIncludeTodaysCashFlows a1 =
  let {a1' = fromMaybeBool a1} in 
  setIncludeTodaysCashFlows'_ a1' >>
  return ()

{-# LINE 74 "./QuantLib/Context.chs" #-}


-- |This flag specifies whether or not Events occurring on the reference date should, by default, be taken into account as not happened yet. It can be overridden locally when calling the Event::hasOccurred method.
includeReferenceDateEvents :: IO ((Bool))
includeReferenceDateEvents =
  includeReferenceDateEvents'_ >>= \res ->
  let {res' = C2HSImp.toBool res} in
  return (res')

{-# LINE 77 "./QuantLib/Context.chs" #-}


-- |sets whether Events occurring on the reference date should, by default, be taken into account as not happened yet
setIncludeReferenceDateEvents :: (Bool) -> IO ()
setIncludeReferenceDateEvents a1 =
  let {a1' = C2HSImp.fromBool a1} in 
  setIncludeReferenceDateEvents'_ a1' >>
  return ()

{-# LINE 80 "./QuantLib/Context.chs" #-}


-- |Disables observer notifications. When @deferred@ is 'True', notifications are queued until
-- 'enableUpdates' is called; otherwise they are discarded.
disableUpdates :: (Bool) -- ^deferred
 -> IO ()
disableUpdates :: Bool -> IO ()
disableUpdates Bool
a1 =
  let {a1' :: CInt
a1' = Bool -> CInt
forall a. Num a => Bool -> a
C2HSImp.fromBool Bool
a1} in 
  CInt -> IO ()
disableUpdates'_ CInt
a1' IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>>
  () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()

{-# LINE 85 "./QuantLib/Context.chs" #-}


-- |Enables observer notifications and runs any notifications queued while updates were deferred.
enableUpdates :: IO ()
enableUpdates =
  preErrorCheck $ \a1' -> 
  enableUpdates'_ a1' >>
  errorCheck  a1'>>
  return ()

{-# LINE 88 "./QuantLib/Context.chs" #-}


-- |Whether observer notifications are currently enabled.
updatesEnabled :: IO ((Bool))
updatesEnabled =
  updatesEnabled'_ >>= \res ->
  let {res' = C2HSImp.toBool res} in
  return (res')

{-# LINE 91 "./QuantLib/Context.chs" #-}


-- |Whether observer notifications are currently disabled with deferred delivery enabled.
updatesDeferred :: IO ((Bool))
updatesDeferred =
  updatesDeferred'_ >>= \res ->
  let {res' = C2HSImp.toBool res} in
  return (res')

{-# LINE 94 "./QuantLib/Context.chs" #-}


-- |brackets to restore settings once action has completed or raised an exception
keepingSettings :: IO b -> IO b
keepingSettings = bracket qlSavedSettings qlFreeSavedSettings . const
-- SavedSettings destructor suppresses all exceptions

-- |brackets to restore settings once action has completed or raised an exception. Before restoring settings
-- 'collectGarbage' is run to avoid problems with market data objects watching evaluation date
keepingSettingsGc :: IO b -> IO b
keepingSettingsGc :: forall b. IO b -> IO b
keepingSettingsGc = IO (Ptr ()) -> (Ptr () -> IO ()) -> (Ptr () -> IO b) -> IO b
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket IO (Ptr ())
qlSavedSettings (\Ptr ()
s -> IO ()
collectGarbage IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr () -> IO ()
qlFreeSavedSettings Ptr ()
s) ((Ptr () -> IO b) -> IO b)
-> (IO b -> Ptr () -> IO b) -> IO b -> IO b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO b -> Ptr () -> IO b
forall a b. a -> b -> a
const

-- |Best effort: give the finalizers of unreachable QuantLib objects a chance to run, so
-- their C++ destructors fire before, say, 'setEvaluationDate' notifies surviving observers.
--
-- 'performGC' only /schedules/ finalizers, it does not run them synchronously, so this is a
-- nudge rather than a guarantee. Where correctness depends on an object being gone, anchor
-- its dates so staleness cannot arise in the first place.
collectGarbage :: IO ()
collectGarbage :: IO ()
collectGarbage = IO ()
performGC IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO ()
performGC

foreign import ccall safe "ql.h qlVersion" qlVersion :: IO CString
foreign import ccall safe "ql.h qlBoostVersion" qlBoostVersion :: IO CString
foreign import ccall safe "ql.h qlEpsilon" qlEpsilon :: CDouble

{-# NOINLINE version #-}
version :: String
version :: String
version = IO String -> String
forall a. IO a -> a
unsafePerformIO (IO String -> String) -> IO String -> String
forall a b. (a -> b) -> a -> b
$ IO (Ptr CChar)
qlVersion IO (Ptr CChar) -> (Ptr CChar -> IO String) -> IO String
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr CChar -> IO String
peekCString

{-# NOINLINE boostVersion #-}
boostVersion :: String
boostVersion :: String
boostVersion = IO String -> String
forall a. IO a -> a
unsafePerformIO (IO String -> String) -> IO String -> String
forall a b. (a -> b) -> a -> b
$ IO (Ptr CChar)
qlBoostVersion IO (Ptr CChar) -> (Ptr CChar -> IO String) -> IO String
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr CChar -> IO String
peekCString

epsilon :: Double
epsilon :: Double
epsilon = CDouble -> Double
forall a b. (Real a, Fractional b) => a -> b
realToFrac CDouble
qlEpsilon

-- vim: set ff=unix ts=8 sts=2 sw=2 et:

foreign import ccall safe "QuantLib/Context.chs.h qlSetExtendedPrecision"
  setExtendedPrecision'_ :: (IO ())

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsEvaluationDate"
  evaluationDate'_ :: (IO C2HSImp.CInt)

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsSetEvaluationDate"
  setEvaluationDate'_ :: (C2HSImp.CInt -> ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO ())))

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsEnforceTodaysHistoricFixings"
  enforceTodaysHistoricFixings'_ :: (IO C2HSImp.CInt)

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsSetEnforceTodaysHistoricFixings"
  setEnforceTodaysHistoricFixings'_ :: (C2HSImp.CInt -> (IO ()))

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsIncludeTodaysCashFlows"
  includeTodaysCashFlows'_ :: (IO C2HSImp.CInt)

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsSetIncludeTodaysCashFlows"
  setIncludeTodaysCashFlows'_ :: (C2HSImp.CInt -> (IO ()))

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsIncludeReferenceDateEvents"
  includeReferenceDateEvents'_ :: (IO C2HSImp.CInt)

foreign import ccall safe "QuantLib/Context.chs.h qlSettingsSetIncludeReferenceDateEvents"
  setIncludeReferenceDateEvents'_ :: (C2HSImp.CInt -> (IO ()))

foreign import ccall safe "QuantLib/Context.chs.h qlObservableSettingsDisableUpdates"
  disableUpdates'_ :: (C2HSImp.CInt -> (IO ()))

foreign import ccall safe "QuantLib/Context.chs.h qlObservableSettingsEnableUpdates"
  enableUpdates'_ :: ((C2HSImp.Ptr (C2HSImp.Ptr C2HSImp.CChar)) -> (IO ()))

foreign import ccall safe "QuantLib/Context.chs.h qlObservableSettingsUpdatesEnabled"
  updatesEnabled'_ :: (IO C2HSImp.CInt)

foreign import ccall safe "QuantLib/Context.chs.h qlObservableSettingsUpdatesDeferred"
  updatesDeferred'_ :: (IO C2HSImp.CInt)