1use crate::BigFloat;
4use crate::Consts;
5use crate::Error;
6use crate::Exponent;
7use crate::RoundingMode;
8use crate::EXPONENT_MAX;
9use crate::EXPONENT_MIN;
10
11#[derive(Debug)]
13pub struct Context {
14 cc: Consts,
15 p: usize,
16 rm: RoundingMode,
17 emin: Exponent,
18 emax: Exponent,
19}
20
21impl Context {
22 pub fn new(p: usize, rm: RoundingMode, cc: Consts, emin: Exponent, emax: Exponent) -> Self {
26 Context {
27 cc,
28 p,
29 rm,
30 emin: emin.clamp(EXPONENT_MIN, 0),
31 emax: emax.clamp(0, EXPONENT_MAX),
32 }
33 }
34
35 pub fn to_raw_parts(self) -> (usize, RoundingMode, Consts, Exponent, Exponent) {
38 let Context {
39 p,
40 rm,
41 cc,
42 emin,
43 emax,
44 } = self;
45 (p, rm, cc, emin, emax)
46 }
47
48 pub fn set_precision(&mut self, p: usize) {
50 self.p = p;
51 }
52
53 pub fn set_rounding_mode(&mut self, rm: RoundingMode) {
55 self.rm = rm;
56 }
57
58 pub fn set_consts(&mut self, cc: Consts) {
60 self.cc = cc;
61 }
62
63 pub fn set_emin(&mut self, emin: Exponent) {
66 self.emin = emin.clamp(EXPONENT_MIN, 0);
67 }
68
69 pub fn set_emax(&mut self, emax: Exponent) {
72 self.emax = emax.clamp(0, EXPONENT_MAX);
73 }
74
75 pub fn precision(&self) -> usize {
77 self.p
78 }
79
80 pub fn rounding_mode(&self) -> RoundingMode {
82 self.rm
83 }
84
85 pub fn consts(&mut self) -> &mut Consts {
87 &mut self.cc
88 }
89
90 pub fn const_pi(&mut self) -> BigFloat {
92 self.cc.pi(self.p, self.rm)
93 }
94
95 pub fn const_e(&mut self) -> BigFloat {
97 self.cc.e(self.p, self.rm)
98 }
99
100 pub fn const_ln2(&mut self) -> BigFloat {
102 self.cc.ln_2(self.p, self.rm)
103 }
104
105 pub fn const_ln10(&mut self) -> BigFloat {
107 self.cc.ln_10(self.p, self.rm)
108 }
109
110 pub fn emin(&self) -> Exponent {
112 self.emin
113 }
114
115 pub fn emax(&self) -> Exponent {
117 self.emax
118 }
119
120 #[allow(clippy::should_implement_trait)]
126 pub fn clone(&self) -> Result<Self, Error> {
127 let cc = Consts::new()?;
128 Ok(Context {
129 p: self.p,
130 rm: self.rm,
131 cc,
132 emin: self.emin,
133 emax: self.emax,
134 })
135 }
136}
137
138pub trait Contextable {
159 fn precision(&self) -> usize;
161
162 fn rounding_mode(&self) -> RoundingMode;
164
165 fn consts(&mut self) -> &mut Consts;
167
168 fn const_pi(&mut self) -> BigFloat;
170
171 fn const_e(&mut self) -> BigFloat;
173
174 fn const_ln2(&mut self) -> BigFloat;
176
177 fn const_ln10(&mut self) -> BigFloat;
179
180 fn emin(&self) -> Exponent;
182
183 fn emax(&self) -> Exponent;
185}
186
187impl Contextable for (usize, RoundingMode, &mut Consts) {
188 fn precision(&self) -> usize {
189 self.0
190 }
191
192 fn rounding_mode(&self) -> RoundingMode {
193 self.1
194 }
195
196 fn consts(&mut self) -> &mut Consts {
197 self.2
198 }
199
200 fn const_pi(&mut self) -> BigFloat {
201 let (p, rm) = (self.0, self.1);
202 self.consts().pi(p, rm)
203 }
204
205 fn const_e(&mut self) -> BigFloat {
206 let (p, rm) = (self.0, self.1);
207 self.consts().e(p, rm)
208 }
209
210 fn const_ln2(&mut self) -> BigFloat {
211 let (p, rm) = (self.0, self.1);
212 self.consts().ln_2(p, rm)
213 }
214
215 fn const_ln10(&mut self) -> BigFloat {
216 let (p, rm) = (self.0, self.1);
217 self.consts().ln_10(p, rm)
218 }
219
220 fn emin(&self) -> Exponent {
221 EXPONENT_MIN
222 }
223
224 fn emax(&self) -> Exponent {
225 EXPONENT_MAX
226 }
227}
228
229impl Contextable for (usize, RoundingMode, &mut Consts, Exponent, Exponent) {
230 fn precision(&self) -> usize {
231 self.0
232 }
233
234 fn rounding_mode(&self) -> RoundingMode {
235 self.1
236 }
237
238 fn consts(&mut self) -> &mut Consts {
239 self.2
240 }
241
242 fn const_pi(&mut self) -> BigFloat {
243 let (p, rm) = (self.0, self.1);
244 self.consts().pi(p, rm)
245 }
246
247 fn const_e(&mut self) -> BigFloat {
248 let (p, rm) = (self.0, self.1);
249 self.consts().e(p, rm)
250 }
251
252 fn const_ln2(&mut self) -> BigFloat {
253 let (p, rm) = (self.0, self.1);
254 self.consts().ln_2(p, rm)
255 }
256
257 fn const_ln10(&mut self) -> BigFloat {
258 let (p, rm) = (self.0, self.1);
259 self.consts().ln_10(p, rm)
260 }
261
262 fn emin(&self) -> Exponent {
263 self.3.clamp(EXPONENT_MIN, 0)
264 }
265
266 fn emax(&self) -> Exponent {
267 self.4.clamp(0, EXPONENT_MAX)
268 }
269}
270
271impl Contextable for Context {
272 fn precision(&self) -> usize {
273 Context::precision(self)
274 }
275
276 fn rounding_mode(&self) -> RoundingMode {
277 Context::rounding_mode(self)
278 }
279
280 fn consts(&mut self) -> &mut Consts {
281 Context::consts(self)
282 }
283
284 fn const_pi(&mut self) -> BigFloat {
285 Context::const_pi(self)
286 }
287
288 fn const_e(&mut self) -> BigFloat {
289 Context::const_e(self)
290 }
291
292 fn const_ln2(&mut self) -> BigFloat {
293 Context::const_ln2(self)
294 }
295
296 fn const_ln10(&mut self) -> BigFloat {
297 Context::const_ln10(self)
298 }
299
300 fn emin(&self) -> Exponent {
301 Context::emin(self)
302 }
303
304 fn emax(&self) -> Exponent {
305 Context::emax(self)
306 }
307}