Skip to content

Commit e7b08cc

Browse files
committed
move iterator into separate module
1 parent 05ef79a commit e7b08cc

File tree

14 files changed

+1493
-1201
lines changed

14 files changed

+1493
-1201
lines changed

makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,16 @@ nextest: $(source_files)
8484
test_all: fmt_check test doc_check | clippy
8585

8686

87+
fmt_check_cmd := $(cargo) $(rust_nightly) $(cargo_fmt) $(cargo_all_flag) $(rustfmt_check_flag)
8788
.PHONY: fmt_check
8889
fmt_check: $(source_files)
89-
$(cargo) $(rust_nightly) $(cargo_fmt) $(cargo_all_flag) $(rustfmt_check_flag)
90+
$(fmt_check_cmd)
9091

9192

9293
.PHONY: fmt
9394
fmt: $(source_files)
94-
$(cargo) $(rust_nightly) $(cargo_all_flag) $(cargo_fmt)
95+
- $(fmt_check_cmd)
96+
$(cargo) $(rust_nightly) $(cargo_fmt) $(cargo_all_flag)
9597

9698

9799
.PHONY: clippy

src/lattice/direction/direction_enum.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use serde::{Deserialize, Serialize};
1313
use utils_lib::Sealed;
1414

1515
use super::{Direction, DirectionIndexing, DirectionList, DirectionTrait};
16-
use crate::lattice::{LatticeCyclic, LatticeElementToIndex};
1716
use crate::Real;
1817

1918
//---------------------------------------

src/lattice/direction/mod.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -285,21 +285,6 @@ impl<const D: usize> Display for Direction<D> {
285285
}
286286
}
287287

288-
// /// TODO impl doc
289-
// impl<const D: usize> NumberOfLatticeElement<D> for Direction<D> {
290-
// #[inline]
291-
// fn number_of_elements(_lattice: &LatticeCyclic<D>) -> usize {
292-
// D
293-
// }
294-
// }
295-
296-
// // TODO impl doc
297-
// impl<const D: usize> IndexToElement<D> for Direction<D> {
298-
// fn index_to_element(_lattice: &LatticeCyclic<D>, index: usize) -> Option<Self> {
299-
// Self::new(index, true)
300-
// }
301-
// }
302-
303288
/// Partial ordering is set as follows: two directions can be compared if they have the same index
304289
/// or the same direction sign. In the first case a positive direction is greater than a negative direction
305290
/// In the latter case the ordering is done on the index.
@@ -542,8 +527,24 @@ implement_direction_from!();
542527
//---------------------------------------
543528
// trait DirectionIndexing
544529

530+
/// An internal trait that direction implements. It is used for auto implementation
531+
/// of trait to avoid conflict. For example [`LatticeElementToIndex`] is implemented
532+
/// for type that are [`DirectionIndexing`] and [`DirectionTrait`]. Moreover we want
533+
///
534+
///
535+
/// This trait is a super trait of [`Sealed`] which is private meaning that It can't be
536+
/// implemented outside of this trait.
545537
pub trait DirectionTrait: Sealed {}
546538

539+
/// Trait to transform (directions) Types to and from indices independently of a Lattice
540+
/// Contrary to [`LatticeElementToIndex`] [`NumberOfLatticeElement`] and [`IndexToElement`].
541+
///
542+
/// This trait is used to automate the code generation for [`Iterator`] and
543+
/// [`rayon::iter::IndexedParallelIterator`] without the overhead of a lattice.
544+
///
545+
///
546+
/// This trait is a super trait of [`Sealed`] which is private meaning that i
547+
/// it can't be implemented outside of this trait.
547548
pub trait DirectionIndexing: Sealed + Sized {
548549
/// Transform an element to an index.
549550
#[must_use]
@@ -590,12 +591,12 @@ impl<const D: usize> DirectionTrait for Direction<D> {}
590591
impl<const D: usize> DirectionIndexing for Direction<D> {
591592
#[inline]
592593
fn direction_to_index(&self) -> usize {
593-
self.index() * 2 + if self.is_positive() { 1 } else { 0 }
594+
self.index() * 2 + usize::from(!self.is_positive())
594595
}
595596

596597
#[inline]
597598
fn direction_from_index(index: usize) -> Option<Self> {
598-
Self::new((index.saturating_sub(1)) / 2, index % 2 == 1)
599+
Self::new((index.saturating_sub(1)) / 2, index % 2 == 0)
599600
}
600601

601602
#[inline]

src/lattice/iterator/direction.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ use rayon::iter::{
1212
#[cfg(feature = "serde-serialize")]
1313
use serde::{Deserialize, Serialize};
1414

15-
use super::{super::Direction, DoubleEndedCounter, IteratorElement, RandomAccessIterator};
16-
use crate::lattice::direction::DirectionIndexing;
15+
use super::{super::Direction, IteratorElement, RandomAccessIterator};
1716

1817
/// Iterator over [`Direction`] with the same sign.
1918
/// # Example
Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
//! Contains [`DoubleEndedCounter`]
2+
3+
//---------------------------------------
4+
// uses
5+
6+
use std::{
7+
fmt::{self, Display},
8+
iter::FusedIterator,
9+
};
10+
11+
#[cfg(feature = "serde-serialize")]
12+
use serde::{Deserialize, Serialize};
13+
use utils_lib::{Getter, Sealed};
14+
15+
use super::{IteratorElement, RandomAccessIterator, Split};
16+
use crate::lattice::direction::DirectionIndexing;
17+
18+
//---------------------------------------
19+
// struct definition
20+
21+
/// An iterator that track the front and the back in order to be able to implement
22+
/// [`DoubleEndedIterator`].
23+
///
24+
/// By itself it is not use a lot in the library it is used as a properties and use
25+
/// to track the front and the back. [`Iterator`] traits are not (yet ?) implemented
26+
/// on this type.
27+
#[derive(Sealed, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
28+
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
29+
#[derive(Getter)]
30+
pub struct DoubleEndedCounter<T> {
31+
/// Front element of the iterator. The state need to be increased before
32+
/// being returned by the next [`Iterator::next`] call.
33+
#[get(Const, Pub)]
34+
#[get_mut(Pub)]
35+
pub(super) front: IteratorElement<T>,
36+
/// End element of the iterator.
37+
/// It needs to be decreased before the next [`DoubleEndedIterator::next_back`] call.
38+
#[get(Const, Pub)]
39+
#[get_mut(Pub)]
40+
pub(super) end: IteratorElement<T>,
41+
}
42+
43+
impl<T> DoubleEndedCounter<T> {
44+
/// Create a new [`Self`] with [`IteratorElement::FirstElement`] as `front` and
45+
/// [`IteratorElement::LastElement`] as `end`
46+
/// # Example
47+
/// ```ignore
48+
/// use lattice_qcd_rs::lattice::iter::{DoubleEndedCounter,IteratorElement};
49+
/// let counter = DoubleEndedCounter::<()>::new();
50+
/// assert_eq!(counter.front(), IteratorElement::FirstElement);
51+
/// assert_eq!(counter.end(), IteratorElement::LastElement);
52+
/// ```
53+
/// TODO restrict to valid iter ?
54+
pub const fn new() -> Self {
55+
Self {
56+
front: IteratorElement::FirstElement,
57+
end: IteratorElement::LastElement,
58+
}
59+
}
60+
61+
/// Create a new self with a given `front` and `end` element
62+
pub(super) const fn new_with_front_end(
63+
front: IteratorElement<T>,
64+
end: IteratorElement<T>,
65+
) -> Self {
66+
Self { front, end }
67+
}
68+
69+
// possible with_first, with_last
70+
}
71+
72+
//---------------------------------------
73+
// common traits
74+
75+
/// It is [`Self::new`],
76+
impl<T> Default for DoubleEndedCounter<T> {
77+
#[inline]
78+
fn default() -> Self {
79+
Self::new()
80+
}
81+
}
82+
83+
impl<T: Display> Display for DoubleEndedCounter<T> {
84+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85+
write!(f, "front: {}, end: {}", self.front(), self.end())
86+
}
87+
}
88+
89+
//---------------------------------------
90+
// conversion
91+
92+
impl<T> From<DoubleEndedCounter<T>> for [IteratorElement<T>; 2] {
93+
#[inline]
94+
fn from(value: DoubleEndedCounter<T>) -> Self {
95+
[value.front, value.end]
96+
}
97+
}
98+
99+
impl<T> From<DoubleEndedCounter<T>> for (IteratorElement<T>, IteratorElement<T>) {
100+
#[inline]
101+
fn from(value: DoubleEndedCounter<T>) -> Self {
102+
(value.front, value.end)
103+
}
104+
}
105+
106+
//---------------------------------------
107+
// impl of RandomAccessIterator
108+
109+
impl<D: DirectionIndexing> RandomAccessIterator for DoubleEndedCounter<D> {
110+
type Item = D;
111+
112+
fn iter_len(&self) -> usize {
113+
self.front()
114+
.direction_to_index()
115+
.saturating_sub(self.end().direction_to_index())
116+
}
117+
118+
fn increase_front_element_by(&self, advance_by: usize) -> IteratorElement<Self::Item> {
119+
let index = match self.front() {
120+
IteratorElement::FirstElement => 0,
121+
IteratorElement::Element(ref element) => element.direction_to_index() + 1,
122+
IteratorElement::LastElement => {
123+
// early return
124+
return IteratorElement::LastElement;
125+
}
126+
};
127+
128+
let new_index = index + advance_by;
129+
IteratorElement::index_to_element(new_index, |index| {
130+
Self::Item::direction_from_index(index)
131+
})
132+
}
133+
134+
fn decrease_end_element_by(&self, back_by: usize) -> IteratorElement<Self::Item> {
135+
let index = match self.end() {
136+
IteratorElement::FirstElement => {
137+
// early return
138+
return IteratorElement::FirstElement;
139+
}
140+
IteratorElement::Element(ref element) => element.direction_to_index() + 1,
141+
IteratorElement::LastElement => Self::Item::number_of_directions() + 1,
142+
};
143+
144+
let new_index = index.saturating_sub(back_by);
145+
IteratorElement::index_to_element(new_index, |index| {
146+
Self::Item::direction_from_index(index)
147+
})
148+
}
149+
}
150+
151+
impl<I> Split for DoubleEndedCounter<I>
152+
where
153+
Self: RandomAccessIterator<Item = I>,
154+
I: Clone,
155+
{
156+
#[inline]
157+
fn split_at(self, index: usize) -> (Self, Self) {
158+
let splinting = self.increase_front_element_by(index);
159+
(
160+
Self::new_with_front_end(self.front, splinting.clone()),
161+
Self::new_with_front_end(splinting, self.end),
162+
)
163+
}
164+
}
165+
166+
//---------------------------------------
167+
// impl of Iterator traits
168+
169+
/// TODO DOC
170+
impl<T> Iterator for DoubleEndedCounter<T>
171+
where
172+
Self: RandomAccessIterator<Item = T>,
173+
T: Clone,
174+
{
175+
type Item = T;
176+
177+
#[inline]
178+
fn next(&mut self) -> Option<Self::Item> {
179+
self.nth(0)
180+
}
181+
182+
#[inline]
183+
fn size_hint(&self) -> (usize, Option<usize>) {
184+
let size = self.iter_len();
185+
(size, Some(size))
186+
}
187+
188+
#[inline]
189+
fn count(self) -> usize
190+
where
191+
Self: Sized,
192+
{
193+
self.iter_len()
194+
}
195+
196+
#[inline]
197+
fn last(mut self) -> Option<Self::Item>
198+
where
199+
Self: Sized,
200+
{
201+
self.nth(self.iter_len().saturating_sub(1))
202+
}
203+
204+
#[inline]
205+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
206+
let len = self.iter_len();
207+
if len <= n {
208+
if len != 0 {
209+
// we need to change the state of the iterator other wise it could
210+
// produce element we should have otherwise skipped.
211+
//*self.front_mut() = self.end().clone();
212+
*self.front_mut() = IteratorElement::LastElement;
213+
}
214+
return None;
215+
}
216+
let next_element = self.increase_front_element_by(n + 1);
217+
*self.front_mut() = next_element.clone();
218+
next_element.into()
219+
}
220+
221+
#[inline]
222+
fn max(self) -> Option<Self::Item>
223+
where
224+
Self: Sized,
225+
Self::Item: Ord,
226+
{
227+
self.last()
228+
}
229+
230+
#[inline]
231+
fn min(mut self) -> Option<Self::Item>
232+
where
233+
Self: Sized,
234+
Self::Item: Ord,
235+
{
236+
self.next()
237+
}
238+
}
239+
240+
/// TODO DOC
241+
impl<T> DoubleEndedIterator for DoubleEndedCounter<T>
242+
where
243+
Self: RandomAccessIterator<Item = T>,
244+
T: Clone,
245+
{
246+
#[inline]
247+
fn next_back(&mut self) -> Option<Self::Item> {
248+
self.nth_back(0)
249+
}
250+
251+
#[inline]
252+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
253+
let len = self.iter_len();
254+
if len <= n {
255+
if len != 0 {
256+
// we need to change the state of the iterator other wise it could
257+
// produce element we should have otherwise skipped.
258+
//*self.end_mut() = self.front().clone();
259+
*self.end_mut() = IteratorElement::FirstElement;
260+
}
261+
return None;
262+
}
263+
let previous_element = self.decrease_end_element_by(n + 1);
264+
*self.end_mut() = previous_element.clone();
265+
previous_element.into()
266+
}
267+
}
268+
269+
impl<T> FusedIterator for DoubleEndedCounter<T> where Self: RandomAccessIterator + Iterator {}
270+
271+
impl<T> ExactSizeIterator for DoubleEndedCounter<T>
272+
where
273+
Self: RandomAccessIterator + Iterator,
274+
{
275+
#[inline]
276+
fn len(&self) -> usize {
277+
self.iter_len()
278+
}
279+
}

0 commit comments

Comments
 (0)