#![doc(html_root_url = "https://docs.rs/small-ord-set/0.1.3")]
#![deny(
missing_debug_implementations,
missing_copy_implementations,
missing_docs
)]
mod entry;
mod map;
pub use self::entry::*;
pub use self::map::*;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::iter::FromIterator;
use std::mem::replace;
use std::ops::{Deref, Index, RangeBounds};
use std::slice::{self, SliceIndex};
use smallvec::{self, Array, SmallVec};
pub struct SmallOrdSet<A: Array> {
vec: SmallVec<A>,
}
impl<A: Array> SmallOrdSet<A> {
pub fn new() -> Self {
SmallOrdSet::default()
}
pub fn as_slice(&self) -> &[A::Item] {
self.vec.as_slice()
}
pub fn capacity(&self) -> usize {
self.vec.capacity()
}
pub fn clear(&mut self) {
self.vec.clear();
}
pub fn drain<R>(&mut self, range: R) -> smallvec::Drain<A>
where
R: RangeBounds<usize>,
{
self.vec.drain(range)
}
pub fn grow(&mut self, new_cap: usize) {
self.vec.grow(new_cap)
}
pub fn inline_size(&self) -> usize {
self.vec.inline_size()
}
pub fn into_vec(self) -> SmallVec<A> {
self.vec
}
pub fn len(&self) -> usize {
self.vec.len()
}
pub fn is_empty(&self) -> bool {
self.vec.is_empty()
}
pub fn reserve(&mut self, additional: usize) {
self.vec.reserve(additional)
}
pub fn reserve_exact(&mut self, additional: usize) {
self.vec.reserve_exact(additional)
}
pub fn retain<F>(&mut self, f: F)
where
F: FnMut(&mut A::Item) -> bool,
{
self.vec.retain(f)
}
pub fn from_vec_unchecked(vec: SmallVec<A>) -> Self {
SmallOrdSet { vec }
}
pub fn iter(&self) -> slice::Iter<A::Item> {
self.vec.iter()
}
pub fn first(&self) -> Option<&A::Item> {
self.vec.first()
}
pub fn last(&self) -> Option<&A::Item> {
self.vec.last()
}
}
impl<A> SmallOrdSet<A>
where
A: Array,
A::Item: Ord,
{
pub fn append(&mut self, other: &mut Self) {
self.extend(other.drain(..))
}
pub fn from_vec(vec: SmallVec<A>) -> Self {
let mut set = SmallOrdSet::from_vec_unchecked(vec);
set.sort_and_dedup();
set
}
pub fn from_buf(buf: A) -> Self {
SmallOrdSet::from_vec(buf.into())
}
pub fn insert(&mut self, element: A::Item) -> bool {
match self.find(&element) {
Ok(_) => false,
Err(idx) => {
self.vec.insert(idx, element);
true
}
}
}
pub fn replace(&mut self, element: A::Item) -> Option<A::Item> {
match self.find(&element) {
Ok(idx) => Some(replace(&mut self.vec[idx], element)),
Err(idx) => {
self.vec.insert(idx, element);
None
}
}
}
pub fn remove<Q>(&mut self, element: &Q) -> Option<A::Item>
where
A::Item: Borrow<Q>,
Q: Ord + ?Sized,
{
match self.find(element) {
Ok(idx) => Some(self.vec.remove(idx)),
Err(_) => None,
}
}
pub fn contains<Q>(&self, element: &Q) -> bool
where
A::Item: Borrow<Q>,
Q: Ord + ?Sized,
{
self.find(element).is_ok()
}
pub fn get<Q>(&self, element: &Q) -> Option<&A::Item>
where
A::Item: Borrow<Q>,
Q: Ord + ?Sized,
{
match self.find(element) {
Ok(idx) => Some(&self.vec[idx]),
Err(_) => None,
}
}
pub fn get_mut<Q>(&mut self, element: &Q) -> Option<&mut A::Item>
where
A::Item: Borrow<Q>,
Q: Ord + ?Sized,
{
match self.find(element) {
Ok(idx) => Some(&mut self.vec[idx]),
Err(_) => None,
}
}
pub fn entry<Q>(&mut self, key: Q) -> Entry<A, Q>
where
A::Item: Borrow<Q>,
Q: Ord,
{
match self.find(&key) {
Ok(idx) => Entry::occupied(self, idx),
Err(idx) => Entry::vacant(self, idx, key),
}
}
fn find<Q>(&self, element: &Q) -> Result<usize, usize>
where
A::Item: Borrow<Q>,
Q: Ord + ?Sized,
{
self.vec
.binary_search_by(|probe| Ord::cmp(probe.borrow(), element))
}
fn sort_and_dedup(&mut self) {
self.vec.sort_unstable();
self.vec.dedup();
}
}
impl<A: Array> AsRef<[A::Item]> for SmallOrdSet<A> {
fn as_ref(&self) -> &[A::Item] {
self.as_slice()
}
}
impl<A: Array> Borrow<[A::Item]> for SmallOrdSet<A> {
fn borrow(&self) -> &[A::Item] {
self.as_slice()
}
}
impl<A> Clone for SmallOrdSet<A>
where
A: Array,
A::Item: Clone,
{
fn clone(&self) -> Self {
SmallOrdSet::from_vec_unchecked(self.vec.clone())
}
fn clone_from(&mut self, source: &Self) {
self.vec.clone_from(&source.vec)
}
}
impl<A> Debug for SmallOrdSet<A>
where
A: Array,
A::Item: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<A: Array> Default for SmallOrdSet<A> {
fn default() -> Self {
SmallOrdSet::from_vec_unchecked(Default::default())
}
}
impl<A: Array> Deref for SmallOrdSet<A> {
type Target = [A::Item];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl<A> Eq for SmallOrdSet<A>
where
A: Array,
A::Item: Eq,
{
}
impl<A> Extend<A::Item> for SmallOrdSet<A>
where
A: Array,
A::Item: Ord,
{
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = A::Item>,
{
self.vec.extend(iter);
self.sort_and_dedup();
}
}
impl<A> From<A> for SmallOrdSet<A>
where
A: Array,
A::Item: Ord,
{
fn from(buf: A) -> Self {
SmallOrdSet::from_buf(buf)
}
}
impl<A> From<SmallVec<A>> for SmallOrdSet<A>
where
A: Array,
A::Item: Ord,
{
fn from(vec: SmallVec<A>) -> Self {
SmallOrdSet::from_vec(vec)
}
}
impl<A> FromIterator<A::Item> for SmallOrdSet<A>
where
A: Array,
A::Item: Ord,
{
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = A::Item>,
{
SmallOrdSet::from_vec(FromIterator::from_iter(iter))
}
}
impl<A> Hash for SmallOrdSet<A>
where
A: Array,
A::Item: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
self.vec.hash(state)
}
}
impl<A: Array, I: SliceIndex<[A::Item]>> Index<I> for SmallOrdSet<A> {
type Output = I::Output;
fn index(&self, index: I) -> &Self::Output {
self.vec.index(index)
}
}
impl<A: Array> IntoIterator for SmallOrdSet<A> {
type IntoIter = smallvec::IntoIter<A>;
type Item = A::Item;
fn into_iter(self) -> Self::IntoIter {
self.vec.into_iter()
}
}
impl<'a, A: Array> IntoIterator for &'a SmallOrdSet<A> {
type IntoIter = slice::Iter<'a, A::Item>;
type Item = &'a A::Item;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<A> Ord for SmallOrdSet<A>
where
A: Array,
A::Item: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&self.vec, &other.vec)
}
}
impl<A> PartialEq for SmallOrdSet<A>
where
A: Array,
A::Item: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
PartialEq::eq(&self.vec, &other.vec)
}
}
impl<A> PartialOrd for SmallOrdSet<A>
where
A: Array,
A::Item: Ord,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
PartialOrd::partial_cmp(&self.vec, &other.vec)
}
}