use crate::bits::BitFieldVec;
use crate::dict::rear_coded_list::RearCodedList;
use crate::traits::{IndexedSeq, IntoIteratorFrom, Types};
use lender::FusedLender;
use lender::{ExactSizeLender, IntoLender, Lender, Lending, check_covariance};
use mem_dbg::*;
use value_traits::slices::SliceByValue;
#[derive(Debug, Clone, MemSize, MemDbg)]
#[cfg_attr(feature = "epserde", derive(epserde::Epserde))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MappedRearCodedList<
I: ?Sized,
O,
D = Box<[u8]>,
P = Box<[usize]>,
Q = BitFieldVec,
const SORTED: bool = true,
> {
rcl: RearCodedList<I, O, D, P, SORTED>,
map: Q,
}
pub type MappedRearCodedListSliceU8<const SORTED: bool = true> =
MappedRearCodedList<[u8], Vec<u8>, Box<[u8]>, Box<[usize]>, BitFieldVec<Box<[usize]>>, SORTED>;
pub type MappedRearCodedListStr<const SORTED: bool = true> =
MappedRearCodedList<str, String, Box<[u8]>, Box<[usize]>, BitFieldVec<Box<[usize]>>, SORTED>;
impl<
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> MappedRearCodedList<I, O, D, P, Q, SORTED>
{
pub fn from_parts(rcl: RearCodedList<I, O, D, P, SORTED>, map: Q) -> Self {
assert_eq!(
rcl.len(),
map.len(),
"Length mismatch between rear-coded list ({}) and mapping ({})",
rcl.len(),
map.len()
);
Self { rcl, map }
}
pub fn into_parts(self) -> (RearCodedList<I, O, D, P, SORTED>, Q) {
(self.rcl, self.map)
}
#[inline]
pub const fn len(&self) -> usize {
self.rcl.len()
}
#[inline]
fn get_in_place_impl(&self, index: usize, result: &mut Vec<u8>) {
let index = self.map.index_value(index);
self.rcl.get_in_place_impl(index, result)
}
}
impl<
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> MappedRearCodedList<I, O, D, P, Q, SORTED>
where
for<'a> Lend<'a, I, O, D, P, Q, SORTED>: Lender,
{
#[inline(always)]
pub fn lender(&self) -> Lend<'_, I, O, D, P, Q, SORTED> {
Lend::new(self)
}
#[inline(always)]
pub fn lender_from(&self, from: usize) -> Lend<'_, I, O, D, P, Q, SORTED> {
Lend::new_from(self, from)
}
#[inline(always)]
pub fn iter(&self) -> Iter<'_, I, O, D, P, Q, SORTED> {
Iter(self.lender())
}
#[inline(always)]
pub fn iter_from(&self, from: usize) -> Iter<'_, I, O, D, P, Q, SORTED> {
Iter(self.lender_from(from))
}
}
impl<
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> Types for MappedRearCodedList<I, O, D, P, Q, SORTED>
{
type Output<'a> = O;
type Input = I;
}
impl<D: AsRef<[u8]>, P: AsRef<[usize]>, Q: SliceByValue<Value = usize>, const SORTED: bool>
IndexedSeq for MappedRearCodedList<[u8], Vec<u8>, D, P, Q, SORTED>
{
#[inline(always)]
unsafe fn get_unchecked(&self, index: usize) -> Self::Output<'_> {
let index = self.map.index_value(index);
unsafe { self.rcl.get_unchecked(index) }
}
#[inline(always)]
fn len(&self) -> usize {
self.rcl.len()
}
}
impl<D: AsRef<[u8]>, P: AsRef<[usize]>, Q: SliceByValue<Value = usize>, const SORTED: bool>
MappedRearCodedList<[u8], Vec<u8>, D, P, Q, SORTED>
{
pub fn get_in_place(&self, index: usize, result: &mut Vec<u8>) {
let index = self.map.index_value(index);
self.rcl.get_in_place_impl(index, result);
}
}
impl<D: AsRef<[u8]>, P: AsRef<[usize]>, Q: SliceByValue<Value = usize>, const SORTED: bool>
IndexedSeq for MappedRearCodedList<str, String, D, P, Q, SORTED>
{
#[inline(always)]
unsafe fn get_unchecked(&self, index: usize) -> Self::Output<'_> {
let index = self.map.index_value(index);
unsafe { self.rcl.get_unchecked(index) }
}
#[inline(always)]
fn len(&self) -> usize {
self.rcl.len()
}
}
impl<D: AsRef<[u8]>, P: AsRef<[usize]>, Q: SliceByValue<Value = usize>, const SORTED: bool>
MappedRearCodedList<str, String, D, P, Q, SORTED>
{
pub fn get_in_place(&self, index: usize, result: &mut String) {
let index = self.map.index_value(index);
self.rcl.get_in_place(index, result)
}
#[inline]
pub fn get_bytes(&self, index: usize) -> Vec<u8> {
let index = self.map.index_value(index);
self.rcl.get_bytes(index)
}
#[inline(always)]
pub fn get_bytes_in_place(&self, index: usize, result: &mut Vec<u8>) {
let index = self.map.index_value(index);
self.rcl.get_in_place_impl(index, result);
}
}
#[derive(Debug, Clone, MemSize, MemDbg)]
pub struct Lend<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> {
prcl: &'a MappedRearCodedList<I, O, D, P, Q, SORTED>,
buffer: Vec<u8>,
index: usize,
}
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> Lend<'a, I, O, D, P, Q, SORTED>
where
Self: Lender,
{
pub fn new(prcl: &'a MappedRearCodedList<I, O, D, P, Q, SORTED>) -> Self {
Self {
prcl,
buffer: Vec::with_capacity(128),
index: 0,
}
}
pub fn new_from(prcl: &'a MappedRearCodedList<I, O, D, P, Q, SORTED>, from: usize) -> Self {
Self {
prcl,
buffer: Vec::with_capacity(128),
index: from,
}
}
fn next_impl(&mut self) -> Option<&[u8]> {
if self.index >= self.prcl.len() {
return None;
}
self.prcl.get_in_place_impl(self.index, &mut self.buffer);
self.index += 1;
Some(&self.buffer)
}
}
impl<
'a,
'b,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> Lending<'b> for Lend<'a, I, O, D, P, Q, SORTED>
{
type Lend = &'b I;
}
impl<
O: PartialEq<str> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> Lender for Lend<'_, str, O, D, P, Q, SORTED>
where
str: PartialEq<O> + PartialEq,
{
check_covariance!();
fn next(&mut self) -> Option<&'_ str> {
self.next_impl().map(|s| std::str::from_utf8(s).unwrap())
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
impl<
O: PartialEq<[u8]> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> Lender for Lend<'_, [u8], O, D, P, Q, SORTED>
where
[u8]: PartialEq<O> + PartialEq,
{
check_covariance!();
fn next(&mut self) -> Option<&[u8]> {
self.next_impl()
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> ExactSizeLender for Lend<'a, I, O, D, P, Q, SORTED>
where
Lend<'a, I, O, D, P, Q, SORTED>: Lender,
{
#[inline(always)]
fn len(&self) -> usize {
self.prcl.len() - self.index
}
}
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> FusedLender for Lend<'a, I, O, D, P, Q, SORTED>
where
Lend<'a, I, O, D, P, Q, SORTED>: Lender,
{
}
#[derive(Debug, Clone, MemSize, MemDbg)]
pub struct Iter<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
>(Lend<'a, I, O, D, P, Q, SORTED>);
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> std::iter::ExactSizeIterator for Iter<'a, I, O, D, P, Q, SORTED>
where
Iter<'a, I, O, D, P, Q, SORTED>: std::iter::Iterator,
Lend<'a, I, O, D, P, Q, SORTED>: ExactSizeLender,
{
#[inline(always)]
fn len(&self) -> usize {
self.0.len()
}
}
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> std::iter::FusedIterator for Iter<'a, I, O, D, P, Q, SORTED>
where
Iter<'a, I, O, D, P, Q, SORTED>: std::iter::Iterator,
Lend<'a, I, O, D, P, Q, SORTED>: FusedLender,
{
}
impl<'a, D: AsRef<[u8]>, P: AsRef<[usize]>, Q: SliceByValue<Value = usize>, const SORTED: bool>
std::iter::Iterator for Iter<'a, str, String, D, P, Q, SORTED>
where
Lend<'a, str, String, D, P, Q, SORTED>: Lender,
{
type Item = String;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0
.next_impl()
.map(|v| String::from_utf8(Vec::from(v)).unwrap())
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
impl<'a, D: AsRef<[u8]>, P: AsRef<[usize]>, Q: SliceByValue<Value = usize>, const SORTED: bool>
std::iter::Iterator for Iter<'a, [u8], Vec<u8>, D, P, Q, SORTED>
where
Lend<'a, [u8], Vec<u8>, D, P, Q, SORTED>: ExactSizeLender,
{
type Item = Vec<u8>;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.0.next_impl().map(|v| v.into())
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.len(), Some(self.len()))
}
}
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> IntoLender for &'a MappedRearCodedList<I, O, D, P, Q, SORTED>
where
Lend<'a, I, O, D, P, Q, SORTED>: Lender,
{
type Lender = Lend<'a, I, O, D, P, Q, SORTED>;
#[inline(always)]
fn into_lender(self) -> Lend<'a, I, O, D, P, Q, SORTED> {
Lend::new(self)
}
}
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> IntoIterator for &'a MappedRearCodedList<I, O, D, P, Q, SORTED>
where
for<'b> Lend<'b, I, O, D, P, Q, SORTED>: Lender,
Iter<'a, I, O, D, P, Q, SORTED>: std::iter::Iterator,
{
type Item = <Iter<'a, I, O, D, P, Q, SORTED> as Iterator>::Item;
type IntoIter = Iter<'a, I, O, D, P, Q, SORTED>;
#[inline(always)]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<
'a,
I: PartialEq<O> + PartialEq + ?Sized,
O: PartialEq<I> + PartialEq,
D: AsRef<[u8]>,
P: AsRef<[usize]>,
Q: SliceByValue<Value = usize>,
const SORTED: bool,
> IntoIteratorFrom for &'a MappedRearCodedList<I, O, D, P, Q, SORTED>
where
for<'b> Lend<'b, I, O, D, P, Q, SORTED>: Lender,
Iter<'a, I, O, D, P, Q, SORTED>: std::iter::Iterator,
{
type IntoIterFrom = Iter<'a, I, O, D, P, Q, SORTED>;
#[inline(always)]
fn into_iter_from(self, from: usize) -> Self::IntoIter {
self.iter_from(from)
}
}