1use crate::prelude::{
18 LenderIntoIterator, LenderLabel, NodeLabelsLender, Pair, RandomAccessGraph,
19 RandomAccessLabeling, SequentialGraph, SequentialLabeling, SortedIterator, SortedLender,
20};
21use crate::traits::SplitLabeling;
22use lender::{ExactSizeLender, IntoLender, Lend, Lender, Lending, unsafe_assume_covariance};
23
24#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
26pub struct Left<S: SequentialLabeling>(pub S)
27where
28 S::Label: Pair;
29
30#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
31pub struct LeftIterator<L>(pub L);
32
33impl<'succ, L> NodeLabelsLender<'succ> for LeftIterator<L>
34where
35 L: Lender + for<'next> NodeLabelsLender<'next>,
36 for<'next> LenderLabel<'next, L>: Pair,
37{
38 type Label = <LenderLabel<'succ, L> as Pair>::Left;
39 type IntoIterator = IntoLeftSucc<<L as NodeLabelsLender<'succ>>::IntoIterator>;
40}
41
42impl<'succ, L> Lending<'succ> for LeftIterator<L>
43where
44 L: Lender + for<'next> NodeLabelsLender<'next>,
45 for<'next> LenderLabel<'next, L>: Pair,
46{
47 type Lend = (usize, LenderIntoIterator<'succ, Self>);
48}
49
50impl<L: ExactSizeLender> ExactSizeLender for LeftIterator<L>
51where
52 L: Lender + for<'next> NodeLabelsLender<'next>,
53 for<'next> LenderLabel<'next, L>: Pair,
54{
55 #[inline(always)]
56 fn len(&self) -> usize {
57 self.0.len()
58 }
59
60 #[inline(always)]
61 fn is_empty(&self) -> bool {
62 self.0.is_empty()
63 }
64}
65
66#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
67pub struct IntoLeftSucc<I: IntoIterator>(pub I)
68where
69 I::Item: Pair;
70
71#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
72pub struct LeftSucc<I: Iterator>(pub I)
73where
74 I::Item: Pair;
75
76impl<I: Iterator> Iterator for LeftSucc<I>
77where
78 I::Item: Pair,
79{
80 type Item = <I::Item as Pair>::Left;
81
82 #[inline(always)]
83 fn next(&mut self) -> Option<Self::Item> {
84 self.0.next().map(|x| x.into_pair().0)
85 }
86
87 #[inline(always)]
88 fn count(self) -> usize {
89 self.0.count()
90 }
91}
92
93impl<I: ExactSizeIterator> ExactSizeIterator for LeftSucc<I>
94where
95 I::Item: Pair,
96{
97 #[inline(always)]
98 fn len(&self) -> usize {
99 self.0.len()
100 }
101}
102
103impl<I: DoubleEndedIterator> DoubleEndedIterator for LeftSucc<I>
104where
105 I::Item: Pair,
106{
107 #[inline(always)]
108 fn next_back(&mut self) -> Option<Self::Item> {
109 self.0.next_back().map(|x| x.into_pair().0)
110 }
111
112 #[inline(always)]
113 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
114 self.0.nth_back(n).map(|x| x.into_pair().0)
115 }
116}
117
118impl<I: IntoIterator> IntoIterator for IntoLeftSucc<I>
119where
120 I::Item: Pair,
121{
122 type Item = <I::Item as Pair>::Left;
123 type IntoIter = LeftSucc<I::IntoIter>;
124
125 #[inline(always)]
126 fn into_iter(self) -> Self::IntoIter {
127 LeftSucc(self.0.into_iter())
128 }
129}
130
131impl<L> Lender for LeftIterator<L>
132where
133 L: Lender + for<'next> NodeLabelsLender<'next>,
134 for<'next> LenderLabel<'next, L>: Pair,
135{
136 unsafe_assume_covariance!();
139
140 #[inline(always)]
141 fn next(&mut self) -> Option<Lend<'_, Self>> {
142 self.0.next().map(|x| {
143 let (node, succ) = x.into_pair();
144 (node, IntoLeftSucc(succ))
145 })
146 }
147
148 #[inline(always)]
149 fn size_hint(&self) -> (usize, Option<usize>) {
150 self.0.size_hint()
151 }
152}
153
154impl<'a, S: SequentialLabeling> IntoLender for &'a Left<S>
155where
156 S::Label: Pair,
157{
158 type Lender = <Left<S> as SequentialLabeling>::Lender<'a>;
159
160 #[inline(always)]
161 fn into_lender(self) -> Self::Lender {
162 self.iter()
163 }
164}
165
166impl<G> SplitLabeling for Left<G>
167where
168 G: SequentialLabeling + SplitLabeling,
169 G::Label: Pair,
170{
171 type SplitLender<'a>
172 = LeftIterator<G::SplitLender<'a>>
173 where
174 Self: 'a;
175 type IntoIterator<'a>
176 = core::iter::Map<
177 <G::IntoIterator<'a> as IntoIterator>::IntoIter,
178 fn(G::SplitLender<'a>) -> Self::SplitLender<'a>,
179 >
180 where
181 Self: 'a;
182
183 fn split_iter(&self, how_many: usize) -> Self::IntoIterator<'_> {
184 self.0.split_iter(how_many).into_iter().map(LeftIterator)
185 }
186}
187
188impl<S: SequentialLabeling> SequentialLabeling for Left<S>
189where
190 S::Label: Pair,
191{
192 type Label = <S::Label as Pair>::Left;
193
194 type Lender<'node>
195 = LeftIterator<S::Lender<'node>>
196 where
197 Self: 'node;
198
199 #[inline(always)]
200 fn num_nodes(&self) -> usize {
201 self.0.num_nodes()
202 }
203
204 #[inline(always)]
205 fn iter_from(&self, from: usize) -> Self::Lender<'_> {
206 LeftIterator(self.0.iter_from(from))
207 }
208
209 #[inline(always)]
210 fn num_arcs_hint(&self) -> Option<u64> {
211 self.0.num_arcs_hint()
212 }
213}
214
215impl<R: RandomAccessLabeling> RandomAccessLabeling for Left<R>
216where
217 R::Label: Pair,
218{
219 type Labels<'succ>
220 = IntoLeftSucc<<R as RandomAccessLabeling>::Labels<'succ>>
221 where
222 Self: 'succ;
223
224 #[inline(always)]
225 fn num_arcs(&self) -> u64 {
226 self.0.num_arcs()
227 }
228
229 #[inline(always)]
230 fn labels(&self, node_id: usize) -> <Self as RandomAccessLabeling>::Labels<'_> {
231 IntoLeftSucc(self.0.labels(node_id))
232 }
233
234 #[inline(always)]
235 fn outdegree(&self, _node_id: usize) -> usize {
236 self.0.outdegree(_node_id)
237 }
238}
239
240impl<S: SequentialLabeling> SequentialGraph for Left<S> where S::Label: Pair<Left = usize> {}
241
242impl<R: RandomAccessLabeling> RandomAccessGraph for Left<R> where R::Label: Pair<Left = usize> {}
243
244unsafe impl<L: SortedLender> SortedLender for LeftIterator<L>
245where
246 L: Lender + for<'next> NodeLabelsLender<'next>,
247 for<'next> LenderLabel<'next, L>: Pair,
248{
249}
250
251unsafe impl<I: SortedIterator> SortedIterator for LeftSucc<I> where I::Item: Pair {}
252
253#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
255pub struct Right<S: SequentialLabeling>(pub S)
256where
257 S::Label: Pair;
258
259#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
260pub struct RightIterator<L>(pub L);
261
262impl<'succ, L> NodeLabelsLender<'succ> for RightIterator<L>
263where
264 L: Lender + for<'next> NodeLabelsLender<'next>,
265 for<'next> LenderLabel<'next, L>: Pair,
266{
267 type Label = <LenderLabel<'succ, L> as Pair>::Right;
268 type IntoIterator = IntoRightSucc<<L as NodeLabelsLender<'succ>>::IntoIterator>;
269}
270
271impl<'succ, L> Lending<'succ> for RightIterator<L>
272where
273 L: Lender + for<'next> NodeLabelsLender<'next>,
274 for<'next> LenderLabel<'next, L>: Pair,
275{
276 type Lend = (usize, LenderIntoIterator<'succ, Self>);
277}
278
279impl<L: ExactSizeLender> ExactSizeLender for RightIterator<L>
280where
281 L: Lender + for<'next> NodeLabelsLender<'next>,
282 for<'next> LenderLabel<'next, L>: Pair,
283{
284 #[inline(always)]
285 fn len(&self) -> usize {
286 self.0.len()
287 }
288
289 #[inline(always)]
290 fn is_empty(&self) -> bool {
291 self.0.is_empty()
292 }
293}
294
295#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
296pub struct IntoRightSucc<I: IntoIterator>(pub I)
297where
298 I::Item: Pair;
299
300#[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
301pub struct RightSucc<I: Iterator>(pub I)
302where
303 I::Item: Pair;
304
305impl<I: Iterator> Iterator for RightSucc<I>
306where
307 I::Item: Pair,
308{
309 type Item = <I::Item as Pair>::Right;
310
311 #[inline(always)]
312 fn next(&mut self) -> Option<Self::Item> {
313 self.0.next().map(|x| x.into_pair().1)
314 }
315
316 #[inline(always)]
317 fn count(self) -> usize {
318 self.0.count()
319 }
320}
321
322impl<I: ExactSizeIterator> ExactSizeIterator for RightSucc<I>
323where
324 I::Item: Pair,
325{
326 #[inline(always)]
327 fn len(&self) -> usize {
328 self.0.len()
329 }
330}
331
332impl<I: DoubleEndedIterator> DoubleEndedIterator for RightSucc<I>
333where
334 I::Item: Pair,
335{
336 #[inline(always)]
337 fn next_back(&mut self) -> Option<Self::Item> {
338 self.0.next_back().map(|x| x.into_pair().1)
339 }
340
341 #[inline(always)]
342 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
343 self.0.nth_back(n).map(|x| x.into_pair().1)
344 }
345}
346
347impl<I: IntoIterator> IntoIterator for IntoRightSucc<I>
348where
349 I::Item: Pair,
350{
351 type Item = <I::Item as Pair>::Right;
352 type IntoIter = RightSucc<I::IntoIter>;
353
354 #[inline(always)]
355 fn into_iter(self) -> Self::IntoIter {
356 RightSucc(self.0.into_iter())
357 }
358}
359
360impl<L> Lender for RightIterator<L>
361where
362 L: Lender + for<'next> NodeLabelsLender<'next>,
363 for<'next> LenderLabel<'next, L>: Pair,
364{
365 unsafe_assume_covariance!();
368
369 #[inline(always)]
370 fn next(&mut self) -> Option<Lend<'_, Self>> {
371 self.0.next().map(|x| {
372 let (node, succ) = x.into_pair();
373 (node, IntoRightSucc(succ))
374 })
375 }
376
377 #[inline(always)]
378 fn size_hint(&self) -> (usize, Option<usize>) {
379 self.0.size_hint()
380 }
381}
382
383impl<'a, S: SequentialLabeling> IntoLender for &'a Right<S>
384where
385 S::Label: Pair,
386{
387 type Lender = <Right<S> as SequentialLabeling>::Lender<'a>;
388
389 #[inline(always)]
390 fn into_lender(self) -> Self::Lender {
391 self.iter()
392 }
393}
394
395impl<G> SplitLabeling for Right<G>
396where
397 G: SequentialLabeling + SplitLabeling,
398 G::Label: Pair,
399{
400 type SplitLender<'a>
401 = RightIterator<G::SplitLender<'a>>
402 where
403 Self: 'a;
404 type IntoIterator<'a>
405 = core::iter::Map<
406 <G::IntoIterator<'a> as IntoIterator>::IntoIter,
407 fn(G::SplitLender<'a>) -> Self::SplitLender<'a>,
408 >
409 where
410 Self: 'a;
411
412 fn split_iter(&self, how_many: usize) -> Self::IntoIterator<'_> {
413 self.0.split_iter(how_many).into_iter().map(RightIterator)
414 }
415}
416
417impl<S: SequentialLabeling> SequentialLabeling for Right<S>
418where
419 S::Label: Pair,
420{
421 type Label = <S::Label as Pair>::Right;
422
423 type Lender<'node>
424 = RightIterator<S::Lender<'node>>
425 where
426 Self: 'node;
427
428 #[inline(always)]
429 fn num_nodes(&self) -> usize {
430 self.0.num_nodes()
431 }
432
433 #[inline(always)]
434 fn num_arcs_hint(&self) -> Option<u64> {
435 self.0.num_arcs_hint()
436 }
437
438 #[inline(always)]
439 fn iter_from(&self, from: usize) -> Self::Lender<'_> {
440 RightIterator(self.0.iter_from(from))
441 }
442}
443
444impl<R: RandomAccessLabeling> RandomAccessLabeling for Right<R>
445where
446 R::Label: Pair,
447{
448 type Labels<'succ>
449 = IntoRightSucc<<R as RandomAccessLabeling>::Labels<'succ>>
450 where
451 Self: 'succ;
452
453 #[inline(always)]
454 fn num_arcs(&self) -> u64 {
455 self.0.num_arcs()
456 }
457
458 #[inline(always)]
459 fn labels(&self, node_id: usize) -> <Self as RandomAccessLabeling>::Labels<'_> {
460 IntoRightSucc(self.0.labels(node_id))
461 }
462
463 #[inline(always)]
464 fn outdegree(&self, _node_id: usize) -> usize {
465 self.0.outdegree(_node_id)
466 }
467}
468
469impl<S: SequentialLabeling> SequentialGraph for Right<S> where S::Label: Pair<Right = usize> {}
470
471impl<R: RandomAccessLabeling> RandomAccessGraph for Right<R> where R::Label: Pair<Right = usize> {}
472
473unsafe impl<L: SortedLender> SortedLender for RightIterator<L>
474where
475 L: Lender + for<'next> NodeLabelsLender<'next>,
476 for<'next> LenderLabel<'next, L>: Pair,
477{
478}
479
480unsafe impl<I: SortedIterator> SortedIterator for RightSucc<I> where I::Item: Pair {}