1pub use std::{
4 convert::{
5 From,
6 TryFrom
7 },
8 fmt,
9 ops::{
10 Add, AddAssign,
11 Neg,
12 Sub, SubAssign,
13 Mul, MulAssign,
14 Range
15 },
16 cmp::{
17 PartialEq,
18 PartialOrd,
19 Ordering,
20 max
21 },
22 num::{
23 TryFromIntError
24 },
25 error::{
26 Error
27 }
28};
29
30use crate::{digit::*, macros::*};
31
32#[derive(Clone, Copy, Eq)]
33pub enum Index {
34 Position(isize),
35 Bit(isize)
36}
37
38pub use Index::*;
39
40#[derive(Clone, Copy, Eq, PartialEq, Debug)]
41pub enum IndexError {
42 AdditionOverflow,
43 MultiplicationOverflow,
44 IntegerCastOverflow
45}
46
47impl fmt::Display for IndexError {
48 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49 write!(f, "{:?}", self)
50 }
51}
52
53impl Error for IndexError {}
54
55impl From<TryFromIntError> for IndexError {
56 fn from(_x: TryFromIntError) -> IndexError {
57 IntegerCastOverflow
58 }
59}
60
61pub use IndexError::*;
62
63impl Index {
64 pub fn castsize(x: usize) -> Result<isize, IndexError> {
66 Ok(TryFrom::try_from(x)?)
67 }
68 pub fn uncastsize(x: isize) -> Result<usize, IndexError> {
70 Ok(TryFrom::try_from(x)?)
71 }
72 pub fn position_to_bit(x: isize) -> Result<isize, IndexError> {
74 x.checked_mul(DIGITBITS as isize).ok_or(MultiplicationOverflow)
75 }
76
77 pub fn bit_to_position(x: isize) -> isize {
78 x.div_euclid(DIGITBITS as isize)
79 }
80
81 pub fn saturating_unsigned(x: isize) -> usize {
82 Index::uncastsize(max(0, x)).unwrap()
83 }
84
85 pub fn cast(&self) -> Result<Index, IndexError> {
86 match self {
87 Position(x) => Ok(Bit(Index::position_to_bit(*x)?)),
88 Bit(x) => Ok(Bit(Index::bit_to_position(*x)))
89 }
90 }
91
92 pub fn cast_to_position(&self) -> Index {
93 match self {
94 Position(_) => *self,
95 Bit(x) => Position(Index::bit_to_position(*x))
96 }
97 }
98
99 pub fn bit_position_excess(&self) -> isize {
100 match self {
101 Position(_) => 0,
102 Bit(x) => x.rem_euclid(DIGITBITS as isize)
103 }
104 }
105
106 pub fn cast_to_bit(&self) -> Result<Index, IndexError> {
107 match self {
108 Position(x) => Ok(Bit(Index::position_to_bit(*x)?)),
109 Bit(_) => Ok(*self)
110 }
111 }
112
113 pub fn saturating_nonnegative(&self) -> Index {
114 match self {
115 Position(x) => Position(max(0, *x)),
116 Bit(x) => Bit(max(0, *x))
117 }
118 }
119
120 pub fn value(&self) -> isize {
121 isize::from(self)
122 }
123
124 pub fn unsigned_value(&self) -> usize {
125 Index::saturating_unsigned(self.value())
126 }
127
128 pub fn bit_value(&self) -> Result<isize, IndexError> {
129 return Ok(self.cast_to_bit()?.value())
130 }
131
132 pub fn neg(self) -> Result<Index, IndexError> {
133 match self {
134 Position(x) => Ok(Position(x.checked_neg().ok_or(IntegerCastOverflow)?)),
135 Bit(x) => Ok(Bit(x.checked_neg().ok_or(IntegerCastOverflow)?))
136 }
137 }
138}
139
140macro_rules! formatter {
143 ($fmt_type: ident, $key: expr) => {
144 impl fmt::$fmt_type for Index {
145 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
146 match self {
147 Position(x) => {
148 write!(f, "(").ok();
149 write!(f, $key, x).ok();
150 write!(f, ")")
151 }, Bit(x) => {
152 write!(f, "[").ok();
153 write!(f, $key, x).ok();
154 write!(f, "]")
155 }
156 }
157 }
158 }
159 };
160}
161
162formatter!(Display, "{}");
163formatter!(Debug, "{:?}");
164formatter!(Octal, "{:o}");
165formatter!(LowerHex, "{:x}");
166formatter!(UpperHex, "{:X}");
167formatter!(Binary, "{:b}");
168
169impl From<&Index> for isize {
170 fn from(a: &Index) -> isize {
171 match a {
172 Position(x) => *x,
173 Bit(x) => *x
174 }
175 }
176}
177
178impl From<Index> for isize {
179 fn from(a: Index) -> isize {
180 isize::from(&a)
181 }
182}
183
184impl From<&Index> for usize {
185 fn from(a: &Index) -> usize {
186 match a.saturating_nonnegative() {
187 Position(x) => x as usize,
188 Bit(x) => x as usize
189 }
190 }
191}
192
193impl From<Index> for usize {
194 fn from(a: Index) -> usize {
195 usize::from(&a)
196 }
197}
198
199unary_copy!(Neg, neg, Index, neg, Index, IndexError);
200
201impl Add for &Index {
202 type Output = Result<Index, IndexError>;
203 fn add(self, other: &Index) -> Result<Index, IndexError> {
204 let a;
205 let b;
206 let position;
207 match (self, other) {
208 (Position(x), Position(y)) => {
209 a = *x;
210 b = *y;
211 position = true;
212 },
213 (Bit(x), Bit(y)) => {
214 a = *x;
215 b = *y;
216 position = false;
217 },
218 (Position(x), Bit(y)) => {
219 a = Index::position_to_bit(*x)?;
220 b = *y;
221 position = false;
222 },
223 (Bit(x), Position(y)) => {
224 a = *x;
225 b = Index::position_to_bit(*y)?;
226 position = false;
227 }
228 };
229 let sum = a.checked_add(b).ok_or(AdditionOverflow)?;
230 if position {
231 Ok(Position(sum))
232 } else {
233 Ok(Bit(sum))
234 }
235 }
236}
237
238op_to_op_assign!(
239 Add, add,
240 AddAssign, add_assign,
241 Index, Index,
242 Index, IndexError
243);
244
245impl Add<&usize> for &Index {
246 type Output = Result<Index, IndexError>;
247 fn add(self, other: &usize) -> Result<Index, IndexError> {
248 match self {
249 Position(x) => {
250 Ok(Position(x.checked_add(Index::castsize(*other)?).ok_or(AdditionOverflow)?))
251 },
252 Bit(x) => {
253 Ok(Bit(x.checked_add(Index::castsize(*other)?).ok_or(AdditionOverflow)?))
254 }
255 }
256 }
257}
258
259op_to_op_assign!(
260 Add, add,
261 AddAssign, add_assign,
262 Index, usize,
263 Index, IndexError
264);
265
266impl Add<&Index> for usize {
267 type Output = Result<Index, IndexError>;
268 fn add(self, other: &Index) -> Result<Index, IndexError> {
269 match other {
270 Position(x) => Ok(Position(x.checked_add(Index::castsize(self)?).ok_or(AdditionOverflow)?)),
271 Bit(x) => Ok(Bit(x.checked_add(Index::castsize(self)?).ok_or(AdditionOverflow)?)),
272 }
273 }
274}
275
276impl Add<Index> for usize {
277 type Output = Result<Index, IndexError>;
278 fn add(self, other: Index) -> Result<Index, IndexError> {
279 self + &other
280 }
281}
282
283impl Add<&isize> for &Index {
284 type Output = Result<Index, IndexError>;
285 fn add(self, other: &isize) -> Result<Index, IndexError> {
286 match self {
287 Position(x) => {
288 Ok(Position(x.checked_add(*other).ok_or(AdditionOverflow)?))
289 },
290 Bit(x) => {
291 Ok(Bit(x.checked_add(*other).ok_or(AdditionOverflow)?))
292 }
293 }
294 }
295}
296
297op_to_op_assign!(
298 Add, add,
299 AddAssign, add_assign,
300 Index, isize,
301 Index, IndexError
302);
303
304impl Add<&Index> for isize {
305 type Output = Result<Index, IndexError>;
306 fn add(self, other: &Index) -> Result<Index, IndexError> {
307 match other {
308 Position(x) => Ok(Position(self.checked_add(*x).ok_or(AdditionOverflow)?)),
309 Bit(x) => Ok(Bit(self.checked_add(*x).ok_or(AdditionOverflow)?))
310 }
311 }
312}
313
314impl Add<Index> for isize {
315 type Output = Result<Index, IndexError>;
316 fn add(self, other: Index) -> Result<Index, IndexError> {
317 self + &other
318 }
319}
320
321impl Sub for &Index {
322 type Output = Result<Index, IndexError>;
323 fn sub(self, other: &Index) -> Result<Index, IndexError> {
324 let a;
325 let b;
326 let position;
327 match (self, other) {
328 (Position(x), Position(y)) => {
329 a = *x;
330 b = *y;
331 position = true;
332 },
333 (Bit(x), Bit(y)) => {
334 a = *x;
335 b = *y;
336 position = false;
337 },
338 (Position(x), Bit(y)) => {
339 a = Index::position_to_bit(*x)?;
340 b = *y;
341 position = false;
342 },
343 (Bit(x), Position(y)) => {
344 a = *x;
345 b = Index::position_to_bit(*y)?;
346 position = false;
347 }
348 };
349 let diff = a.checked_sub(b).ok_or(AdditionOverflow)?;
350 if position {
351 Ok(Position(diff))
352 } else {
353 Ok(Bit(diff))
354 }
355 }
356}
357
358op_to_op_assign!(
359 Sub, sub,
360 SubAssign, sub_assign,
361 Index, Index,
362 Index, IndexError
363);
364
365impl Sub<&usize> for &Index {
366 type Output = Result<Index, IndexError>;
367 fn sub(self, other: &usize) -> Result<Index, IndexError> {
368 match self {
369 Position(x) => {
370 Ok(Position(x.checked_sub(Index::castsize(*other)?).ok_or(AdditionOverflow)?))
371 },
372 Bit(x) => {
373 Ok(Bit(x.checked_sub(Index::castsize(*other)?).ok_or(AdditionOverflow)?))
374 }
375 }
376 }
377}
378
379op_to_op_assign!(
380 Sub, sub,
381 SubAssign, sub_assign,
382 Index, usize,
383 Index, IndexError
384);
385
386impl Sub<&Index> for usize {
387 type Output = Result<Index, IndexError>;
388 fn sub(self, other: &Index) -> Result<Index, IndexError> {
389 match other {
390 Position(x) => Ok(Position(Index::castsize(self)?.checked_sub(*x).ok_or(AdditionOverflow)?)),
391 Bit(x) => Ok(Bit(Index::castsize(self)?.checked_sub(*x).ok_or(AdditionOverflow)?)),
392 }
393 }
394}
395
396impl Sub<Index> for usize {
397 type Output = Result<Index, IndexError>;
398 fn sub(self, other: Index) -> Result<Index, IndexError> {
399 self - &other
400 }
401}
402
403impl Sub<&isize> for &Index {
404 type Output = Result<Index, IndexError>;
405 fn sub(self, other: &isize) -> Result<Index, IndexError> {
406 match self {
407 Position(x) => {
408 Ok(Position(x.checked_sub(*other).ok_or(AdditionOverflow)?))
409 },
410 Bit(x) => {
411 Ok(Bit(x.checked_sub(*other).ok_or(AdditionOverflow)?))
412 }
413 }
414 }
415}
416
417op_to_op_assign!(
418 Sub, sub,
419 SubAssign, sub_assign,
420 Index, isize,
421 Index, IndexError
422);
423
424impl Sub<&Index> for isize {
425 type Output = Result<Index, IndexError>;
426 fn sub(self, other: &Index) -> Result<Index, IndexError> {
427 match other {
428 Position(x) => Ok(Position(self.checked_sub(*x).ok_or(AdditionOverflow)?)),
429 Bit(x) => Ok(Bit(self.checked_sub(*x).ok_or(AdditionOverflow)?))
430 }
431 }
432}
433
434impl Sub<Index> for isize {
435 type Output = Result<Index, IndexError>;
436 fn sub(self, other: Index) -> Result<Index, IndexError> {
437 self - &other
438 }
439}
440
441impl Mul for &Index {
442 type Output = Result<Index, IndexError>;
443 fn mul(self, other: &Index) -> Result<Index, IndexError> {
444 let a;
445 let b;
446 let position;
447 match (self, other) {
448 (Position(x), Position(y)) => {
449 a = *x;
450 b = *y;
451 position = true;
452 },
453 (Bit(x), Bit(y)) => {
454 a = *x;
455 b = *y;
456 position = false;
457 },
458 (Position(x), Bit(y)) => {
459 a = Index::position_to_bit(*x)?;
460 b = *y;
461 position = false;
462 },
463 (Bit(x), Position(y)) => {
464 a = *x;
465 b = Index::position_to_bit(*y)?;
466 position = false;
467 }
468 };
469 let prod = a.checked_mul(b).ok_or(AdditionOverflow)?;
470 if position {
471 Ok(Position(prod))
472 } else {
473 Ok(Bit(prod))
474 }
475 }
476}
477
478op_to_op_assign!(
479 Mul, mul,
480 MulAssign, mul_assign,
481 Index, Index,
482 Index, IndexError
483);
484
485impl Mul<&usize> for &Index {
486 type Output = Result<Index, IndexError>;
487 fn mul(self, other: &usize) -> Result<Index, IndexError> {
488 match self {
489 Position(x) => {
490 Ok(Position(x.checked_mul(Index::castsize(*other)?).ok_or(AdditionOverflow)?))
491 },
492 Bit(x) => {
493 Ok(Bit(x.checked_mul(Index::castsize(*other)?).ok_or(AdditionOverflow)?))
494 }
495 }
496 }
497}
498
499op_to_op_assign!(
500 Mul, mul,
501 MulAssign, mul_assign,
502 Index, usize,
503 Index, IndexError
504);
505
506impl Mul<&Index> for usize {
507 type Output = Result<Index, IndexError>;
508 fn mul(self, other: &Index) -> Result<Index, IndexError> {
509 match other {
510 Position(x) => Ok(Position(x.checked_mul(Index::castsize(self)?).ok_or(AdditionOverflow)?)),
511 Bit(x) => Ok(Bit(x.checked_mul(Index::castsize(self)?).ok_or(AdditionOverflow)?)),
512 }
513 }
514}
515
516impl Mul<Index> for usize {
517 type Output = Result<Index, IndexError>;
518 fn mul(self, other: Index) -> Result<Index, IndexError> {
519 self * &other
520 }
521}
522
523impl Mul<&isize> for &Index {
524 type Output = Result<Index, IndexError>;
525 fn mul(self, other: &isize) -> Result<Index, IndexError> {
526 match self {
527 Position(x) => {
528 Ok(Position(x.checked_mul(*other).ok_or(AdditionOverflow)?))
529 },
530 Bit(x) => {
531 Ok(Bit(x.checked_mul(*other).ok_or(AdditionOverflow)?))
532 }
533 }
534 }
535}
536
537op_to_op_assign!(
538 Mul, mul,
539 MulAssign, mul_assign,
540 Index, isize,
541 Index, IndexError
542);
543
544impl Mul<&Index> for isize {
545 type Output = Result<Index, IndexError>;
546 fn mul(self, other: &Index) -> Result<Index, IndexError> {
547 match other {
548 Position(x) => Ok(Position(self.checked_mul(*x).ok_or(AdditionOverflow)?)),
549 Bit(x) => Ok(Bit(self.checked_mul(*x).ok_or(AdditionOverflow)?))
550 }
551 }
552}
553
554impl Mul<Index> for isize {
555 type Output = Result<Index, IndexError>;
556 fn mul(self, other: Index) -> Result<Index, IndexError> {
557 self * &other
558 }
559}
560
561impl PartialEq for Index {
562 fn eq(&self, other: &Index) -> bool {
563 match (self, other) {
564 (Position(x), Position(y)) => x == y,
565 (Bit(x), Bit(y)) => x == y,
566 (Position(x), Bit(y)) => {
567 *x == Index::bit_to_position(*y)
568 },
569 (Bit(x), Position(y)) => {
570 *y == Index::bit_to_position(*x)
571 }
572 }
573 }
574}
575
576impl PartialEq<isize> for Index {
577 fn eq(&self, other: &isize) -> bool {
578 match self {
579 Position(x) => *x == *other,
580 Bit(x) => *x == *other
581 }
582 }
583}
584
585impl PartialEq<usize> for Index {
586 fn eq(&self, other: &usize) -> bool {
587 let o = Index::castsize(*other).unwrap();
588 match self {
589 Position(x) => *x == o,
590 Bit(x) => *x == o
591 }
592 }
593}
594
595impl PartialOrd for Index {
596 fn partial_cmp(&self, other: &Index) -> Option<Ordering> {
597 match (self, other) {
598 (Position(x), Position(y)) => x.partial_cmp(y),
599 (Bit(x), Bit(y)) => x.partial_cmp(y),
600 (Position(x), Bit(y)) => {
601 match Index::position_to_bit(*x) {
602 Ok(z) => z.partial_cmp(y),
603 Err(_) => None
604 }
605 },
606 (Bit(x), Position(y)) => {
607 match Index::position_to_bit(*y) {
608 Ok(z) => x.partial_cmp(&z),
609 Err(_) => None
610 }
611 }
612 }
613 }
614}
615
616impl Ord for Index {
617 fn cmp(&self, other: &Index) -> Ordering {
618 self.partial_cmp(other).unwrap()
619 }
620}
621
622impl PartialOrd<isize> for Index {
623 fn partial_cmp(&self, other: &isize) -> Option<Ordering> {
624 match self {
625 Position(x) => x.partial_cmp(other),
626 Bit(x) => x.partial_cmp(other)
627 }
628 }
629}
630
631impl PartialOrd<usize> for Index {
632 fn partial_cmp(&self, other: &usize) -> Option<Ordering> {
633 let o = &Index::castsize(*other).unwrap();
634 match self {
635 Position(x) => x.partial_cmp(o),
636 Bit(x) => x.partial_cmp(o)
637 }
638 }
639}
640