1
2use storage::{Storage};
3use digit::{Digit, Bit};
4use apint::{ApInt};
5use errors::{Error, Result};
6use traits::Width;
7use bitwidth::BitWidth;
8use digit_seq::{
9 ContiguousDigitSeq,
10 ContiguousDigitSeqMut
11};
12
13use std::fmt;
14use std::hash::{Hash, Hasher};
15
16impl fmt::Debug for ApInt {
17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18 f.debug_struct("ApInt")
19 .field("len", &self.width())
20 .field("digits", &self.as_digit_slice())
21 .finish()
22 }
23}
24
25impl Hash for ApInt {
26 fn hash<H: Hasher>(&self, state: &mut H) {
27 self.len.hash(state);
28 self.as_digit_slice().hash(state);
29 }
30}
31
32impl ApInt {
35 pub(in apint) fn digits(&self) -> ContiguousDigitSeq {
36 ContiguousDigitSeq::from(self.as_digit_slice())
37 }
38
39 pub(in apint) fn digits_mut(&mut self) -> ContiguousDigitSeqMut {
40 ContiguousDigitSeqMut::from(self.as_digit_slice_mut())
41 }
42}
43
44#[derive(Debug, Copy, Clone, PartialEq, Eq)]
47pub(crate) enum DataAccess<'a> {
48 Inl(Digit),
49 Ext(&'a [Digit])
50}
51
52#[derive(Debug, PartialEq, Eq)]
53pub(crate) enum DataAccessMut<'a> {
54 Inl(&'a mut Digit),
55 Ext(&'a mut [Digit])
56}
57
58#[derive(Debug, Copy, Clone, PartialEq, Eq)]
59pub(crate) enum ZipDataAccess<'a, 'b> {
60 Inl(Digit, Digit),
61 Ext(&'a [Digit], &'b [Digit])
62}
63
64#[derive(Debug, PartialEq, Eq)]
65pub(crate) enum ZipDataAccessMut<'a, 'b> {
66 Inl(&'a mut Digit, Digit),
67 Ext(&'a mut [Digit], &'b [Digit])
68}
69
70impl Width for ApInt {
73 #[inline]
75 fn width(&self) -> BitWidth {
76 BitWidth::new(self.len_bits()).unwrap()
77 }
78}
79
80impl ApInt {
82 #[inline]
84 pub(in apint) fn len_bits(&self) -> usize {
85 self.len.to_usize()
86 }
87
88 #[inline]
91 pub(in apint) fn len_digits(&self) -> usize {
92 self.len.required_digits()
93 }
94
95 #[inline]
100 pub(in apint) fn storage(&self) -> Storage {
101 self.len.storage()
102 }
103
104 #[inline]
106 pub(in apint) fn access_data(&self) -> DataAccess {
107 match self.storage() {
108 Storage::Inl => DataAccess::Inl(unsafe{self.data.inl}),
109 Storage::Ext => DataAccess::Ext(self.as_digit_slice())
110 }
111 }
112
113 #[inline]
115 pub(in apint) fn access_data_mut(&mut self) -> DataAccessMut {
116 match self.storage() {
117 Storage::Inl => DataAccessMut::Inl(unsafe{&mut self.data.inl}),
118 Storage::Ext => DataAccessMut::Ext(self.as_digit_slice_mut())
119 }
120 }
121
122 pub(in apint) fn zip_access_data<'a, 'b>(&'a self, other: &'b ApInt) -> Result<ZipDataAccess<'a, 'b>> {
128 if self.width() != other.width() {
129 return Error::unmatching_bitwidths(self.width(), other.width()).into()
130 }
131 Ok(match self.storage() {
132 Storage::Inl => {
133 ZipDataAccess::Inl(
134 unsafe{ self.data.inl},
135 unsafe{other.data.inl})
136 },
137 Storage::Ext => {
138 ZipDataAccess::Ext(
139 self.as_digit_slice(),
140 other.as_digit_slice())
141 }
142 })
143 }
144
145 pub(in apint) fn zip_access_data_mut<'a, 'b>(&'a mut self, other: &'b ApInt) -> Result<ZipDataAccessMut<'a, 'b>> {
151 if self.width() != other.width() {
152 return Error::unmatching_bitwidths(self.width(), other.width()).into()
153 }
154 Ok(match self.storage() {
155 Storage::Inl => {
156 ZipDataAccessMut::Inl(
157 unsafe{&mut self.data.inl},
158 unsafe{other.data.inl})
159 },
160 Storage::Ext => {
161 ZipDataAccessMut::Ext(
162 self.as_digit_slice_mut(),
163 other.as_digit_slice())
164 }
165 })
166 }
167
168 pub(in apint) fn modify_digits<F>(&mut self, f: F)
176 where F: Fn(&mut Digit)
177 {
178 use self::DataAccessMut::*;
179 match self.access_data_mut() {
180 Inl(digit) => f(digit),
181 Ext(digits) => {
182 for digit in digits {
183 f(digit)
184 }
185 }
186 }
187 }
188
189 pub(in apint) fn modify_zipped_digits<F>(&mut self, rhs: &ApInt, f: F) -> Result<()>
197 where F: Fn(&mut Digit, Digit)
198 {
199 use self::ZipDataAccessMut::*;
200 match self.zip_access_data_mut(rhs)? {
201 Inl(lhs, rhs) => f(lhs, rhs),
202 Ext(lhs, rhs) => {
203 for (l, &r) in lhs.into_iter().zip(rhs) {
204 f(l, r)
205 }
206 }
207 }
208 Ok(())
209 }
210
211 pub(in apint) fn as_digit_slice(&self) -> &[Digit] {
213 use std::slice;
214 match self.len.storage() {
215 Storage::Inl => unsafe {
216 slice::from_raw_parts(&self.data.inl, 1)
217 },
218 Storage::Ext => unsafe {
219 slice::from_raw_parts(self.data.ext.as_ptr(), self.len_digits())
220 }
221 }
222 }
223
224 pub(in apint) fn as_digit_slice_mut(&mut self) -> &mut [Digit] {
226 use std::slice;
227 match self.len.storage() {
228 Storage::Inl => unsafe {
229 slice::from_raw_parts_mut(&mut self.data.inl, 1)
230 },
231 Storage::Ext => unsafe {
232 slice::from_raw_parts_mut(self.data.ext.as_ptr(), self.len_digits())
233 }
234 }
235 }
236
237 pub(in apint) fn most_significant_digit(&self) -> Digit {
239 match self.access_data() {
240 DataAccess::Inl(digit) => digit,
241 DataAccess::Ext(digits) => {
242 *digits.last().unwrap()
243 }
244 }
245 }
246
247 pub(in apint) fn most_significant_digit_mut(&mut self) -> &mut Digit {
249 match self.access_data_mut() {
250 DataAccessMut::Inl(digit) => digit,
251 DataAccessMut::Ext(digits) => {
252 digits.last_mut().unwrap()
253 }
254 }
255 }
256
257 pub(in apint) fn least_significant_digit(&self) -> Digit {
259 match self.access_data() {
260 DataAccess::Inl(digit) => digit,
261 DataAccess::Ext(digits) => digits[0]
262 }
263 }
264
265 pub(in apint) fn most_significant_bit(&self) -> Bit {
268 let sign_bit_pos = self.width().sign_bit_pos();
269 self.most_significant_digit()
270 .get(sign_bit_pos.to_pos_within_digit())
271 .expect("`BitWidth::excess_bits` returns a number that \
272 is always a valid `BitPos` for a `Digit` so this \
273 operation cannot fail.")
274 }
275
276 pub(in apint) fn least_significant_bit(&self) -> Bit {
279 self.least_significant_digit().least_significant_bit()
280 }
281
282 pub(in apint) fn clear_unused_bits(&mut self) {
293 if let Some(bits) = self.width().excess_bits() {
294 self.most_significant_digit_mut()
295 .retain_last_n(bits)
296 .expect("`BitWidth::excess_bits` always returns a number of \
297 bits that can safely forwarded to `Digit::retain_last_n`.");
298 }
299 }
300
301 pub fn is_zero(&self) -> bool {
309 match self.access_data() {
310 DataAccess::Inl(digit) => digit.is_zero(),
311 DataAccess::Ext(digits) => {
312 digits.into_iter().all(|digit| digit.is_zero())
313 }
314 }
315 }
316
317 pub fn is_one(&self) -> bool {
325 match self.access_data() {
326 DataAccess::Inl(digit) => digit == Digit::one(),
327 DataAccess::Ext(digits) => {
328 let (last, rest) = digits.split_last()
329 .expect("An `ApInt` always has at least one digit so calling \
330 `split_last` on a slice of its digits will never \
331 return `None`.");
332 last.is_one() && rest.into_iter().all(|digit| digit.is_zero())
333 }
334 }
335 }
336
337 #[inline]
339 pub fn is_even(&self) -> bool {
340 self.least_significant_bit() == Bit::Unset
341 }
342
343 #[inline]
345 pub fn is_odd(&self) -> bool {
346 self.least_significant_bit() == Bit::Set
347 }
348
349 pub(in apint) fn split_least_significant_digit(&self) -> (Digit, &[Digit]) {
352 match self.access_data() {
353 DataAccess::Inl(digit) => (digit, &[]),
354 DataAccess::Ext(digits) => {
355 let (lsd, rest) = digits.split_first()
356 .expect("An `ApInt` always has at least one digit so calling \
357 `split_first` on a slice of its digits will never \
358 return `None`.");
359 (*lsd, rest)
360 }
361 }
362 }
363
364 pub(in apint) fn split_most_significant_digit(&self) -> (Digit, &[Digit]) {
367 match self.access_data() {
368 DataAccess::Inl(digit) => (digit, &[]),
369 DataAccess::Ext(digits) => {
370 let (lsd, rest) = digits.split_last()
371 .expect("An `ApInt` always has at least one digit so calling \
372 `split_last` on a slice of its digits will never \
373 return `None`.");
374 (*lsd, rest)
375 }
376 }
377 }
378}
379
380#[cfg(test)]
381mod tests {
382 use super::*;
383
384 #[test]
385 fn most_significant_bit() {
386 assert_eq!(Bit::Unset,
387 ApInt::from_bit(false).most_significant_bit());
388 assert_eq!(Bit::Set,
389 ApInt::from_bit(true).most_significant_bit());
390 assert_eq!(Bit::Unset,
391 ApInt::from_u8(0b0101_0101).most_significant_bit());
392 assert_eq!(Bit::Set,
393 ApInt::from_u8(0b1101_0101).most_significant_bit());
394 assert_eq!(Bit::Unset,
395 ApInt::from_u16(0b0111_1000_1101_0101).most_significant_bit());
396 assert_eq!(Bit::Set,
397 ApInt::from_u16(0b1011_0001_0101_0101).most_significant_bit());
398 assert_eq!(Bit::Unset,
399 ApInt::from_u32(0x7000_0000).most_significant_bit());
400 assert_eq!(Bit::Set,
401 ApInt::from_u32(0x8000_0000).most_significant_bit());
402 assert_eq!(Bit::Unset,
403 ApInt::from_u64(0x70FC_A875_4321_1234).most_significant_bit());
404 assert_eq!(Bit::Set,
405 ApInt::from_u64(0x8765_4321_5555_6666).most_significant_bit());
406 }
407}