use core::ops;
use crate::{
bintree::{NodesCmpKey, NodesLink},
node_data::NodesData,
};
use super::*;
impl<'tree, Nodes, Index> TreeAccessor<'tree, Nodes, Index>
where
Nodes: NodesRb<Index>,
Index: PartialEq + Clone,
{
#[inline]
pub fn iter(&self) -> Iter<'tree, &Nodes, Index> {
Iter(self.raw.iter())
}
#[inline]
pub fn iter_index_range(
&self,
range: impl ops::RangeBounds<Option<Index>>,
) -> Iter<'tree, &Nodes, Index> {
Iter(self.raw.iter_index_range(range))
}
#[inline]
pub fn into_iter_index_range(
self,
range: impl ops::RangeBounds<Option<Index>>,
) -> Iter<'tree, Nodes, Index> {
Iter(self.raw.into_iter_index_range(range))
}
#[inline]
pub fn indices(&self) -> Indices<'tree, &Nodes, Index> {
Indices(self.raw.indices())
}
#[inline]
pub fn into_indices(self) -> Indices<'tree, Nodes, Index> {
Indices(self.raw.into_indices())
}
#[inline]
pub fn indices_index_range(
&self,
range: impl ops::RangeBounds<Option<Index>>,
) -> Indices<'tree, &Nodes, Index> {
Indices(self.raw.indices_index_range(range))
}
#[inline]
pub fn into_indices_index_range(
self,
range: impl ops::RangeBounds<Option<Index>>,
) -> Indices<'tree, Nodes, Index> {
Indices(self.raw.into_indices_index_range(range))
}
#[inline]
pub fn values(&self) -> Values<'tree, &Nodes, Index> {
Values(self.raw.values())
}
#[inline]
pub fn into_values(self) -> Values<'tree, Nodes, Index> {
Values(self.raw.into_values())
}
#[inline]
pub fn values_index_range(
&self,
range: impl ops::RangeBounds<Option<Index>>,
) -> Values<'tree, &Nodes, Index> {
Values(self.raw.values_index_range(range))
}
#[inline]
pub fn into_values_index_range(
self,
range: impl ops::RangeBounds<Option<Index>>,
) -> Values<'tree, Nodes, Index> {
Values(self.raw.into_values_index_range(range))
}
}
impl<'tree, Nodes, Index> TreeAccessor<'tree, Nodes, Index>
where
Nodes: NodesRb<Index>,
Index: PartialEq + Clone,
{
#[inline]
pub fn bst_iter_key_range<Key>(
&self,
range: impl ops::RangeBounds<Key>,
) -> Iter<'tree, &Nodes, Index>
where
Nodes: NodesCmpKey<Index, Key>,
{
Iter(self.raw.bst_iter_key_range(range))
}
#[inline]
pub fn bst_into_iter_key_range<Key>(
self,
range: impl ops::RangeBounds<Key>,
) -> Iter<'tree, Nodes, Index>
where
Nodes: NodesCmpKey<Index, Key>,
{
Iter(self.raw.bst_into_iter_key_range(range))
}
#[inline]
pub fn bst_indices_key_range<Key>(
&self,
range: impl ops::RangeBounds<Key>,
) -> Indices<'tree, &Nodes, Index>
where
Nodes: NodesCmpKey<Index, Key>,
{
Indices(self.raw.bst_indices_key_range(range))
}
#[inline]
pub fn bst_into_indices_key_range<Key>(
self,
range: impl ops::RangeBounds<Key>,
) -> Indices<'tree, Nodes, Index>
where
Nodes: NodesCmpKey<Index, Key>,
{
Indices(self.raw.bst_into_indices_key_range(range))
}
#[inline]
pub fn bst_values_key_range<Key>(
&self,
range: impl ops::RangeBounds<Key>,
) -> Values<'tree, &Nodes, Index>
where
Nodes: NodesCmpKey<Index, Key>,
{
Values(self.raw.bst_values_key_range(range))
}
#[inline]
pub fn bst_into_values_key_range<Key>(
self,
range: impl ops::RangeBounds<Key>,
) -> Values<'tree, Nodes, Index>
where
Nodes: NodesCmpKey<Index, Key>,
{
Values(self.raw.bst_into_values_key_range(range))
}
}
impl<'tree, Nodes, Index> IntoIterator for TreeAccessor<'tree, Nodes, Index>
where
Nodes: NodesLink<Index> + NodesData<Index>,
Index: PartialEq + Clone,
{
type Item = (Index, Nodes::Data);
type IntoIter = Iter<'tree, Nodes, Index>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Iter(self.raw.into_iter())
}
}
impl<'a, 'tree, Nodes, Index> IntoIterator for &'a TreeAccessor<'tree, Nodes, Index>
where
Nodes: NodesLink<Index> + NodesDataLend<Index>,
Index: PartialEq + Clone,
{
type Item = (Index, <Nodes as NodesDataLendGat<'a, Index>>::Data);
type IntoIter = Iter<'tree, &'a Nodes, Index>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Iter((&self.raw).into_iter())
}
}
#[derive(Debug, Clone)]
pub struct Iter<'tree, Nodes, Index>(crate::bintree::accessor::Iter<'tree, Nodes, Index>);
#[derive(Debug, Clone)]
pub struct Values<'tree, Nodes, Index>(crate::bintree::accessor::Values<'tree, Nodes, Index>);
#[derive(Debug, Clone)]
pub struct Indices<'tree, Nodes, Index>(crate::bintree::accessor::Indices<'tree, Nodes, Index>);
dry::macro_for!($Ty in [Iter, Values, Indices] {
impl<'tree, Nodes, Index> Default for $Ty<'tree, Nodes, Index>
where
Nodes: Default,
{
#[inline]
fn default() -> Self {
Self(Default::default())
}
}
impl<'tree, Nodes, Index> Iterator for $Ty<'tree, Nodes, Index>
where
Nodes: NodesLink<Index> + NodesData<Index>,
Index: PartialEq + Clone,
{
type Item = <crate::bintree::accessor::$Ty<'tree, Nodes, Index> as Iterator>::Item;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
impl<'tree, Nodes, Index> DoubleEndedIterator for $Ty<'tree, Nodes, Index>
where
Nodes: NodesLink<Index> + NodesData<Index>,
Index: PartialEq + Clone,
{
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.0.next_back()
}
}
impl<'tree, Nodes, Index> core::iter::FusedIterator for $Ty<'tree, Nodes, Index>
where
Nodes: NodesLink<Index> + NodesData<Index>,
Index: PartialEq + Clone,
{
}
});
#[cfg(test)]
mod tests {
use core::ops::RangeBounds as _;
use std::vec::Vec;
use crate::rbtree::tests::{Node, any_rbbst};
use super::*;
#[proptest::property_test]
fn pt_bst_values_range(
#[strategy = any_rbbst(true)] (nodes, root): (Vec<Node<u8>>, Tree),
start: Bound<u8>,
end: Bound<u8>,
) {
let got_values: Vec<u8> = root
.read(&nodes[..])
.bst_values_key_range((start, end))
.copied()
.collect();
let expected_values: Vec<u8> = root
.read(&nodes[..])
.values()
.copied()
.filter(|i| (start, end).contains(i))
.collect();
assert_eq!(got_values, expected_values);
}
}