use std::marker::PhantomData; use crate::replacement::EvaluatedPopulation; pub type ParentPairing = (usize, usize); pub trait Pairing { type Chromosome; type Out; fn pair>( &mut self, population: &EvaluatedPopulation, parents: T ) -> impl Iterator; } pub struct AdjacentPairing { _phantom1: PhantomData, _phantom2: PhantomData, } impl AdjacentPairing { pub fn new() -> Self { Self { _phantom1: PhantomData, _phantom2: PhantomData, } } } impl Pairing for AdjacentPairing { type Chromosome = TChromosome; type Out = TOutput; fn pair>( &mut self, _: &EvaluatedPopulation, parents: T ) -> impl Iterator { AdjacentIterator(parents, 0) } } pub struct AdjacentIterator>(T, usize); impl> Iterator for AdjacentIterator { type Item = ParentPairing; fn next(&mut self) -> Option { let first = self.0.next(); let second = self.0.next(); match (first, second) { // Still two elements left, return them (Some(first), Some(second)) => { self.1 = second; // Save previous Some((first, second)) }, // Only one element remaining, return it and the previous one (Some(first), _) => Some((first, self.1)), (None, Some(_)) => panic!("Iterators cannot return something after they return none."), // No more elements _ => None } } }