bigfixed/big_fixed/
index_ops.rs1use crate::{digit::*, Index as Indx, BigFixed};
2
3use std::{ops::{Index, IndexMut}};
4
5impl Index<Indx> for BigFixed {
6 type Output = Digit;
7 fn index(&self, position: Indx) -> &Digit {
8 assert!(self.properly_positioned(), "indexing into an impoperly positioned BigFixed");
9 match position {
10 Indx::Position(_) => {
11 let shifted = (position - self.position).unwrap();
12 if shifted >= self.body.len() as isize {
13 &self.head
14 } else if shifted >= 0isize {
15 &self.body[usize::from(shifted)]
16 } else {
17 &0
18 }
19 },
20 Indx::Bit(b) => {
21 let d = self[Indx::bit_to_position(b)];
22 if (d >> position.bit_position_excess()) & 1 == 1 {
23 &1
24 } else {
25 &0
26 }
27 }
28 }
29 }
30}
31
32impl Index<isize> for BigFixed {
33 type Output = Digit;
34 fn index(&self, position: isize) -> &Digit {
35 &self[Indx::Position(position)]
36 }
37}
38
39impl IndexMut<Indx> for BigFixed {
41 fn index_mut(&mut self, position: Indx) -> &mut Digit {
42 let position = position.cast_to_position();
43 self.ensure_valid_position(position).unwrap(); self.body.index_mut(usize::from((position - self.position).unwrap()))
45 }
46}
47
48impl IndexMut<isize> for BigFixed {
49 fn index_mut(&mut self, position: isize) -> &mut Digit {
50 self.index_mut(Indx::Position(position))
51 }
52}
53
54impl BigFixed {
55 pub fn set_bit(&mut self, index: isize, value: Digit) {
56 assert!(value == 0 || value == 1, "set_bit requires a bit (0 or 1)");
57 let position = Indx::Bit(index);
58 let shift = Indx::bit_position_excess(&position);
59 self[position] = (self[position.cast_to_position()] & !(1 << shift)) | (value << shift);
60 }
61}