use crate::input::error::InputError;
use crate::input::{InputBlock, InputBlockIterator};
use crate::{FallibleIterator, BLOCK_SIZE};
use cfg_if::cfg_if;
pub struct QuoteClassifiedBlock<B, const N: usize> {
pub block: B,
pub within_quotes_mask: u64,
}
pub trait QuoteClassifiedIterator<'i, I: InputBlockIterator<'i, N>, const N: usize>:
FallibleIterator<Item = QuoteClassifiedBlock<I::Block, N>, Error = InputError>
{
fn get_offset(&self) -> usize;
fn offset(&mut self, count: isize);
fn flip_quotes_bit(&mut self);
}
pub trait InnerIter<I> {
fn into_inner(self) -> I;
}
impl<'i, B, const N: usize> QuoteClassifiedBlock<B, N>
where
B: InputBlock<'i, N>,
{
#[must_use]
#[inline(always)]
pub fn len(&self) -> usize {
self.block.len()
}
#[must_use]
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.block.is_empty()
}
}
cfg_if! {
if #[cfg(any(doc, not(feature = "simd")))] {
mod nosimd;
type ClassifierImpl<'i, I, const N: usize> = nosimd::SequentialQuoteClassifier<'i, I, N>;
}
else if #[cfg(simd = "avx2")] {
mod avx2;
type ClassifierImpl<'i, I> = avx2::Avx2QuoteClassifier<'i, I>;
}
else {
compile_error!("Target architecture is not supported by SIMD features of this crate. Disable the default `simd` feature.");
}
}
#[must_use]
#[inline(always)]
pub fn classify_quoted_sequences<'i, I>(iter: I) -> impl QuoteClassifiedIterator<'i, I, BLOCK_SIZE> + InnerIter<I>
where
I: InputBlockIterator<'i, BLOCK_SIZE>,
{
ClassifierImpl::new(iter)
}
pub(crate) fn resume_quote_classification<'i, I>(
iter: I,
first_block: Option<I::Block>,
) -> (
impl QuoteClassifiedIterator<'i, I, BLOCK_SIZE> + InnerIter<I>,
Option<QuoteClassifiedBlock<I::Block, BLOCK_SIZE>>,
)
where
I: InputBlockIterator<'i, BLOCK_SIZE>,
{
ClassifierImpl::resume(iter, first_block)
}