1#![allow(dead_code, non_snake_case, non_camel_case_types)]
7
8use core::{
9 cmp::Ordering,
10 ops::{
11 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign,
12 Sub, SubAssign,
13 },
14};
15
16use crate::{error::Error, util::t::Constant};
17
18macro_rules! define_ranged {
19 (
20 $name:ident,
21 $repr:ty,
22 smaller { $($smaller_name:ident $smaller_repr:ty),* },
23 bigger { $($bigger_name:ident $bigger_repr:ty),* }
24 ) => {
25 #[derive(Clone, Copy, Hash)]
26 pub(crate) struct $name<const MIN: i128, const MAX: i128> {
27 pub(crate) val: $repr,
35 #[cfg(debug_assertions)]
48 pub(crate) min: $repr,
49 #[cfg(debug_assertions)]
62 pub(crate) max: $repr,
63 }
64
65 impl<const MIN: i128, const MAX: i128> $name<MIN, MAX> {
66 const PRIMITIVE_MIN: i128 = <$repr>::MIN as i128;
69 const PRIMITIVE_MAX: i128 = <$repr>::MAX as i128;
70
71 const IS_PRIMITIVE: bool = Self::MIN_REPR == <$repr>::MIN
74 && Self::MAX_REPR == <$repr>::MAX;
75
76 pub(crate) const MIN: i128 = MIN;
78 pub(crate) const MAX: i128 = MAX;
79
80 pub(crate) const LEN: i128 = {
82 assert!(Self::PRIMITIVE_MIN < Self::PRIMITIVE_MAX);
83 MAX - MIN + 1
84 };
85
86 pub(crate) const MIN_REPR: $repr = {
89 assert!(
90 Self::PRIMITIVE_MIN <= MIN && MIN <= Self::PRIMITIVE_MAX
91 );
92 MIN as $repr
93 };
94 pub(crate) const MAX_REPR: $repr = {
95 assert!(
96 Self::PRIMITIVE_MIN <= MAX && MAX <= Self::PRIMITIVE_MAX
97 );
98 MAX as $repr
99 };
100
101 pub(crate) const MIN_SELF: Self =
103 Self::new_unchecked(Self::MIN_REPR);
104 pub(crate) const MAX_SELF: Self =
105 Self::new_unchecked(Self::MAX_REPR);
106
107 pub(crate) const MIN_CONST: Constant =
109 Constant(Self::MIN_REPR as i64);
110 pub(crate) const MAX_CONST: Constant =
111 Constant(Self::MAX_REPR as i64);
112
113 #[inline]
114 pub(crate) fn error(
115 what: &'static str,
116 given: $repr,
117 ) -> Error {
118 Error::range(what, given, Self::MIN_REPR, Self::MAX_REPR)
119 }
120
121 #[inline]
122 pub(crate) fn new(val: impl TryInto<$repr>) -> Option<Self> {
123 let val = val.try_into().ok()?;
124 if !Self::contains(val) {
125 return None;
126 }
127 #[cfg(not(debug_assertions))]
128 {
129 Some(Self { val })
130 }
131 #[cfg(debug_assertions)]
132 {
133 Some(Self {
134 val,
135 min: Self::MIN_REPR,
136 max: Self::MAX_REPR,
137 })
138 }
139 }
140
141 #[inline]
143 pub(crate) const fn new_const(val: $repr) -> Option<Self> {
144 if !Self::contains(val) {
145 return None;
146 }
147 #[cfg(not(debug_assertions))]
148 {
149 Some(Self { val })
150 }
151 #[cfg(debug_assertions)]
152 {
153 Some(Self {
154 val,
155 min: Self::MIN_REPR,
156 max: Self::MAX_REPR,
157 })
158 }
159 }
160
161 #[inline]
162 pub(crate) fn try_new(
163 what: &'static str,
164 val: impl Into<i64>,
165 ) -> Result<Self, Error> {
166 let val = val.into();
167 #[allow(irrefutable_let_patterns)]
168 let Ok(val) = <$repr>::try_from(val) else {
169 return Err(Error::range(
170 what,
171 val,
172 Self::MIN_REPR,
173 Self::MAX_REPR,
174 ));
175 };
176 Self::new(val).ok_or_else(|| Self::error(what, val))
177 }
178
179 #[inline]
180 pub(crate) fn try_new128(
181 what: &'static str,
182 val: impl Into<i128>,
183 ) -> Result<Self, Error> {
184 let val = val.into();
185 #[allow(irrefutable_let_patterns)]
186 let Ok(val) = <$repr>::try_from(val) else {
187 return Err(Error::range(
188 what,
189 val,
190 Self::MIN_REPR,
191 Self::MAX_REPR,
192 ));
193 };
194 Self::new(val).ok_or_else(|| Self::error(what, val))
195 }
196
197 #[inline]
198 pub(crate) fn constrain(val: impl Into<$repr>) -> Self {
199 let val = val.into().clamp(Self::MIN_REPR, Self::MAX_REPR);
200 Self::new_unchecked(val)
201 }
202
203 #[inline]
204 pub(crate) const fn new_unchecked(val: $repr) -> Self {
205 #[cfg(not(debug_assertions))]
206 {
207 Self { val }
208 }
209 #[cfg(debug_assertions)]
210 {
211 assert!(Self::contains(val), "val is not in range");
212 Self { val, min: Self::MIN_REPR, max: Self::MAX_REPR }
213 }
214 }
215
216 #[inline]
217 pub(crate) const fn N<const VAL: $repr>() -> Self {
218 #[cfg(not(debug_assertions))]
219 {
220 Self { val: VAL }
221 }
222 #[cfg(debug_assertions)]
223 {
224 Self { val: VAL, min: VAL, max: VAL }
225 }
226 }
227
228 #[inline]
229 pub(crate) const fn N128<const VAL: i128>() -> Self {
230 #[cfg(not(debug_assertions))]
231 {
232 Self { val: VAL as $repr }
233 }
234 #[cfg(debug_assertions)]
235 {
236 if !(MIN <= VAL && VAL <= MAX) {
237 panic!("constant out of range");
238 }
239 let val = VAL as $repr;
240 Self { val, min: val, max: val }
241 }
242 }
243
244 #[inline]
245 pub(crate) const fn V<
246 const VAL: $repr,
247 const START: $repr,
248 const END: $repr,
249 >() -> Self {
250 #[cfg(not(debug_assertions))]
251 {
252 Self { val: VAL }
253 }
254 #[cfg(debug_assertions)]
255 {
256 Self { val: VAL, min: START, max: END }
257 }
258 }
259
260 #[inline]
261 pub(crate) const fn contains(val: $repr) -> bool {
262 Self::MIN_REPR <= val && val <= Self::MAX_REPR
263 }
264
265 #[inline]
266 pub(crate) fn vary<
267 const N: usize,
268 const MIN2: i128,
269 const MAX2: i128,
270 >(
271 numbers: [Self; N],
272 with: impl Fn([Self; N]) -> $name<MIN2, MAX2>,
273 ) -> $name<MIN2, MAX2> {
274 let [result] =
275 Self::vary_many(numbers, |numbers| [with(numbers)]);
276 result
277 }
278
279 #[inline]
280 pub(crate) fn vary_many<
281 const N: usize,
282 const M: usize,
283 const MIN2: i128,
284 const MAX2: i128,
285 >(
286 numbers: [Self; N],
287 with: impl Fn([Self; N]) -> [$name<MIN2, MAX2>; M],
288 ) -> [$name<MIN2, MAX2>; M] {
289 #[cfg(not(debug_assertions))]
290 {
291 with(numbers)
292 }
293 #[cfg(debug_assertions)]
294 {
295 let vals = with(numbers);
296 let mins = with(numbers.map(|n| Self {
297 val: n.min,
298 min: n.min,
299 max: n.max,
300 }));
301 let maxs = with(numbers.map(|n| Self {
302 val: n.max,
303 min: n.min,
304 max: n.max,
305 }));
306 let mut result = [$name::MIN_SELF; M];
307 let it = vals.into_iter().zip(mins).zip(maxs).enumerate();
308 for (i, ((val, min), max)) in it {
309 result[i] =
310 $name { val: val.val, min: min.val, max: max.val };
311 }
312 result
313 }
314 }
315
316 #[inline]
317 pub(crate) fn get(self) -> $repr {
318 #[cfg(not(debug_assertions))]
319 {
320 self.val
321 }
322 #[cfg(debug_assertions)]
323 {
324 assert!(
325 Self::contains(self.val),
326 concat!(
327 stringify!($name),
328 " val {val:?} is not in range {MIN:?}..={MAX:?}"
329 ),
330 val = self.val,
331 MIN = MIN,
332 MAX = MAX,
333 );
334 assert!(
335 Self::contains(self.min),
336 concat!(
337 stringify!($name),
338 " min {min:?} is not in range {MIN:?}..={MAX:?}"
339 ),
340 min = self.min,
341 MIN = MIN,
342 MAX = MAX,
343 );
344 assert!(
345 Self::contains(self.max),
346 concat!(
347 stringify!($name),
348 " max {max:?} is not in range {MIN:?}..={MAX:?}"
349 ),
350 max = self.max,
351 MIN = MIN,
352 MAX = MAX,
353 );
354 self.val
355 }
356 }
357
358 #[inline]
369 pub(crate) const fn get_unchecked(self) -> $repr {
370 self.val
371 }
372
373 #[inline]
383 pub(crate) fn to_error_with_bounds(
384 self,
385 what: &'static str,
386 min: impl Into<i128>,
387 max: impl Into<i128>,
388 ) -> Error {
389 Error::range(
390 what,
391 self.get_unchecked(),
392 min.into(),
393 max.into(),
394 )
395 }
396
397 #[inline]
398 pub(crate) fn abs(self) -> Self {
399 #[cfg(not(debug_assertions))]
400 {
401 $name { val: self.val.abs() }
402 }
403 #[cfg(debug_assertions)]
404 {
405 let val = self.val.checked_abs().expect(concat!(
406 "absolute value of ",
407 stringify!($name),
408 " value overflowed",
409 ));
410 let min = self.min.checked_abs().expect(concat!(
411 "absolute value of ",
412 stringify!($name),
413 " minimum overflowed",
414 ));
415 let max = self.max.checked_abs().expect(concat!(
416 "absolute value of ",
417 stringify!($name),
418 " maximum overflowed",
419 ));
420 $name { val, min, max }
421 }
422 }
423
424 #[inline]
425 pub(crate) fn signum(self) -> $name<-1, 1> {
426 #[cfg(not(debug_assertions))]
427 {
428 $name { val: self.val.signum() }
429 }
430 #[cfg(debug_assertions)]
431 {
432 let val = self.val.signum();
433 let min = self.min.signum();
434 let max = self.max.signum();
435 $name { val, min, max }
436 }
437 }
438
439 #[inline]
440 pub(crate) fn min(self, other: impl RInto<Self>) -> Self {
441 let other = other.rinto();
442 #[cfg(not(debug_assertions))]
443 {
444 Self { val: self.val.min(other.val) }
445 }
446 #[cfg(debug_assertions)]
447 {
448 let val = self.val.min(other.val);
449 let min = self.val.min(other.min);
450 let max = self.max.min(other.max);
451 Self { val, min, max }
452 }
453 }
454
455 #[inline]
456 pub(crate) fn max(self, other: impl RInto<Self>) -> Self {
457 let other = other.rinto();
458 #[cfg(not(debug_assertions))]
459 {
460 Self { val: self.val.max(other.val) }
461 }
462 #[cfg(debug_assertions)]
463 {
464 let val = self.val.max(other.val);
465 let min = self.val.max(other.min);
466 let max = self.max.max(other.max);
467 Self { val, min, max }
468 }
469 }
470
471 #[inline]
472 pub(crate) fn clamp(
473 self,
474 min: impl RInto<Self>,
475 max: impl RInto<Self>,
476 ) -> Self {
477 self.min(max).max(min)
478 }
479
480 #[inline]
481 pub(crate) fn div_ceil(self, rhs: impl RInto<Self>) -> Self {
482 let rhs = rhs.rinto();
483 #[cfg(not(debug_assertions))]
484 {
485 let val = self.val.wrapping_div(rhs.val);
486 Self { val }
487 }
488 #[cfg(debug_assertions)]
489 {
490 let val = self.val.checked_div(rhs.val).expect(concat!(
491 "dividing(ceil) ",
492 stringify!($name),
493 " values overflowed"
494 ));
495 let min = self.min.checked_div(rhs.min).expect(concat!(
496 "dividing(ceil) ",
497 stringify!($name),
498 " minimums overflowed"
499 ));
500 let max = self.max.checked_div(rhs.max).expect(concat!(
501 "dividing(ceil) ",
502 stringify!($name),
503 " maximums overflowed"
504 ));
505 Self { val, min, max }
506 }
507 }
508
509 #[inline]
510 pub(crate) fn div_floor(self, rhs: impl RInto<Self>) -> Self {
511 let rhs = rhs.rinto();
512 #[cfg(not(debug_assertions))]
513 {
514 let val = self.val.wrapping_div_euclid(rhs.val);
515 Self { val }
516 }
517 #[cfg(debug_assertions)]
518 {
519 let val =
520 self.val.checked_div_euclid(rhs.val).expect(concat!(
521 "dividing(ceil) ",
522 stringify!($name),
523 " values overflowed"
524 ));
525 let min =
526 self.min.checked_div_euclid(rhs.min).expect(concat!(
527 "dividing(ceil) ",
528 stringify!($name),
529 " minimums overflowed"
530 ));
531 let max =
532 self.max.checked_div_euclid(rhs.max).expect(concat!(
533 "dividing(ceil) ",
534 stringify!($name),
535 " maximums overflowed"
536 ));
537 Self { val, min, max }
538 }
539 }
540
541 #[inline]
542 pub(crate) fn rem_ceil(self, rhs: impl RInto<Self>) -> Self {
543 let rhs = rhs.rinto();
544 #[cfg(not(debug_assertions))]
545 {
546 let val = self.val.wrapping_rem(rhs.val);
547 Self { val }
548 }
549 #[cfg(debug_assertions)]
550 {
551 let val = self.val.checked_rem(rhs.val).expect(concat!(
552 "modulo(ceil) ",
553 stringify!($name),
554 " values overflowed"
555 ));
556 let min = self.min.checked_rem(rhs.min).expect(concat!(
557 "modulo(ceil) ",
558 stringify!($name),
559 " minimums overflowed"
560 ));
561 let max = self.max.checked_rem(rhs.max).expect(concat!(
562 "modulo(ceil) ",
563 stringify!($name),
564 " maximums overflowed"
565 ));
566 Self { val, min, max }
567 }
568 }
569
570 #[inline]
571 pub(crate) fn rem_floor(self, rhs: impl RInto<Self>) -> Self {
572 let rhs = rhs.rinto();
573 #[cfg(not(debug_assertions))]
574 {
575 let val = self.val.wrapping_rem_euclid(rhs.val);
576 Self { val }
577 }
578 #[cfg(debug_assertions)]
579 {
580 let val =
581 self.val.checked_rem_euclid(rhs.val).expect(concat!(
582 "modulo(ceil) ",
583 stringify!($name),
584 " values overflowed"
585 ));
586 let min =
587 self.min.checked_rem_euclid(rhs.min).expect(concat!(
588 "modulo(ceil) ",
589 stringify!($name),
590 " minimums overflowed"
591 ));
592 let max =
593 self.max.checked_rem_euclid(rhs.max).expect(concat!(
594 "modulo(ceil) ",
595 stringify!($name),
596 " maximums overflowed"
597 ));
598 Self { val, min, max }
599 }
600 }
601
602 #[inline]
603 pub(crate) fn try_checked_add(
604 self,
605 what: &'static str,
606 rhs: impl RInto<Self>,
607 ) -> Result<Self, Error> {
608 let rhs = rhs.rinto();
609 self.checked_add(rhs)
610 .ok_or_else(|| Self::error(what, rhs.get_unchecked()))
611 }
612
613 #[inline]
614 pub(crate) fn try_checked_sub(
615 self,
616 what: &'static str,
617 rhs: impl RInto<Self>,
618 ) -> Result<Self, Error> {
619 let rhs = rhs.rinto();
620 self.checked_sub(rhs)
621 .ok_or_else(|| Self::error(what, rhs.get_unchecked()))
622 }
623
624 #[inline]
625 pub(crate) fn try_checked_mul(
626 self,
627 what: &'static str,
628 rhs: impl RInto<Self>,
629 ) -> Result<Self, Error> {
630 let rhs = rhs.rinto();
631 self.checked_mul(rhs)
632 .ok_or_else(|| Self::error(what, rhs.get_unchecked()))
633 }
634
635 #[inline]
636 pub(crate) fn checked_add(
637 self,
638 rhs: impl RInto<Self>,
639 ) -> Option<Self> {
640 let rhs = rhs.rinto();
641 #[cfg(not(debug_assertions))]
642 {
643 let val = self.val.checked_add(rhs.val)?;
644 Self::new(val)
645 }
646 #[cfg(debug_assertions)]
647 {
648 let val = self.val.checked_add(rhs.val)?;
649 if !Self::contains(val) {
650 return None;
651 }
652 let min = self
660 .min
661 .saturating_add(rhs.min)
662 .clamp(Self::MIN_REPR, Self::MAX_REPR);
663 let max = self
664 .max
665 .saturating_add(rhs.max)
666 .clamp(Self::MIN_REPR, Self::MAX_REPR);
667 Some(Self { val, min, max })
668 }
669 }
670
671 #[inline]
672 pub(crate) fn checked_sub(
673 self,
674 rhs: impl RInto<Self>,
675 ) -> Option<Self> {
676 let rhs = rhs.rinto();
677 #[cfg(not(debug_assertions))]
678 {
679 let val = self.val.checked_sub(rhs.val)?;
680 Self::new(val)
681 }
682 #[cfg(debug_assertions)]
683 {
684 let val = self.val.checked_sub(rhs.val)?;
685 if !Self::contains(val) {
686 return None;
687 }
688 let min = self
690 .min
691 .saturating_sub(rhs.min)
692 .clamp(Self::MIN_REPR, Self::MAX_REPR);
693 let max = self
694 .max
695 .saturating_sub(rhs.max)
696 .clamp(Self::MIN_REPR, Self::MAX_REPR);
697 Some(Self { val, min, max })
698 }
699 }
700
701 #[inline]
702 pub(crate) fn checked_mul(
703 self,
704 rhs: impl RInto<Self>,
705 ) -> Option<Self> {
706 let rhs = rhs.rinto();
707 #[cfg(not(debug_assertions))]
708 {
709 let val = self.val.checked_mul(rhs.val)?;
710 Self::new(val)
711 }
712 #[cfg(debug_assertions)]
713 {
714 let val = self.val.checked_mul(rhs.val)?;
715 if !Self::contains(val) {
716 return None;
717 }
718 let min = self
720 .min
721 .saturating_mul(rhs.min)
722 .clamp(Self::MIN_REPR, Self::MAX_REPR);
723 let max = self
724 .max
725 .saturating_mul(rhs.max)
726 .clamp(Self::MIN_REPR, Self::MAX_REPR);
727 Some(Self { val, min, max })
728 }
729 }
730
731 #[inline]
732 pub(crate) fn wrapping_add(self, rhs: impl RInto<Self>) -> Self {
733 let rhs = rhs.rinto();
734 #[cfg(not(debug_assertions))]
735 {
736 if Self::IS_PRIMITIVE {
742 Self { val: self.val.wrapping_add(rhs.val) }
743 } else {
744 unimplemented!(
745 "wrapping arithmetic for non-primitive \
746 ranged integers is not implemented yet",
747 );
748 }
749 }
750 #[cfg(debug_assertions)]
751 {
752 if Self::IS_PRIMITIVE {
753 let val = self.val.wrapping_add(rhs.val);
754 let min = self.min.wrapping_add(rhs.min);
755 let max = self.max.wrapping_add(rhs.max);
756 Self { val, min, max }
757 } else {
758 unimplemented!(
759 "wrapping arithmetic for non-primitive \
760 ranged integers is not implemented yet",
761 );
762 }
763 }
764 }
765
766 #[inline]
767 pub(crate) fn wrapping_sub(self, rhs: impl RInto<Self>) -> Self {
768 let rhs = rhs.rinto();
769 #[cfg(not(debug_assertions))]
770 {
771 if Self::IS_PRIMITIVE {
777 Self { val: self.val.wrapping_sub(rhs.val) }
778 } else {
779 unimplemented!(
780 "wrapping arithmetic for non-primitive \
781 ranged integers is not implemented yet",
782 );
783 }
784 }
785 #[cfg(debug_assertions)]
786 {
787 if Self::IS_PRIMITIVE {
788 let val = self.val.wrapping_sub(rhs.val);
789 let min = self.min.wrapping_sub(rhs.min);
790 let max = self.max.wrapping_sub(rhs.max);
791 Self { val, min, max }
792 } else {
793 unimplemented!(
794 "wrapping arithmetic for non-primitive \
795 ranged integers is not implemented yet",
796 );
797 }
798 }
799 }
800
801 #[inline]
802 pub(crate) fn wrapping_mul(self, rhs: impl RInto<Self>) -> Self {
803 let rhs = rhs.rinto();
804 #[cfg(not(debug_assertions))]
805 {
806 if Self::IS_PRIMITIVE {
812 Self { val: self.val.wrapping_mul(rhs.val) }
813 } else {
814 unimplemented!(
815 "wrapping arithmetic for non-primitive \
816 ranged integers is not implemented yet",
817 );
818 }
819 }
820 #[cfg(debug_assertions)]
821 {
822 if Self::IS_PRIMITIVE {
823 let val = self.val.wrapping_mul(rhs.val);
824 let min = self.min.wrapping_mul(rhs.min);
825 let max = self.max.wrapping_mul(rhs.max);
826 Self { val, min, max }
827 } else {
828 unimplemented!(
829 "wrapping arithmetic for non-primitive \
830 ranged integers is not implemented yet",
831 );
832 }
833 }
834 }
835
836 #[inline]
837 pub(crate) fn saturating_add(self, rhs: impl RInto<Self>) -> Self {
838 let rhs = rhs.rinto();
839 #[cfg(not(debug_assertions))]
840 {
841 let val = self
842 .val
843 .saturating_add(rhs.val)
844 .clamp(Self::MIN_REPR, Self::MAX_REPR);
845 Self { val }
846 }
847 #[cfg(debug_assertions)]
848 {
849 let val = self
850 .val
851 .saturating_add(rhs.val)
852 .clamp(Self::MIN_REPR, Self::MAX_REPR);
853 let min = self
854 .min
855 .saturating_add(rhs.val)
856 .clamp(Self::MIN_REPR, Self::MAX_REPR);
857 let max = self
858 .max
859 .saturating_add(rhs.val)
860 .clamp(Self::MIN_REPR, Self::MAX_REPR);
861 Self { val, min, max }
862 }
863 }
864
865 #[inline]
866 pub(crate) fn saturating_sub(self, rhs: impl RInto<Self>) -> Self {
867 let rhs = rhs.rinto();
868 #[cfg(not(debug_assertions))]
869 {
870 let val = self
871 .val
872 .saturating_sub(rhs.val)
873 .clamp(Self::MIN_REPR, Self::MAX_REPR);
874 Self { val }
875 }
876 #[cfg(debug_assertions)]
877 {
878 let val = self
879 .val
880 .saturating_sub(rhs.val)
881 .clamp(Self::MIN_REPR, Self::MAX_REPR);
882 let min = self
883 .min
884 .saturating_sub(rhs.val)
885 .clamp(Self::MIN_REPR, Self::MAX_REPR);
886 let max = self
887 .max
888 .saturating_sub(rhs.val)
889 .clamp(Self::MIN_REPR, Self::MAX_REPR);
890 Self { val, min, max }
891 }
892 }
893
894 #[inline]
895 pub(crate) fn saturating_mul(self, rhs: impl RInto<Self>) -> Self {
896 let rhs = rhs.rinto();
897 #[cfg(not(debug_assertions))]
898 {
899 let val = self
900 .val
901 .saturating_mul(rhs.val)
902 .clamp(Self::MIN_REPR, Self::MAX_REPR);
903 Self { val }
904 }
905 #[cfg(debug_assertions)]
906 {
907 let val = self
908 .val
909 .saturating_mul(rhs.val)
910 .clamp(Self::MIN_REPR, Self::MAX_REPR);
911 let min = self
912 .min
913 .saturating_mul(rhs.val)
914 .clamp(Self::MIN_REPR, Self::MAX_REPR);
915 let max = self
916 .max
917 .saturating_mul(rhs.val)
918 .clamp(Self::MIN_REPR, Self::MAX_REPR);
919 Self { val, min, max }
920 }
921 }
922
923 pub(crate) fn debug(self) -> RangedDebug<MIN, MAX> {
924 RangedDebug { rint: self.rinto() }
925 }
926 }
927
928 impl<
929 const MIN1: i128,
930 const MAX1: i128,
931 const MIN2: i128,
932 const MAX2: i128,
933 > RFrom<$name<MIN1, MAX1>> for $name<MIN2, MAX2>
934 {
935 #[inline]
936 fn rfrom(r: $name<MIN1, MAX1>) -> Self {
937 #[cfg(not(debug_assertions))]
938 {
939 $name { val: r.val }
940 }
941 #[cfg(debug_assertions)]
942 {
943 $name { val: r.val, min: r.min, max: r.max }
944 }
945 }
946 }
947
948 impl<const MIN: i128, const MAX: i128> RFrom<$name<MIN, MAX>>
949 for $repr
950 {
951 #[inline]
952 fn rfrom(r: $name<MIN, MAX>) -> $repr {
953 r.get()
954 }
955 }
956
957 impl<const MIN: i128, const MAX: i128> From<$name<MIN, MAX>>
958 for $repr
959 {
960 #[inline]
961 fn from(r: $name<MIN, MAX>) -> $repr {
962 r.get()
963 }
964 }
965
966 impl<const MIN: i128, const MAX: i128> RFrom<Constant>
967 for $name<MIN, MAX>
968 {
969 #[inline]
970 fn rfrom(c: Constant) -> Self {
971 #[cfg(not(debug_assertions))]
972 {
973 Self { val: c.value() as $repr }
974 }
975 #[cfg(debug_assertions)]
976 {
977 #[allow(irrefutable_let_patterns)]
983 let Ok(val) = <$repr>::try_from(c.value()) else {
984 panic!(
985 "{c:?} does not fit in {name:?}",
986 name = stringify!($name),
987 )
988 };
989 Self { val, min: val, max: val }
990 }
991 }
992 }
993
994 impl<
995 const MIN1: i128,
996 const MAX1: i128,
997 const MIN2: i128,
998 const MAX2: i128,
999 > TryRFrom<$name<MIN1, MAX1>> for $name<MIN2, MAX2>
1000 {
1001 #[inline]
1002 fn try_rfrom(
1003 what: &'static str, r: $name<MIN1, MAX1>,
1004 ) -> Result<Self, Error> {
1005 #[cfg(not(debug_assertions))]
1006 {
1007 if !Self::contains(r.val) {
1008 return Err(Self::error(what, r.val));
1009 }
1010 Ok($name { val: r.val })
1011 }
1012 #[cfg(debug_assertions)]
1013 {
1014 if !Self::contains(r.val) {
1015 return Err(Self::error(what, r.val));
1016 }
1017 Ok($name {
1018 val: r.val,
1019 min: r.min.clamp(Self::MIN_REPR, Self::MAX_REPR),
1020 max: r.max.clamp(Self::MIN_REPR, Self::MAX_REPR),
1021 })
1022 }
1023 }
1024 }
1025
1026 $(
1027 impl<
1028 const MIN1: i128,
1029 const MAX1: i128,
1030 const MIN2: i128,
1031 const MAX2: i128,
1032 > RFrom<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1033 {
1034 #[inline]
1035 fn rfrom(r: $smaller_name<MIN1, MAX1>) -> Self {
1036 #[cfg(not(debug_assertions))]
1037 {
1038 Self { val: <$repr>::from(r.val) }
1039 }
1040 #[cfg(debug_assertions)]
1041 {
1042 Self {
1043 val: <$repr>::from(r.val),
1044 min: <$repr>::from(r.min),
1045 max: <$repr>::from(r.max),
1046 }
1047 }
1048 }
1049 }
1050
1051 impl<
1052 const MIN: i128,
1053 const MAX: i128,
1054 > RFrom<$name<MIN, MAX>> for $smaller_repr
1055 {
1056 #[inline]
1057 fn rfrom(r: $name<MIN, MAX>) -> $smaller_repr {
1058 #[cfg(not(debug_assertions))]
1059 {
1060 r.val as $smaller_repr
1061 }
1062 #[cfg(debug_assertions)]
1063 {
1064 let Ok(val) = <$smaller_repr>::try_from(r.val) else {
1065 panic!(
1066 "{from} value {val} does not fit in {to}",
1067 from = stringify!($name),
1068 val = r.val,
1069 to = stringify!($smaller_name),
1070 );
1071 };
1072 if <$smaller_repr>::try_from(r.min).is_err() {
1073 panic!(
1074 "{from} min value {val} does not fit in {to}",
1075 from = stringify!($name),
1076 val = r.min,
1077 to = stringify!($smaller_name),
1078 );
1079 }
1080 if <$smaller_repr>::try_from(r.max).is_err() {
1081 panic!(
1082 "{from} max value {val} does not fit in {to}",
1083 from = stringify!($name),
1084 val = r.max,
1085 to = stringify!($smaller_name),
1086 );
1087 }
1088 val
1089 }
1090 }
1091 }
1092
1093 impl<
1094 const MIN: i128,
1095 const MAX: i128,
1096 > From<$name<MIN, MAX>> for $smaller_repr
1097 {
1098 #[inline]
1099 fn from(r: $name<MIN, MAX>) -> $smaller_repr {
1100 <$smaller_repr>::rfrom(r)
1101 }
1102 }
1103
1104 impl<
1105 const MIN1: i128,
1106 const MAX1: i128,
1107 const MIN2: i128,
1108 const MAX2: i128,
1109 > TryRFrom<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1110 {
1111 #[inline]
1112 fn try_rfrom(
1113 what: &'static str, r: $smaller_name<MIN1, MAX1>,
1114 ) -> Result<Self, Error> {
1115 #[cfg(not(debug_assertions))]
1116 {
1117 let val = <$repr>::from(r.val);
1118 if !Self::contains(val) {
1119 return Err(Self::error(what, val));
1120 }
1121 Ok(Self { val })
1122 }
1123 #[cfg(debug_assertions)]
1124 {
1125 let val = <$repr>::from(r.val);
1126 if !Self::contains(val) {
1127 return Err(Self::error(what, val));
1128 }
1129 Ok(Self {
1130 val: val,
1131 min: <$repr>::from(r.min)
1132 .clamp(Self::MIN_REPR, Self::MAX_REPR),
1133 max: <$repr>::from(r.max)
1134 .clamp(Self::MIN_REPR, Self::MAX_REPR),
1135 })
1136 }
1137 }
1138 }
1139
1140 impl<
1141 const MIN1: i128,
1142 const MAX1: i128,
1143 const MIN2: i128,
1144 const MAX2: i128,
1145 > PartialEq<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1146 {
1147 #[inline]
1148 fn eq(&self, other: &$smaller_name<MIN1, MAX1>) -> bool {
1149 self.eq(&Self::rfrom(*other))
1150 }
1151 }
1152
1153 impl<
1154 const MIN1: i128,
1155 const MAX1: i128,
1156 const MIN2: i128,
1157 const MAX2: i128,
1158 > PartialOrd<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1159 {
1160 #[inline]
1161 fn partial_cmp(
1162 &self,
1163 other: &$smaller_name<MIN1, MAX1>,
1164 ) -> Option<Ordering> {
1165 self.partial_cmp(&Self::rfrom(*other))
1166 }
1167 }
1168
1169 impl<
1170 const MIN1: i128,
1171 const MAX1: i128,
1172 const MIN2: i128,
1173 const MAX2: i128,
1174 > Add<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1175 {
1176 type Output = Self;
1177
1178 #[inline]
1179 fn add(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1180 self.add(Self::rfrom(rhs))
1181 }
1182 }
1183
1184 impl<
1185 const MIN1: i128,
1186 const MAX1: i128,
1187 const MIN2: i128,
1188 const MAX2: i128,
1189 > AddAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1190 {
1191 #[inline]
1192 fn add_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1193 self.add_assign(Self::rfrom(rhs))
1194 }
1195 }
1196
1197 impl<
1198 const MIN1: i128,
1199 const MAX1: i128,
1200 const MIN2: i128,
1201 const MAX2: i128,
1202 > Sub<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1203 {
1204 type Output = Self;
1205
1206 #[inline]
1207 fn sub(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1208 self.sub(Self::rfrom(rhs))
1209 }
1210 }
1211
1212 impl<
1213 const MIN1: i128,
1214 const MAX1: i128,
1215 const MIN2: i128,
1216 const MAX2: i128,
1217 > SubAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1218 {
1219 #[inline]
1220 fn sub_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1221 self.sub_assign(Self::rfrom(rhs))
1222 }
1223 }
1224
1225 impl<
1226 const MIN1: i128,
1227 const MAX1: i128,
1228 const MIN2: i128,
1229 const MAX2: i128,
1230 > Mul<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1231 {
1232 type Output = Self;
1233
1234 #[inline]
1235 fn mul(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1236 self.mul(Self::rfrom(rhs))
1237 }
1238 }
1239
1240 impl<
1241 const MIN1: i128,
1242 const MAX1: i128,
1243 const MIN2: i128,
1244 const MAX2: i128,
1245 > MulAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1246 {
1247 #[inline]
1248 fn mul_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1249 self.mul_assign(Self::rfrom(rhs))
1250 }
1251 }
1252
1253 impl<
1254 const MIN1: i128,
1255 const MAX1: i128,
1256 const MIN2: i128,
1257 const MAX2: i128,
1258 > Div<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1259 {
1260 type Output = Self;
1261
1262 #[inline]
1263 fn div(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1264 self.div(Self::rfrom(rhs))
1265 }
1266 }
1267
1268 impl<
1269 const MIN1: i128,
1270 const MAX1: i128,
1271 const MIN2: i128,
1272 const MAX2: i128,
1273 > DivAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1274 {
1275 #[inline]
1276 fn div_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1277 self.div_assign(Self::rfrom(rhs))
1278 }
1279 }
1280
1281 impl<
1282 const MIN1: i128,
1283 const MAX1: i128,
1284 const MIN2: i128,
1285 const MAX2: i128,
1286 > Rem<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1287 {
1288 type Output = Self;
1289
1290 #[inline]
1291 fn rem(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1292 self.rem(Self::rfrom(rhs))
1293 }
1294 }
1295
1296 impl<
1297 const MIN1: i128,
1298 const MAX1: i128,
1299 const MIN2: i128,
1300 const MAX2: i128,
1301 > RemAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1302 {
1303 #[inline]
1304 fn rem_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1305 self.rem_assign(Self::rfrom(rhs))
1306 }
1307 }
1308 )*
1309
1310 $(
1311 impl<
1312 const MIN1: i128,
1313 const MAX1: i128,
1314 const MIN2: i128,
1315 const MAX2: i128,
1316 > RFrom<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1317 {
1318 #[inline]
1319 fn rfrom(r: $bigger_name<MIN1, MAX1>) -> Self {
1320 #[cfg(not(debug_assertions))]
1321 {
1322 Self { val: r.val as $repr }
1323 }
1324 #[cfg(debug_assertions)]
1325 {
1326 let Ok(val) = <$repr>::try_from(r.val) else {
1327 panic!(
1328 "{from} value {val} does not fit in {to}",
1329 from = stringify!($bigger_name),
1330 val = r.val,
1331 to = stringify!($name),
1332 );
1333 };
1334 let Ok(min) = <$repr>::try_from(r.min) else {
1335 panic!(
1336 "{from} min value {val} does not fit in {to}",
1337 from = stringify!($bigger_name),
1338 val = r.min,
1339 to = stringify!($name),
1340 );
1341 };
1342 let Ok(max) = <$repr>::try_from(r.max) else {
1343 panic!(
1344 "{from} max value {val} does not fit in {to}",
1345 from = stringify!($bigger_name),
1346 val = r.max,
1347 to = stringify!($name),
1348 );
1349 };
1350 Self { val, min, max }
1351 }
1352 }
1353 }
1354
1355 impl<
1356 const MIN: i128,
1357 const MAX: i128,
1358 > RFrom<$name<MIN, MAX>> for $bigger_repr
1359 {
1360 #[inline]
1361 fn rfrom(r: $name<MIN, MAX>) -> $bigger_repr {
1362 <$bigger_repr>::from(r.get())
1363 }
1364 }
1365
1366 impl<
1367 const MIN: i128,
1368 const MAX: i128,
1369 > From<$name<MIN, MAX>> for $bigger_repr
1370 {
1371 #[inline]
1372 fn from(r: $name<MIN, MAX>) -> $bigger_repr {
1373 <$bigger_repr>::rfrom(r)
1374 }
1375 }
1376
1377 impl<
1378 const MIN1: i128,
1379 const MAX1: i128,
1380 const MIN2: i128,
1381 const MAX2: i128,
1382 > TryRFrom<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1383 {
1384 #[inline]
1385 fn try_rfrom(
1386 what: &'static str, r: $bigger_name<MIN1, MAX1>,
1387 ) -> Result<Self, Error> {
1388 #[cfg(not(debug_assertions))]
1389 {
1390 let val = <$repr>::try_from(r.val).map_err(|_| {
1391 Error::range(what, r.val, MIN2, MAX2)
1392 })?;
1393 if !Self::contains(val) {
1394 return Err(Self::error(what, val));
1395 }
1396 Ok(Self { val })
1397 }
1398 #[cfg(debug_assertions)]
1399 {
1400 let val = <$repr>::try_from(r.val).map_err(|_| {
1401 Error::range(what, r.val, MIN2, MAX2)
1402 })?;
1403 if !Self::contains(val) {
1404 return Err(Self::error(what, val));
1405 }
1406 let min = <$repr>::try_from(r.min).unwrap_or_else(|_| {
1407 if (r.min as i128) < MIN2 {
1408 Self::MIN_REPR
1409 } else {
1410 assert!(r.min as i128 > MAX2);
1411 Self::MAX_REPR
1412 }
1413 });
1414 let max = <$repr>::try_from(r.max).unwrap_or_else(|_| {
1415 if (r.max as i128) < MIN2 {
1416 Self::MIN_REPR
1417 } else {
1418 assert!(r.max as i128 > MAX2);
1419 Self::MAX_REPR
1420 }
1421 });
1422 Ok(Self {
1423 val,
1424 min: min.clamp(Self::MIN_REPR, Self::MAX_REPR),
1425 max: max.clamp(Self::MIN_REPR, Self::MAX_REPR),
1426 })
1427 }
1428 }
1429 }
1430
1431 impl<
1432 const MIN1: i128,
1433 const MAX1: i128,
1434 const MIN2: i128,
1435 const MAX2: i128,
1436 > PartialEq<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1437 {
1438 #[inline]
1439 fn eq(&self, other: &$bigger_name<MIN1, MAX1>) -> bool {
1440 <$bigger_name<MIN1, MAX1>>::rfrom(*self).eq(other)
1441 }
1442 }
1443
1444 impl<
1445 const MIN1: i128,
1446 const MAX1: i128,
1447 const MIN2: i128,
1448 const MAX2: i128,
1449 > PartialOrd<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1450 {
1451 #[inline]
1452 fn partial_cmp(
1453 &self,
1454 other: &$bigger_name<MIN1, MAX1>,
1455 ) -> Option<Ordering> {
1456 <$bigger_name<MIN1, MAX1>>::rfrom(*self).partial_cmp(other)
1457 }
1458 }
1459
1460 impl<
1461 const MIN1: i128,
1462 const MAX1: i128,
1463 const MIN2: i128,
1464 const MAX2: i128,
1465 > Add<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1466 {
1467 type Output = Self;
1468
1469 #[inline]
1470 fn add(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1471 self.add(Self::rfrom(rhs))
1472 }
1473 }
1474
1475 impl<
1476 const MIN1: i128,
1477 const MAX1: i128,
1478 const MIN2: i128,
1479 const MAX2: i128,
1480 > AddAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1481 {
1482 #[inline]
1483 fn add_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1484 self.add_assign(Self::rfrom(rhs))
1485 }
1486 }
1487
1488 impl<
1489 const MIN1: i128,
1490 const MAX1: i128,
1491 const MIN2: i128,
1492 const MAX2: i128,
1493 > Sub<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1494 {
1495 type Output = Self;
1496
1497 #[inline]
1498 fn sub(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1499 self.sub(Self::rfrom(rhs))
1500 }
1501 }
1502
1503 impl<
1504 const MIN1: i128,
1505 const MAX1: i128,
1506 const MIN2: i128,
1507 const MAX2: i128,
1508 > SubAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1509 {
1510 #[inline]
1511 fn sub_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1512 self.sub_assign(Self::rfrom(rhs))
1513 }
1514 }
1515
1516 impl<
1517 const MIN1: i128,
1518 const MAX1: i128,
1519 const MIN2: i128,
1520 const MAX2: i128,
1521 > Mul<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1522 {
1523 type Output = Self;
1524
1525 #[inline]
1526 fn mul(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1527 self.mul(Self::rfrom(rhs))
1528 }
1529 }
1530
1531 impl<
1532 const MIN1: i128,
1533 const MAX1: i128,
1534 const MIN2: i128,
1535 const MAX2: i128,
1536 > MulAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1537 {
1538 #[inline]
1539 fn mul_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1540 self.mul_assign(Self::rfrom(rhs))
1541 }
1542 }
1543
1544 impl<
1545 const MIN1: i128,
1546 const MAX1: i128,
1547 const MIN2: i128,
1548 const MAX2: i128,
1549 > Div<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1550 {
1551 type Output = Self;
1552
1553 #[inline]
1554 fn div(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1555 self.div(Self::rfrom(rhs))
1556 }
1557 }
1558
1559 impl<
1560 const MIN1: i128,
1561 const MAX1: i128,
1562 const MIN2: i128,
1563 const MAX2: i128,
1564 > DivAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1565 {
1566 #[inline]
1567 fn div_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1568 self.div_assign(Self::rfrom(rhs))
1569 }
1570 }
1571
1572 impl<
1573 const MIN1: i128,
1574 const MAX1: i128,
1575 const MIN2: i128,
1576 const MAX2: i128,
1577 > Rem<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1578 {
1579 type Output = Self;
1580
1581 #[inline]
1582 fn rem(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1583 self.rem(Self::rfrom(rhs))
1584 }
1585 }
1586
1587 impl<
1588 const MIN1: i128,
1589 const MAX1: i128,
1590 const MIN2: i128,
1591 const MAX2: i128,
1592 > RemAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1593 {
1594 #[inline]
1595 fn rem_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1596 self.rem_assign(Self::rfrom(rhs))
1597 }
1598 }
1599 )*
1600
1601 impl<const MIN: i128, const MAX: i128> Neg for $name<MIN, MAX> {
1602 type Output = Self;
1603
1604 #[inline]
1605 fn neg(self) -> Self {
1606 #[cfg(not(debug_assertions))]
1607 {
1608 let val = self.val.wrapping_neg();
1609 Self { val }
1610 }
1611 #[cfg(debug_assertions)]
1612 {
1613 let val = self.val.checked_neg().expect(concat!(
1614 "negating ",
1615 stringify!($name),
1616 " values overflowed"
1617 ));
1618 let min = self.min.checked_neg().expect(concat!(
1619 "negating ",
1620 stringify!($name),
1621 " minimums overflowed"
1622 ));
1623 let max = self.max.checked_neg().expect(concat!(
1624 "negating ",
1625 stringify!($name),
1626 " maximums overflowed"
1627 ));
1628 Self { val, min, max }
1629 }
1630 }
1631 }
1632
1633 impl<
1634 const MIN1: i128,
1635 const MAX1: i128,
1636 const MIN2: i128,
1637 const MAX2: i128,
1638 > Add<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1639 type Output = Self;
1640
1641 #[inline]
1642 fn add(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1643 #[cfg(not(debug_assertions))]
1644 {
1645 let val = self.val.wrapping_add(rhs.val);
1646 Self { val }
1647 }
1648 #[cfg(debug_assertions)]
1649 {
1650 let val = self.val.checked_add(rhs.val).expect(concat!(
1651 "adding ",
1652 stringify!($name),
1653 " values overflowed"
1654 ));
1655 let min = self.min.checked_add(rhs.min).expect(concat!(
1656 "adding ",
1657 stringify!($name),
1658 " minimums overflowed"
1659 ));
1660 let max = self.max.checked_add(rhs.max).expect(concat!(
1661 "adding ",
1662 stringify!($name),
1663 " maximums overflowed"
1664 ));
1665 Self { val, min, max }
1666 }
1667 }
1668 }
1669
1670 impl<
1671 const MIN1: i128,
1672 const MAX1: i128,
1673 const MIN2: i128,
1674 const MAX2: i128,
1675 > AddAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1676 #[inline]
1677 fn add_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1678 *self = self.add(rhs);
1679 }
1680 }
1681
1682 impl<
1683 const MIN1: i128,
1684 const MAX1: i128,
1685 const MIN2: i128,
1686 const MAX2: i128,
1687 > Sub<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1688 type Output = Self;
1689
1690 #[inline]
1691 fn sub(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1692 #[cfg(not(debug_assertions))]
1693 {
1694 let val = self.val.wrapping_sub(rhs.val);
1695 Self { val }
1696 }
1697 #[cfg(debug_assertions)]
1698 {
1699 let val = self.val.checked_sub(rhs.val).expect(concat!(
1700 "subtracting ",
1701 stringify!($name),
1702 " values overflowed"
1703 ));
1704 let min = self.min.checked_sub(rhs.min).expect(concat!(
1705 "subtracting ",
1706 stringify!($name),
1707 " minimums overflowed"
1708 ));
1709 let max = self.max.checked_sub(rhs.max).expect(concat!(
1710 "subtracting ",
1711 stringify!($name),
1712 " maximums overflowed"
1713 ));
1714 Self { val, min, max }
1715 }
1716 }
1717 }
1718
1719 impl<
1720 const MIN1: i128,
1721 const MAX1: i128,
1722 const MIN2: i128,
1723 const MAX2: i128,
1724 > SubAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1725 #[inline]
1726 fn sub_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1727 *self = self.sub(rhs);
1728 }
1729 }
1730
1731 impl<
1732 const MIN1: i128,
1733 const MAX1: i128,
1734 const MIN2: i128,
1735 const MAX2: i128,
1736 > Mul<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1737 type Output = Self;
1738
1739 #[inline]
1740 fn mul(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1741 #[cfg(not(debug_assertions))]
1742 {
1743 let val = self.val.wrapping_mul(rhs.val);
1744 Self { val }
1745 }
1746 #[cfg(debug_assertions)]
1747 {
1748 let val = self.val.checked_mul(rhs.val).expect(concat!(
1749 "multiplying ",
1750 stringify!($name),
1751 " values overflowed"
1752 ));
1753 let min = self.min.checked_mul(rhs.min).expect(concat!(
1754 "multiplying ",
1755 stringify!($name),
1756 " minimums overflowed"
1757 ));
1758 let max = self.max.checked_mul(rhs.max).expect(concat!(
1759 "multiplying ",
1760 stringify!($name),
1761 " maximums overflowed"
1762 ));
1763 Self { val, min, max }
1764 }
1765 }
1766 }
1767
1768 impl<
1769 const MIN1: i128,
1770 const MAX1: i128,
1771 const MIN2: i128,
1772 const MAX2: i128,
1773 > MulAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1774 #[inline]
1775 fn mul_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1776 *self = self.mul(rhs);
1777 }
1778 }
1779
1780 impl<
1781 const MIN1: i128,
1782 const MAX1: i128,
1783 const MIN2: i128,
1784 const MAX2: i128,
1785 > Div<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1786 type Output = Self;
1787
1788 #[inline]
1789 fn div(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1790 #[cfg(not(debug_assertions))]
1791 {
1792 let val = self.val.wrapping_div_euclid(rhs.val);
1793 Self { val }
1794 }
1795 #[cfg(debug_assertions)]
1796 {
1797 let val =
1798 self.val.checked_div_euclid(rhs.val).expect(concat!(
1799 "dividing ",
1800 stringify!($name),
1801 " values overflowed"
1802 ));
1803 let min =
1804 self.min.checked_div_euclid(rhs.min).expect(concat!(
1805 "dividing ",
1806 stringify!($name),
1807 " minimums overflowed"
1808 ));
1809 let max =
1810 self.max.checked_div_euclid(rhs.max).expect(concat!(
1811 "dividing ",
1812 stringify!($name),
1813 " maximums overflowed"
1814 ));
1815 Self { val, min, max }
1816 }
1817 }
1818 }
1819
1820 impl<
1821 const MIN1: i128,
1822 const MAX1: i128,
1823 const MIN2: i128,
1824 const MAX2: i128,
1825 > DivAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1826 #[inline]
1827 fn div_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1828 *self = self.div(rhs);
1829 }
1830 }
1831
1832 impl<
1833 const MIN1: i128,
1834 const MAX1: i128,
1835 const MIN2: i128,
1836 const MAX2: i128,
1837 > Rem<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1838 type Output = Self;
1839
1840 #[inline]
1841 fn rem(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1842 #[cfg(not(debug_assertions))]
1843 {
1844 let val = self.val.wrapping_rem_euclid(rhs.val);
1845 Self { val }
1846 }
1847 #[cfg(debug_assertions)]
1848 {
1849 let val =
1850 self.val.checked_rem_euclid(rhs.val).expect(concat!(
1851 "modulo ",
1852 stringify!($name),
1853 " values overflowed"
1854 ));
1855 let min =
1856 self.min.checked_rem_euclid(rhs.min).expect(concat!(
1857 "modulo ",
1858 stringify!($name),
1859 " minimums overflowed"
1860 ));
1861 let max =
1862 self.max.checked_rem_euclid(rhs.max).expect(concat!(
1863 "modulo ",
1864 stringify!($name),
1865 " maximums overflowed"
1866 ));
1867 Self { val, min, max }
1868 }
1869 }
1870 }
1871
1872 impl<
1873 const MIN1: i128,
1874 const MAX1: i128,
1875 const MIN2: i128,
1876 const MAX2: i128,
1877 > RemAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1878 #[inline]
1879 fn rem_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1880 *self = self.rem(rhs);
1881 }
1882 }
1883
1884 impl<const MIN: i128, const MAX: i128> Add<$name<MIN, MAX>>
1885 for Constant
1886 {
1887 type Output = $name<MIN, MAX>;
1888
1889 #[inline]
1890 fn add(self, rhs: $name<MIN, MAX>) -> Self::Output {
1891 $name::rfrom(self).add(rhs)
1892 }
1893 }
1894
1895 impl<const MIN: i128, const MAX: i128> Add<Constant> for $name<MIN, MAX> {
1896 type Output = $name<MIN, MAX>;
1897
1898 #[inline]
1899 fn add(self, rhs: Constant) -> Self::Output {
1900 self.add(Self::rfrom(rhs))
1901 }
1902 }
1903
1904 impl<const MIN: i128, const MAX: i128> AddAssign<Constant> for $name<MIN, MAX> {
1905 #[inline]
1906 fn add_assign(&mut self, rhs: Constant) {
1907 self.add_assign(Self::rfrom(rhs))
1908 }
1909 }
1910
1911 impl<const MIN: i128, const MAX: i128> Sub<$name<MIN, MAX>> for Constant {
1912 type Output = $name<MIN, MAX>;
1913
1914 #[inline]
1915 fn sub(self, rhs: $name<MIN, MAX>) -> Self::Output {
1916 $name::rfrom(self).sub(rhs)
1917 }
1918 }
1919
1920 impl<const MIN: i128, const MAX: i128> Sub<Constant> for $name<MIN, MAX> {
1921 type Output = $name<MIN, MAX>;
1922
1923 #[inline]
1924 fn sub(self, rhs: Constant) -> Self::Output {
1925 self.sub(Self::rfrom(rhs))
1926 }
1927 }
1928
1929 impl<const MIN: i128, const MAX: i128> SubAssign<Constant> for $name<MIN, MAX> {
1930 #[inline]
1931 fn sub_assign(&mut self, rhs: Constant) {
1932 self.sub_assign(Self::rfrom(rhs))
1933 }
1934 }
1935
1936 impl<const MIN: i128, const MAX: i128> Mul<$name<MIN, MAX>> for Constant {
1937 type Output = $name<MIN, MAX>;
1938
1939 #[inline]
1940 fn mul(self, rhs: $name<MIN, MAX>) -> Self::Output {
1941 $name::rfrom(self).mul(rhs)
1942 }
1943 }
1944
1945 impl<const MIN: i128, const MAX: i128> Mul<Constant> for $name<MIN, MAX> {
1946 type Output = $name<MIN, MAX>;
1947
1948 #[inline]
1949 fn mul(self, rhs: Constant) -> Self::Output {
1950 self.mul(Self::rfrom(rhs))
1951 }
1952 }
1953
1954 impl<const MIN: i128, const MAX: i128> MulAssign<Constant> for $name<MIN, MAX> {
1955 #[inline]
1956 fn mul_assign(&mut self, rhs: Constant) {
1957 self.mul_assign(Self::rfrom(rhs))
1958 }
1959 }
1960
1961 impl<const MIN: i128, const MAX: i128> Div<$name<MIN, MAX>> for Constant {
1962 type Output = $name<MIN, MAX>;
1963
1964 #[inline]
1965 fn div(self, rhs: $name<MIN, MAX>) -> Self::Output {
1966 $name::rfrom(self).div(rhs)
1967 }
1968 }
1969
1970 impl<const MIN: i128, const MAX: i128> Div<Constant> for $name<MIN, MAX> {
1971 type Output = $name<MIN, MAX>;
1972
1973 #[inline]
1974 fn div(self, rhs: Constant) -> Self::Output {
1975 self.div(Self::rfrom(rhs))
1976 }
1977 }
1978 impl<const MIN: i128, const MAX: i128> DivAssign<Constant> for $name<MIN, MAX> {
1979 #[inline]
1980 fn div_assign(&mut self, rhs: Constant) {
1981 self.div_assign(Self::rfrom(rhs))
1982 }
1983 }
1984
1985 impl<const MIN: i128, const MAX: i128> Rem<$name<MIN, MAX>> for Constant {
1986 type Output = $name<MIN, MAX>;
1987
1988 #[inline]
1989 fn rem(self, rhs: $name<MIN, MAX>) -> Self::Output {
1990 $name::rfrom(self).rem(rhs)
1991 }
1992 }
1993
1994 impl<const MIN: i128, const MAX: i128> Rem<Constant> for $name<MIN, MAX> {
1995 type Output = $name<MIN, MAX>;
1996
1997 #[inline]
1998 fn rem(self, rhs: Constant) -> Self::Output {
1999 self.rem(Self::rfrom(rhs))
2000 }
2001 }
2002 impl<const MIN: i128, const MAX: i128> RemAssign<Constant> for $name<MIN, MAX> {
2003 #[inline]
2004 fn rem_assign(&mut self, rhs: Constant) {
2005 self.rem_assign(Self::rfrom(rhs))
2006 }
2007 }
2008
2009 impl<const MIN: i128, const MAX: i128> Eq for $name<MIN, MAX> {}
2010
2011 impl<
2012 const MIN1: i128,
2013 const MAX1: i128,
2014 const MIN2: i128,
2015 const MAX2: i128,
2016 > PartialEq<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
2017 #[inline]
2018 fn eq(&self, other: &$name<MIN2, MAX2>) -> bool {
2019 self.val.eq(&other.val)
2020 }
2021 }
2022
2023 impl<const MIN: i128, const MAX: i128> PartialEq<Constant> for $name<MIN, MAX> {
2024 #[inline]
2025 fn eq(&self, other: &Constant) -> bool {
2026 self.val.eq(&<$repr>::from(*other))
2027 }
2028 }
2029
2030 impl<const MIN: i128, const MAX: i128> PartialEq<$name<MIN, MAX>> for Constant {
2031 #[inline]
2032 fn eq(&self, other: &$name<MIN, MAX>) -> bool {
2033 <$repr>::from(*self).eq(&other.val)
2034 }
2035 }
2036
2037 impl<const MIN: i128, const MAX: i128> Ord for $name<MIN, MAX> {
2038 #[inline]
2039 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
2040 self.val.cmp(&other.val)
2041 }
2042 }
2043
2044 impl<
2045 const MIN1: i128,
2046 const MAX1: i128,
2047 const MIN2: i128,
2048 const MAX2: i128,
2049 > PartialOrd<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
2050 #[inline]
2051 fn partial_cmp(
2052 &self,
2053 other: &$name<MIN2, MAX2>,
2054 ) -> Option<core::cmp::Ordering> {
2055 self.val.partial_cmp(&other.val)
2056 }
2057 }
2058
2059 impl<const MIN: i128, const MAX: i128> PartialOrd<Constant> for $name<MIN, MAX> {
2060 #[inline]
2061 fn partial_cmp(
2062 &self,
2063 other: &Constant,
2064 ) -> Option<core::cmp::Ordering> {
2065 self.val.partial_cmp(&<$repr>::from(*other))
2066 }
2067 }
2068
2069 impl<const MIN: i128, const MAX: i128> PartialOrd<$name<MIN, MAX>> for Constant {
2070 #[inline]
2071 fn partial_cmp(
2072 &self,
2073 other: &$name<MIN, MAX>,
2074 ) -> Option<core::cmp::Ordering> {
2075 <$repr>::from(*self).partial_cmp(&other.val)
2076 }
2077 }
2078
2079 impl<const MIN: i128, const MAX: i128> core::fmt::Display for $name<MIN, MAX> {
2080 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2081 match self.checked_add(Self::N::<0>()) {
2087 Some(val) => core::fmt::Display::fmt(&val.get(), f),
2088 None => write!(f, "{:?}", self),
2089 }
2090 }
2091 }
2092
2093 impl<const MIN: i128, const MAX: i128> core::fmt::Debug for $name<MIN, MAX> {
2094 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2095 self.debug().fmt(f)
2096 }
2121 }
2122
2123 #[cfg(test)]
2124 impl<const MIN: i128, const MAX: i128> quickcheck::Arbitrary for $name<MIN, MAX> {
2125 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
2126 let mut n: $repr = <$repr>::arbitrary(g);
2127 if !Self::IS_PRIMITIVE {
2128 n = n.wrapping_rem_euclid(Self::LEN as $repr);
2129 n += Self::MIN_REPR;
2130 }
2131 Self::new(n).unwrap()
2132 }
2133
2134 fn shrink(&self) -> alloc::boxed::Box<dyn Iterator<Item = Self>> {
2135 alloc::boxed::Box::new(self.val.shrink().filter_map(Self::new))
2136 }
2137 }
2138 };
2139}
2140
2141define_ranged!(ri8, i8, smaller {}, bigger { ri16 i16, ri32 i32, ri64 i64, ri128 i128 });
2142define_ranged!(ri16, i16, smaller { ri8 i8 }, bigger { ri32 i32, ri64 i64, ri128 i128 });
2143define_ranged!(ri32, i32, smaller { ri8 i8, ri16 i16 }, bigger { ri64 i64, ri128 i128 });
2144define_ranged!(ri64, i64, smaller { ri8 i8, ri16 i16, ri32 i32 }, bigger { ri128 i128 });
2145define_ranged!(ri128, i128, smaller { ri8 i8, ri16 i16, ri32 i32, ri64 i64 }, bigger {});
2146
2147impl<const MIN: i128, const MAX: i128> ri8<MIN, MAX> {
2148 #[inline]
2149 pub(crate) fn without_bounds(
2150 self,
2151 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2152 ri64::rfrom(self)
2153 }
2154}
2155
2156impl<const MIN: i128, const MAX: i128> ri16<MIN, MAX> {
2157 #[inline]
2158 pub(crate) fn without_bounds(
2159 self,
2160 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2161 ri64::rfrom(self)
2162 }
2163}
2164
2165impl<const MIN: i128, const MAX: i128> ri32<MIN, MAX> {
2166 #[inline]
2167 pub(crate) fn without_bounds(
2168 self,
2169 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2170 ri64::rfrom(self)
2171 }
2172}
2173
2174impl<const MIN: i128, const MAX: i128> ri64<MIN, MAX> {
2175 #[inline]
2176 pub(crate) fn without_bounds(
2177 self,
2178 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2179 ri64::rfrom(self)
2180 }
2181}
2182
2183impl<const MIN: i128, const MAX: i128> ri128<MIN, MAX> {
2184 #[inline]
2185 pub(crate) fn without_bounds(self) -> ri128<{ i128::MIN }, { i128::MAX }> {
2186 ri128::rfrom(self)
2187 }
2188}
2189
2190pub(crate) struct RangedDebug<const MIN: i128, const MAX: i128> {
2191 rint: ri128<MIN, MAX>,
2192}
2193
2194impl<const MIN: i128, const MAX: i128> core::fmt::Debug
2195 for RangedDebug<MIN, MAX>
2196{
2197 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2198 #[cfg(not(debug_assertions))]
2199 {
2200 let val = self.rint.get_unchecked();
2201 if <ri128<MIN, MAX>>::contains(val) {
2202 val.fmt(f)
2203 } else {
2204 write!(f, "#{val:?} [out of range: {MIN}..={MAX}]#")
2205 }
2206 }
2207 #[cfg(debug_assertions)]
2208 {
2209 let val = self.rint.get_unchecked();
2210 let min = self.rint.min;
2211 let max = self.rint.max;
2212 if <ri128<MIN, MAX>>::contains(val)
2213 && <ri128<MIN, MAX>>::contains(min)
2214 && <ri128<MIN, MAX>>::contains(max)
2215 {
2216 val.fmt(f)
2217 } else {
2218 write!(
2219 f,
2220 "#{val:?} \
2221 [out of range: {MIN}..={MAX}] \
2222 [possible range: {min}..={max}]#",
2223 )
2224 }
2225 }
2226 }
2227}
2228
2229pub(crate) trait RFrom<T>: Sized {
2261 fn rfrom(value: T) -> Self;
2262}
2263
2264pub(crate) trait RInto<T>: Sized {
2271 fn rinto(self) -> T;
2272}
2273
2274impl<T, U> RInto<U> for T
2275where
2276 U: RFrom<T>,
2277{
2278 fn rinto(self) -> U {
2279 RFrom::rfrom(self)
2280 }
2281}
2282
2283pub(crate) trait TryRFrom<T>: Sized {
2284 fn try_rfrom(what: &'static str, value: T) -> Result<Self, Error>;
2285}
2286
2287pub(crate) trait TryRInto<T>: Sized {
2288 fn try_rinto(self, what: &'static str) -> Result<T, Error>;
2289}
2290
2291impl<T, U> TryRInto<U> for T
2292where
2293 U: TryRFrom<T>,
2294{
2295 #[inline]
2296 fn try_rinto(self, what: &'static str) -> Result<U, Error> {
2297 U::try_rfrom(what, self)
2298 }
2299}
2300
2301macro_rules! composite {
2302 (($($name:ident),* $(,)?) => $with:expr) => {{
2303 crate::util::rangeint::composite!(($($name = $name),*) => $with)
2304 }};
2305 (($($name:ident = $rangeint:expr),* $(,)?) => $with:expr) => {{
2306 #[cfg(not(debug_assertions))]
2307 {
2308 $(
2309 let $name = $rangeint.val;
2310 )*
2311 let val = $with;
2312 crate::util::rangeint::Composite { val }
2313 }
2314 #[cfg(debug_assertions)]
2315 {
2316 let val = {
2317 $(
2318 let $name = $rangeint.val;
2319 )*
2320 $with
2321 };
2322 let min = {
2323 $(
2324 let $name = $rangeint.min;
2325 )*
2326 $with
2327 };
2328 let max = {
2329 $(
2330 let $name = $rangeint.max;
2331 )*
2332 $with
2333 };
2334 crate::util::rangeint::Composite { val, min, max }
2335 }
2336 }};
2337}
2338
2339macro_rules! uncomposite {
2340 ($composite:expr, $val:ident => ($($get:expr),* $(,)?) $(,)?) => {{
2341 #[cfg(not(debug_assertions))]
2342 {
2343 ($({
2344 let val = {
2345 let $val = $composite.val;
2346 $get
2347 };
2348 crate::util::rangeint::Composite { val }
2349 }),*)
2350 }
2351 #[cfg(debug_assertions)]
2352 {
2353 ($({
2354 let val = {
2355 let $val = $composite.val;
2356 $get
2357 };
2358 let min = {
2359 let $val = $composite.min;
2360 $get
2361 };
2362 let max = {
2363 let $val = $composite.max;
2364 $get
2365 };
2366 crate::util::rangeint::Composite { val, min, max }
2367 }),*)
2368 }
2369 }};
2370}
2371
2372pub(crate) use {composite, uncomposite};
2373
2374#[derive(Clone, Debug, Eq, PartialEq)]
2375pub(crate) struct Composite<T> {
2376 pub(crate) val: T,
2377 #[cfg(debug_assertions)]
2378 pub(crate) min: T,
2379 #[cfg(debug_assertions)]
2380 pub(crate) max: T,
2381}
2382
2383impl<T> Composite<T> {
2384 #[inline]
2385 pub(crate) fn map<U>(self, map: impl Fn(T) -> U) -> Composite<U> {
2386 #[cfg(not(debug_assertions))]
2387 {
2388 Composite { val: map(self.val) }
2389 }
2390 #[cfg(debug_assertions)]
2391 {
2392 Composite {
2393 val: map(self.val),
2394 min: map(self.min),
2395 max: map(self.max),
2396 }
2397 }
2398 }
2399
2400 #[inline]
2401 pub(crate) fn zip2<U>(self, other: Composite<U>) -> Composite<(T, U)> {
2402 #[cfg(not(debug_assertions))]
2403 {
2404 Composite { val: (self.val, other.val) }
2405 }
2406 #[cfg(debug_assertions)]
2407 {
2408 Composite {
2409 val: (self.val, other.val),
2410 min: (self.min, other.min),
2411 max: (self.max, other.max),
2412 }
2413 }
2414 }
2415}
2416
2417impl<T, U> Composite<(T, U)> {
2418 #[inline]
2419 pub(crate) fn unzip2(self) -> (Composite<T>, Composite<U>) {
2420 #[cfg(not(debug_assertions))]
2421 {
2422 (Composite { val: self.val.0 }, Composite { val: self.val.1 })
2423 }
2424 #[cfg(debug_assertions)]
2425 {
2426 (
2427 Composite {
2428 val: self.val.0,
2429 min: self.min.0,
2430 max: self.max.0,
2431 },
2432 Composite {
2433 val: self.val.1,
2434 min: self.min.1,
2435 max: self.max.1,
2436 },
2437 )
2438 }
2439 }
2440}
2441
2442impl Composite<i8> {
2443 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2444 self,
2445 ) -> ri8<MIN, MAX> {
2446 #[cfg(not(debug_assertions))]
2447 {
2448 ri8 { val: self.val }
2449 }
2450 #[cfg(debug_assertions)]
2451 {
2452 ri8 { val: self.val, min: self.min, max: self.max }
2453 }
2454 }
2455}
2456
2457impl Composite<i16> {
2458 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2459 self,
2460 ) -> ri16<MIN, MAX> {
2461 #[cfg(not(debug_assertions))]
2462 {
2463 ri16 { val: self.val }
2464 }
2465 #[cfg(debug_assertions)]
2466 {
2467 ri16 { val: self.val, min: self.min, max: self.max }
2468 }
2469 }
2470}
2471
2472impl Composite<i32> {
2473 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2474 self,
2475 ) -> ri32<MIN, MAX> {
2476 #[cfg(not(debug_assertions))]
2477 {
2478 ri32 { val: self.val }
2479 }
2480 #[cfg(debug_assertions)]
2481 {
2482 ri32 { val: self.val, min: self.min, max: self.max }
2483 }
2484 }
2485}
2486
2487impl Composite<i64> {
2488 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2489 self,
2490 ) -> ri64<MIN, MAX> {
2491 #[cfg(not(debug_assertions))]
2492 {
2493 ri64 { val: self.val }
2494 }
2495 #[cfg(debug_assertions)]
2496 {
2497 ri64 { val: self.val, min: self.min, max: self.max }
2498 }
2499 }
2500
2501 pub(crate) fn try_to_rint<const MIN: i128, const MAX: i128>(
2502 self,
2503 what: &'static str,
2504 ) -> Result<ri64<MIN, MAX>, Error> {
2505 #[cfg(not(debug_assertions))]
2506 {
2507 if !ri64::<MIN, MAX>::contains(self.val) {
2508 return Err(ri64::<MIN, MAX>::error(what, self.val));
2509 }
2510 Ok(ri64 { val: self.val })
2511 }
2512 #[cfg(debug_assertions)]
2513 {
2514 if !ri64::<MIN, MAX>::contains(self.val) {
2515 return Err(ri64::<MIN, MAX>::error(what, self.val));
2516 }
2517 Ok(ri64 {
2518 val: self.val,
2519 min: self.min.clamp(MIN as i64, MAX as i64),
2520 max: self.max.clamp(MIN as i64, MAX as i64),
2521 })
2522 }
2523 }
2524}
2525
2526#[cfg(test)]
2527mod tests {
2528 }