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)]
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<const MIN: i128, const MAX: i128> core::hash::Hash for $name<MIN, MAX> {
933 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
934 self.val.hash(state);
935 }
936 }
937
938 impl<
939 const MIN1: i128,
940 const MAX1: i128,
941 const MIN2: i128,
942 const MAX2: i128,
943 > RFrom<$name<MIN1, MAX1>> for $name<MIN2, MAX2>
944 {
945 #[inline]
946 fn rfrom(r: $name<MIN1, MAX1>) -> Self {
947 #[cfg(not(debug_assertions))]
948 {
949 $name { val: r.val }
950 }
951 #[cfg(debug_assertions)]
952 {
953 $name { val: r.val, min: r.min, max: r.max }
954 }
955 }
956 }
957
958 impl<const MIN: i128, const MAX: i128> RFrom<$name<MIN, MAX>>
959 for $repr
960 {
961 #[inline]
962 fn rfrom(r: $name<MIN, MAX>) -> $repr {
963 r.get()
964 }
965 }
966
967 impl<const MIN: i128, const MAX: i128> From<$name<MIN, MAX>>
968 for $repr
969 {
970 #[inline]
971 fn from(r: $name<MIN, MAX>) -> $repr {
972 r.get()
973 }
974 }
975
976 impl<const MIN: i128, const MAX: i128> RFrom<Constant>
977 for $name<MIN, MAX>
978 {
979 #[inline]
980 fn rfrom(c: Constant) -> Self {
981 #[cfg(not(debug_assertions))]
982 {
983 Self { val: c.value() as $repr }
984 }
985 #[cfg(debug_assertions)]
986 {
987 #[allow(irrefutable_let_patterns)]
993 let Ok(val) = <$repr>::try_from(c.value()) else {
994 panic!(
995 "{c:?} does not fit in {name:?}",
996 name = stringify!($name),
997 )
998 };
999 Self { val, min: val, max: val }
1000 }
1001 }
1002 }
1003
1004 impl<
1005 const MIN1: i128,
1006 const MAX1: i128,
1007 const MIN2: i128,
1008 const MAX2: i128,
1009 > TryRFrom<$name<MIN1, MAX1>> for $name<MIN2, MAX2>
1010 {
1011 #[inline]
1012 fn try_rfrom(
1013 what: &'static str, r: $name<MIN1, MAX1>,
1014 ) -> Result<Self, Error> {
1015 #[cfg(not(debug_assertions))]
1016 {
1017 if !Self::contains(r.val) {
1018 return Err(Self::error(what, r.val));
1019 }
1020 Ok($name { val: r.val })
1021 }
1022 #[cfg(debug_assertions)]
1023 {
1024 if !Self::contains(r.val) {
1025 return Err(Self::error(what, r.val));
1026 }
1027 Ok($name {
1028 val: r.val,
1029 min: r.min.clamp(Self::MIN_REPR, Self::MAX_REPR),
1030 max: r.max.clamp(Self::MIN_REPR, Self::MAX_REPR),
1031 })
1032 }
1033 }
1034 }
1035
1036 $(
1037 impl<
1038 const MIN1: i128,
1039 const MAX1: i128,
1040 const MIN2: i128,
1041 const MAX2: i128,
1042 > RFrom<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1043 {
1044 #[inline]
1045 fn rfrom(r: $smaller_name<MIN1, MAX1>) -> Self {
1046 #[cfg(not(debug_assertions))]
1047 {
1048 Self { val: <$repr>::from(r.val) }
1049 }
1050 #[cfg(debug_assertions)]
1051 {
1052 Self {
1053 val: <$repr>::from(r.val),
1054 min: <$repr>::from(r.min),
1055 max: <$repr>::from(r.max),
1056 }
1057 }
1058 }
1059 }
1060
1061 impl<
1062 const MIN: i128,
1063 const MAX: i128,
1064 > RFrom<$name<MIN, MAX>> for $smaller_repr
1065 {
1066 #[inline]
1067 fn rfrom(r: $name<MIN, MAX>) -> $smaller_repr {
1068 #[cfg(not(debug_assertions))]
1069 {
1070 r.val as $smaller_repr
1071 }
1072 #[cfg(debug_assertions)]
1073 {
1074 let Ok(val) = <$smaller_repr>::try_from(r.val) else {
1075 panic!(
1076 "{from} value {val} does not fit in {to}",
1077 from = stringify!($name),
1078 val = r.val,
1079 to = stringify!($smaller_name),
1080 );
1081 };
1082 if <$smaller_repr>::try_from(r.min).is_err() {
1083 panic!(
1084 "{from} min value {val} does not fit in {to}",
1085 from = stringify!($name),
1086 val = r.min,
1087 to = stringify!($smaller_name),
1088 );
1089 }
1090 if <$smaller_repr>::try_from(r.max).is_err() {
1091 panic!(
1092 "{from} max value {val} does not fit in {to}",
1093 from = stringify!($name),
1094 val = r.max,
1095 to = stringify!($smaller_name),
1096 );
1097 }
1098 val
1099 }
1100 }
1101 }
1102
1103 impl<
1104 const MIN: i128,
1105 const MAX: i128,
1106 > From<$name<MIN, MAX>> for $smaller_repr
1107 {
1108 #[inline]
1109 fn from(r: $name<MIN, MAX>) -> $smaller_repr {
1110 <$smaller_repr>::rfrom(r)
1111 }
1112 }
1113
1114 impl<
1115 const MIN1: i128,
1116 const MAX1: i128,
1117 const MIN2: i128,
1118 const MAX2: i128,
1119 > TryRFrom<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1120 {
1121 #[inline]
1122 fn try_rfrom(
1123 what: &'static str, r: $smaller_name<MIN1, MAX1>,
1124 ) -> Result<Self, Error> {
1125 #[cfg(not(debug_assertions))]
1126 {
1127 let val = <$repr>::from(r.val);
1128 if !Self::contains(val) {
1129 return Err(Self::error(what, val));
1130 }
1131 Ok(Self { val })
1132 }
1133 #[cfg(debug_assertions)]
1134 {
1135 let val = <$repr>::from(r.val);
1136 if !Self::contains(val) {
1137 return Err(Self::error(what, val));
1138 }
1139 Ok(Self {
1140 val: val,
1141 min: <$repr>::from(r.min)
1142 .clamp(Self::MIN_REPR, Self::MAX_REPR),
1143 max: <$repr>::from(r.max)
1144 .clamp(Self::MIN_REPR, Self::MAX_REPR),
1145 })
1146 }
1147 }
1148 }
1149
1150 impl<
1151 const MIN1: i128,
1152 const MAX1: i128,
1153 const MIN2: i128,
1154 const MAX2: i128,
1155 > PartialEq<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1156 {
1157 #[inline]
1158 fn eq(&self, other: &$smaller_name<MIN1, MAX1>) -> bool {
1159 self.eq(&Self::rfrom(*other))
1160 }
1161 }
1162
1163 impl<
1164 const MIN1: i128,
1165 const MAX1: i128,
1166 const MIN2: i128,
1167 const MAX2: i128,
1168 > PartialOrd<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1169 {
1170 #[inline]
1171 fn partial_cmp(
1172 &self,
1173 other: &$smaller_name<MIN1, MAX1>,
1174 ) -> Option<Ordering> {
1175 self.partial_cmp(&Self::rfrom(*other))
1176 }
1177 }
1178
1179 impl<
1180 const MIN1: i128,
1181 const MAX1: i128,
1182 const MIN2: i128,
1183 const MAX2: i128,
1184 > Add<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1185 {
1186 type Output = Self;
1187
1188 #[inline]
1189 fn add(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1190 self.add(Self::rfrom(rhs))
1191 }
1192 }
1193
1194 impl<
1195 const MIN1: i128,
1196 const MAX1: i128,
1197 const MIN2: i128,
1198 const MAX2: i128,
1199 > AddAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1200 {
1201 #[inline]
1202 fn add_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1203 self.add_assign(Self::rfrom(rhs))
1204 }
1205 }
1206
1207 impl<
1208 const MIN1: i128,
1209 const MAX1: i128,
1210 const MIN2: i128,
1211 const MAX2: i128,
1212 > Sub<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1213 {
1214 type Output = Self;
1215
1216 #[inline]
1217 fn sub(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1218 self.sub(Self::rfrom(rhs))
1219 }
1220 }
1221
1222 impl<
1223 const MIN1: i128,
1224 const MAX1: i128,
1225 const MIN2: i128,
1226 const MAX2: i128,
1227 > SubAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1228 {
1229 #[inline]
1230 fn sub_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1231 self.sub_assign(Self::rfrom(rhs))
1232 }
1233 }
1234
1235 impl<
1236 const MIN1: i128,
1237 const MAX1: i128,
1238 const MIN2: i128,
1239 const MAX2: i128,
1240 > Mul<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1241 {
1242 type Output = Self;
1243
1244 #[inline]
1245 fn mul(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1246 self.mul(Self::rfrom(rhs))
1247 }
1248 }
1249
1250 impl<
1251 const MIN1: i128,
1252 const MAX1: i128,
1253 const MIN2: i128,
1254 const MAX2: i128,
1255 > MulAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1256 {
1257 #[inline]
1258 fn mul_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1259 self.mul_assign(Self::rfrom(rhs))
1260 }
1261 }
1262
1263 impl<
1264 const MIN1: i128,
1265 const MAX1: i128,
1266 const MIN2: i128,
1267 const MAX2: i128,
1268 > Div<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1269 {
1270 type Output = Self;
1271
1272 #[inline]
1273 fn div(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1274 self.div(Self::rfrom(rhs))
1275 }
1276 }
1277
1278 impl<
1279 const MIN1: i128,
1280 const MAX1: i128,
1281 const MIN2: i128,
1282 const MAX2: i128,
1283 > DivAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1284 {
1285 #[inline]
1286 fn div_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1287 self.div_assign(Self::rfrom(rhs))
1288 }
1289 }
1290
1291 impl<
1292 const MIN1: i128,
1293 const MAX1: i128,
1294 const MIN2: i128,
1295 const MAX2: i128,
1296 > Rem<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1297 {
1298 type Output = Self;
1299
1300 #[inline]
1301 fn rem(self, rhs: $smaller_name<MIN1, MAX1>) -> Self::Output {
1302 self.rem(Self::rfrom(rhs))
1303 }
1304 }
1305
1306 impl<
1307 const MIN1: i128,
1308 const MAX1: i128,
1309 const MIN2: i128,
1310 const MAX2: i128,
1311 > RemAssign<$smaller_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1312 {
1313 #[inline]
1314 fn rem_assign(&mut self, rhs: $smaller_name<MIN1, MAX1>) {
1315 self.rem_assign(Self::rfrom(rhs))
1316 }
1317 }
1318 )*
1319
1320 $(
1321 impl<
1322 const MIN1: i128,
1323 const MAX1: i128,
1324 const MIN2: i128,
1325 const MAX2: i128,
1326 > RFrom<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1327 {
1328 #[inline]
1329 fn rfrom(r: $bigger_name<MIN1, MAX1>) -> Self {
1330 #[cfg(not(debug_assertions))]
1331 {
1332 Self { val: r.val as $repr }
1333 }
1334 #[cfg(debug_assertions)]
1335 {
1336 let Ok(val) = <$repr>::try_from(r.val) else {
1337 panic!(
1338 "{from} value {val} does not fit in {to}",
1339 from = stringify!($bigger_name),
1340 val = r.val,
1341 to = stringify!($name),
1342 );
1343 };
1344 let Ok(min) = <$repr>::try_from(r.min) else {
1345 panic!(
1346 "{from} min value {val} does not fit in {to}",
1347 from = stringify!($bigger_name),
1348 val = r.min,
1349 to = stringify!($name),
1350 );
1351 };
1352 let Ok(max) = <$repr>::try_from(r.max) else {
1353 panic!(
1354 "{from} max value {val} does not fit in {to}",
1355 from = stringify!($bigger_name),
1356 val = r.max,
1357 to = stringify!($name),
1358 );
1359 };
1360 Self { val, min, max }
1361 }
1362 }
1363 }
1364
1365 impl<
1366 const MIN: i128,
1367 const MAX: i128,
1368 > RFrom<$name<MIN, MAX>> for $bigger_repr
1369 {
1370 #[inline]
1371 fn rfrom(r: $name<MIN, MAX>) -> $bigger_repr {
1372 <$bigger_repr>::from(r.get())
1373 }
1374 }
1375
1376 impl<
1377 const MIN: i128,
1378 const MAX: i128,
1379 > From<$name<MIN, MAX>> for $bigger_repr
1380 {
1381 #[inline]
1382 fn from(r: $name<MIN, MAX>) -> $bigger_repr {
1383 <$bigger_repr>::rfrom(r)
1384 }
1385 }
1386
1387 impl<
1388 const MIN1: i128,
1389 const MAX1: i128,
1390 const MIN2: i128,
1391 const MAX2: i128,
1392 > TryRFrom<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1393 {
1394 #[inline]
1395 fn try_rfrom(
1396 what: &'static str, r: $bigger_name<MIN1, MAX1>,
1397 ) -> Result<Self, Error> {
1398 #[cfg(not(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 Ok(Self { val })
1407 }
1408 #[cfg(debug_assertions)]
1409 {
1410 let val = <$repr>::try_from(r.val).map_err(|_| {
1411 Error::range(what, r.val, MIN2, MAX2)
1412 })?;
1413 if !Self::contains(val) {
1414 return Err(Self::error(what, val));
1415 }
1416 let min = <$repr>::try_from(r.min).unwrap_or_else(|_| {
1417 if (r.min as i128) < MIN2 {
1418 Self::MIN_REPR
1419 } else {
1420 assert!(r.min as i128 > MAX2);
1421 Self::MAX_REPR
1422 }
1423 });
1424 let max = <$repr>::try_from(r.max).unwrap_or_else(|_| {
1425 if (r.max as i128) < MIN2 {
1426 Self::MIN_REPR
1427 } else {
1428 assert!(r.max as i128 > MAX2);
1429 Self::MAX_REPR
1430 }
1431 });
1432 Ok(Self {
1433 val,
1434 min: min.clamp(Self::MIN_REPR, Self::MAX_REPR),
1435 max: max.clamp(Self::MIN_REPR, Self::MAX_REPR),
1436 })
1437 }
1438 }
1439 }
1440
1441 impl<
1442 const MIN1: i128,
1443 const MAX1: i128,
1444 const MIN2: i128,
1445 const MAX2: i128,
1446 > PartialEq<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1447 {
1448 #[inline]
1449 fn eq(&self, other: &$bigger_name<MIN1, MAX1>) -> bool {
1450 <$bigger_name<MIN1, MAX1>>::rfrom(*self).eq(other)
1451 }
1452 }
1453
1454 impl<
1455 const MIN1: i128,
1456 const MAX1: i128,
1457 const MIN2: i128,
1458 const MAX2: i128,
1459 > PartialOrd<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1460 {
1461 #[inline]
1462 fn partial_cmp(
1463 &self,
1464 other: &$bigger_name<MIN1, MAX1>,
1465 ) -> Option<Ordering> {
1466 <$bigger_name<MIN1, MAX1>>::rfrom(*self).partial_cmp(other)
1467 }
1468 }
1469
1470 impl<
1471 const MIN1: i128,
1472 const MAX1: i128,
1473 const MIN2: i128,
1474 const MAX2: i128,
1475 > Add<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1476 {
1477 type Output = Self;
1478
1479 #[inline]
1480 fn add(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1481 self.add(Self::rfrom(rhs))
1482 }
1483 }
1484
1485 impl<
1486 const MIN1: i128,
1487 const MAX1: i128,
1488 const MIN2: i128,
1489 const MAX2: i128,
1490 > AddAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1491 {
1492 #[inline]
1493 fn add_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1494 self.add_assign(Self::rfrom(rhs))
1495 }
1496 }
1497
1498 impl<
1499 const MIN1: i128,
1500 const MAX1: i128,
1501 const MIN2: i128,
1502 const MAX2: i128,
1503 > Sub<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1504 {
1505 type Output = Self;
1506
1507 #[inline]
1508 fn sub(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1509 self.sub(Self::rfrom(rhs))
1510 }
1511 }
1512
1513 impl<
1514 const MIN1: i128,
1515 const MAX1: i128,
1516 const MIN2: i128,
1517 const MAX2: i128,
1518 > SubAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1519 {
1520 #[inline]
1521 fn sub_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1522 self.sub_assign(Self::rfrom(rhs))
1523 }
1524 }
1525
1526 impl<
1527 const MIN1: i128,
1528 const MAX1: i128,
1529 const MIN2: i128,
1530 const MAX2: i128,
1531 > Mul<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1532 {
1533 type Output = Self;
1534
1535 #[inline]
1536 fn mul(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1537 self.mul(Self::rfrom(rhs))
1538 }
1539 }
1540
1541 impl<
1542 const MIN1: i128,
1543 const MAX1: i128,
1544 const MIN2: i128,
1545 const MAX2: i128,
1546 > MulAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1547 {
1548 #[inline]
1549 fn mul_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1550 self.mul_assign(Self::rfrom(rhs))
1551 }
1552 }
1553
1554 impl<
1555 const MIN1: i128,
1556 const MAX1: i128,
1557 const MIN2: i128,
1558 const MAX2: i128,
1559 > Div<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1560 {
1561 type Output = Self;
1562
1563 #[inline]
1564 fn div(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1565 self.div(Self::rfrom(rhs))
1566 }
1567 }
1568
1569 impl<
1570 const MIN1: i128,
1571 const MAX1: i128,
1572 const MIN2: i128,
1573 const MAX2: i128,
1574 > DivAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1575 {
1576 #[inline]
1577 fn div_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1578 self.div_assign(Self::rfrom(rhs))
1579 }
1580 }
1581
1582 impl<
1583 const MIN1: i128,
1584 const MAX1: i128,
1585 const MIN2: i128,
1586 const MAX2: i128,
1587 > Rem<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1588 {
1589 type Output = Self;
1590
1591 #[inline]
1592 fn rem(self, rhs: $bigger_name<MIN1, MAX1>) -> Self::Output {
1593 self.rem(Self::rfrom(rhs))
1594 }
1595 }
1596
1597 impl<
1598 const MIN1: i128,
1599 const MAX1: i128,
1600 const MIN2: i128,
1601 const MAX2: i128,
1602 > RemAssign<$bigger_name<MIN1, MAX1>> for $name<MIN2, MAX2>
1603 {
1604 #[inline]
1605 fn rem_assign(&mut self, rhs: $bigger_name<MIN1, MAX1>) {
1606 self.rem_assign(Self::rfrom(rhs))
1607 }
1608 }
1609 )*
1610
1611 impl<const MIN: i128, const MAX: i128> Neg for $name<MIN, MAX> {
1612 type Output = Self;
1613
1614 #[inline]
1615 fn neg(self) -> Self {
1616 #[cfg(not(debug_assertions))]
1617 {
1618 let val = self.val.wrapping_neg();
1619 Self { val }
1620 }
1621 #[cfg(debug_assertions)]
1622 {
1623 let val = self.val.checked_neg().expect(concat!(
1624 "negating ",
1625 stringify!($name),
1626 " values overflowed"
1627 ));
1628 let min = self.min.checked_neg().expect(concat!(
1629 "negating ",
1630 stringify!($name),
1631 " minimums overflowed"
1632 ));
1633 let max = self.max.checked_neg().expect(concat!(
1634 "negating ",
1635 stringify!($name),
1636 " maximums overflowed"
1637 ));
1638 Self { val, min, max }
1639 }
1640 }
1641 }
1642
1643 impl<
1644 const MIN1: i128,
1645 const MAX1: i128,
1646 const MIN2: i128,
1647 const MAX2: i128,
1648 > Add<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1649 type Output = Self;
1650
1651 #[inline]
1652 fn add(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1653 #[cfg(not(debug_assertions))]
1654 {
1655 let val = self.val.wrapping_add(rhs.val);
1656 Self { val }
1657 }
1658 #[cfg(debug_assertions)]
1659 {
1660 let val = self.val.checked_add(rhs.val).expect(concat!(
1661 "adding ",
1662 stringify!($name),
1663 " values overflowed"
1664 ));
1665 let min = self.min.checked_add(rhs.min).expect(concat!(
1666 "adding ",
1667 stringify!($name),
1668 " minimums overflowed"
1669 ));
1670 let max = self.max.checked_add(rhs.max).expect(concat!(
1671 "adding ",
1672 stringify!($name),
1673 " maximums overflowed"
1674 ));
1675 Self { val, min, max }
1676 }
1677 }
1678 }
1679
1680 impl<
1681 const MIN1: i128,
1682 const MAX1: i128,
1683 const MIN2: i128,
1684 const MAX2: i128,
1685 > AddAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1686 #[inline]
1687 fn add_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1688 *self = self.add(rhs);
1689 }
1690 }
1691
1692 impl<
1693 const MIN1: i128,
1694 const MAX1: i128,
1695 const MIN2: i128,
1696 const MAX2: i128,
1697 > Sub<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1698 type Output = Self;
1699
1700 #[inline]
1701 fn sub(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1702 #[cfg(not(debug_assertions))]
1703 {
1704 let val = self.val.wrapping_sub(rhs.val);
1705 Self { val }
1706 }
1707 #[cfg(debug_assertions)]
1708 {
1709 let val = self.val.checked_sub(rhs.val).expect(concat!(
1710 "subtracting ",
1711 stringify!($name),
1712 " values overflowed"
1713 ));
1714 let min = self.min.checked_sub(rhs.min).expect(concat!(
1715 "subtracting ",
1716 stringify!($name),
1717 " minimums overflowed"
1718 ));
1719 let max = self.max.checked_sub(rhs.max).expect(concat!(
1720 "subtracting ",
1721 stringify!($name),
1722 " maximums overflowed"
1723 ));
1724 Self { val, min, max }
1725 }
1726 }
1727 }
1728
1729 impl<
1730 const MIN1: i128,
1731 const MAX1: i128,
1732 const MIN2: i128,
1733 const MAX2: i128,
1734 > SubAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1735 #[inline]
1736 fn sub_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1737 *self = self.sub(rhs);
1738 }
1739 }
1740
1741 impl<
1742 const MIN1: i128,
1743 const MAX1: i128,
1744 const MIN2: i128,
1745 const MAX2: i128,
1746 > Mul<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1747 type Output = Self;
1748
1749 #[inline]
1750 fn mul(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1751 #[cfg(not(debug_assertions))]
1752 {
1753 let val = self.val.wrapping_mul(rhs.val);
1754 Self { val }
1755 }
1756 #[cfg(debug_assertions)]
1757 {
1758 let val = self.val.checked_mul(rhs.val).expect(concat!(
1759 "multiplying ",
1760 stringify!($name),
1761 " values overflowed"
1762 ));
1763 let min = self.min.checked_mul(rhs.min).expect(concat!(
1764 "multiplying ",
1765 stringify!($name),
1766 " minimums overflowed"
1767 ));
1768 let max = self.max.checked_mul(rhs.max).expect(concat!(
1769 "multiplying ",
1770 stringify!($name),
1771 " maximums overflowed"
1772 ));
1773 Self { val, min, max }
1774 }
1775 }
1776 }
1777
1778 impl<
1779 const MIN1: i128,
1780 const MAX1: i128,
1781 const MIN2: i128,
1782 const MAX2: i128,
1783 > MulAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1784 #[inline]
1785 fn mul_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1786 *self = self.mul(rhs);
1787 }
1788 }
1789
1790 impl<
1791 const MIN1: i128,
1792 const MAX1: i128,
1793 const MIN2: i128,
1794 const MAX2: i128,
1795 > Div<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1796 type Output = Self;
1797
1798 #[inline]
1799 fn div(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1800 #[cfg(not(debug_assertions))]
1801 {
1802 let val = self.val.wrapping_div_euclid(rhs.val);
1803 Self { val }
1804 }
1805 #[cfg(debug_assertions)]
1806 {
1807 let val =
1808 self.val.checked_div_euclid(rhs.val).expect(concat!(
1809 "dividing ",
1810 stringify!($name),
1811 " values overflowed"
1812 ));
1813 let min =
1814 self.min.checked_div_euclid(rhs.min).expect(concat!(
1815 "dividing ",
1816 stringify!($name),
1817 " minimums overflowed"
1818 ));
1819 let max =
1820 self.max.checked_div_euclid(rhs.max).expect(concat!(
1821 "dividing ",
1822 stringify!($name),
1823 " maximums overflowed"
1824 ));
1825 Self { val, min, max }
1826 }
1827 }
1828 }
1829
1830 impl<
1831 const MIN1: i128,
1832 const MAX1: i128,
1833 const MIN2: i128,
1834 const MAX2: i128,
1835 > DivAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1836 #[inline]
1837 fn div_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1838 *self = self.div(rhs);
1839 }
1840 }
1841
1842 impl<
1843 const MIN1: i128,
1844 const MAX1: i128,
1845 const MIN2: i128,
1846 const MAX2: i128,
1847 > Rem<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1848 type Output = Self;
1849
1850 #[inline]
1851 fn rem(self, rhs: $name<MIN2, MAX2>) -> Self::Output {
1852 #[cfg(not(debug_assertions))]
1853 {
1854 let val = self.val.wrapping_rem_euclid(rhs.val);
1855 Self { val }
1856 }
1857 #[cfg(debug_assertions)]
1858 {
1859 let val =
1860 self.val.checked_rem_euclid(rhs.val).expect(concat!(
1861 "modulo ",
1862 stringify!($name),
1863 " values overflowed"
1864 ));
1865 let min =
1866 self.min.checked_rem_euclid(rhs.min).expect(concat!(
1867 "modulo ",
1868 stringify!($name),
1869 " minimums overflowed"
1870 ));
1871 let max =
1872 self.max.checked_rem_euclid(rhs.max).expect(concat!(
1873 "modulo ",
1874 stringify!($name),
1875 " maximums overflowed"
1876 ));
1877 Self { val, min, max }
1878 }
1879 }
1880 }
1881
1882 impl<
1883 const MIN1: i128,
1884 const MAX1: i128,
1885 const MIN2: i128,
1886 const MAX2: i128,
1887 > RemAssign<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
1888 #[inline]
1889 fn rem_assign(&mut self, rhs: $name<MIN2, MAX2>) {
1890 *self = self.rem(rhs);
1891 }
1892 }
1893
1894 impl<const MIN: i128, const MAX: i128> Add<$name<MIN, MAX>>
1895 for Constant
1896 {
1897 type Output = $name<MIN, MAX>;
1898
1899 #[inline]
1900 fn add(self, rhs: $name<MIN, MAX>) -> Self::Output {
1901 $name::rfrom(self).add(rhs)
1902 }
1903 }
1904
1905 impl<const MIN: i128, const MAX: i128> Add<Constant> for $name<MIN, MAX> {
1906 type Output = $name<MIN, MAX>;
1907
1908 #[inline]
1909 fn add(self, rhs: Constant) -> Self::Output {
1910 self.add(Self::rfrom(rhs))
1911 }
1912 }
1913
1914 impl<const MIN: i128, const MAX: i128> AddAssign<Constant> for $name<MIN, MAX> {
1915 #[inline]
1916 fn add_assign(&mut self, rhs: Constant) {
1917 self.add_assign(Self::rfrom(rhs))
1918 }
1919 }
1920
1921 impl<const MIN: i128, const MAX: i128> Sub<$name<MIN, MAX>> for Constant {
1922 type Output = $name<MIN, MAX>;
1923
1924 #[inline]
1925 fn sub(self, rhs: $name<MIN, MAX>) -> Self::Output {
1926 $name::rfrom(self).sub(rhs)
1927 }
1928 }
1929
1930 impl<const MIN: i128, const MAX: i128> Sub<Constant> for $name<MIN, MAX> {
1931 type Output = $name<MIN, MAX>;
1932
1933 #[inline]
1934 fn sub(self, rhs: Constant) -> Self::Output {
1935 self.sub(Self::rfrom(rhs))
1936 }
1937 }
1938
1939 impl<const MIN: i128, const MAX: i128> SubAssign<Constant> for $name<MIN, MAX> {
1940 #[inline]
1941 fn sub_assign(&mut self, rhs: Constant) {
1942 self.sub_assign(Self::rfrom(rhs))
1943 }
1944 }
1945
1946 impl<const MIN: i128, const MAX: i128> Mul<$name<MIN, MAX>> for Constant {
1947 type Output = $name<MIN, MAX>;
1948
1949 #[inline]
1950 fn mul(self, rhs: $name<MIN, MAX>) -> Self::Output {
1951 $name::rfrom(self).mul(rhs)
1952 }
1953 }
1954
1955 impl<const MIN: i128, const MAX: i128> Mul<Constant> for $name<MIN, MAX> {
1956 type Output = $name<MIN, MAX>;
1957
1958 #[inline]
1959 fn mul(self, rhs: Constant) -> Self::Output {
1960 self.mul(Self::rfrom(rhs))
1961 }
1962 }
1963
1964 impl<const MIN: i128, const MAX: i128> MulAssign<Constant> for $name<MIN, MAX> {
1965 #[inline]
1966 fn mul_assign(&mut self, rhs: Constant) {
1967 self.mul_assign(Self::rfrom(rhs))
1968 }
1969 }
1970
1971 impl<const MIN: i128, const MAX: i128> Div<$name<MIN, MAX>> for Constant {
1972 type Output = $name<MIN, MAX>;
1973
1974 #[inline]
1975 fn div(self, rhs: $name<MIN, MAX>) -> Self::Output {
1976 $name::rfrom(self).div(rhs)
1977 }
1978 }
1979
1980 impl<const MIN: i128, const MAX: i128> Div<Constant> for $name<MIN, MAX> {
1981 type Output = $name<MIN, MAX>;
1982
1983 #[inline]
1984 fn div(self, rhs: Constant) -> Self::Output {
1985 self.div(Self::rfrom(rhs))
1986 }
1987 }
1988 impl<const MIN: i128, const MAX: i128> DivAssign<Constant> for $name<MIN, MAX> {
1989 #[inline]
1990 fn div_assign(&mut self, rhs: Constant) {
1991 self.div_assign(Self::rfrom(rhs))
1992 }
1993 }
1994
1995 impl<const MIN: i128, const MAX: i128> Rem<$name<MIN, MAX>> for Constant {
1996 type Output = $name<MIN, MAX>;
1997
1998 #[inline]
1999 fn rem(self, rhs: $name<MIN, MAX>) -> Self::Output {
2000 $name::rfrom(self).rem(rhs)
2001 }
2002 }
2003
2004 impl<const MIN: i128, const MAX: i128> Rem<Constant> for $name<MIN, MAX> {
2005 type Output = $name<MIN, MAX>;
2006
2007 #[inline]
2008 fn rem(self, rhs: Constant) -> Self::Output {
2009 self.rem(Self::rfrom(rhs))
2010 }
2011 }
2012 impl<const MIN: i128, const MAX: i128> RemAssign<Constant> for $name<MIN, MAX> {
2013 #[inline]
2014 fn rem_assign(&mut self, rhs: Constant) {
2015 self.rem_assign(Self::rfrom(rhs))
2016 }
2017 }
2018
2019 impl<const MIN: i128, const MAX: i128> Eq for $name<MIN, MAX> {}
2020
2021 impl<
2022 const MIN1: i128,
2023 const MAX1: i128,
2024 const MIN2: i128,
2025 const MAX2: i128,
2026 > PartialEq<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
2027 #[inline]
2028 fn eq(&self, other: &$name<MIN2, MAX2>) -> bool {
2029 self.val.eq(&other.val)
2030 }
2031 }
2032
2033 impl<const MIN: i128, const MAX: i128> PartialEq<Constant> for $name<MIN, MAX> {
2034 #[inline]
2035 fn eq(&self, other: &Constant) -> bool {
2036 self.val.eq(&<$repr>::from(*other))
2037 }
2038 }
2039
2040 impl<const MIN: i128, const MAX: i128> PartialEq<$name<MIN, MAX>> for Constant {
2041 #[inline]
2042 fn eq(&self, other: &$name<MIN, MAX>) -> bool {
2043 <$repr>::from(*self).eq(&other.val)
2044 }
2045 }
2046
2047 impl<const MIN: i128, const MAX: i128> Ord for $name<MIN, MAX> {
2048 #[inline]
2049 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
2050 self.val.cmp(&other.val)
2051 }
2052 }
2053
2054 impl<
2055 const MIN1: i128,
2056 const MAX1: i128,
2057 const MIN2: i128,
2058 const MAX2: i128,
2059 > PartialOrd<$name<MIN2, MAX2>> for $name<MIN1, MAX1> {
2060 #[inline]
2061 fn partial_cmp(
2062 &self,
2063 other: &$name<MIN2, MAX2>,
2064 ) -> Option<core::cmp::Ordering> {
2065 self.val.partial_cmp(&other.val)
2066 }
2067 }
2068
2069 impl<const MIN: i128, const MAX: i128> PartialOrd<Constant> for $name<MIN, MAX> {
2070 #[inline]
2071 fn partial_cmp(
2072 &self,
2073 other: &Constant,
2074 ) -> Option<core::cmp::Ordering> {
2075 self.val.partial_cmp(&<$repr>::from(*other))
2076 }
2077 }
2078
2079 impl<const MIN: i128, const MAX: i128> PartialOrd<$name<MIN, MAX>> for Constant {
2080 #[inline]
2081 fn partial_cmp(
2082 &self,
2083 other: &$name<MIN, MAX>,
2084 ) -> Option<core::cmp::Ordering> {
2085 <$repr>::from(*self).partial_cmp(&other.val)
2086 }
2087 }
2088
2089 impl<const MIN: i128, const MAX: i128> core::fmt::Display for $name<MIN, MAX> {
2090 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2091 match self.checked_add(Self::N::<0>()) {
2097 Some(val) => core::fmt::Display::fmt(&val.get(), f),
2098 None => write!(f, "{:?}", self),
2099 }
2100 }
2101 }
2102
2103 impl<const MIN: i128, const MAX: i128> core::fmt::Debug for $name<MIN, MAX> {
2104 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2105 self.debug().fmt(f)
2106 }
2131 }
2132
2133 #[cfg(test)]
2134 impl<const MIN: i128, const MAX: i128> quickcheck::Arbitrary for $name<MIN, MAX> {
2135 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
2136 let mut n: $repr = <$repr>::arbitrary(g);
2137 if !Self::IS_PRIMITIVE {
2138 n = n.wrapping_rem_euclid(Self::LEN as $repr);
2139 n += Self::MIN_REPR;
2140 }
2141 Self::new(n).unwrap()
2142 }
2143
2144 fn shrink(&self) -> alloc::boxed::Box<dyn Iterator<Item = Self>> {
2145 alloc::boxed::Box::new(self.val.shrink().filter_map(Self::new))
2146 }
2147 }
2148 };
2149}
2150
2151define_ranged!(ri8, i8, smaller {}, bigger { ri16 i16, ri32 i32, ri64 i64, ri128 i128 });
2152define_ranged!(ri16, i16, smaller { ri8 i8 }, bigger { ri32 i32, ri64 i64, ri128 i128 });
2153define_ranged!(ri32, i32, smaller { ri8 i8, ri16 i16 }, bigger { ri64 i64, ri128 i128 });
2154define_ranged!(ri64, i64, smaller { ri8 i8, ri16 i16, ri32 i32 }, bigger { ri128 i128 });
2155define_ranged!(ri128, i128, smaller { ri8 i8, ri16 i16, ri32 i32, ri64 i64 }, bigger {});
2156
2157impl<const MIN: i128, const MAX: i128> ri8<MIN, MAX> {
2158 #[inline]
2159 pub(crate) fn without_bounds(
2160 self,
2161 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2162 ri64::rfrom(self)
2163 }
2164}
2165
2166impl<const MIN: i128, const MAX: i128> ri16<MIN, MAX> {
2167 #[inline]
2168 pub(crate) fn without_bounds(
2169 self,
2170 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2171 ri64::rfrom(self)
2172 }
2173}
2174
2175impl<const MIN: i128, const MAX: i128> ri32<MIN, MAX> {
2176 #[inline]
2177 pub(crate) fn without_bounds(
2178 self,
2179 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2180 ri64::rfrom(self)
2181 }
2182}
2183
2184impl<const MIN: i128, const MAX: i128> ri64<MIN, MAX> {
2185 #[inline]
2186 pub(crate) fn without_bounds(
2187 self,
2188 ) -> ri64<{ i64::MIN as i128 }, { i64::MAX as i128 }> {
2189 ri64::rfrom(self)
2190 }
2191}
2192
2193impl<const MIN: i128, const MAX: i128> ri128<MIN, MAX> {
2194 #[inline]
2195 pub(crate) fn without_bounds(self) -> ri128<{ i128::MIN }, { i128::MAX }> {
2196 ri128::rfrom(self)
2197 }
2198}
2199
2200pub(crate) struct RangedDebug<const MIN: i128, const MAX: i128> {
2201 rint: ri128<MIN, MAX>,
2202}
2203
2204impl<const MIN: i128, const MAX: i128> core::fmt::Debug
2205 for RangedDebug<MIN, MAX>
2206{
2207 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
2208 #[cfg(not(debug_assertions))]
2209 {
2210 let val = self.rint.get_unchecked();
2211 if <ri128<MIN, MAX>>::contains(val) {
2212 val.fmt(f)
2213 } else {
2214 write!(f, "#{val:?} [out of range: {MIN}..={MAX}]#")
2215 }
2216 }
2217 #[cfg(debug_assertions)]
2218 {
2219 let val = self.rint.get_unchecked();
2220 let min = self.rint.min;
2221 let max = self.rint.max;
2222 if <ri128<MIN, MAX>>::contains(val)
2223 && <ri128<MIN, MAX>>::contains(min)
2224 && <ri128<MIN, MAX>>::contains(max)
2225 {
2226 val.fmt(f)
2227 } else {
2228 write!(
2229 f,
2230 "#{val:?} \
2231 [out of range: {MIN}..={MAX}] \
2232 [possible range: {min}..={max}]#",
2233 )
2234 }
2235 }
2236 }
2237}
2238
2239pub(crate) trait RFrom<T>: Sized {
2271 fn rfrom(value: T) -> Self;
2272}
2273
2274pub(crate) trait RInto<T>: Sized {
2281 fn rinto(self) -> T;
2282}
2283
2284impl<T, U> RInto<U> for T
2285where
2286 U: RFrom<T>,
2287{
2288 fn rinto(self) -> U {
2289 RFrom::rfrom(self)
2290 }
2291}
2292
2293pub(crate) trait TryRFrom<T>: Sized {
2294 fn try_rfrom(what: &'static str, value: T) -> Result<Self, Error>;
2295}
2296
2297pub(crate) trait TryRInto<T>: Sized {
2298 fn try_rinto(self, what: &'static str) -> Result<T, Error>;
2299}
2300
2301impl<T, U> TryRInto<U> for T
2302where
2303 U: TryRFrom<T>,
2304{
2305 #[inline]
2306 fn try_rinto(self, what: &'static str) -> Result<U, Error> {
2307 U::try_rfrom(what, self)
2308 }
2309}
2310
2311macro_rules! composite {
2312 (($($name:ident),* $(,)?) => $with:expr) => {{
2313 crate::util::rangeint::composite!(($($name = $name),*) => $with)
2314 }};
2315 (($($name:ident = $rangeint:expr),* $(,)?) => $with:expr) => {{
2316 #[cfg(not(debug_assertions))]
2317 {
2318 $(
2319 let $name = $rangeint.val;
2320 )*
2321 let val = $with;
2322 crate::util::rangeint::Composite { val }
2323 }
2324 #[cfg(debug_assertions)]
2325 {
2326 let val = {
2327 $(
2328 let $name = $rangeint.val;
2329 )*
2330 $with
2331 };
2332 let min = {
2333 $(
2334 let $name = $rangeint.min;
2335 )*
2336 $with
2337 };
2338 let max = {
2339 $(
2340 let $name = $rangeint.max;
2341 )*
2342 $with
2343 };
2344 crate::util::rangeint::Composite { val, min, max }
2345 }
2346 }};
2347}
2348
2349macro_rules! uncomposite {
2350 ($composite:expr, $val:ident => ($($get:expr),* $(,)?) $(,)?) => {{
2351 #[cfg(not(debug_assertions))]
2352 {
2353 ($({
2354 let val = {
2355 let $val = $composite.val;
2356 $get
2357 };
2358 crate::util::rangeint::Composite { val }
2359 }),*)
2360 }
2361 #[cfg(debug_assertions)]
2362 {
2363 ($({
2364 let val = {
2365 let $val = $composite.val;
2366 $get
2367 };
2368 let min = {
2369 let $val = $composite.min;
2370 $get
2371 };
2372 let max = {
2373 let $val = $composite.max;
2374 $get
2375 };
2376 crate::util::rangeint::Composite { val, min, max }
2377 }),*)
2378 }
2379 }};
2380}
2381
2382pub(crate) use {composite, uncomposite};
2383
2384#[derive(Clone, Debug, Eq, PartialEq)]
2385pub(crate) struct Composite<T> {
2386 pub(crate) val: T,
2387 #[cfg(debug_assertions)]
2388 pub(crate) min: T,
2389 #[cfg(debug_assertions)]
2390 pub(crate) max: T,
2391}
2392
2393impl<T> Composite<T> {
2394 #[inline]
2395 pub(crate) fn map<U>(self, map: impl Fn(T) -> U) -> Composite<U> {
2396 #[cfg(not(debug_assertions))]
2397 {
2398 Composite { val: map(self.val) }
2399 }
2400 #[cfg(debug_assertions)]
2401 {
2402 Composite {
2403 val: map(self.val),
2404 min: map(self.min),
2405 max: map(self.max),
2406 }
2407 }
2408 }
2409
2410 #[inline]
2411 pub(crate) fn zip2<U>(self, other: Composite<U>) -> Composite<(T, U)> {
2412 #[cfg(not(debug_assertions))]
2413 {
2414 Composite { val: (self.val, other.val) }
2415 }
2416 #[cfg(debug_assertions)]
2417 {
2418 Composite {
2419 val: (self.val, other.val),
2420 min: (self.min, other.min),
2421 max: (self.max, other.max),
2422 }
2423 }
2424 }
2425}
2426
2427impl<T, U> Composite<(T, U)> {
2428 #[inline]
2429 pub(crate) fn unzip2(self) -> (Composite<T>, Composite<U>) {
2430 #[cfg(not(debug_assertions))]
2431 {
2432 (Composite { val: self.val.0 }, Composite { val: self.val.1 })
2433 }
2434 #[cfg(debug_assertions)]
2435 {
2436 (
2437 Composite {
2438 val: self.val.0,
2439 min: self.min.0,
2440 max: self.max.0,
2441 },
2442 Composite {
2443 val: self.val.1,
2444 min: self.min.1,
2445 max: self.max.1,
2446 },
2447 )
2448 }
2449 }
2450}
2451
2452impl Composite<i8> {
2453 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2454 self,
2455 ) -> ri8<MIN, MAX> {
2456 #[cfg(not(debug_assertions))]
2457 {
2458 ri8 { val: self.val }
2459 }
2460 #[cfg(debug_assertions)]
2461 {
2462 ri8 { val: self.val, min: self.min, max: self.max }
2463 }
2464 }
2465}
2466
2467impl Composite<i16> {
2468 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2469 self,
2470 ) -> ri16<MIN, MAX> {
2471 #[cfg(not(debug_assertions))]
2472 {
2473 ri16 { val: self.val }
2474 }
2475 #[cfg(debug_assertions)]
2476 {
2477 ri16 { val: self.val, min: self.min, max: self.max }
2478 }
2479 }
2480}
2481
2482impl Composite<i32> {
2483 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2484 self,
2485 ) -> ri32<MIN, MAX> {
2486 #[cfg(not(debug_assertions))]
2487 {
2488 ri32 { val: self.val }
2489 }
2490 #[cfg(debug_assertions)]
2491 {
2492 ri32 { val: self.val, min: self.min, max: self.max }
2493 }
2494 }
2495}
2496
2497impl Composite<i64> {
2498 pub(crate) const fn to_rint<const MIN: i128, const MAX: i128>(
2499 self,
2500 ) -> ri64<MIN, MAX> {
2501 #[cfg(not(debug_assertions))]
2502 {
2503 ri64 { val: self.val }
2504 }
2505 #[cfg(debug_assertions)]
2506 {
2507 ri64 { val: self.val, min: self.min, max: self.max }
2508 }
2509 }
2510
2511 pub(crate) fn try_to_rint<const MIN: i128, const MAX: i128>(
2512 self,
2513 what: &'static str,
2514 ) -> Result<ri64<MIN, MAX>, Error> {
2515 #[cfg(not(debug_assertions))]
2516 {
2517 if !ri64::<MIN, MAX>::contains(self.val) {
2518 return Err(ri64::<MIN, MAX>::error(what, self.val));
2519 }
2520 Ok(ri64 { val: self.val })
2521 }
2522 #[cfg(debug_assertions)]
2523 {
2524 if !ri64::<MIN, MAX>::contains(self.val) {
2525 return Err(ri64::<MIN, MAX>::error(what, self.val));
2526 }
2527 Ok(ri64 {
2528 val: self.val,
2529 min: self.min.clamp(MIN as i64, MAX as i64),
2530 max: self.max.clamp(MIN as i64, MAX as i64),
2531 })
2532 }
2533 }
2534}
2535
2536#[cfg(test)]
2537mod tests {
2538 }