1pub trait PartialOrder<Rhs: ?Sized = Self>: PartialEq<Rhs> {
9 fn less_than(&self, other: &Rhs) -> bool {
11 self.less_equal(other) && self != other
12 }
13 fn less_equal(&self, other: &Rhs) -> 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 use columnar::Columnar;
64 use serde::{Deserialize, Serialize};
65
66 use columnation::{Columnation, Region};
67 use crate::order::{Empty, TotalOrder};
68 use crate::progress::Timestamp;
69 use crate::progress::timestamp::PathSummary;
70 use crate::progress::timestamp::Refines;
71
72 #[derive(Copy, Clone, Hash, Eq, PartialEq, Default, Ord, PartialOrd, Serialize, Deserialize, Columnar)]
77 #[columnar(derive(Eq, PartialEq, Ord, PartialOrd))]
78 pub struct Product<TOuter, TInner> {
79 pub outer: TOuter,
81 pub inner: TInner,
83 }
84
85 impl<TOuter, TInner> Product<TOuter, TInner> {
86 pub fn new(outer: TOuter, inner: TInner) -> Self {
88 Product {
89 outer,
90 inner,
91 }
92 }
93 }
94
95 impl<TOuter: Debug, TInner: Debug> Debug for Product<TOuter, TInner> {
97 fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
98 f.write_str(&format!("({:?}, {:?})", self.outer, self.inner))
99 }
100 }
101
102 use super::PartialOrder;
103 impl<TOuter, TOuter2, TInner, TInner2> PartialOrder<Product<TOuter2, TInner2>> for Product<TOuter, TInner>
104 where
105 TOuter: PartialOrder<TOuter2>,
106 TInner: PartialOrder<TInner2>,
107 Self: PartialEq<Product<TOuter2, TInner2>>,
108 {
109 #[inline]
110 fn less_equal(&self, other: &Product<TOuter2, TInner2>) -> bool {
111 self.outer.less_equal(&other.outer) && self.inner.less_equal(&other.inner)
112 }
113 }
114
115 impl<TOuter: Timestamp, TInner: Timestamp> Timestamp for Product<TOuter, TInner> {
116 type Summary = Product<TOuter::Summary, TInner::Summary>;
117 fn minimum() -> Self { Self { outer: TOuter::minimum(), inner: TInner::minimum() }}
118 }
119
120 impl<TOuter: Timestamp, TInner: Timestamp> PathSummary<Product<TOuter, TInner>> for Product<TOuter::Summary, TInner::Summary> {
121 #[inline]
122 fn results_in(&self, product: &Product<TOuter, TInner>) -> Option<Product<TOuter, TInner>> {
123 self.outer.results_in(&product.outer)
124 .and_then(|outer|
125 self.inner.results_in(&product.inner)
126 .map(|inner| Product::new(outer, inner))
127 )
128 }
129 #[inline]
130 fn followed_by(&self, other: &Self) -> Option<Self> {
131 self.outer.followed_by(&other.outer)
132 .and_then(|outer|
133 self.inner.followed_by(&other.inner)
134 .map(|inner| Product::new(outer, inner))
135 )
136 }
137 }
138
139 impl<TOuter: Timestamp, TInner: Timestamp> Refines<TOuter> for Product<TOuter, TInner> {
140 fn to_inner(other: TOuter) -> Self {
141 Product::new(other, TInner::minimum())
142 }
143 fn to_outer(self: Product<TOuter, TInner>) -> TOuter {
144 self.outer
145 }
146 fn summarize(path: <Self as Timestamp>::Summary) -> <TOuter as Timestamp>::Summary {
147 path.outer
148 }
149 }
150
151 impl<T1: Empty, T2: Empty> Empty for Product<T1, T2> { }
152 impl<T1, T2> TotalOrder for Product<T1, T2> where T1: Empty, T2: TotalOrder { }
153
154 impl<T1: Columnation, T2: Columnation> Columnation for Product<T1, T2> {
155 type InnerRegion = ProductRegion<T1::InnerRegion, T2::InnerRegion>;
156 }
157
158 #[derive(Default)]
159 pub struct ProductRegion<T1, T2> {
160 outer_region: T1,
161 inner_region: T2,
162 }
163
164 impl<T1: Region, T2: Region> Region for ProductRegion<T1, T2> {
165 type Item = Product<T1::Item, T2::Item>;
166
167 #[inline]
168 unsafe fn copy(&mut self, item: &Self::Item) -> Self::Item {
169 Product { outer: self.outer_region.copy(&item.outer), inner: self.inner_region.copy(&item.inner) }
170 }
171
172 fn clear(&mut self) {
173 self.outer_region.clear();
174 self.inner_region.clear();
175 }
176
177 fn reserve_items<'a, I>(&mut self, items1: I) where Self: 'a, I: Iterator<Item=&'a Self::Item> + Clone {
178 let items2 = items1.clone();
179 self.outer_region.reserve_items(items1.map(|x| &x.outer));
180 self.inner_region.reserve_items(items2.map(|x| &x.inner))
181 }
182
183 fn reserve_regions<'a, I>(&mut self, regions1: I) where Self: 'a, I: Iterator<Item=&'a Self> + Clone {
184 let regions2 = regions1.clone();
185 self.outer_region.reserve_regions(regions1.map(|r| &r.outer_region));
186 self.inner_region.reserve_regions(regions2.map(|r| &r.inner_region));
187 }
188
189 fn heap_size(&self, mut callback: impl FnMut(usize, usize)) {
190 self.outer_region.heap_size(&mut callback);
191 self.inner_region.heap_size(callback);
192 }
193 }
194}
195
196mod tuple {
198
199 use super::PartialOrder;
200 impl<TOuter, TOuter2, TInner, TInner2> PartialOrder<(TOuter2, TInner2)> for (TOuter, TInner)
201 where
202 TOuter: PartialOrder<TOuter2>,
203 TInner: PartialOrder<TInner2>,
204 (TOuter, TInner): PartialEq<(TOuter2, TInner2)>,
205 {
206 #[inline]
207 fn less_equal(&self, other: &(TOuter2, TInner2)) -> bool {
208 self.0.less_than(&other.0) || (self.0.eq(&other.0) && self.1.less_equal(&other.1))
210 }
211 }
212
213 use super::TotalOrder;
214 impl<T1, T2> TotalOrder for (T1, T2) where T1: TotalOrder, T2: TotalOrder { }
215
216 use crate::progress::Timestamp;
217 impl<TOuter: Timestamp, TInner: Timestamp> Timestamp for (TOuter, TInner) {
218 type Summary = (TOuter::Summary, TInner::Summary);
219 fn minimum() -> Self { (TOuter::minimum(), TInner::minimum()) }
220 }
221
222 use crate::progress::timestamp::PathSummary;
223 impl<TOuter: Timestamp, TInner: Timestamp> PathSummary<(TOuter, TInner)> for (TOuter::Summary, TInner::Summary) {
224 #[inline]
225 fn results_in(&self, (outer, inner): &(TOuter, TInner)) -> Option<(TOuter, TInner)> {
226 self.0.results_in(outer)
227 .and_then(|outer|
228 self.1.results_in(inner)
229 .map(|inner| (outer, inner))
230 )
231 }
232 #[inline]
233 fn followed_by(&self, (outer, inner): &(TOuter::Summary, TInner::Summary)) -> Option<(TOuter::Summary, TInner::Summary)> {
234 self.0.followed_by(outer)
235 .and_then(|outer|
236 self.1.followed_by(inner)
237 .map(|inner| (outer, inner))
238 )
239 }
240 }
241
242 use crate::progress::timestamp::Refines;
243 impl<TOuter: Timestamp, TInner: Timestamp> Refines<TOuter> for (TOuter, TInner) {
244 fn to_inner(other: TOuter) -> Self {
245 (other, TInner::minimum())
246 }
247 fn to_outer(self: (TOuter, TInner)) -> TOuter {
248 self.0
249 }
250 fn summarize(path: <Self as Timestamp>::Summary) -> <TOuter as Timestamp>::Summary {
251 path.0
252 }
253 }
254
255 use super::Empty;
256 impl<T1: Empty, T2: Empty> Empty for (T1, T2) { }
257}