#![forbid(unsafe_code)]
use core::cmp::Ordering;
use core::convert::Infallible;
use core::fmt;
use core::ops::ControlFlow;
use super::Iter;
use crate::inline_key::InlineKeyStrategy;
use crate::tree::node::leaf::KeyRun;
pub(super) struct SetCursor<'a, T, S> {
iter: Iter<'a, T, S>,
run: KeyRun<'a, T>,
}
impl<T, S> Clone for SetCursor<'_, T, S> {
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
run: self.run,
}
}
}
impl<'a, T, S: InlineKeyStrategy<T>> SetCursor<'a, T, S> {
fn new(iter: Iter<'a, T, S>) -> Self {
Self {
iter,
run: KeyRun::EMPTY,
}
}
#[inline]
pub(super) fn peek(&mut self) -> Option<&'a T> {
match self.run.peek() {
Some(element) => Some(element),
None => self.next_run(),
}
}
#[inline(never)]
fn next_run(&mut self) -> Option<&'a T> {
self.run = self.iter.next_key_run()?;
self.run.peek()
}
#[inline]
pub(super) fn advance(&mut self) {
self.run.advance();
}
#[inline]
pub(super) fn next(&mut self) -> Option<&'a T> {
let element = self.peek()?;
self.advance();
Some(element)
}
fn len(&self) -> usize {
self.run.len() + self.iter.len()
}
fn remaining(&self) -> impl Iterator<Item = &'a T> + Clone {
self.run.chain(self.iter.clone())
}
pub(super) fn first_remaining(&self) -> Option<&'a T> {
self.remaining().next()
}
pub(super) fn printed_as_iter(&self, first_held: bool) -> PrintedAsIter<'_, 'a, T, S> {
PrintedAsIter {
cursor: self,
first_held,
}
}
}
pub(super) struct PrintedAsIter<'c, 'a, T, S> {
cursor: &'c SetCursor<'a, T, S>,
first_held: bool,
}
impl<T: fmt::Debug, S: InlineKeyStrategy<T>> fmt::Debug for PrintedAsIter<'_, '_, T, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let elements = self.cursor.remaining().skip(usize::from(self.first_held));
f.debug_tuple("Iter").field(&PrintedList(elements)).finish()
}
}
struct PrintedList<I>(I);
impl<I: Iterator + Clone> fmt::Debug for PrintedList<I>
where
I::Item: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.0.clone()).finish()
}
}
pub(super) enum MergeStep<'a, T> {
Left(&'a T),
Right(&'a T),
Both(&'a T),
}
impl<'a, T> MergeStep<'a, T> {
pub(super) fn element(self) -> &'a T {
match self {
Self::Left(element) | Self::Right(element) | Self::Both(element) => element,
}
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub(super) enum HeldSide {
Neither,
Left,
Right,
}
#[derive(Debug)]
#[expect(dead_code, reason = "read by `Debug` alone, printing as std's")]
enum Peeked<'a, T> {
A(&'a T),
B(&'a T),
}
pub(super) struct MergeSides<'a, T, S> {
pub(super) left: SetCursor<'a, T, S>,
pub(super) right: SetCursor<'a, T, S>,
}
impl<T, S> Clone for MergeSides<'_, T, S> {
fn clone(&self) -> Self {
Self {
left: self.left.clone(),
right: self.right.clone(),
}
}
}
impl<'a, T, S: InlineKeyStrategy<T>> MergeSides<'a, T, S> {
pub(super) fn new(left: Iter<'a, T, S>, right: Iter<'a, T, S>) -> Self {
Self {
left: SetCursor::new(left),
right: SetCursor::new(right),
}
}
pub(super) fn lens(&self) -> (usize, usize) {
(self.left.len(), self.right.len())
}
pub(super) fn printed_as_merge_iter(&self, held: HeldSide) -> PrintedAsMergeIter<'_, 'a, T, S> {
PrintedAsMergeIter { sides: self, held }
}
}
impl<'a, T: Ord, S: InlineKeyStrategy<T>> MergeSides<'a, T, S> {
#[inline]
pub(super) fn next_step(&mut self) -> Option<(MergeStep<'a, T>, HeldSide)> {
match (self.left.peek(), self.right.peek()) {
(Some(left), Some(right)) => Some(match left.cmp(right) {
Ordering::Less => {
self.left.advance();
(MergeStep::Left(left), HeldSide::Right)
}
Ordering::Greater => {
self.right.advance();
(MergeStep::Right(right), HeldSide::Left)
}
Ordering::Equal => {
self.left.advance();
self.right.advance();
(MergeStep::Both(left), HeldSide::Neither)
}
}),
(Some(left), None) => {
self.left.advance();
Some((MergeStep::Left(left), HeldSide::Neither))
}
(None, Some(right)) => {
self.right.advance();
Some((MergeStep::Right(right), HeldSide::Neither))
}
(None, None) => None,
}
}
pub(super) fn try_fold_steps<A, R, const LEFT_TAIL: bool, const RIGHT_TAIL: bool>(
self,
mut accumulator: A,
mut on: impl FnMut(A, MergeStep<'a, T>) -> ControlFlow<R, A>,
) -> ControlFlow<R, A> {
let Self { left, right } = self;
let (mut left_iter, mut left_run) = (left.iter, left.run);
let (mut right_iter, mut right_run) = (right.iter, right.run);
loop {
let Some(left) = left_run.peek() else {
match left_iter.next_key_run() {
Some(run) => {
left_run = run;
continue;
}
None if RIGHT_TAIL => {
return Self::fold_tail(
accumulator,
right_run,
right_iter,
|acc, right| on(acc, MergeStep::Right(right)),
);
}
None => return ControlFlow::Continue(accumulator),
}
};
let Some(right) = right_run.peek() else {
match right_iter.next_key_run() {
Some(run) => {
right_run = run;
continue;
}
None if LEFT_TAIL => {
return Self::fold_tail(accumulator, left_run, left_iter, |acc, left| {
on(acc, MergeStep::Left(left))
});
}
None => return ControlFlow::Continue(accumulator),
}
};
let step = match left.cmp(right) {
Ordering::Less => {
left_run.advance();
MergeStep::Left(left)
}
Ordering::Greater => {
right_run.advance();
MergeStep::Right(right)
}
Ordering::Equal => {
left_run.advance();
right_run.advance();
MergeStep::Both(left)
}
};
accumulator = on(accumulator, step)?;
}
}
pub(super) fn fold_steps<A, const LEFT_TAIL: bool, const RIGHT_TAIL: bool>(
self,
accumulator: A,
mut on: impl FnMut(A, MergeStep<'a, T>) -> A,
) -> A {
let ControlFlow::Continue(accumulator) = self
.try_fold_steps::<A, Infallible, LEFT_TAIL, RIGHT_TAIL>(
accumulator,
|accumulator, step| ControlFlow::Continue(on(accumulator, step)),
);
accumulator
}
fn fold_tail<A, R>(
mut accumulator: A,
run: KeyRun<'a, T>,
mut iter: Iter<'a, T, S>,
mut on: impl FnMut(A, &'a T) -> ControlFlow<R, A>,
) -> ControlFlow<R, A> {
for element in run {
accumulator = on(accumulator, element)?;
}
while let Some(run) = iter.next_key_run() {
for element in run {
accumulator = on(accumulator, element)?;
}
}
ControlFlow::Continue(accumulator)
}
}
pub(super) struct PrintedAsMergeIter<'m, 'a, T, S> {
sides: &'m MergeSides<'a, T, S>,
held: HeldSide,
}
impl<T: fmt::Debug, S: InlineKeyStrategy<T>> fmt::Debug for PrintedAsMergeIter<'_, '_, T, S> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let Self { sides, held } = *self;
let peeked = match held {
HeldSide::Neither => None,
HeldSide::Left => sides.left.first_remaining().map(Peeked::A),
HeldSide::Right => sides.right.first_remaining().map(Peeked::B),
};
f.debug_tuple("MergeIterInner")
.field(&sides.left.printed_as_iter(held == HeldSide::Left))
.field(&sides.right.printed_as_iter(held == HeldSide::Right))
.field(&peeked)
.finish()
}
}