// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//! An ordered set.
//!
//! An immutable ordered set implemented as a [B-tree] [1].
//!
//! Most operations on this type of set are O(log n). A
//! [`HashSet`][hashset::HashSet] is usually a better choice for
//! performance, but the `OrdSet` has the advantage of only requiring
//! an [`Ord`][std::cmp::Ord] constraint on its values, and of being
//! ordered, so values always come out from lowest to highest, where a
//! [`HashSet`][hashset::HashSet] has no guaranteed ordering.
//!
//! [1]: https://en.wikipedia.org/wiki/B-tree
//! [hashset::HashSet]: ./struct.HashSet.html
//! [std::cmp::Ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::collections;
use std::fmt::{Debug, Error, Formatter};
use std::hash::{BuildHasher, Hash, Hasher};
use std::iter::{FromIterator, IntoIterator, Sum};
use std::ops::{Add, Deref, Mul, RangeBounds};
use crate::hashset::HashSet;
use crate::nodes::btree::{
BTreeValue, ConsumingIter as ConsumingNodeIter, DiffIter as NodeDiffIter, Insert,
Iter as NodeIter, Node, Remove,
};
#[cfg(has_specialisation)]
use crate::util::linear_search_by;
use crate::util::{Pool, PoolRef};
pub use crate::nodes::btree::DiffItem;
/// Construct a set from a sequence of values.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// # fn main() {
/// assert_eq!(
/// ordset![1, 2, 3],
/// OrdSet::from(vec![1, 2, 3])
/// );
/// # }
/// ```
#[macro_export]
macro_rules! ordset {
() => { $crate::ordset::OrdSet::new() };
( $($x:expr),* ) => {{
let mut l = $crate::ordset::OrdSet::new();
$(
l.insert($x);
)*
l
}};
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
struct Value(A);
impl Deref for Value {
type Target = A;
fn deref(&self) -> &Self::Target {
&self.0
}
}
// FIXME lacking specialisation, we can't simply implement `BTreeValue`
// for `A`, we have to use the `Value` indirection.
#[cfg(not(has_specialisation))]
impl BTreeValue for Value {
type Key = A;
fn ptr_eq(&self, _other: &Self) -> bool {
false
}
fn search_key(slice: &[Self], key: &BK) -> Result
where
BK: Ord + ?Sized,
Self::Key: Borrow,
{
slice.binary_search_by(|value| Self::Key::borrow(value).cmp(key))
}
fn search_value(slice: &[Self], key: &Self) -> Result {
slice.binary_search_by(|value| value.cmp(key))
}
fn cmp_keys(&self, other: &BK) -> Ordering
where
BK: Ord + ?Sized,
Self::Key: Borrow,
{
Self::Key::borrow(self).cmp(other)
}
fn cmp_values(&self, other: &Self) -> Ordering {
self.cmp(other)
}
}
#[cfg(has_specialisation)]
impl BTreeValue for Value {
type Key = A;
fn ptr_eq(&self, _other: &Self) -> bool {
false
}
default fn search_key(slice: &[Self], key: &BK) -> Result
where
BK: Ord + ?Sized,
Self::Key: Borrow,
{
slice.binary_search_by(|value| Self::Key::borrow(value).cmp(key))
}
default fn search_value(slice: &[Self], key: &Self) -> Result {
slice.binary_search_by(|value| value.cmp(key))
}
fn cmp_keys(&self, other: &BK) -> Ordering
where
BK: Ord + ?Sized,
Self::Key: Borrow,
{
Self::Key::borrow(self).cmp(other)
}
fn cmp_values(&self, other: &Self) -> Ordering {
self.cmp(other)
}
}
#[cfg(has_specialisation)]
impl BTreeValue for Value {
fn search_key(slice: &[Self], key: &BK) -> Result
where
BK: Ord + ?Sized,
Self::Key: Borrow,
{
linear_search_by(slice, |value| Self::Key::borrow(value).cmp(key))
}
fn search_value(slice: &[Self], key: &Self) -> Result {
linear_search_by(slice, |value| value.cmp(key))
}
}
def_pool!(OrdSetPool, Node>);
/// An ordered set.
///
/// An immutable ordered set implemented as a [B-tree] [1].
///
/// Most operations on this type of set are O(log n). A
/// [`HashSet`][hashset::HashSet] is usually a better choice for
/// performance, but the `OrdSet` has the advantage of only requiring
/// an [`Ord`][std::cmp::Ord] constraint on its values, and of being
/// ordered, so values always come out from lowest to highest, where a
/// [`HashSet`][hashset::HashSet] has no guaranteed ordering.
///
/// [1]: https://en.wikipedia.org/wiki/B-tree
/// [hashset::HashSet]: ./struct.HashSet.html
/// [std::cmp::Ord]: https://doc.rust-lang.org/std/cmp/trait.Ord.html
pub struct OrdSet {
size: usize,
pool: OrdSetPool,
root: PoolRef>>,
}
impl OrdSet {
/// Construct an empty set.
#[must_use]
pub fn new() -> Self {
let pool = OrdSetPool::default();
let root = PoolRef::default(&pool.0);
OrdSet {
size: 0,
pool,
root,
}
}
/// Construct an empty set using a specific memory pool.
#[cfg(feature = "pool")]
#[must_use]
pub fn with_pool(pool: &OrdSetPool) -> Self {
let root = PoolRef::default(&pool.0);
OrdSet {
size: 0,
pool: pool.clone(),
root,
}
}
/// Construct a set with a single value.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let set = OrdSet::unit(123);
/// assert!(set.contains(&123));
/// ```
#[inline]
#[must_use]
pub fn unit(a: A) -> Self {
let pool = OrdSetPool::default();
let root = PoolRef::new(&pool.0, Node::unit(Value(a)));
OrdSet {
size: 1,
pool,
root,
}
}
/// Test whether a set is empty.
///
/// Time: O(1)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// assert!(
/// !ordset![1, 2, 3].is_empty()
/// );
/// assert!(
/// OrdSet::::new().is_empty()
/// );
/// ```
#[inline]
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Get the size of a set.
///
/// Time: O(1)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// assert_eq!(3, ordset![1, 2, 3].len());
/// ```
#[inline]
#[must_use]
pub fn len(&self) -> usize {
self.size
}
/// Test whether two sets refer to the same content in memory.
///
/// This is true if the two sides are references to the same set,
/// or if the two sets refer to the same root node.
///
/// This would return true if you're comparing a set to itself, or
/// if you're comparing a set to a fresh clone of itself.
///
/// Time: O(1)
pub fn ptr_eq(&self, other: &Self) -> bool {
std::ptr::eq(self, other) || PoolRef::ptr_eq(&self.root, &other.root)
}
/// Get a reference to the memory pool used by this set.
///
/// Note that if you didn't specifically construct it with a pool, you'll
/// get back a reference to a pool of size 0.
#[cfg(feature = "pool")]
pub fn pool(&self) -> &OrdSetPool {
&self.pool
}
/// Discard all elements from the set.
///
/// This leaves you with an empty set, and all elements that
/// were previously inside it are dropped.
///
/// Time: O(n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::OrdSet;
/// let mut set = ordset![1, 2, 3];
/// set.clear();
/// assert!(set.is_empty());
/// ```
pub fn clear(&mut self) {
if !self.is_empty() {
self.root = PoolRef::default(&self.pool.0);
self.size = 0;
}
}
}
impl OrdSet
where
A: Ord,
{
/// Get the smallest value in a set.
///
/// If the set is empty, returns `None`.
///
/// Time: O(log n)
#[must_use]
pub fn get_min(&self) -> Option<&A> {
self.root.min().map(Deref::deref)
}
/// Get the largest value in a set.
///
/// If the set is empty, returns `None`.
///
/// Time: O(log n)
#[must_use]
pub fn get_max(&self) -> Option<&A> {
self.root.max().map(Deref::deref)
}
/// Create an iterator over the contents of the set.
#[must_use]
pub fn iter(&self) -> Iter<'_, A> {
Iter {
it: NodeIter::new(&self.root, self.size, ..),
}
}
/// Create an iterator over a range inside the set.
#[must_use]
pub fn range(&self, range: R) -> RangedIter<'_, A>
where
R: RangeBounds,
A: Borrow,
BA: Ord + ?Sized,
{
RangedIter {
it: NodeIter::new(&self.root, self.size, range),
}
}
/// Get an iterator over the differences between this set and
/// another, i.e. the set of entries to add or remove to this set
/// in order to make it equal to the other set.
///
/// This function will avoid visiting nodes which are shared
/// between the two sets, meaning that even very large sets can be
/// compared quickly if most of their structure is shared.
///
/// Time: O(n) (where n is the number of unique elements across
/// the two sets, minus the number of elements belonging to nodes
/// shared between them)
#[must_use]
pub fn diff<'a>(&'a self, other: &'a Self) -> DiffIter<'_, A> {
DiffIter {
it: NodeDiffIter::new(&self.root, &other.root),
}
}
/// Test if a value is part of a set.
///
/// Time: O(log n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let mut set = ordset!{1, 2, 3};
/// assert!(set.contains(&1));
/// assert!(!set.contains(&4));
/// ```
#[inline]
#[must_use]
pub fn contains(&self, a: &BA) -> bool
where
BA: Ord + ?Sized,
A: Borrow,
{
self.root.lookup(a).is_some()
}
/// Get the closest smaller value in a set to a given value.
///
/// If the set contains the given value, this is returned.
/// Otherwise, the closest value in the set smaller than the
/// given value is returned. If the smallest value in the set
/// is larger than the given value, `None` is returned.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate im_rc as im;
/// # use im::OrdSet;
/// let set = ordset![1, 3, 5, 7, 9];
/// assert_eq!(Some(&5), set.get_prev(&6));
/// ```
#[must_use]
pub fn get_prev(&self, key: &A) -> Option<&A> {
self.root.lookup_prev(key).map(|v| &v.0)
}
/// Get the closest larger value in a set to a given value.
///
/// If the set contains the given value, this is returned.
/// Otherwise, the closest value in the set larger than the
/// given value is returned. If the largest value in the set
/// is smaller than the given value, `None` is returned.
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate im_rc as im;
/// # use im::OrdSet;
/// let set = ordset![1, 3, 5, 7, 9];
/// assert_eq!(Some(&5), set.get_next(&4));
/// ```
#[must_use]
pub fn get_next(&self, key: &A) -> Option<&A> {
self.root.lookup_next(key).map(|v| &v.0)
}
/// Test whether a set is a subset of another set, meaning that
/// all values in our set must also be in the other set.
///
/// Time: O(n log m) where m is the size of the other set
#[must_use]
pub fn is_subset(&self, other: RS) -> bool
where
RS: Borrow,
{
let other = other.borrow();
if other.len() < self.len() {
return false;
}
self.iter().all(|a| other.contains(a))
}
/// Test whether a set is a proper subset of another set, meaning
/// that all values in our set must also be in the other set. A
/// proper subset must also be smaller than the other set.
///
/// Time: O(n log m) where m is the size of the other set
#[must_use]
pub fn is_proper_subset(&self, other: RS) -> bool
where
RS: Borrow,
{
self.len() != other.borrow().len() && self.is_subset(other)
}
}
impl OrdSet
where
A: Ord + Clone,
{
/// Insert a value into a set.
///
/// Time: O(log n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let mut set = ordset!{};
/// set.insert(123);
/// set.insert(456);
/// assert_eq!(
/// set,
/// ordset![123, 456]
/// );
/// ```
#[inline]
pub fn insert(&mut self, a: A) -> Option {
let new_root = {
let root = PoolRef::make_mut(&self.pool.0, &mut self.root);
match root.insert(&self.pool.0, Value(a)) {
Insert::Replaced(Value(old_value)) => return Some(old_value),
Insert::Added => {
self.size += 1;
return None;
}
Insert::Split(left, median, right) => PoolRef::new(
&self.pool.0,
Node::new_from_split(&self.pool.0, left, median, right),
),
}
};
self.size += 1;
self.root = new_root;
None
}
/// Remove a value from a set.
///
/// Time: O(log n)
#[inline]
pub fn remove(&mut self, a: &BA) -> Option
where
BA: Ord + ?Sized,
A: Borrow,
{
let (new_root, removed_value) = {
let root = PoolRef::make_mut(&self.pool.0, &mut self.root);
match root.remove(&self.pool.0, a) {
Remove::Update(value, root) => (PoolRef::new(&self.pool.0, root), Some(value.0)),
Remove::Removed(value) => {
self.size -= 1;
return Some(value.0);
}
Remove::NoChange => return None,
}
};
self.size -= 1;
self.root = new_root;
removed_value
}
/// Remove the smallest value from a set.
///
/// Time: O(log n)
pub fn remove_min(&mut self) -> Option {
// FIXME implement this at the node level for better efficiency
let key = match self.get_min() {
None => return None,
Some(v) => v,
}
.clone();
self.remove(&key)
}
/// Remove the largest value from a set.
///
/// Time: O(log n)
pub fn remove_max(&mut self) -> Option {
// FIXME implement this at the node level for better efficiency
let key = match self.get_max() {
None => return None,
Some(v) => v,
}
.clone();
self.remove(&key)
}
/// Construct a new set from the current set with the given value
/// added.
///
/// Time: O(log n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let set = ordset![456];
/// assert_eq!(
/// set.update(123),
/// ordset![123, 456]
/// );
/// ```
#[must_use]
pub fn update(&self, a: A) -> Self {
let mut out = self.clone();
out.insert(a);
out
}
/// Construct a new set with the given value removed if it's in
/// the set.
///
/// Time: O(log n)
#[must_use]
pub fn without(&self, a: &BA) -> Self
where
BA: Ord + ?Sized,
A: Borrow,
{
let mut out = self.clone();
out.remove(a);
out
}
/// Remove the smallest value from a set, and return that value as
/// well as the updated set.
///
/// Time: O(log n)
#[must_use]
pub fn without_min(&self) -> (Option, Self) {
match self.get_min() {
Some(v) => (Some(v.clone()), self.without(v)),
None => (None, self.clone()),
}
}
/// Remove the largest value from a set, and return that value as
/// well as the updated set.
///
/// Time: O(log n)
#[must_use]
pub fn without_max(&self) -> (Option, Self) {
match self.get_max() {
Some(v) => (Some(v.clone()), self.without(v)),
None => (None, self.clone()),
}
}
/// Construct the union of two sets.
///
/// Time: O(n log n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let set1 = ordset!{1, 2};
/// let set2 = ordset!{2, 3};
/// let expected = ordset!{1, 2, 3};
/// assert_eq!(expected, set1.union(set2));
/// ```
#[must_use]
pub fn union(self, other: Self) -> Self {
let (mut to_mutate, to_consume) = if self.len() >= other.len() {
(self, other)
} else {
(other, self)
};
for value in to_consume {
to_mutate.insert(value);
}
to_mutate
}
/// Construct the union of multiple sets.
///
/// Time: O(n log n)
#[must_use]
pub fn unions(i: I) -> Self
where
I: IntoIterator- ,
{
i.into_iter().fold(Self::default(), Self::union)
}
/// Construct the symmetric difference between two sets.
///
/// This is an alias for the
/// [`symmetric_difference`][symmetric_difference] method.
///
/// Time: O(n log n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let set1 = ordset!{1, 2};
/// let set2 = ordset!{2, 3};
/// let expected = ordset!{1, 3};
/// assert_eq!(expected, set1.difference(set2));
/// ```
///
/// [symmetric_difference]: #method.symmetric_difference
#[must_use]
pub fn difference(self, other: Self) -> Self {
self.symmetric_difference(other)
}
/// Construct the symmetric difference between two sets.
///
/// Time: O(n log n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let set1 = ordset!{1, 2};
/// let set2 = ordset!{2, 3};
/// let expected = ordset!{1, 3};
/// assert_eq!(expected, set1.symmetric_difference(set2));
/// ```
#[must_use]
pub fn symmetric_difference(mut self, other: Self) -> Self {
for value in other {
if self.remove(&value).is_none() {
self.insert(value);
}
}
self
}
/// Construct the relative complement between two sets, that is the set
/// of values in `self` that do not occur in `other`.
///
/// Time: O(m log n) where m is the size of the other set
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let set1 = ordset!{1, 2};
/// let set2 = ordset!{2, 3};
/// let expected = ordset!{1};
/// assert_eq!(expected, set1.relative_complement(set2));
/// ```
#[must_use]
pub fn relative_complement(mut self, other: Self) -> Self {
for value in other {
let _ = self.remove(&value);
}
self
}
/// Construct the intersection of two sets.
///
/// Time: O(n log n)
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate im_rc as im;
/// # use im::ordset::OrdSet;
/// let set1 = ordset!{1, 2};
/// let set2 = ordset!{2, 3};
/// let expected = ordset!{2};
/// assert_eq!(expected, set1.intersection(set2));
/// ```
#[must_use]
pub fn intersection(self, other: Self) -> Self {
let mut out = Self::default();
for value in other {
if self.contains(&value) {
out.insert(value);
}
}
out
}
/// Split a set into two, with the left hand set containing values
/// which are smaller than `split`, and the right hand set
/// containing values which are larger than `split`.
///
/// The `split` value itself is discarded.
///
/// Time: O(n)
#[must_use]
pub fn split(self, split: &BA) -> (Self, Self)
where
BA: Ord + ?Sized,
A: Borrow,
{
let (left, _, right) = self.split_member(split);
(left, right)
}
/// Split a set into two, with the left hand set containing values
/// which are smaller than `split`, and the right hand set
/// containing values which are larger than `split`.
///
/// Returns a tuple of the two sets and a boolean which is true if
/// the `split` value existed in the original set, and false
/// otherwise.
///
/// Time: O(n)
#[must_use]
pub fn split_member(self, split: &BA) -> (Self, bool, Self)
where
BA: Ord + ?Sized,
A: Borrow,
{
let mut left = Self::default();
let mut right = Self::default();
let mut present = false;
for value in self {
match value.borrow().cmp(split) {
Ordering::Less => {
left.insert(value);
}
Ordering::Equal => {
present = true;
}
Ordering::Greater => {
right.insert(value);
}
}
}
(left, present, right)
}
/// Construct a set with only the `n` smallest values from a given
/// set.
///
/// Time: O(n)
#[must_use]
pub fn take(&self, n: usize) -> Self {
self.iter().take(n).cloned().collect()
}
/// Construct a set with the `n` smallest values removed from a
/// given set.
///
/// Time: O(n)
#[must_use]
pub fn skip(&self, n: usize) -> Self {
self.iter().skip(n).cloned().collect()
}
}
// Core traits
impl Clone for OrdSet {
/// Clone a set.
///
/// Time: O(1)
#[inline]
fn clone(&self) -> Self {
OrdSet {
size: self.size,
pool: self.pool.clone(),
root: self.root.clone(),
}
}
}
impl PartialEq for OrdSet {
fn eq(&self, other: &Self) -> bool {
PoolRef::ptr_eq(&self.root, &other.root)
|| (self.len() == other.len() && self.diff(other).next().is_none())
}
}
impl Eq for OrdSet {}
impl PartialOrd for OrdSet {
fn partial_cmp(&self, other: &Self) -> Option {
self.iter().partial_cmp(other.iter())
}
}
impl Ord for OrdSet {
fn cmp(&self, other: &Self) -> Ordering {
self.iter().cmp(other.iter())
}
}
impl Hash for OrdSet {
fn hash(&self, state: &mut H)
where
H: Hasher,
{
for i in self.iter() {
i.hash(state);
}
}
}
impl Default for OrdSet {
fn default() -> Self {
OrdSet::new()
}
}
impl Add for OrdSet {
type Output = OrdSet;
fn add(self, other: Self) -> Self::Output {
self.union(other)
}
}
impl<'a, A: Ord + Clone> Add for &'a OrdSet {
type Output = OrdSet;
fn add(self, other: Self) -> Self::Output {
self.clone().union(other.clone())
}
}
impl Mul for OrdSet {
type Output = OrdSet;
fn mul(self, other: Self) -> Self::Output {
self.intersection(other)
}
}
impl<'a, A: Ord + Clone> Mul for &'a OrdSet {
type Output = OrdSet;
fn mul(self, other: Self) -> Self::Output {
self.clone().intersection(other.clone())
}
}
impl Sum for OrdSet {
fn sum(it: I) -> Self
where
I: Iterator
- ,
{
it.fold(Self::new(), |a, b| a + b)
}
}
impl Extend for OrdSet
where
A: Ord + Clone + From,
{
fn extend(&mut self, iter: I)
where
I: IntoIterator
- ,
{
for value in iter {
self.insert(From::from(value));
}
}
}
impl Debug for OrdSet {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
f.debug_set().entries(self.iter()).finish()
}
}
// Iterators
/// An iterator over the elements of a set.
pub struct Iter<'a, A> {
it: NodeIter<'a, Value>,
}
impl<'a, A> Iterator for Iter<'a, A>
where
A: 'a + Ord,
{
type Item = &'a A;
/// Advance the iterator and return the next value.
///
/// Time: O(1)*
fn next(&mut self) -> Option {
self.it.next().map(Deref::deref)
}
fn size_hint(&self) -> (usize, Option) {
(self.it.remaining, Some(self.it.remaining))
}
}
impl<'a, A> DoubleEndedIterator for Iter<'a, A>
where
A: 'a + Ord,
{
fn next_back(&mut self) -> Option {
self.it.next_back().map(Deref::deref)
}
}
impl<'a, A> ExactSizeIterator for Iter<'a, A> where A: 'a + Ord {}
/// A ranged iterator over the elements of a set.
///
/// The only difference from `Iter` is that this one doesn't implement
/// `ExactSizeIterator` because we can't know the size of the range without first
/// iterating over it to count.
pub struct RangedIter<'a, A> {
it: NodeIter<'a, Value>,
}
impl<'a, A> Iterator for RangedIter<'a, A>
where
A: 'a + Ord,
{
type Item = &'a A;
/// Advance the iterator and return the next value.
///
/// Time: O(1)*
fn next(&mut self) -> Option {
self.it.next().map(Deref::deref)
}
fn size_hint(&self) -> (usize, Option) {
self.it.size_hint()
}
}
impl<'a, A> DoubleEndedIterator for RangedIter<'a, A>
where
A: 'a + Ord,
{
fn next_back(&mut self) -> Option {
self.it.next_back().map(Deref::deref)
}
}
/// A consuming iterator over the elements of a set.
pub struct ConsumingIter {
it: ConsumingNodeIter>,
}
impl Iterator for ConsumingIter
where
A: Ord + Clone,
{
type Item = A;
/// Advance the iterator and return the next value.
///
/// Time: O(1)*
fn next(&mut self) -> Option {
self.it.next().map(|v| v.0)
}
}
/// An iterator over the difference between two sets.
pub struct DiffIter<'a, A> {
it: NodeDiffIter<'a, Value>,
}
impl<'a, A> Iterator for DiffIter<'a, A>
where
A: Ord + PartialEq,
{
type Item = DiffItem<'a, A>;
/// Advance the iterator and return the next value.
///
/// Time: O(1)*
fn next(&mut self) -> Option {
self.it.next().map(|item| match item {
DiffItem::Add(v) => DiffItem::Add(v.deref()),
DiffItem::Update { old, new } => DiffItem::Update {
old: old.deref(),
new: new.deref(),
},
DiffItem::Remove(v) => DiffItem::Remove(v.deref()),
})
}
}
impl FromIterator for OrdSet
where
A: Ord + Clone + From,
{
fn from_iter(i: T) -> Self
where
T: IntoIterator
- ,
{
let mut out = Self::new();
for item in i {
out.insert(From::from(item));
}
out
}
}
impl<'a, A> IntoIterator for &'a OrdSet
where
A: 'a + Ord,
{
type Item = &'a A;
type IntoIter = Iter<'a, A>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl IntoIterator for OrdSet
where
A: Ord + Clone,
{
type Item = A;
type IntoIter = ConsumingIter;
fn into_iter(self) -> Self::IntoIter {
ConsumingIter {
it: ConsumingNodeIter::new(&self.root, self.size),
}
}
}
// Conversions
impl<'s, 'a, A, OA> From<&'s OrdSet<&'a A>> for OrdSet
where
A: ToOwned + Ord + ?Sized,
OA: Borrow + Ord + Clone,
{
fn from(set: &OrdSet<&A>) -> Self {
set.iter().map(|a| (*a).to_owned()).collect()
}
}
impl<'a, A> From<&'a [A]> for OrdSet
where
A: Ord + Clone,
{
fn from(slice: &'a [A]) -> Self {
slice.iter().cloned().collect()
}
}
impl From> for OrdSet {
fn from(vec: Vec) -> Self {
vec.into_iter().collect()
}
}
impl<'a, A: Ord + Clone> From<&'a Vec> for OrdSet {
fn from(vec: &Vec) -> Self {
vec.iter().cloned().collect()
}
}
impl From> for OrdSet {
fn from(hash_set: collections::HashSet) -> Self {
hash_set.into_iter().collect()
}
}
impl<'a, A: Eq + Hash + Ord + Clone> From<&'a collections::HashSet> for OrdSet {
fn from(hash_set: &collections::HashSet) -> Self {
hash_set.iter().cloned().collect()
}
}
impl From> for OrdSet {
fn from(btree_set: collections::BTreeSet) -> Self {
btree_set.into_iter().collect()
}
}
impl<'a, A: Ord + Clone> From<&'a collections::BTreeSet> for OrdSet {
fn from(btree_set: &collections::BTreeSet) -> Self {
btree_set.iter().cloned().collect()
}
}
impl From> for OrdSet {
fn from(hashset: HashSet) -> Self {
hashset.into_iter().collect()
}
}
impl<'a, A: Hash + Eq + Ord + Clone, S: BuildHasher> From<&'a HashSet> for OrdSet {
fn from(hashset: &HashSet) -> Self {
hashset.into_iter().cloned().collect()
}
}
// Proptest
#[cfg(any(test, feature = "proptest"))]
#[doc(hidden)]
pub mod proptest {
#[deprecated(
since = "14.3.0",
note = "proptest strategies have moved to im::proptest"
)]
pub use crate::proptest::ord_set;
}
#[cfg(test)]
mod test {
use super::*;
use crate::proptest::*;
use ::proptest::proptest;
#[test]
fn match_strings_with_string_slices() {
let mut set: OrdSet = From::from(&ordset!["foo", "bar"]);
set = set.without("bar");
assert!(!set.contains("bar"));
set.remove("foo");
assert!(!set.contains("foo"));
}
#[test]
fn ranged_iter() {
let set: OrdSet = ordset![1, 2, 3, 4, 5];
let range: Vec = set.range(..).cloned().collect();
assert_eq!(vec![1, 2, 3, 4, 5], range);
let range: Vec = set.range(..).rev().cloned().collect();
assert_eq!(vec![5, 4, 3, 2, 1], range);
let range: Vec = set.range(2..5).cloned().collect();
assert_eq!(vec![2, 3, 4], range);
let range: Vec = set.range(2..5).rev().cloned().collect();
assert_eq!(vec![4, 3, 2], range);
let range: Vec = set.range(3..).cloned().collect();
assert_eq!(vec![3, 4, 5], range);
let range: Vec = set.range(3..).rev().cloned().collect();
assert_eq!(vec![5, 4, 3], range);
let range: Vec = set.range(..4).cloned().collect();
assert_eq!(vec![1, 2, 3], range);
let range: Vec = set.range(..4).rev().cloned().collect();
assert_eq!(vec![3, 2, 1], range);
let range: Vec = set.range(..=3).cloned().collect();
assert_eq!(vec![1, 2, 3], range);
let range: Vec = set.range(..=3).rev().cloned().collect();
assert_eq!(vec![3, 2, 1], range);
}
proptest! {
#[test]
fn proptest_a_set(ref s in ord_set(".*", 10..100)) {
assert!(s.len() < 100);
assert!(s.len() >= 10);
}
#[test]
fn long_ranged_iter(max in 1..1000) {
let range = 0..max;
let expected: Vec = range.clone().collect();
let set: OrdSet = range.clone().collect::>();
let result: Vec = set.range(..).cloned().collect();
assert_eq!(expected, result);
let expected: Vec = range.clone().rev().collect();
let set: OrdSet = range.collect::>();
let result: Vec = set.range(..).rev().cloned().collect();
assert_eq!(expected, result);
}
}
}