pipecircuit 0.0.10

Correct. Robust. Fast. Portable.
Documentation
use core::{iter::FusedIterator, ops::Range};

use super::inconsistency::invariant_violation;
use super::{WarpTable, WarpTableGetAtOutcome, WarpTableInconsistency, WarpTableRow};

#[must_use]
pub struct WarpTableRows<'table, Row: WarpTableRow, Brand = Row> {
    table: &'table WarpTable<Row, Brand>,
    dense_rows: Range<usize>,
}

impl<'table, Row: WarpTableRow, Brand> Iterator for WarpTableRows<'table, Row, Brand> {
    type Item = Row::Ref<'table>;

    fn next(&mut self) -> Option<Self::Item> {
        let dense_row = self.dense_rows.next()?;
        match self.table.get_at(dense_row) {
            WarpTableGetAtOutcome::Present { row, .. } => Some(row),
            WarpTableGetAtOutcome::Absent { dense_row } => {
                invariant_violation(WarpTableInconsistency::DenseRowUnavailable {
                    row: dense_row,
                    rows: self.table.len(),
                })
            }
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.dense_rows.size_hint()
    }
}

impl<Row: WarpTableRow, Brand> ExactSizeIterator for WarpTableRows<'_, Row, Brand> {}
impl<Row: WarpTableRow, Brand> FusedIterator for WarpTableRows<'_, Row, Brand> {}

impl<Row: WarpTableRow, Brand> WarpTable<Row, Brand> {
    pub fn rows(&self) -> WarpTableRows<'_, Row, Brand> {
        WarpTableRows {
            table: self,
            dense_rows: 0..self.len,
        }
    }
}