Skip to main content

devela/num/quant/
value.rs

1// devela/src/num/quant/value.rs
2//
3//! Defines [`ValueQuant`].
4//
5// Boundary: ValueQuant only associates V with Q.
6// The meaning and validity of that relation belong to the caller.
7//
8
9#[doc = crate::_tags!(quant result)]
10/// A value with associated quantification.
11#[doc = crate::_doc_meta!{
12    location("num/quant", struct ValueQuant),
13}]
14#[must_use]
15pub struct ValueQuant<V, Q> {
16    /// The main value.
17    pub v: V,
18    /// The quantification of the value.
19    pub q: Q,
20}
21
22impl<V, Q> ValueQuant<V, Q> {
23    /// A constructor with the given `value` and `quant`.
24    pub const fn new(value: V, quant: Q) -> ValueQuant<V, Q> {
25        ValueQuant { v: value, q: quant }
26    }
27
28    /// Constructs itself from a tuple.
29    #[rustfmt::skip]
30    pub fn from_vq(tuple: (V, Q)) -> ValueQuant<V, Q> {
31        ValueQuant { v: tuple.0, q: tuple.1, }
32    }
33
34    /// Transforms itself into a tuple.
35    #[must_use] #[rustfmt::skip]
36    pub fn vq(self) -> (V, Q) { (self.v, self.q) }
37
38    /// Returns a tuple of shared references to its fields.
39    #[must_use] #[rustfmt::skip]
40    pub const fn vq_ref(&self) -> (&V, &Q) { (&self.v, &self.q) }
41
42    /// Returns a tuple of exclusive references to its fields.
43    #[must_use] #[rustfmt::skip]
44    pub const fn vq_mut(&mut self) -> (&mut V, &mut Q) { (&mut self.v, &mut self.q) }
45}
46
47impl<V: Copy, Q: Copy> ValueQuant<V, Q> {
48    /// Constructs itself from a tuple, in compile-time.
49    #[rustfmt::skip]
50    pub const fn from_vq_const(tuple: (V, Q)) -> ValueQuant<V, Q> {
51        ValueQuant { v: tuple.0, q: tuple.1,
52        }
53    }
54
55    /// Transforms itself into a tuple, in compile-time.
56    #[must_use] #[rustfmt::skip]
57    pub const fn vq_const(self) -> (V, Q) { (self.v, self.q) }
58}
59
60mod core_impls {
61    use crate::{Ordering, ValueQuant, impl_trait};
62
63    impl<V: Clone, Q: Clone> Clone for ValueQuant<V, Q> {
64        fn clone(&self) -> Self {
65            Self { v: self.v.clone(), q: self.q.clone() }
66        }
67    }
68    impl<V: Copy, Q: Copy> Copy for ValueQuant<V, Q> {}
69
70    impl<V: Default, Q: Default> Default for ValueQuant<V, Q> {
71        /// Returns an empty ValueQuant with `None` for both fields.
72        fn default() -> Self {
73            Self { v: Default::default(), q: Default::default() }
74        }
75    }
76
77    impl_trait! { fmt::Debug for ValueQuant[V, Q][V, Q] where V, Q |self, f|
78       f.debug_struct("ValueQuant").field("v", &self.v).field("q", &self.q).finish()
79    }
80    impl_trait! { fmt::Display for ValueQuant[V, Q][V, Q] where V, Q |self, f|
81        write!(f, "Value: {}, Quant: {}", self.v, self.q)
82    }
83
84    impl<V: PartialEq, Q: PartialEq> PartialEq for ValueQuant<V, Q> {
85        fn eq(&self, other: &Self) -> bool {
86            self.v == other.v && self.q == other.q
87        }
88    }
89    impl<V: Eq, Q: Eq> Eq for ValueQuant<V, Q> {}
90    // with a tuple:
91    impl<V: PartialEq, Q: PartialEq> PartialEq<(V, Q)> for ValueQuant<V, Q> {
92        fn eq(&self, other: &(V, Q)) -> bool {
93            self.v == other.0 && self.q == other.1
94        }
95    }
96
97    impl<V: PartialOrd, Q: PartialOrd> PartialOrd for ValueQuant<V, Q> {
98        /// Compare `value` first. If they are equal, then compare `quant`.
99        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
100            match self.v.partial_cmp(&other.v) {
101                Some(Ordering::Equal) => self.q.partial_cmp(&other.q),
102                other => other,
103            }
104        }
105    }
106    impl<V: Ord, Q: Ord> Ord for ValueQuant<V, Q> {
107        /// Compare `value` first. If they are equal, then compare `quant`.
108        fn cmp(&self, other: &Self) -> Ordering {
109            match self.v.cmp(&other.v) {
110                Ordering::Equal => self.q.cmp(&other.q),
111                order => order,
112            }
113        }
114    }
115    impl_trait! { Hash for ValueQuant[V, Q][V, Q] where V, Q |self, state|
116        { self.v.hash(state); self.q.hash(state); }
117    }
118}