Skip to main content

devela/num/quant/
value.rs

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