ndstruct 1.0.0

Structures for N-dimensions
Documentation
use crate::{
  csl::{CslLineIterMut, CslLineIterRef, CslMut, CslRef},
  ParallelIteratorWrapper, ParallelProducerWrapper,
};
use rayon::iter::{
  plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer},
  IndexedParallelIterator, ParallelIterator,
};

macro_rules! create_rayon_iter {
  ($csl_rayon_iter:ident, $ref:ident) => {
    impl<'slices, T, const D: usize> ParallelIterator
      for ParallelIteratorWrapper<$csl_rayon_iter<'slices, T, D>>
    where
      T: Send + Sync + 'slices,
    {
      type Item = $ref<'slices, T, D>;

      #[inline]
      fn drive_unindexed<C>(self, consumer: C) -> C::Result
      where
        C: UnindexedConsumer<Self::Item>,
      {
        bridge(self, consumer)
      }

      #[inline]
      fn opt_len(&self) -> Option<usize> {
        Some(self.0.len())
      }
    }

    impl<'slices, T, const D: usize> IndexedParallelIterator
      for ParallelIteratorWrapper<$csl_rayon_iter<'slices, T, D>>
    where
      T: Send + Sync + 'slices,
    {
      #[inline]
      fn drive<C>(self, consumer: C) -> C::Result
      where
        C: Consumer<Self::Item>,
      {
        bridge(self, consumer)
      }

      #[inline]
      fn len(&self) -> usize {
        ExactSizeIterator::len(&self.0)
      }

      #[inline]
      fn with_producer<Cb>(self, callback: Cb) -> Cb::Output
      where
        Cb: ProducerCallback<Self::Item>,
      {
        callback.callback(ParallelProducerWrapper(self.0))
      }
    }

    impl<'slices, T, const D: usize> IntoIterator
      for ParallelProducerWrapper<$csl_rayon_iter<'slices, T, D>>
    where
      T: 'slices,
    {
      type IntoIter = $csl_rayon_iter<'slices, T, D>;
      type Item = <Self::IntoIter as Iterator>::Item;

      #[inline]
      fn into_iter(self) -> Self::IntoIter {
        self.0
      }
    }

    impl<'slices, T, const D: usize> Producer
      for ParallelProducerWrapper<$csl_rayon_iter<'slices, T, D>>
    where
      T: Send + Sync + 'slices,
    {
      type IntoIter = $csl_rayon_iter<'slices, T, D>;
      type Item = <Self::IntoIter as Iterator>::Item;

      #[inline]
      fn into_iter(self) -> Self::IntoIter {
        self.0
      }

      #[inline]
      fn split_at(self, i: usize) -> (Self, Self) {
        let [a, b] = self.0.split_at(i).unwrap();
        (ParallelProducerWrapper(a), ParallelProducerWrapper(b))
      }
    }
  };
}

create_rayon_iter!(CslLineIterRef, CslRef);
create_rayon_iter!(CslLineIterMut, CslMut);