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
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
use serde::{Deserialize, Serialize};
use sum::*;

use super::{
	ConsumerMulti, DistributedIteratorMulti, DistributedReducer, ReduceFactory, Reducer, ReducerA
};
use crate::pool::ProcessSend;

macro_rules! impl_iterator_multi_tuple {
	($reduceafactory:ident $reducea:ident $reduceb:ident $enum:ident $($copy:ident)* : $($i:ident $r:ident $o:ident $c:ident $iterator:ident $reducera:ident $reducerb:ident $num:tt $t:ident),*) => (
		impl<
				$($i: DistributedIteratorMulti<Source>,)*
				Source,
				$($r: DistributedReducer<$i, Source, $o>,)*
				$($o,)*
			> DistributedReducer<($($i,)*), Source, ($($o,)*)> for ($($r,)*)
				where Source: $($copy)*,
		{
			type ReduceAFactory = $reduceafactory<$($r::ReduceAFactory,)*>;
			type ReduceA = $reducea<$($r::ReduceA,)*>;
			type ReduceB = $reduceb<$($r::ReduceB,)*>;

			fn reducers(self) -> (($($i,)*), Self::ReduceAFactory, Self::ReduceB) {
				$(let ($iterator, $reducera, $reducerb) = self.$num.reducers();)*
				(
					($($iterator,)*),
					$reduceafactory($($reducera,)*),
					$reduceb($($reducerb,)*),
				)
			}
		}

		impl<Source, $($i: DistributedIteratorMulti<Source>,)*>
			DistributedIteratorMulti<Source> for ($($i,)*)
				where Source: $($copy)*,
		{
			type Item = $enum<$($i::Item,)*>;
			type Task = ($($i::Task,)*);

			fn task(&self) -> Self::Task {
				($(self.$num.task(),)*)
			}
		}

		#[allow(unused_variables)]
		impl<Source, $($c: ConsumerMulti<Source>,)*> ConsumerMulti<Source>
			for ($($c,)*)
				where Source: $($copy)*,
		{
			type Item = $enum<$($c::Item,)*>;

			fn run(&self, source: Source, i: &mut impl FnMut(Self::Item) -> bool) -> bool {
				$(self.$num.run(source, &mut |x| i($enum::$t(x))) | )* false
			}
		}

		pub struct $reduceafactory<$($r,)*>($(pub(super) $r,)*);
		impl<$($r:ReduceFactory,)*> ReduceFactory for $reduceafactory<$($r,)*> {
			type Reducer = $reducea<$($r::Reducer,)*>;
			fn make(&self) -> Self::Reducer {
				$reducea($((self.$num.make(),true),)*)
			}
		}

		#[derive(Serialize, Deserialize)]
		pub struct $reducea<$($t,)*>($(($t,bool),)*);
		#[allow(unused_variables)]
		impl<$($t: Reducer,)*> Reducer for $reducea<$($t,)*> {
			type Item = $enum<$($t::Item,)*>;
			type Output = ($($t::Output,)*);

			fn push(&mut self, item: Self::Item) -> bool {
				match item {
					$($enum::$t(item) => self.$num.1 = self.$num.1 && self.$num.0.push(item),)*
				}
				#[allow(unreachable_code)] {
					$(self.$num.1 |)* false
				}
			}
			fn ret(self) -> Self::Output {
				($(self.$num.0.ret(),)*)
			}
		}
		impl<$($t: Reducer,)*> ReducerA for $reducea<$($t,)*> where $($t: ProcessSend,)* $($t::Output: ProcessSend,)* {
			type Output = ($($t::Output,)*);
		}

		pub struct $reduceb<$($t,)*>($(pub(super) $t,)*);
		#[allow(unused_variables)]
		impl<$($t: Reducer,)*> Reducer for $reduceb<$($t,)*> {
			type Item = ($($t::Item,)*);
			type Output = ($($t::Output,)*);

			fn push(&mut self, item: Self::Item) -> bool {
				$(self.$num.push(item.$num) |)* false
			}
			fn ret(self) -> Self::Output {
				($(self.$num.ret(),)*)
			}
		}
	);
}
impl_iterator_multi_tuple!(ReduceA0Factory ReduceA0 ReduceB0 Sum0:);
impl_iterator_multi_tuple!(ReduceA1Factory ReduceA1 ReduceB1 Sum1: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A);
impl_iterator_multi_tuple!(ReduceA2Factory ReduceA2 ReduceB2 Sum2 Copy: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A, I1 R1 O1 C1 iterator_1 reducer_a_1 reducer_b_1 1 B);
impl_iterator_multi_tuple!(ReduceA3Factory ReduceA3 ReduceB3 Sum3 Copy: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A, I1 R1 O1 C1 iterator_1 reducer_a_1 reducer_b_1 1 B, I2 R2 O2 C2 iterator_2 reducer_a_2 reducer_b_2 2 C);
impl_iterator_multi_tuple!(ReduceA4Factory ReduceA4 ReduceB4 Sum4 Copy: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A, I1 R1 O1 C1 iterator_1 reducer_a_1 reducer_b_1 1 B, I2 R2 O2 C2 iterator_2 reducer_a_2 reducer_b_2 2 C, I3 R3 O3 C3 iterator_3 reducer_a_3 reducer_b_3 3 D);
impl_iterator_multi_tuple!(ReduceA5Factory ReduceA5 ReduceB5 Sum5 Copy: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A, I1 R1 O1 C1 iterator_1 reducer_a_1 reducer_b_1 1 B, I2 R2 O2 C2 iterator_2 reducer_a_2 reducer_b_2 2 C, I3 R3 O3 C3 iterator_3 reducer_a_3 reducer_b_3 3 D, I4 R4 O4 C4 iterator_4 reducer_a_4 reducer_b_4 4 E);
impl_iterator_multi_tuple!(ReduceA6Factory ReduceA6 ReduceB6 Sum6 Copy: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A, I1 R1 O1 C1 iterator_1 reducer_a_1 reducer_b_1 1 B, I2 R2 O2 C2 iterator_2 reducer_a_2 reducer_b_2 2 C, I3 R3 O3 C3 iterator_3 reducer_a_3 reducer_b_3 3 D, I4 R4 O4 C4 iterator_4 reducer_a_4 reducer_b_4 4 E, I5 R5 O5 C5 iterator_5 reducer_a_5 reducer_b_5 5 F);
impl_iterator_multi_tuple!(ReduceA7Factory ReduceA7 ReduceB7 Sum7 Copy: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A, I1 R1 O1 C1 iterator_1 reducer_a_1 reducer_b_1 1 B, I2 R2 O2 C2 iterator_2 reducer_a_2 reducer_b_2 2 C, I3 R3 O3 C3 iterator_3 reducer_a_3 reducer_b_3 3 D, I4 R4 O4 C4 iterator_4 reducer_a_4 reducer_b_4 4 E, I5 R5 O5 C5 iterator_5 reducer_a_5 reducer_b_5 5 F, I6 R6 O6 C6 iterator_6 reducer_a_6 reducer_b_6 6 G);
impl_iterator_multi_tuple!(ReduceA8Factory ReduceA8 ReduceB8 Sum8 Copy: I0 R0 O0 C0 iterator_0 reducer_a_0 reducer_b_0 0 A, I1 R1 O1 C1 iterator_1 reducer_a_1 reducer_b_1 1 B, I2 R2 O2 C2 iterator_2 reducer_a_2 reducer_b_2 2 C, I3 R3 O3 C3 iterator_3 reducer_a_3 reducer_b_3 3 D, I4 R4 O4 C4 iterator_4 reducer_a_4 reducer_b_4 4 E, I5 R5 O5 C5 iterator_5 reducer_a_5 reducer_b_5 5 F, I6 R6 O6 C6 iterator_6 reducer_a_6 reducer_b_6 6 G, I7 R7 O7 C7 iterator_7 reducer_a_7 reducer_b_7 7 H);