use crate::BigFloat;
use crate::Consts;
use crate::Error;
use crate::Exponent;
use crate::RoundingMode;
use crate::EXPONENT_MAX;
use crate::EXPONENT_MIN;
#[derive(Debug)]
pub struct Context {
cc: Consts,
p: usize,
rm: RoundingMode,
emin: Exponent,
emax: Exponent,
}
impl Context {
pub fn new(p: usize, rm: RoundingMode, cc: Consts, emin: Exponent, emax: Exponent) -> Self {
Context {
cc,
p,
rm,
emin: emin.clamp(EXPONENT_MIN, 0),
emax: emax.clamp(0, EXPONENT_MAX),
}
}
pub fn to_raw_parts(self) -> (usize, RoundingMode, Consts, Exponent, Exponent) {
let Context {
p,
rm,
cc,
emin,
emax,
} = self;
(p, rm, cc, emin, emax)
}
pub fn set_precision(&mut self, p: usize) {
self.p = p;
}
pub fn set_rounding_mode(&mut self, rm: RoundingMode) {
self.rm = rm;
}
pub fn set_consts(&mut self, cc: Consts) {
self.cc = cc;
}
pub fn set_emin(&mut self, emin: Exponent) {
self.emin = emin.clamp(EXPONENT_MIN, 0);
}
pub fn set_emax(&mut self, emax: Exponent) {
self.emax = emax.clamp(0, EXPONENT_MAX);
}
pub fn precision(&self) -> usize {
self.p
}
pub fn rounding_mode(&self) -> RoundingMode {
self.rm
}
pub fn consts(&mut self) -> &mut Consts {
&mut self.cc
}
pub fn const_pi(&mut self) -> BigFloat {
self.cc.pi(self.p, self.rm)
}
pub fn const_e(&mut self) -> BigFloat {
self.cc.e(self.p, self.rm)
}
pub fn const_ln2(&mut self) -> BigFloat {
self.cc.ln_2(self.p, self.rm)
}
pub fn const_ln10(&mut self) -> BigFloat {
self.cc.ln_10(self.p, self.rm)
}
pub fn emin(&self) -> Exponent {
self.emin
}
pub fn emax(&self) -> Exponent {
self.emax
}
#[allow(clippy::should_implement_trait)]
pub fn clone(&self) -> Result<Self, Error> {
let cc = Consts::new()?;
Ok(Context {
p: self.p,
rm: self.rm,
cc,
emin: self.emin,
emax: self.emax,
})
}
}
pub trait Contextable {
fn precision(&self) -> usize;
fn rounding_mode(&self) -> RoundingMode;
fn consts(&mut self) -> &mut Consts;
fn const_pi(&mut self) -> BigFloat;
fn const_e(&mut self) -> BigFloat;
fn const_ln2(&mut self) -> BigFloat;
fn const_ln10(&mut self) -> BigFloat;
fn emin(&self) -> Exponent;
fn emax(&self) -> Exponent;
}
impl Contextable for (usize, RoundingMode, &mut Consts) {
fn precision(&self) -> usize {
self.0
}
fn rounding_mode(&self) -> RoundingMode {
self.1
}
fn consts(&mut self) -> &mut Consts {
self.2
}
fn const_pi(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().pi(p, rm)
}
fn const_e(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().e(p, rm)
}
fn const_ln2(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().ln_2(p, rm)
}
fn const_ln10(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().ln_10(p, rm)
}
fn emin(&self) -> Exponent {
EXPONENT_MIN
}
fn emax(&self) -> Exponent {
EXPONENT_MAX
}
}
impl Contextable for (usize, RoundingMode, &mut Consts, Exponent, Exponent) {
fn precision(&self) -> usize {
self.0
}
fn rounding_mode(&self) -> RoundingMode {
self.1
}
fn consts(&mut self) -> &mut Consts {
self.2
}
fn const_pi(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().pi(p, rm)
}
fn const_e(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().e(p, rm)
}
fn const_ln2(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().ln_2(p, rm)
}
fn const_ln10(&mut self) -> BigFloat {
let (p, rm) = (self.0, self.1);
self.consts().ln_10(p, rm)
}
fn emin(&self) -> Exponent {
self.3.clamp(EXPONENT_MIN, 0)
}
fn emax(&self) -> Exponent {
self.4.clamp(0, EXPONENT_MAX)
}
}
impl Contextable for Context {
fn precision(&self) -> usize {
Context::precision(self)
}
fn rounding_mode(&self) -> RoundingMode {
Context::rounding_mode(self)
}
fn consts(&mut self) -> &mut Consts {
Context::consts(self)
}
fn const_pi(&mut self) -> BigFloat {
Context::const_pi(self)
}
fn const_e(&mut self) -> BigFloat {
Context::const_e(self)
}
fn const_ln2(&mut self) -> BigFloat {
Context::const_ln2(self)
}
fn const_ln10(&mut self) -> BigFloat {
Context::const_ln10(self)
}
fn emin(&self) -> Exponent {
Context::emin(self)
}
fn emax(&self) -> Exponent {
Context::emax(self)
}
}