1use std::cmp::{max, Ordering};
2use std::fmt::{Debug, Display, Formatter};
3use std::ops::{
4 Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Range, RangeBounds, RangeFrom, RangeFull,
5 RangeInclusive, RangeTo, RangeToInclusive, Sub, SubAssign
6};
7use std::time::{Duration, Instant};
8
9use chrono::NaiveDateTime;
10
11use crate::algebra::concept::*;
12use crate::algebra::operator::*;
13
14use super::bound::*;
15use super::interval::*;
16use super::value_wrapper::*;
17use super::error::IllegalArgumentError;
18
19pub(self) fn empty<T: 'static + PartialOrd>(
20 lb: &ValueWrapper<T>,
21 ub: &ValueWrapper<T>,
22 lb_interval: Interval,
23 ub_interval: Interval,
24) -> bool {
25 if let ValueWrapper::NegInf = lb {
26 false
27 } else if let ValueWrapper::Inf = ub {
28 false
29 } else if let (ValueWrapper::Value(new_lb), ValueWrapper::Value(new_ub)) = (lb, ub) {
30 !(lb_interval.lb_op())(new_lb, new_ub) || !(ub_interval.ub_op())(new_ub, new_lb)
31 } else {
32 true
33 }
34}
35
36pub(self) fn ls<T>(lhs: &Bound<T>, rhs: &Bound<T>) -> Ordering
37where
38 ValueWrapper<T>: PartialOrd,
39{
40 match lhs.value.partial_cmp(&rhs.value).unwrap() {
41 Ordering::Less => Ordering::Less,
42 Ordering::Equal => {
43 if lhs.interval.outer(&rhs.interval) {
44 Ordering::Less
45 } else {
46 Ordering::Greater
47 }
48 }
49 Ordering::Greater => Ordering::Greater,
50 }
51}
52
53pub(self) fn gr<T>(lhs: &Bound<T>, rhs: &Bound<T>) -> Ordering
54where
55 ValueWrapper<T>: PartialOrd,
56{
57 match lhs.value.partial_cmp(&rhs.value).unwrap() {
58 Ordering::Less => Ordering::Less,
59 Ordering::Equal => {
60 if lhs.interval.outer(&rhs.interval) {
61 Ordering::Less
62 } else {
63 Ordering::Greater
64 }
65 }
66 Ordering::Greater => Ordering::Greater,
67 }
68}
69
70#[derive(Clone, Copy)]
71pub struct ValueRange<T> {
72 pub lb: Bound<T>,
73 pub ub: Bound<T>,
74}
75
76impl<T> ValueRange<T> {
77 pub fn new() -> Self {
78 Self {
79 lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
80 ub: Bound::new(ValueWrapper::Inf, Interval::Open),
81 }
82 }
83
84 pub fn new_with_constant(value: T) -> Self where T: Clone {
85 Self {
86 lb: Bound::new(ValueWrapper::Value(value.clone()), Interval::Closed),
87 ub: Bound::new(ValueWrapper::Value(value), Interval::Closed),
88 }
89 }
90
91 pub fn new_with(
92 lb: T,
93 ub: T,
94 lb_interval: Interval,
95 ub_interval: Interval,
96 ) -> Result<Self, IllegalArgumentError>
97 where
98 T: 'static + PartialOrd + Display,
99 {
100 let lower_bound_value = ValueWrapper::Value(lb);
101 let upper_bound_value = ValueWrapper::Value(ub);
102 Self::new_by(
103 lower_bound_value,
104 upper_bound_value,
105 lb_interval,
106 ub_interval,
107 )
108 }
109
110 pub fn new_with_lb(lb: T, lb_interval: Interval) -> Result<Self, IllegalArgumentError>
111 where
112 T: 'static + PartialOrd + Display,
113 {
114 let lower_bound_value = ValueWrapper::Value(lb);
115 Self::new_by(
116 lower_bound_value,
117 ValueWrapper::Inf,
118 lb_interval,
119 Interval::Open,
120 )
121 }
122
123 pub fn new_with_ub(ub: T, ub_interval: Interval) -> Result<Self, IllegalArgumentError>
124 where
125 T: 'static + PartialOrd + Display,
126 {
127 let upper_bound_value = ValueWrapper::Value(ub);
128 Self::new_by(
129 ValueWrapper::NegInf,
130 upper_bound_value,
131 Interval::Open,
132 ub_interval,
133 )
134 }
135
136 pub fn new_by(
137 lb: ValueWrapper<T>,
138 ub: ValueWrapper<T>,
139 lb_interval: Interval,
140 ub_interval: Interval,
141 ) -> Result<Self, IllegalArgumentError>
142 where
143 T: 'static + PartialOrd + Display,
144 {
145 if !empty(&lb, &ub, lb_interval, ub_interval) {
146 Ok(Self {
147 lb: Bound::new(lb, lb_interval),
148 ub: Bound::new(ub, ub_interval),
149 })
150 } else {
151 Err(IllegalArgumentError {
152 msg: format!(
153 "Invalid range {}{}, {}{}",
154 lb_interval.lb_sign(),
155 lb,
156 ub,
157 ub_interval.ub_sign()
158 ),
159 })
160 }
161 }
162
163 pub fn fixed(&self) -> bool
164 where
165 T: PartialEq
166 {
167 self.lb.interval == Interval::Closed
168 && self.ub.interval == Interval::Closed
169 && if let (ValueWrapper::Value(lower_value), ValueWrapper::Value(upper_value)) =
170 (&self.lb.value, &self.ub.value)
171 {
172 let eq_op = Equal::new();
173 eq_op(lower_value, upper_value)
174 } else {
175 false
176 }
177 }
178
179 pub fn fixed_value(&self) -> Option<&ValueWrapper<T>>
180 where
181 T: PartialEq
182 {
183 if self.fixed() {
184 Some(&self.lb.value)
185 } else {
186 None
187 }
188 }
189
190 pub fn mean(&self) -> Result<ValueWrapper<T>, IllegalArgumentError>
191 where
192 T: RealNumber,
193 for<'a> &'a ValueWrapper<T>: Add<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
194 ValueWrapper<T>: for<'a> Div<&'a T, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
195 {
196 (&self.lb.value + &self.ub.value)? / T::TWO
197 }
198
199 pub fn diff(&self) -> Result<ValueWrapper<T>, IllegalArgumentError>
200 where
201 for<'a> &'a ValueWrapper<T>: Sub<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
202 {
203 &self.ub.value - &self.lb.value
204 }
205
206 pub fn gap(&self) -> Result<ValueWrapper<T>, IllegalArgumentError>
207 where
208 T: RealNumber + Ord,
209 for<'a> &'a T: Abs<Output = T>,
210 for<'a> &'a ValueWrapper<T>: Add<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
211 for<'a> &'a ValueWrapper<T>: Sub<&'a ValueWrapper<T>, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
212 ValueWrapper<T>: for<'a> Div<&'a T, Output = Result<ValueWrapper<T>, IllegalArgumentError>>,
213 {
214 self.diff()? / max(T::DECIMAL_PRECISION, &self.mean()?.unwrap().abs())
215 }
216
217 pub fn union(&self, rhs: &ValueRange<T>) -> Option<ValueRange<T>>
218 where
219 T: 'static + PartialOrd + Display + Clone,
220 {
221 if self.ub.value < rhs.lb.value || rhs.ub.value < self.lb.value {
222 return None;
223 }
224
225 let new_lb = if self.lb.value < rhs.lb.value {
226 &self.lb.value
227 } else {
228 &rhs.lb.value
229 };
230 let new_lb_interval = match self.lb.value.partial_cmp(&rhs.lb.value) {
231 Some(Ordering::Less) => self.lb.interval,
232 Some(Ordering::Greater) => rhs.lb.interval,
233 _ => self.lb.interval.union(&rhs.lb.interval),
234 };
235 let new_ub = if self.ub.value < rhs.ub.value {
236 &rhs.ub.value
237 } else {
238 &self.ub.value
239 };
240 let new_ub_interval = match self.ub.value.partial_cmp(&rhs.ub.value) {
241 Some(Ordering::Less) => rhs.ub.interval,
242 Some(Ordering::Greater) => self.ub.interval,
243 _ => self.ub.interval.union(&rhs.ub.interval),
244 };
245 match ValueRange::new_by(
246 new_lb.clone(),
247 new_ub.clone(),
248 new_lb_interval,
249 new_ub_interval,
250 ) {
251 Ok(new_range) => Some(new_range),
252 Err(_) => None,
253 }
254 }
255
256 pub fn intersect(&self, rhs: &ValueRange<T>) -> Option<ValueRange<T>>
257 where
258 T: 'static + PartialOrd + Display + Clone,
259 {
260 let new_lb = if self.lb.value < rhs.lb.value {
261 &rhs.lb.value
262 } else {
263 &self.lb.value
264 };
265 let new_lb_interval = if self.lb.value.is_inf_or_neg_inf() {
266 rhs.lb.interval
267 } else if rhs.lb.value.is_inf_or_neg_inf() {
268 self.lb.interval
269 } else {
270 match self.lb.value.partial_cmp(&rhs.lb.value) {
271 Some(Ordering::Less) => rhs.lb.interval,
272 Some(Ordering::Greater) => self.lb.interval,
273 _ => self.lb.interval.intersect(&rhs.lb.interval),
274 }
275 };
276 let new_ub = if self.ub.value < rhs.ub.value {
277 &self.ub.value
278 } else {
279 &rhs.ub.value
280 };
281 let new_ub_interval = if self.ub.value.is_inf_or_neg_inf() {
282 rhs.ub.interval
283 } else if rhs.ub.value.is_inf_or_neg_inf() {
284 self.ub.interval
285 } else {
286 match self.ub.value.partial_cmp(&rhs.ub.value) {
287 Some(Ordering::Less) => self.ub.interval,
288 Some(Ordering::Greater) => rhs.ub.interval,
289 _ => self.ub.interval.intersect(&rhs.ub.interval),
290 }
291 };
292 match ValueRange::new_by(
293 new_lb.clone(),
294 new_ub.clone(),
295 new_lb_interval,
296 new_ub_interval,
297 ) {
298 Ok(new_range) => Some(new_range),
299 Err(_) => None,
300 }
301 }
302
303 pub fn contains(&self, value: &T) -> bool
304 where
305 ValueWrapper<T>: PartialOrd<T>,
306 T: 'static,
307 {
308 (self.lb.interval.lb_op())(&self.lb.value, value)
309 && (self.ub.interval.ub_op())(&self.ub.value, value)
310 }
311
312 pub fn contains_range(&self, range: &ValueRange<T>) -> bool
313 where
314 ValueWrapper<T>: PartialOrd,
315 T: 'static,
316 {
317 let lb_interval = self.lb.interval.intersect(&range.lb.interval);
318 let ub_interval = self.ub.interval.intersect(&range.ub.interval);
319 (lb_interval.lb_op())(&self.lb.value, &range.lb.value)
320 && (ub_interval.ub_op())(&self.ub.value, &range.ub.value)
321 }
322}
323
324impl<T: Display> Display for ValueRange<T> {
325 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
326 write!(
327 f,
328 "{}{}, {}{}",
329 self.lb.interval.lb_sign(),
330 self.lb.value,
331 self.ub.value,
332 self.ub.interval.ub_sign()
333 )
334 }
335}
336
337impl<T: Display> Debug for ValueRange<T> {
338 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
339 write!(
340 f,
341 "{}{}, {}{}",
342 self.lb.interval.lb_sign(),
343 self.lb.value,
344 self.ub.value,
345 self.ub.interval.ub_sign()
346 )
347 }
348}
349
350impl<T> From<Range<T>> for ValueRange<T> {
351 fn from(range: Range<T>) -> Self {
352 Self {
353 lb: Bound::new(ValueWrapper::Value(range.start), Interval::Closed),
354 ub: Bound::new(ValueWrapper::Value(range.end), Interval::Open),
355 }
356 }
357}
358
359impl<T: Clone> From<&Range<T>> for ValueRange<T> {
360 fn from(range: &Range<T>) -> Self {
361 Self {
362 lb: Bound::new(ValueWrapper::Value(range.start.clone()), Interval::Closed),
363 ub: Bound::new(ValueWrapper::Value(range.end.clone()), Interval::Open),
364 }
365 }
366}
367
368impl<T> From<RangeFrom<T>> for ValueRange<T> {
369 fn from(range: RangeFrom<T>) -> Self {
370 Self {
371 lb: Bound::new(ValueWrapper::Value(range.start), Interval::Closed),
372 ub: Bound::new(ValueWrapper::Inf, Interval::Open),
373 }
374 }
375}
376
377impl<T: Clone> From<&RangeFrom<T>> for ValueRange<T> {
378 fn from(range: &RangeFrom<T>) -> Self {
379 Self {
380 lb: Bound::new(ValueWrapper::Value(range.start.clone()), Interval::Closed),
381 ub: Bound::new(ValueWrapper::Inf, Interval::Open),
382 }
383 }
384}
385
386impl<T: Clone> From<RangeInclusive<T>> for ValueRange<T> {
387 fn from(range: RangeInclusive<T>) -> Self {
388 Self {
389 lb: Bound::new(ValueWrapper::Value(range.start().clone()), Interval::Closed),
390 ub: Bound::new(ValueWrapper::Value(range.end().clone()), Interval::Closed),
391 }
392 }
393}
394
395impl<T: Clone> From<&RangeInclusive<T>> for ValueRange<T> {
396 fn from(range: &RangeInclusive<T>) -> Self {
397 Self {
398 lb: Bound::new(ValueWrapper::Value(range.start().clone()), Interval::Closed),
399 ub: Bound::new(ValueWrapper::Value(range.end().clone()), Interval::Closed),
400 }
401 }
402}
403
404impl<T> From<RangeTo<T>> for ValueRange<T> {
405 fn from(range: RangeTo<T>) -> Self {
406 Self {
407 lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
408 ub: Bound::new(ValueWrapper::Value(range.end), Interval::Open),
409 }
410 }
411}
412
413impl<T: Clone> From<&RangeTo<T>> for ValueRange<T> {
414 fn from(range: &RangeTo<T>) -> Self {
415 Self {
416 lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
417 ub: Bound::new(ValueWrapper::Value(range.end.clone()), Interval::Open),
418 }
419 }
420}
421
422impl<T> From<RangeToInclusive<T>> for ValueRange<T> {
423 fn from(range: RangeToInclusive<T>) -> Self {
424 Self {
425 lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
426 ub: Bound::new(ValueWrapper::Value(range.end), Interval::Closed),
427 }
428 }
429}
430
431impl<T: Clone> From<&RangeToInclusive<T>> for ValueRange<T> {
432 fn from(range: &RangeToInclusive<T>) -> Self {
433 Self {
434 lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
435 ub: Bound::new(ValueWrapper::Value(range.end.clone()), Interval::Closed),
436 }
437 }
438}
439
440impl From<RangeFull> for ValueRange<i64> {
441 fn from(_range: RangeFull) -> Self {
442 Self {
443 lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
444 ub: Bound::new(ValueWrapper::Inf, Interval::Open),
445 }
446 }
447}
448
449impl<T> From<&RangeFull> for ValueRange<T> {
450 fn from(_range: &RangeFull) -> Self {
451 Self {
452 lb: Bound::new(ValueWrapper::NegInf, Interval::Open),
453 ub: Bound::new(ValueWrapper::Inf, Interval::Open),
454 }
455 }
456}
457
458impl<T, U> From<&ValueRange<U>> for ValueRange<T>
459where
460 Bound<T>: for<'a> From<&'a Bound<U>>,
461{
462 fn from(value: &ValueRange<U>) -> Self {
463 Self {
464 lb: Bound::from(&value.lb),
465 ub: Bound::from(&value.ub),
466 }
467 }
468}
469
470impl<T, U> PartialEq<ValueRange<U>> for ValueRange<T>
471where
472 ValueWrapper<T>: PartialEq<ValueWrapper<U>>,
473{
474 fn eq(&self, other: &ValueRange<U>) -> bool {
475 self.lb == other.lb && self.ub == other.ub
476 }
477}
478
479macro_rules! value_range_template {
480 ($type:ident, $rhs:ident) => {
481 impl Add<$rhs> for ValueRange<$type> {
482 type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
483
484 fn add(self, rhs: $rhs) -> Self::Output {
485 let new_lb = (self.lb + rhs)?;
486 let new_ub = (self.ub + rhs)?;
487 Ok(ValueRange {
488 lb: new_lb,
489 ub: new_ub,
490 })
491 }
492 }
493
494 impl<'a> Add<&'a $rhs> for ValueRange<$type> {
495 type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
496
497 fn add(self, rhs: &'a $rhs) -> Self::Output {
498 let new_lb = (self.lb + rhs)?;
499 let new_ub = (self.ub + rhs)?;
500 Ok(ValueRange {
501 lb: new_lb,
502 ub: new_ub,
503 })
504 }
505 }
506
507 impl<'a> Add<$rhs> for &'a ValueRange<$type> {
508 type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
509
510 fn add(self, rhs: $rhs) -> Self::Output {
511 let new_lb = (self.lb + rhs)?;
512 let new_ub = (self.ub + rhs)?;
513 Ok(ValueRange {
514 lb: new_lb,
515 ub: new_ub,
516 })
517 }
518 }
519
520 impl<'a, 'b> Add<&'b $rhs> for &'a ValueRange<$type> {
521 type Output = Result<ValueRange<<$type as Add<$rhs>>::Output>, IllegalArgumentError>;
522
523 fn add(self, rhs: &'b $rhs) -> Self::Output {
524 let new_lb = (self.lb + rhs)?;
525 let new_ub = (self.ub + rhs)?;
526 Ok(ValueRange {
527 lb: new_lb,
528 ub: new_ub,
529 })
530 }
531 }
532
533 impl AddAssign<$rhs> for ValueRange<$type> {
534 fn add_assign(&mut self, rhs: $rhs) {
535 let new_lb = (self.lb + rhs).expect("illegal argument");
536 let new_ub = (self.ub + rhs).expect("illegal argument");
537 self.lb = new_lb;
538 self.ub = new_ub;
539 }
540 }
541
542 impl<'a> AddAssign<&'a $rhs> for ValueRange<$type> {
543 fn add_assign(&mut self, rhs: &'a $rhs) {
544 let new_lb = (self.lb + rhs).expect("illegal argument");
545 let new_ub = (self.ub + rhs).expect("illegal argument");
546 self.lb = new_lb;
547 self.ub = new_ub;
548 }
549 }
550
551 impl Sub<$rhs> for ValueRange<$type> {
552 type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
553
554 fn sub(self, rhs: $rhs) -> Self::Output {
555 let new_lb = (self.lb - rhs)?;
556 let new_ub = (self.ub - rhs)?;
557 Ok(ValueRange {
558 lb: new_lb,
559 ub: new_ub,
560 })
561 }
562 }
563
564 impl<'a> Sub<&'a $rhs> for ValueRange<$type> {
565 type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
566
567 fn sub(self, rhs: &'a $rhs) -> Self::Output {
568 let new_lb = (self.lb - rhs)?;
569 let new_ub = (self.ub - rhs)?;
570 Ok(ValueRange {
571 lb: new_lb,
572 ub: new_ub,
573 })
574 }
575 }
576
577 impl<'a> Sub<$rhs> for &'a ValueRange<$type> {
578 type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
579
580 fn sub(self, rhs: $rhs) -> Self::Output {
581 let new_lb = (self.lb - rhs)?;
582 let new_ub = (self.ub - rhs)?;
583 Ok(ValueRange {
584 lb: new_lb,
585 ub: new_ub,
586 })
587 }
588 }
589
590 impl<'a, 'b> Sub<&'b $rhs> for &'a ValueRange<$type> {
591 type Output = Result<ValueRange<<$type as Sub<$rhs>>::Output>, IllegalArgumentError>;
592
593 fn sub(self, rhs: &'b $rhs) -> Self::Output {
594 let new_lb = (self.lb - rhs)?;
595 let new_ub = (self.ub - rhs)?;
596 Ok(ValueRange {
597 lb: new_lb,
598 ub: new_ub,
599 })
600 }
601 }
602
603 impl SubAssign<$rhs> for ValueRange<$type> {
604 fn sub_assign(&mut self, rhs: $rhs) {
605 let new_lb = (self.lb - rhs).expect("illegal argument");
606 let new_ub = (self.ub - rhs).expect("illegal argument");
607 self.lb = new_lb;
608 self.ub = new_ub;
609 }
610 }
611
612 impl<'a> SubAssign<&'a $rhs> for ValueRange<$type> {
613 fn sub_assign(&mut self, rhs: &'a $rhs) {
614 let new_lb = (self.lb - rhs).expect("illegal argument");
615 let new_ub = (self.ub - rhs).expect("illegal argument");
616 self.lb = new_lb;
617 self.ub = new_ub;
618 }
619 }
620 };
621}
622value_range_template!(Instant, Duration);
623value_range_template!(NaiveDateTime, Duration);
624
625macro_rules! signed_value_range_template {
626 ($($type:ident)*) => ($(
627 impl Neg for ValueRange<$type> {
628 type Output = Result<ValueRange<<$type as Neg>::Output>, IllegalArgumentError>;
629
630 fn neg(self) -> Self::Output {
631 let new_lb = (-self.ub)?;
632 let new_ub = (-self.lb)?;
633 Ok(ValueRange {
634 lb: new_lb,
635 ub: new_ub,
636 })
637 }
638 }
639
640 impl Neg for &ValueRange<$type> {
641 type Output = Result<ValueRange<<$type as Neg>::Output>, IllegalArgumentError>;
642
643 fn neg(self) -> Self::Output {
644 let new_lb = (-self.ub)?;
645 let new_ub = (-self.lb)?;
646 Ok(ValueRange {
647 lb: new_lb,
648 ub: new_ub,
649 })
650 }
651 }
652 )*)
653}
654signed_value_range_template! { i8 i16 i32 i64 i128 isize f32 f64 }
655
656macro_rules! real_number_value_range_template {
657 ($($type:ident)*) => ($(
658 impl Add<$type> for ValueRange<$type> {
659 type Output = Result<ValueRange<<$type as Add<$type>>::Output>, IllegalArgumentError>;
660
661 fn add(self, rhs: $type) -> Self::Output {
662 let new_lb = (self.lb + rhs)?;
663 let new_ub = (self.ub + rhs)?;
664 Ok(ValueRange {
665 lb: new_lb,
666 ub: new_ub,
667 })
668 }
669 }
670
671 impl<'a> Add<&'a $type> for ValueRange<$type> {
672 type Output = Result<ValueRange<<$type as Add<&'a $type>>::Output>, IllegalArgumentError>;
673
674 fn add(self, rhs: &'a $type) -> Self::Output {
675 let new_lb = (self.lb + rhs)?;
676 let new_ub = (self.ub + rhs)?;
677 Ok(ValueRange {
678 lb: new_lb,
679 ub: new_ub,
680 })
681 }
682 }
683
684 impl<'a> Add<$type> for &'a ValueRange<$type> {
685 type Output = Result<ValueRange<<&'a $type as Add<$type>>::Output>, IllegalArgumentError>;
686
687 fn add(self, rhs: $type) -> Self::Output {
688 let new_lb = (self.lb + rhs)?;
689 let new_ub = (self.ub + rhs)?;
690 Ok(ValueRange {
691 lb: new_lb,
692 ub: new_ub,
693 })
694 }
695 }
696
697 impl<'a, 'b> Add<&'b $type> for &'a ValueRange<$type> {
698 type Output = Result<ValueRange<<&'a $type as Add<&'b $type>>::Output>, IllegalArgumentError>;
699
700 fn add(self, rhs: &'b $type) -> Self::Output {
701 let new_lb = (self.lb + rhs)?;
702 let new_ub = (self.ub + rhs)?;
703 Ok(ValueRange {
704 lb: new_lb,
705 ub: new_ub,
706 })
707 }
708 }
709
710 impl AddAssign<$type> for ValueRange<$type> {
711 fn add_assign(&mut self, rhs: $type) {
712 let new_lb = (self.lb + rhs).expect("illegal argument");
713 let new_ub = (self.ub + rhs).expect("illegal argument");
714 self.lb = new_lb;
715 self.ub = new_ub;
716 }
717 }
718
719 impl<'a> AddAssign<&'a $type> for ValueRange<$type> {
720 fn add_assign(&mut self, rhs: &'a $type) {
721 let new_lb = (self.lb + rhs).expect("illegal argument");
722 let new_ub = (self.ub + rhs).expect("illegal argument");
723 self.lb = new_lb;
724 self.ub = new_ub;
725 }
726 }
727
728 impl Add<ValueRange<$type>> for $type {
729 type Output = Result<ValueRange<<$type as Add<$type>>::Output>, IllegalArgumentError>;
730
731 fn add(self, rhs: ValueRange<$type>) -> Self::Output {
732 let new_lb = (self + rhs.lb)?;
733 let new_ub = (self + rhs.ub)?;
734 Ok(ValueRange {
735 lb: new_lb,
736 ub: new_ub,
737 })
738 }
739 }
740
741 impl<'a> Add<ValueRange<$type>> for &'a $type {
742 type Output = Result<ValueRange<<&'a $type as Add<$type>>::Output>, IllegalArgumentError>;
743
744 fn add(self, rhs: ValueRange<$type>) -> Self::Output {
745 let new_lb = (self + rhs.lb)?;
746 let new_ub = (self + rhs.ub)?;
747 Ok(ValueRange {
748 lb: new_lb,
749 ub: new_ub,
750 })
751 }
752 }
753
754 impl<'a> Add<&'a ValueRange<$type>> for $type {
755 type Output = Result<ValueRange<<$type as Add<&'a $type>>::Output>, IllegalArgumentError>;
756
757 fn add(self, rhs: &'a ValueRange<$type>) -> Self::Output {
758 let new_lb = (self + rhs.lb)?;
759 let new_ub = (self + rhs.ub)?;
760 Ok(ValueRange {
761 lb: new_lb,
762 ub: new_ub,
763 })
764 }
765 }
766
767 impl<'a, 'b> Add<&'b ValueRange<$type>> for &'a $type {
768 type Output = Result<ValueRange<<&'a $type as Add<&'b $type>>::Output>, IllegalArgumentError>;
769
770 fn add(self, rhs: &'b ValueRange<$type>) -> Self::Output {
771 let new_lb = (self + rhs.lb)?;
772 let new_ub = (self + rhs.ub)?;
773 Ok(ValueRange {
774 lb: new_lb,
775 ub: new_ub,
776 })
777 }
778 }
779
780 impl Add<ValueRange<$type>> for ValueRange<$type> {
781 type Output = Result<ValueRange<<$type as Add<$type>>::Output>, IllegalArgumentError>;
782
783 fn add(self, rhs: ValueRange<$type>) -> Self::Output {
784 let new_lb = (self.lb + rhs.lb)?;
785 let new_ub = (self.ub + rhs.ub)?;
786 Ok(ValueRange {
787 lb: new_lb,
788 ub: new_ub,
789 })
790 }
791 }
792
793 impl<'a> Add<&'a ValueRange<$type>> for ValueRange<$type> {
794 type Output = Result<ValueRange<<$type as Add<&'a $type>>::Output>, IllegalArgumentError>;
795
796 fn add(self, rhs: &'a ValueRange<$type>) -> Self::Output {
797 let new_lb = (self.lb + rhs.lb)?;
798 let new_ub = (self.ub + rhs.ub)?;
799 Ok(ValueRange {
800 lb: new_lb,
801 ub: new_ub,
802 })
803 }
804 }
805
806 impl<'a> Add<ValueRange<$type>> for &'a ValueRange<$type> {
807 type Output = Result<ValueRange<<&'a $type as Add<$type>>::Output>, IllegalArgumentError>;
808
809 fn add(self, rhs: ValueRange<$type>) -> Self::Output {
810 let new_lb = (self.lb + rhs.lb)?;
811 let new_ub = (self.ub + rhs.ub)?;
812 Ok(ValueRange {
813 lb: new_lb,
814 ub: new_ub,
815 })
816 }
817 }
818
819 impl<'a, 'b> Add<&'b ValueRange<$type>> for &'a ValueRange<$type> {
820 type Output = Result<ValueRange<<&'a $type as Add<&'b $type>>::Output>, IllegalArgumentError>;
821
822 fn add(self, rhs: &'b ValueRange<$type>) -> Self::Output {
823 let new_lb = (self.lb + rhs.lb)?;
824 let new_ub = (self.ub + rhs.ub)?;
825 Ok(ValueRange {
826 lb: new_lb,
827 ub: new_ub,
828 })
829 }
830 }
831
832 impl AddAssign<ValueRange<$type>> for ValueRange<$type> {
833 fn add_assign(&mut self, rhs: ValueRange<$type>) {
834 let new_lb = (self.lb + rhs.lb).expect("illegal argument");
835 let new_ub = (self.ub + rhs.ub).expect("illegal argument");
836 self.lb = new_lb;
837 self.ub = new_ub;
838 }
839 }
840
841 impl<'a> AddAssign<&'a ValueRange<$type>> for ValueRange<$type> {
842 fn add_assign(&mut self, rhs: &'a ValueRange<$type>) {
843 let new_lb = (self.lb + rhs.lb).expect("illegal argument");
844 let new_ub = (self.ub + rhs.ub).expect("illegal argument");
845 self.lb = new_lb;
846 self.ub = new_ub;
847 }
848 }
849
850 impl Sub<$type> for ValueRange<$type> {
851 type Output = Result<ValueRange<<$type as Sub<$type>>::Output>, IllegalArgumentError>;
852
853 fn sub(self, rhs: $type) -> Self::Output {
854 let new_lb = (self.lb - rhs)?;
855 let new_ub = (self.ub - rhs)?;
856 Ok(ValueRange {
857 lb: new_lb,
858 ub: new_ub,
859 })
860 }
861 }
862
863 impl<'a> Sub<&'a $type> for ValueRange<$type> {
864 type Output = Result<ValueRange<<$type as Sub<&'a $type>>::Output>, IllegalArgumentError>;
865
866 fn sub(self, rhs: &'a $type) -> Self::Output {
867 let new_lb = (self.lb - rhs)?;
868 let new_ub = (self.ub - rhs)?;
869 Ok(ValueRange {
870 lb: new_lb,
871 ub: new_ub,
872 })
873 }
874 }
875
876 impl<'a> Sub<$type> for &'a ValueRange<$type> {
877 type Output = Result<ValueRange<<&'a $type as Sub<$type>>::Output>, IllegalArgumentError>;
878
879 fn sub(self, rhs: $type) -> Self::Output {
880 let new_lb = (self.lb - rhs)?;
881 let new_ub = (self.ub - rhs)?;
882 Ok(ValueRange {
883 lb: new_lb,
884 ub: new_ub,
885 })
886 }
887 }
888
889 impl<'a, 'b> Sub<&'b $type> for &'a ValueRange<$type> {
890 type Output = Result<ValueRange<<&'a $type as Sub<&'b $type>>::Output>, IllegalArgumentError>;
891
892 fn sub(self, rhs: &'b $type) -> Self::Output {
893 let new_lb = (self.lb - rhs)?;
894 let new_ub = (self.ub - rhs)?;
895 Ok(ValueRange {
896 lb: new_lb,
897 ub: new_ub,
898 })
899 }
900 }
901
902 impl SubAssign<$type> for ValueRange<$type> {
903 fn sub_assign(&mut self, rhs: $type) {
904 let new_lb = (self.lb - rhs).expect("illegal argument");
905 let new_ub = (self.ub - rhs).expect("illegal argument");
906 self.lb = new_lb;
907 self.ub = new_ub;
908 }
909 }
910
911 impl<'a> SubAssign<&'a $type> for ValueRange<$type> {
912 fn sub_assign(&mut self, rhs: &'a $type) {
913 let new_lb = (self.lb - rhs).expect("illegal argument");
914 let new_ub = (self.ub - rhs).expect("illegal argument");
915 self.lb = new_lb;
916 self.ub = new_ub;
917 }
918 }
919
920 impl Sub<ValueRange<$type>> for $type {
921 type Output = Result<ValueRange<<$type as Sub<$type>>::Output>, IllegalArgumentError>;
922
923 fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
924 let new_lb = (self - rhs.ub)?;
925 let new_ub = (self - rhs.lb)?;
926 Ok(ValueRange {
927 lb: new_lb,
928 ub: new_ub,
929 })
930 }
931 }
932
933 impl<'a> Sub<ValueRange<$type>> for &'a $type {
934 type Output = Result<ValueRange<<&'a $type as Sub<$type>>::Output>, IllegalArgumentError>;
935
936 fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
937 let new_lb = (self - rhs.ub)?;
938 let new_ub = (self - rhs.lb)?;
939 Ok(ValueRange {
940 lb: new_lb,
941 ub: new_ub,
942 })
943 }
944 }
945
946 impl<'a> Sub<&'a ValueRange<$type>> for $type {
947 type Output = Result<ValueRange<<$type as Sub<&'a $type>>::Output>, IllegalArgumentError>;
948
949 fn sub(self, rhs: &'a ValueRange<$type>) -> Self::Output {
950 let new_lb = (self - rhs.ub)?;
951 let new_ub = (self - rhs.lb)?;
952 Ok(ValueRange {
953 lb: new_lb,
954 ub: new_ub,
955 })
956 }
957 }
958
959 impl<'a, 'b> Sub<&'b ValueRange<$type>> for &'a $type {
960 type Output = Result<ValueRange<<&'a $type as Sub<&'b $type>>::Output>, IllegalArgumentError>;
961
962 fn sub(self, rhs: &'b ValueRange<$type>) -> Self::Output {
963 let new_lb = (self - rhs.ub)?;
964 let new_ub = (self - rhs.lb)?;
965 Ok(ValueRange {
966 lb: new_lb,
967 ub: new_ub,
968 })
969 }
970 }
971
972 impl Sub<ValueRange<$type>> for ValueRange<$type> {
973 type Output = Result<ValueRange<<$type as Sub<$type>>::Output>, IllegalArgumentError>;
974
975 fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
976 let new_lb = (self.lb - rhs.ub)?;
977 let new_ub = (self.ub - rhs.lb)?;
978 Ok(ValueRange {
979 lb: new_lb,
980 ub: new_ub,
981 })
982 }
983 }
984
985 impl<'a> Sub<&'a ValueRange<$type>> for ValueRange<$type> {
986 type Output = Result<ValueRange<<$type as Sub<&'a $type>>::Output>, IllegalArgumentError>;
987
988 fn sub(self, rhs: &'a ValueRange<$type>) -> Self::Output {
989 let new_lb = (self.lb - rhs.ub)?;
990 let new_ub = (self.ub - rhs.lb)?;
991 Ok(ValueRange {
992 lb: new_lb,
993 ub: new_ub,
994 })
995 }
996 }
997
998 impl<'a> Sub<ValueRange<$type>> for &'a ValueRange<$type> {
999 type Output = Result<ValueRange<<&'a $type as Sub<$type>>::Output>, IllegalArgumentError>;
1000
1001 fn sub(self, rhs: ValueRange<$type>) -> Self::Output {
1002 let new_lb = (self.lb - rhs.ub)?;
1003 let new_ub = (self.ub - rhs.lb)?;
1004 Ok(ValueRange {
1005 lb: new_lb,
1006 ub: new_ub,
1007 })
1008 }
1009 }
1010
1011 impl<'a, 'b> Sub<&'b ValueRange<$type>> for &'a ValueRange<$type> {
1012 type Output = Result<ValueRange<<&'a $type as Sub<&'b $type>>::Output>, IllegalArgumentError>;
1013
1014 fn sub(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1015 let new_lb = (self.lb - rhs.ub)?;
1016 let new_ub = (self.ub - rhs.lb)?;
1017 Ok(ValueRange {
1018 lb: new_lb,
1019 ub: new_ub,
1020 })
1021 }
1022 }
1023
1024 impl SubAssign<ValueRange<$type>> for ValueRange<$type> {
1025 fn sub_assign(&mut self, rhs: ValueRange<$type>) {
1026 let new_lb = (self.lb - rhs.ub).expect("illegal argument");
1027 let new_ub = (self.ub - rhs.lb).expect("illegal argument");
1028 self.lb = new_lb;
1029 self.ub = new_ub;
1030 }
1031 }
1032
1033 impl<'a> SubAssign<&'a ValueRange<$type>> for ValueRange<$type> {
1034 fn sub_assign(&mut self, rhs: &'a ValueRange<$type>) {
1035 let new_lb = (self.lb - rhs.ub).expect("illegal argument");
1036 let new_ub = (self.ub - rhs.lb).expect("illegal argument");
1037 self.lb = new_lb;
1038 self.ub = new_ub;
1039 }
1040 }
1041
1042 impl Mul<$type> for ValueRange<$type> {
1043 type Output = Result<ValueRange<<$type as Mul<$type>>::Output>, IllegalArgumentError>;
1044
1045 fn mul(self, rhs: $type) -> Self::Output {
1046 if &rhs >= $type::ZERO {
1047 let new_lb = (self.lb * rhs)?;
1048 let new_ub = (self.ub * rhs)?;
1049 Ok(ValueRange {
1050 lb: new_lb,
1051 ub: new_ub,
1052 })
1053 } else {
1054 let new_lb = (self.ub * rhs)?;
1055 let new_ub = (self.lb * rhs)?;
1056 Ok(ValueRange {
1057 lb: new_lb,
1058 ub: new_ub,
1059 })
1060 }
1061 }
1062 }
1063
1064 impl<'a> Mul<&'a $type> for ValueRange<$type> {
1065 type Output = Result<ValueRange<<$type as Mul<&'a $type>>::Output>, IllegalArgumentError>;
1066
1067 fn mul(self, rhs: &'a $type) -> Self::Output {
1068 if rhs >= $type::ZERO {
1069 let new_lb = (self.lb * rhs)?;
1070 let new_ub = (self.ub * rhs)?;
1071 Ok(ValueRange {
1072 lb: new_lb,
1073 ub: new_ub,
1074 })
1075 } else {
1076 let new_lb = (self.ub * rhs)?;
1077 let new_ub = (self.lb * rhs)?;
1078 Ok(ValueRange {
1079 lb: new_lb,
1080 ub: new_ub,
1081 })
1082 }
1083 }
1084 }
1085
1086 impl<'a> Mul<$type> for &'a ValueRange<$type> {
1087 type Output = Result<ValueRange<<&'a $type as Mul<$type>>::Output>, IllegalArgumentError>;
1088
1089 fn mul(self, rhs: $type) -> Self::Output {
1090 if &rhs >= $type::ZERO {
1091 let new_lb = (self.lb * rhs)?;
1092 let new_ub = (self.ub * rhs)?;
1093 Ok(ValueRange {
1094 lb: new_lb,
1095 ub: new_ub,
1096 })
1097 } else {
1098 let new_lb = (self.ub * rhs)?;
1099 let new_ub = (self.lb * rhs)?;
1100 Ok(ValueRange {
1101 lb: new_lb,
1102 ub: new_ub,
1103 })
1104 }
1105 }
1106 }
1107
1108 impl<'a, 'b> Mul<&'b $type> for &'a ValueRange<$type> {
1109 type Output = Result<ValueRange<<&'a $type as Mul<&'b $type>>::Output>, IllegalArgumentError>;
1110
1111 fn mul(self, rhs: &'b $type) -> Self::Output {
1112 if rhs >= $type::ZERO {
1113 let new_lb = (self.lb * rhs)?;
1114 let new_ub = (self.ub * rhs)?;
1115 Ok(ValueRange {
1116 lb: new_lb,
1117 ub: new_ub,
1118 })
1119 } else {
1120 let new_lb = (self.ub * rhs)?;
1121 let new_ub = (self.lb * rhs)?;
1122 Ok(ValueRange {
1123 lb: new_lb,
1124 ub: new_ub,
1125 })
1126 }
1127 }
1128 }
1129
1130 impl MulAssign<$type> for ValueRange<$type> {
1131 fn mul_assign(&mut self, rhs: $type) {
1132 if &rhs >= $type::ZERO {
1133 let new_lb = (self.lb * rhs).expect("illegal argument");
1134 let new_ub = (self.ub * rhs).expect("illegal argument");
1135 self.lb = new_lb;
1136 self.ub = new_ub;
1137 } else {
1138 let new_lb = (self.ub * rhs).expect("illegal argument");
1139 let new_ub = (self.lb * rhs).expect("illegal argument");
1140 self.lb = new_lb;
1141 self.ub = new_ub;
1142 }
1143 }
1144 }
1145
1146 impl<'a> MulAssign<&'a $type> for ValueRange<$type> {
1147 fn mul_assign(&mut self, rhs: &'a $type) {
1148 if rhs >= $type::ZERO {
1149 let new_lb = (self.lb * rhs).expect("illegal argument");
1150 let new_ub = (self.ub * rhs).expect("illegal argument");
1151 self.lb = new_lb;
1152 self.ub = new_ub;
1153 } else {
1154 let new_lb = (self.ub * rhs).expect("illegal argument");
1155 let new_ub = (self.lb * rhs).expect("illegal argument");
1156 self.lb = new_lb;
1157 self.ub = new_ub;
1158 }
1159 }
1160 }
1161
1162 impl Mul<ValueRange<$type>> for $type {
1163 type Output = Result<ValueRange<<$type as Mul<$type>>::Output>, IllegalArgumentError>;
1164
1165 fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1166 if &self >= $type::ZERO {
1167 let new_lb = (self * rhs.lb)?;
1168 let new_ub = (self * rhs.ub)?;
1169 Ok(ValueRange {
1170 lb: new_lb,
1171 ub: new_ub,
1172 })
1173 } else {
1174 let new_lb = (self * rhs.ub)?;
1175 let new_ub = (self * rhs.lb)?;
1176 Ok(ValueRange {
1177 lb: new_lb,
1178 ub: new_ub,
1179 })
1180 }
1181 }
1182 }
1183
1184 impl<'a> Mul<ValueRange<$type>> for &'a $type {
1185 type Output = Result<ValueRange<<&'a $type as Mul<$type>>::Output>, IllegalArgumentError>;
1186
1187 fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1188 if self >= $type::ZERO {
1189 let new_lb = (self * rhs.lb)?;
1190 let new_ub = (self * rhs.ub)?;
1191 Ok(ValueRange {
1192 lb: new_lb,
1193 ub: new_ub,
1194 })
1195 } else {
1196 let new_lb = (self * rhs.ub)?;
1197 let new_ub = (self * rhs.lb)?;
1198 Ok(ValueRange {
1199 lb: new_lb,
1200 ub: new_ub,
1201 })
1202 }
1203 }
1204 }
1205
1206 impl<'a> Mul<&'a ValueRange<$type>> for $type {
1207 type Output = Result<ValueRange<<$type as Mul<&'a $type>>::Output>, IllegalArgumentError>;
1208
1209 fn mul(self, rhs: &'a ValueRange<$type>) -> Self::Output {
1210 if &self >= $type::ZERO {
1211 let new_lb = (self * rhs.lb)?;
1212 let new_ub = (self * rhs.ub)?;
1213 Ok(ValueRange {
1214 lb: new_lb,
1215 ub: new_ub,
1216 })
1217 } else {
1218 let new_lb = (self * rhs.ub)?;
1219 let new_ub = (self * rhs.lb)?;
1220 Ok(ValueRange {
1221 lb: new_lb,
1222 ub: new_ub,
1223 })
1224 }
1225 }
1226 }
1227
1228 impl<'a, 'b> Mul<&'b ValueRange<$type>> for &'a $type {
1229 type Output = Result<ValueRange<<&'a $type as Mul<&'b $type>>::Output>, IllegalArgumentError>;
1230
1231 fn mul(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1232 if self >= $type::ZERO {
1233 let new_lb = (self * rhs.lb)?;
1234 let new_ub = (self * rhs.ub)?;
1235 Ok(ValueRange {
1236 lb: new_lb,
1237 ub: new_ub,
1238 })
1239 } else {
1240 let new_lb = (self * rhs.ub)?;
1241 let new_ub = (self * rhs.lb)?;
1242 Ok(ValueRange {
1243 lb: new_lb,
1244 ub: new_ub,
1245 })
1246 }
1247 }
1248 }
1249
1250 impl Mul<ValueRange<$type>> for ValueRange<$type> {
1251 type Output = Result<ValueRange<<$type as Mul<$type>>::Output>, IllegalArgumentError>;
1252
1253 fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1254 let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1255 let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1256 let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1257 Ok(ValueRange {
1258 lb: *new_lb,
1259 ub: *new_ub,
1260 })
1261 }
1262 }
1263
1264 impl<'a> Mul<&'a ValueRange<$type>> for ValueRange<$type> {
1265 type Output = Result<ValueRange<<$type as Mul<&'a $type>>::Output>, IllegalArgumentError>;
1266
1267 fn mul(self, rhs: &'a ValueRange<$type>) -> Self::Output {
1268 let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1269 let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1270 let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1271 Ok(ValueRange {
1272 lb: *new_lb,
1273 ub: *new_ub,
1274 })
1275 }
1276 }
1277
1278 impl<'a> Mul<ValueRange<$type>> for &'a ValueRange<$type> {
1279 type Output = Result<ValueRange<<&'a $type as Mul<$type>>::Output>, IllegalArgumentError>;
1280
1281 fn mul(self, rhs: ValueRange<$type>) -> Self::Output {
1282 let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1283 let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1284 let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1285 Ok(ValueRange {
1286 lb: *new_lb,
1287 ub: *new_ub,
1288 })
1289 }
1290 }
1291
1292 impl<'a, 'b> Mul<&'b ValueRange<$type>> for &'a ValueRange<$type> {
1293 type Output = Result<ValueRange<<&'a $type as Mul<&'b $type>>::Output>, IllegalArgumentError>;
1294
1295 fn mul(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1296 let bounds = vec![(self.lb * rhs.lb)?, (self.lb * rhs.ub)?, (self.ub * rhs.lb)?, (self.ub * rhs.ub)?];
1297 let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1298 let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1299 Ok(ValueRange {
1300 lb: *new_lb,
1301 ub: *new_ub,
1302 })
1303 }
1304 }
1305
1306 impl MulAssign<ValueRange<$type>> for ValueRange<$type> {
1307 fn mul_assign(&mut self, rhs: ValueRange<$type>) {
1308 let bounds = vec![
1309 (self.lb * rhs.lb).expect("illegal argument"),
1310 (self.lb * rhs.ub).expect("illegal argument"),
1311 (self.ub * rhs.lb).expect("illegal argument"),
1312 (self.ub * rhs.ub).expect("illegal argument")
1313 ];
1314 let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1315 let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1316 self.lb = *new_lb;
1317 self.ub = *new_ub;
1318 }
1319 }
1320
1321 impl<'a> MulAssign<&'a ValueRange<$type>> for ValueRange<$type> {
1322 fn mul_assign(&mut self, rhs: &'a ValueRange<$type>) {
1323 let bounds = vec![
1324 (self.lb * rhs.lb).expect("illegal argument"),
1325 (self.lb * rhs.ub).expect("illegal argument"),
1326 (self.ub * rhs.lb).expect("illegal argument"),
1327 (self.ub * rhs.ub).expect("illegal argument")
1328 ];
1329 let new_lb = bounds.iter().min_by(|lhs, rhs| ls(lhs, rhs)).unwrap();
1330 let new_ub = bounds.iter().max_by(|lhs, rhs| gr(lhs, rhs)).unwrap();
1331 self.lb = *new_lb;
1332 self.ub = *new_ub;
1333 }
1334 }
1335
1336 impl Div<$type> for ValueRange<$type> {
1337 type Output = Result<ValueRange<<$type as Div<$type>>::Output>, IllegalArgumentError>;
1338
1339 fn div(self, rhs: $type) -> Self::Output {
1340 if &rhs > $type::ZERO {
1341 let new_lb = (self.lb / rhs)?;
1342 let new_ub = (self.ub / rhs)?;
1343 Ok(ValueRange {
1344 lb: new_lb,
1345 ub: new_ub,
1346 })
1347 } else if &rhs < $type::ZERO {
1348 let new_lb = (self.ub / rhs)?;
1349 let new_ub = (self.lb / rhs)?;
1350 Ok(ValueRange {
1351 lb: new_lb,
1352 ub: new_ub,
1353 })
1354 } else {
1355 Err(IllegalArgumentError {
1356 msg: "division by zero".to_string()
1357 })
1358 }
1359 }
1360 }
1361
1362 impl<'a> Div<&'a $type> for ValueRange<$type> {
1363 type Output = Result<ValueRange<<$type as Div<&'a $type>>::Output>, IllegalArgumentError>;
1364
1365 fn div(self, rhs: &'a $type) -> Self::Output {
1366 if rhs > $type::ZERO {
1367 let new_lb = (self.lb / rhs)?;
1368 let new_ub = (self.ub / rhs)?;
1369 Ok(ValueRange {
1370 lb: new_lb,
1371 ub: new_ub,
1372 })
1373 } else if rhs < $type::ZERO {
1374 let new_lb = (self.ub / rhs)?;
1375 let new_ub = (self.lb / rhs)?;
1376 Ok(ValueRange {
1377 lb: new_lb,
1378 ub: new_ub,
1379 })
1380 } else {
1381 Err(IllegalArgumentError {
1382 msg: "division by zero".to_string()
1383 })
1384 }
1385 }
1386 }
1387
1388 impl<'a> Div<$type> for &'a ValueRange<$type> {
1389 type Output = Result<ValueRange<<&'a $type as Div<$type>>::Output>, IllegalArgumentError>;
1390
1391 fn div(self, rhs: $type) -> Self::Output {
1392 if &rhs > $type::ZERO {
1393 let new_lb = (self.lb / rhs)?;
1394 let new_ub = (self.ub / rhs)?;
1395 Ok(ValueRange {
1396 lb: new_lb,
1397 ub: new_ub,
1398 })
1399 } else if &rhs < $type::ZERO {
1400 let new_lb = (self.ub / rhs)?;
1401 let new_ub = (self.lb / rhs)?;
1402 Ok(ValueRange {
1403 lb: new_lb,
1404 ub: new_ub,
1405 })
1406 } else {
1407 Err(IllegalArgumentError {
1408 msg: "division by zero".to_string()
1409 })
1410 }
1411 }
1412 }
1413
1414 impl<'a, 'b> Div<&'b $type> for &'a ValueRange<$type> {
1415 type Output = Result<ValueRange<<&'a $type as Div<&'b $type>>::Output>, IllegalArgumentError>;
1416
1417 fn div(self, rhs: &'b $type) -> Self::Output {
1418 if rhs > $type::ZERO {
1419 let new_lb = (self.lb / rhs)?;
1420 let new_ub = (self.ub / rhs)?;
1421 Ok(ValueRange {
1422 lb: new_lb,
1423 ub: new_ub,
1424 })
1425 } else if rhs < $type::ZERO {
1426 let new_lb = (self.ub / rhs)?;
1427 let new_ub = (self.lb / rhs)?;
1428 Ok(ValueRange {
1429 lb: new_lb,
1430 ub: new_ub,
1431 })
1432 } else {
1433 Err(IllegalArgumentError {
1434 msg: "division by zero".to_string()
1435 })
1436 }
1437 }
1438 }
1439
1440 impl DivAssign<$type> for ValueRange<$type> {
1441 fn div_assign(&mut self, rhs: $type) {
1442 if &rhs > $type::ZERO {
1443 let new_lb = (self.lb / rhs).expect("illegal argument");
1444 let new_ub = (self.ub / rhs).expect("illegal argument");
1445 self.lb = new_lb;
1446 self.ub = new_ub;
1447 } else if &rhs < $type::ZERO {
1448 let new_lb = (self.ub / rhs).expect("illegal argument");
1449 let new_ub = (self.lb / rhs).expect("illegal argument");
1450 self.lb = new_lb;
1451 self.ub = new_ub;
1452 } else {
1453 panic!("division by zero")
1454 }
1455 }
1456 }
1457
1458 impl<'a> DivAssign<&'a $type> for ValueRange<$type> {
1459 fn div_assign(&mut self, rhs: &'a $type) {
1460 if rhs > $type::ZERO {
1461 let new_lb = (self.lb / rhs).expect("illegal argument");
1462 let new_ub = (self.ub / rhs).expect("illegal argument");
1463 self.lb = new_lb;
1464 self.ub = new_ub;
1465 } else if rhs < $type::ZERO {
1466 let new_lb = (self.ub / rhs).expect("illegal argument");
1467 let new_ub = (self.lb / rhs).expect("illegal argument");
1468 self.lb = new_lb;
1469 self.ub = new_ub;
1470 } else {
1471 panic!("division by zero")
1472 }
1473 }
1474 }
1475
1476 impl Div<ValueRange<$type>> for $type {
1477 type Output = Result<ValueRange<<$type as Div<$type>>::Output>, IllegalArgumentError>;
1478
1479 fn div(self, rhs: ValueRange<$type>) -> Self::Output {
1480 if &self > $type::ZERO {
1481 let new_lb = (self / rhs.lb)?;
1482 let new_ub = (self / rhs.ub)?;
1483 Ok(ValueRange {
1484 lb: new_lb,
1485 ub: new_ub,
1486 })
1487 } else if &self < $type::ZERO {
1488 let new_lb = (self / rhs.ub)?;
1489 let new_ub = (self / rhs.lb)?;
1490 Ok(ValueRange {
1491 lb: new_lb,
1492 ub: new_ub,
1493 })
1494 } else {
1495 Err(IllegalArgumentError {
1496 msg: "division by zero".to_string()
1497 })
1498 }
1499 }
1500 }
1501
1502 impl<'a> Div<ValueRange<$type>> for &'a $type {
1503 type Output = Result<ValueRange<<&'a $type as Div<$type>>::Output>, IllegalArgumentError>;
1504
1505 fn div(self, rhs: ValueRange<$type>) -> Self::Output {
1506 if self > $type::ZERO {
1507 let new_lb = (self / rhs.lb)?;
1508 let new_ub = (self / rhs.ub)?;
1509 Ok(ValueRange {
1510 lb: new_lb,
1511 ub: new_ub,
1512 })
1513 } else if self < $type::ZERO {
1514 let new_lb = (self / rhs.ub)?;
1515 let new_ub = (self / rhs.lb)?;
1516 Ok(ValueRange {
1517 lb: new_lb,
1518 ub: new_ub,
1519 })
1520 } else {
1521 Err(IllegalArgumentError {
1522 msg: "division by zero".to_string()
1523 })
1524 }
1525 }
1526 }
1527
1528 impl<'a> Div<&'a ValueRange<$type>> for $type {
1529 type Output = Result<ValueRange<<$type as Div<&'a $type>>::Output>, IllegalArgumentError>;
1530
1531 fn div(self, rhs: &'a ValueRange<$type>) -> Self::Output {
1532 if &self > $type::ZERO {
1533 let new_lb = (self / rhs.lb)?;
1534 let new_ub = (self / rhs.ub)?;
1535 Ok(ValueRange {
1536 lb: new_lb,
1537 ub: new_ub,
1538 })
1539 } else if &self < $type::ZERO {
1540 let new_lb = (self / rhs.ub)?;
1541 let new_ub = (self / rhs.lb)?;
1542 Ok(ValueRange {
1543 lb: new_lb,
1544 ub: new_ub,
1545 })
1546 } else {
1547 Err(IllegalArgumentError {
1548 msg: "division by zero".to_string()
1549 })
1550 }
1551 }
1552 }
1553
1554 impl<'a, 'b> Div<&'b ValueRange<$type>> for &'a $type {
1555 type Output = Result<ValueRange<<&'a $type as Div<&'b $type>>::Output>, IllegalArgumentError>;
1556
1557 fn div(self, rhs: &'b ValueRange<$type>) -> Self::Output {
1558 if self > $type::ZERO {
1559 let new_lb = (self / rhs.lb)?;
1560 let new_ub = (self / rhs.ub)?;
1561 Ok(ValueRange {
1562 lb: new_lb,
1563 ub: new_ub,
1564 })
1565 } else if self < $type::ZERO {
1566 let new_lb = (self / rhs.ub)?;
1567 let new_ub = (self / rhs.lb)?;
1568 Ok(ValueRange {
1569 lb: new_lb,
1570 ub: new_ub,
1571 })
1572 } else {
1573 Err(IllegalArgumentError {
1574 msg: "division by zero".to_string()
1575 })
1576 }
1577 }
1578 }
1579 )*)
1580}
1581real_number_value_range_template! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64 }
1582
1583#[macro_export]
1584macro_rules! value_range {
1585 ((..,$ub:expr)) => {
1586 ValueRange::new_with_ub($ub, Interval::Open)
1587 };
1588 (($lb:expr,..)) => {
1589 ValueRange::new_with_lb($lb, Interval::Open)
1590 };
1591 (($lb:expr, $ub:expr)) => {
1592 ValueRange::new_with($lb, $ub, Interval::Open, Interval::Open)
1593 };
1594 ([..,$ub:expr]) => {
1595 ValueRange::new_with_ub($ub, Interval::Closed)
1596 };
1597 ([$lb:expr,..]) => {
1598 ValueRange::new_with_lb($lb, Interval::Closed)
1599 };
1600 ([$lb:expr, $ub:expr]) => {
1601 ValueRange::new_with($lb, $ub, Interval::Closed, Interval::Closed)
1602 };
1603 (($lb:expr)..($ub:expr)) => {
1604 ValueRange::new_with($lb, $ub, Interval::Open, Interval::Open)
1605 };
1606 (($lb:expr)..=($ub:expr)) => {
1607 ValueRange::new_with($lb, $ub, Interval::Closed, Interval::Closed)
1608 };
1609 (($lb:expr)..) => {
1610 ValueRange::new_with_lb($lb, Interval::Closed)
1611 };
1612 (..($ub:expr)) => {
1613 ValueRange::new_with_ub($ub, Interval::Open)
1614 };
1615 (..=($ub:expr)) => {
1616 ValueRange::new_with_ub($ub, Interval::Closed)
1617 };
1618}
1619
1620#[cfg(test)]
1621mod tests {
1622 use super::*;
1623
1624 #[test]
1625 fn test_constructor() {
1626 let open_range = value_range!((1.0f64, 2.0f64));
1627 assert!(open_range.is_ok());
1628 assert_eq!(open_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1629 assert_eq!(open_range.as_ref().unwrap().ub.interval, Interval::Open);
1630 assert_eq!(open_range.as_ref().unwrap().ub.value.unwrap(), &2.0);
1631 assert_eq!(open_range.as_ref().unwrap().ub.interval, Interval::Open);
1632 let closed_range = value_range!([1.0f64, 2.0f64]);
1633 assert!(closed_range.is_ok());
1634 assert_eq!(closed_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1635 assert_eq!(closed_range.as_ref().unwrap().ub.interval, Interval::Closed);
1636 assert_eq!(closed_range.as_ref().unwrap().ub.value.unwrap(), &2.0);
1637 assert_eq!(closed_range.as_ref().unwrap().ub.interval, Interval::Closed);
1638 let range_range = value_range!((1.0f64)..(2.0f64)).unwrap();
1639 assert_eq!(range_range.lb.value.unwrap(), &1.0);
1640 assert_eq!(range_range.ub.interval, Interval::Open);
1641 assert_eq!(range_range.ub.value.unwrap(), &2.0);
1642 assert_eq!(range_range.ub.interval, Interval::Open);
1643 let range_inclusive_range = value_range!((1.0f64)..=(2.0f64)).unwrap();
1644 assert_eq!(range_inclusive_range.lb.value.unwrap(), &1.0);
1645 assert_eq!(range_inclusive_range.ub.interval, Interval::Closed);
1646 assert_eq!(range_inclusive_range.ub.value.unwrap(), &2.0);
1647 assert_eq!(range_inclusive_range.ub.interval, Interval::Closed);
1648 let invalid_range = value_range!([2.0f64, 1.0f64]);
1649 assert!(invalid_range.is_err());
1650 }
1651
1652 #[test]
1653 fn test_plus() {
1654 let range = value_range!([1.0f64, 2.0f64]).unwrap();
1655 let added_range = (range + 1.0f64).unwrap();
1656 assert_eq!(added_range.lb.value.unwrap(), &2.0);
1657 assert_eq!(added_range.ub.value.unwrap(), &3.0);
1658 let twice_range = (range + range).unwrap();
1659 assert_eq!(twice_range.lb.value.unwrap(), &2.0);
1660 assert_eq!(twice_range.ub.value.unwrap(), &4.0);
1661 let inf_range = (range + f64::INFINITY).unwrap();
1662 assert_eq!(inf_range.lb.value.unwrap(), f64::INF.as_ref().unwrap());
1663 assert_eq!(inf_range.lb.interval, Interval::Open);
1664 assert_eq!(inf_range.ub.value.unwrap(), f64::INF.as_ref().unwrap());
1665 assert_eq!(inf_range.ub.interval, Interval::Open);
1666 let neg_inf_range = (range - f64::INFINITY).unwrap();
1667 assert_eq!(
1668 neg_inf_range.lb.value.unwrap(),
1669 f64::NEG_INF.as_ref().unwrap()
1670 );
1671 assert_eq!(neg_inf_range.lb.interval, Interval::Open);
1672 assert_eq!(
1673 neg_inf_range.ub.value.unwrap(),
1674 f64::NEG_INF.as_ref().unwrap()
1675 );
1676 assert_eq!(neg_inf_range.ub.interval, Interval::Open);
1677 let inf_range2 = (value_range!([1.0f64, ..]).unwrap() + 1.0f64).unwrap();
1678 assert_eq!(inf_range2.lb.value.unwrap(), &2.0);
1679 assert_eq!(inf_range2.lb.interval, Interval::Closed);
1680 assert_eq!(inf_range2.ub.value.unwrap(), f64::INF.as_ref().unwrap());
1681 assert_eq!(inf_range2.ub.interval, Interval::Open);
1682 let neg_inf_range2 = (value_range!([.., 1.0f64]).unwrap() + 1.0f64).unwrap();
1683 assert_eq!(
1684 neg_inf_range2.lb.value.unwrap(),
1685 f64::NEG_INF.as_ref().unwrap()
1686 );
1687 assert_eq!(neg_inf_range2.lb.interval, Interval::Open);
1688 assert_eq!(neg_inf_range2.ub.value.unwrap(), &2.0);
1689 assert_eq!(neg_inf_range2.ub.interval, Interval::Closed);
1690 }
1691
1692 #[test]
1693 fn test_subtract() {
1694 let range = value_range!([1.0f64, 2.0f64]).unwrap();
1695 let added_range = (range - 1.0f64).unwrap();
1696 assert_eq!(added_range.lb.value.unwrap(), &0.0);
1697 assert_eq!(added_range.ub.value.unwrap(), &1.0);
1698 let twice_range = (range - range).unwrap();
1699 assert_eq!(twice_range.lb.value.unwrap(), &-1.0);
1700 assert_eq!(twice_range.ub.value.unwrap(), &1.0);
1701 }
1702
1703 #[test]
1704 fn test_multiply() {
1705 let range = value_range!([1.0f64, 2.0f64]).unwrap();
1706 let zero_range = (range * 0.0f64).unwrap();
1707 assert!(zero_range.fixed());
1708 assert_eq!(zero_range.fixed_value().unwrap().unwrap(), &0.0);
1709 let twice_range = (range * 2.0f64).unwrap();
1710 assert_eq!(twice_range.lb.value.unwrap(), &2.0);
1711 assert_eq!(twice_range.ub.value.unwrap(), &4.0);
1712 let neg_twice_range = (range * -2.0f64).unwrap();
1713 assert_eq!(neg_twice_range.lb.value.unwrap(), &-4.0);
1714 assert_eq!(neg_twice_range.ub.value.unwrap(), &-2.0);
1715 let square_range = (range * range).unwrap();
1716 assert_eq!(square_range.lb.value.unwrap(), &1.0);
1717 assert_eq!(square_range.ub.value.unwrap(), &4.0);
1718 }
1719
1720 #[test]
1721 fn test_divide() {
1722 let range = value_range!([1.0f64, 2.0f64]).unwrap();
1723 let half_range = (range / 2.0f64).unwrap();
1724 assert_eq!(half_range.lb.value.unwrap(), &0.5);
1725 assert_eq!(half_range.ub.value.unwrap(), &1.0);
1726 let neg_half_range = (range / -2.0f64).unwrap();
1727 assert_eq!(neg_half_range.lb.value.unwrap(), &-1.0);
1728 assert_eq!(neg_half_range.ub.value.unwrap(), &-0.5);
1729 }
1730
1731 #[test]
1732 fn test_intersection() {
1733 let range = value_range!([1.0f64, 3.0f64]).unwrap();
1734 let left_half_range1 = value_range!([0.0f64, 2.0f64]).unwrap().intersect(&range);
1735 assert!(left_half_range1.is_some());
1736 assert_eq!(left_half_range1.unwrap().lb.value.unwrap(), &1.0);
1737 assert_eq!(left_half_range1.unwrap().ub.value.unwrap(), &2.0);
1738 let right_half_range1 = range.intersect(&value_range!([0.0f64, 2.0f64]).unwrap());
1739 assert!(right_half_range1.is_some());
1740 assert_eq!(right_half_range1.unwrap().lb.value.unwrap(), &1.0);
1741 assert_eq!(right_half_range1.unwrap().ub.value.unwrap(), &2.0);
1742 let left_half_range2 = value_range!([2.0f64, 4.0f64]).unwrap().intersect(&range);
1743 assert!(left_half_range2.is_some());
1744 assert_eq!(left_half_range2.unwrap().lb.value.unwrap(), &2.0);
1745 assert_eq!(left_half_range2.unwrap().ub.value.unwrap(), &3.0);
1746 let right_half_range2 = range.intersect(&value_range!([2.0f64, 4.0f64]).unwrap());
1747 assert!(right_half_range2.is_some());
1748 assert_eq!(right_half_range2.unwrap().lb.value.unwrap(), &2.0);
1749 assert_eq!(right_half_range2.unwrap().ub.value.unwrap(), &3.0);
1750 let none_range = range.intersect(&value_range!([4.0f64, 10.0f64]).unwrap());
1751 assert!(none_range.is_none());
1752 let inf_range = range.intersect(&value_range!([1.0f64, ..]).unwrap());
1753 assert!(inf_range.is_some());
1754 assert_eq!(inf_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1755 assert_eq!(inf_range.as_ref().unwrap().lb.interval, Interval::Closed);
1756 assert_eq!(inf_range.as_ref().unwrap().ub.value.unwrap(), &3.0);
1757 assert_eq!(inf_range.as_ref().unwrap().ub.interval, Interval::Closed);
1758 let neg_inf_range = range.intersect(&value_range!([.., 2.0f64]).unwrap());
1759 assert!(neg_inf_range.is_some());
1760 assert_eq!(neg_inf_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1761 assert_eq!(
1762 neg_inf_range.as_ref().unwrap().lb.interval,
1763 Interval::Closed
1764 );
1765 assert_eq!(neg_inf_range.as_ref().unwrap().ub.value.unwrap(), &2.0);
1766 assert_eq!(
1767 neg_inf_range.as_ref().unwrap().ub.interval,
1768 Interval::Closed
1769 );
1770 }
1771
1772 #[test]
1773 fn test_union() {
1774 let range = value_range!([1.0f64, 3.0f64]).unwrap();
1775 let union_range1 = range.union(&value_range!([0.0f64, 2.0f64]).unwrap());
1776 assert!(union_range1.is_some());
1777 assert_eq!(union_range1.unwrap().lb.value.unwrap(), &0.0);
1778 assert_eq!(union_range1.unwrap().ub.value.unwrap(), &3.0);
1779 let union_range2 = range.union(&value_range!([2.0f64, 10.0f64]).unwrap());
1780 assert!(union_range2.is_some());
1781 assert_eq!(union_range2.unwrap().lb.value.unwrap(), &1.0);
1782 assert_eq!(union_range2.unwrap().ub.value.unwrap(), &10.0);
1783 let union_range3 = range.union(&value_range!([0.0f64, 10.0f64]).unwrap());
1784 assert!(union_range3.is_some());
1785 assert_eq!(union_range3.unwrap().lb.value.unwrap(), &0.0);
1786 assert_eq!(union_range3.unwrap().ub.value.unwrap(), &10.0);
1787 let none_range = range.union(&value_range!([4.0f64, 10.0f64]).unwrap());
1788 assert!(none_range.is_none());
1789 let inf_range = range.union(&value_range!([1.0f64, ..]).unwrap());
1790 assert!(inf_range.is_some());
1791 assert_eq!(inf_range.as_ref().unwrap().lb.value.unwrap(), &1.0);
1792 assert_eq!(inf_range.as_ref().unwrap().lb.interval, Interval::Closed);
1793 assert_eq!(
1794 inf_range.as_ref().unwrap().ub.value.unwrap(),
1795 f64::INF.as_ref().unwrap()
1796 );
1797 assert_eq!(inf_range.as_ref().unwrap().ub.interval, Interval::Open);
1798 let neg_inf_range = range.union(&value_range!([.., 1.0f64]).unwrap());
1799 assert!(neg_inf_range.is_some());
1800 assert_eq!(
1801 neg_inf_range.as_ref().unwrap().lb.value.unwrap(),
1802 f64::NEG_INF.as_ref().unwrap()
1803 );
1804 assert_eq!(neg_inf_range.as_ref().unwrap().lb.interval, Interval::Open);
1805 assert_eq!(neg_inf_range.as_ref().unwrap().ub.value.unwrap(), &3.0);
1806 assert_eq!(
1807 neg_inf_range.as_ref().unwrap().ub.interval,
1808 Interval::Closed
1809 );
1810 }
1811
1812 #[test]
1813 fn test_contains() {
1814 let range = value_range!([1.0f64, 3.0f64]).unwrap();
1815 assert!(range.contains(&1.0f64));
1816 assert!(range.contains(&2.0f64));
1817 assert!(range.contains(&3.0f64));
1818 assert!(!range.contains(&0.0f64));
1819 assert!(!range.contains(&4.0f64));
1820
1821 assert!(range.contains_range(&value_range!([1.0f64, 2.0f64]).unwrap()));
1822 assert!(range.contains_range(&value_range!([2.0f64, 3.0f64]).unwrap()));
1823 assert!(range.contains_range(&value_range!([1.0f64, 3.0f64]).unwrap()));
1824 assert!(!range.contains_range(&value_range!([0.0f64, 1.0f64]).unwrap()));
1825 assert!(!range.contains_range(&value_range!([0.0f64, 2.0f64]).unwrap()));
1826 assert!(!range.contains_range(&value_range!([2.0f64, 10.0f64]).unwrap()));
1827 }
1828}