-
Notifications
You must be signed in to change notification settings - Fork 557
/
Copy pathchain_adapter.cairo
51 lines (46 loc) · 1.45 KB
/
chain_adapter.cairo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/// An iterator that links two iterators together, in a chain.
///
/// This `struct` is created by [`Iterator::chain`]. See the
/// documentation for more.
#[derive(Drop)]
pub struct Chain<A, B> {
// These are "fused" with `Option` so we don't need separate state to track which part is
// already exhausted, and we may also get niche layout for `None`.
//
// Only the "first" iterator is actually set `None` when exhausted.
a: Option<A>,
b: Option<B>,
}
#[inline]
pub fn chained_iterator<A, B>(a: A, b: B) -> Chain<A, B> {
Chain { a: Option::Some(a), b: Option::Some(b) }
}
impl ChainIterator<
A,
B,
impl IterA: Iterator<A>,
+Iterator<B>[Item: IterA::Item],
+Drop<A>,
+Drop<B>,
+Drop<IterA::Item>,
> of Iterator<Chain<A, B>> {
type Item = IterA::Item;
fn next(ref self: Chain<A, B>) -> Option<Self::Item> {
// First iterate over first container values
if self.a.is_some() {
let mut first_container = self.a.unwrap();
let value = first_container.next();
if value.is_some() {
self.a = Option::Some(first_container);
return value;
} else {
self.a = Option::None;
}
}
// Then iterate over second container values
let mut second_container = self.b.unwrap();
let value = second_container.next();
self.b = Option::Some(second_container);
value
}
}