1pub trait PartialOrder : Eq {
9 fn less_than(&self, other: &Self) -> bool {
11 self.less_equal(other) && self != other
12 }
13 fn less_equal(&self, other: &Self) -> bool;
15}
16
17pub trait TotalOrder : PartialOrder { }
27
28pub trait Empty : PartialOrder { }
34
35impl Empty for () { }
36
37macro_rules! implement_partial {
38 ($($index_type:ty,)*) => (
39 $(
40 impl PartialOrder for $index_type {
41 #[inline] fn less_than(&self, other: &Self) -> bool { self < other }
42 #[inline] fn less_equal(&self, other: &Self) -> bool { self <= other }
43 }
44 )*
45 )
46}
47
48macro_rules! implement_total {
49 ($($index_type:ty,)*) => (
50 $(
51 impl TotalOrder for $index_type { }
52 )*
53 )
54}
55
56implement_partial!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, (), ::std::time::Duration,);
57implement_total!(u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, (), ::std::time::Duration,);
58
59pub use product::Product;
60mod product {
62 use std::fmt::{Formatter, Error, Debug};
63
64 use crate::container::columnation::{Columnation, Region};
65 use crate::order::{Empty, TotalOrder};
66 use crate::progress::Timestamp;
67 use crate::progress::timestamp::PathSummary;
68 use crate::progress::timestamp::Refines;
69
70 #[derive(Abomonation, Copy, Clone, Hash, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize)]
75 pub struct Product<TOuter, TInner> {
76 pub outer: TOuter,
78 pub inner: TInner,
80 }
81
82 impl<TOuter, TInner> Product<TOuter, TInner> {
83 pub fn new(outer: TOuter, inner: TInner) -> Self {
85 Product {
86 outer,
87 inner,
88 }
89 }
90 }
91
92 impl<TOuter: Debug, TInner: Debug> Debug for Product<TOuter, TInner> {
94 fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
95 f.write_str(&format!("({:?}, {:?})", self.outer, self.inner))
96 }
97 }
98
99 use super::PartialOrder;
100 impl<TOuter: PartialOrder, TInner: PartialOrder> PartialOrder for Product<TOuter, TInner> {
101 #[inline]
102 fn less_equal(&self, other: &Self) -> bool {
103 self.outer.less_equal(&other.outer) && self.inner.less_equal(&other.inner)
104 }
105 }
106
107 impl<TOuter: Timestamp, TInner: Timestamp> Timestamp for Product<TOuter, TInner> {
108 type Summary = Product<TOuter::Summary, TInner::Summary>;
109 fn minimum() -> Self { Self { outer: TOuter::minimum(), inner: TInner::minimum() }}
110 }
111
112 impl<TOuter: Timestamp, TInner: Timestamp> PathSummary<Product<TOuter, TInner>> for Product<TOuter::Summary, TInner::Summary> {
113 #[inline]
114 fn results_in(&self, product: &Product<TOuter, TInner>) -> Option<Product<TOuter, TInner>> {
115 self.outer.results_in(&product.outer)
116 .and_then(|outer|
117 self.inner.results_in(&product.inner)
118 .map(|inner| Product::new(outer, inner))
119 )
120 }
121 #[inline]
122 fn followed_by(&self, other: &Self) -> Option<Self> {
123 self.outer.followed_by(&other.outer)
124 .and_then(|outer|
125 self.inner.followed_by(&other.inner)
126 .map(|inner| Product::new(outer, inner))
127 )
128 }
129 }
130
131 impl<TOuter: Timestamp, TInner: Timestamp> Refines<TOuter> for Product<TOuter, TInner> {
132 fn to_inner(other: TOuter) -> Self {
133 Product::new(other, TInner::minimum())
134 }
135 fn to_outer(self: Product<TOuter, TInner>) -> TOuter {
136 self.outer
137 }
138 fn summarize(path: <Self as Timestamp>::Summary) -> <TOuter as Timestamp>::Summary {
139 path.outer
140 }
141 }
142
143 impl<T1: Empty, T2: Empty> Empty for Product<T1, T2> { }
144 impl<T1, T2> TotalOrder for Product<T1, T2> where T1: Empty, T2: TotalOrder { }
145
146 impl<T1: Columnation, T2: Columnation> Columnation for Product<T1, T2> {
147 type InnerRegion = ProductRegion<T1::InnerRegion, T2::InnerRegion>;
148 }
149
150 #[derive(Default)]
151 pub struct ProductRegion<T1, T2> {
152 outer_region: T1,
153 inner_region: T2,
154 }
155
156 impl<T1: Region, T2: Region> Region for ProductRegion<T1, T2> {
157 type Item = Product<T1::Item, T2::Item>;
158
159 #[inline]
160 unsafe fn copy(&mut self, item: &Self::Item) -> Self::Item {
161 Product { outer: self.outer_region.copy(&item.outer), inner: self.inner_region.copy(&item.inner) }
162 }
163
164 fn clear(&mut self) {
165 self.outer_region.clear();
166 self.inner_region.clear();
167 }
168
169 fn reserve_items<'a, I>(&mut self, items1: I) where Self: 'a, I: Iterator<Item=&'a Self::Item> + Clone {
170 let items2 = items1.clone();
171 self.outer_region.reserve_items(items1.map(|x| &x.outer));
172 self.inner_region.reserve_items(items2.map(|x| &x.inner))
173 }
174
175 fn reserve_regions<'a, I>(&mut self, regions1: I) where Self: 'a, I: Iterator<Item=&'a Self> + Clone {
176 let regions2 = regions1.clone();
177 self.outer_region.reserve_regions(regions1.map(|r| &r.outer_region));
178 self.inner_region.reserve_regions(regions2.map(|r| &r.inner_region));
179 }
180
181 fn heap_size(&self, mut callback: impl FnMut(usize, usize)) {
182 self.outer_region.heap_size(&mut callback);
183 self.inner_region.heap_size(callback);
184 }
185 }
186}
187
188mod tuple {
190
191 use super::PartialOrder;
192 impl<TOuter: PartialOrder, TInner: PartialOrder> PartialOrder for (TOuter, TInner) {
193 #[inline]
194 fn less_equal(&self, other: &Self) -> bool {
195 self.0.less_than(&other.0) || (self.0.eq(&other.0) && self.1.less_equal(&other.1))
197 }
198 }
199
200 use super::TotalOrder;
201 impl<T1, T2> TotalOrder for (T1, T2) where T1: TotalOrder, T2: TotalOrder { }
202
203 use crate::progress::Timestamp;
204 impl<TOuter: Timestamp, TInner: Timestamp> Timestamp for (TOuter, TInner) {
205 type Summary = (TOuter::Summary, TInner::Summary);
206 fn minimum() -> Self { (TOuter::minimum(), TInner::minimum()) }
207 }
208
209 use crate::progress::timestamp::PathSummary;
210 impl<TOuter: Timestamp, TInner: Timestamp> PathSummary<(TOuter, TInner)> for (TOuter::Summary, TInner::Summary) {
211 #[inline]
212 fn results_in(&self, (outer, inner): &(TOuter, TInner)) -> Option<(TOuter, TInner)> {
213 self.0.results_in(outer)
214 .and_then(|outer|
215 self.1.results_in(inner)
216 .map(|inner| (outer, inner))
217 )
218 }
219 #[inline]
220 fn followed_by(&self, (outer, inner): &(TOuter::Summary, TInner::Summary)) -> Option<(TOuter::Summary, TInner::Summary)> {
221 self.0.followed_by(outer)
222 .and_then(|outer|
223 self.1.followed_by(inner)
224 .map(|inner| (outer, inner))
225 )
226 }
227 }
228
229 use crate::progress::timestamp::Refines;
230 impl<TOuter: Timestamp, TInner: Timestamp> Refines<TOuter> for (TOuter, TInner) {
231 fn to_inner(other: TOuter) -> Self {
232 (other, TInner::minimum())
233 }
234 fn to_outer(self: (TOuter, TInner)) -> TOuter {
235 self.0
236 }
237 fn summarize(path: <Self as Timestamp>::Summary) -> <TOuter as Timestamp>::Summary {
238 path.0
239 }
240 }
241
242 use super::Empty;
243 impl<T1: Empty, T2: Empty> Empty for (T1, T2) { }
244}