1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
//!
//! The __Utote__ crate provides statically allocated multisets of unsigned
//! integers. A nightly only `simd` feature can also be used to greatly improve
//! performance.
//!
//! A [multiset], also known as a "bag", is an extension to the concept of set
//! where elements can occur multiple times. Utote calls the number of times an
//! element occurs its `count`, though the term `multiplicity` is more often
//! used in mathematical descriptions of multisets. All the common operations
//! on sets have implementations on multisets, so you can `intersect` and
//! `union` multisets, along with everything else you would expect to be able
//! to do.
//!
//! [multiset]: https://en.wikipedia.org/wiki/Multiset
//!
//! If you have a known number of things that you want to count and do set-like
//! operations on, then this crate will likely be useful to you.
//!
//! # Recipes
//!
//! `Multiset` can only keep track of uint counters, but if you have a fixed
//! number of non-uint items then pairing a `HashMap` with a `Multiset` can
//! provide significant performance benefits.
//!
//! ```
//! use std::collections::HashMap;
//! use utote::Multiset;
//!
//! let mut item_map: HashMap<&str, usize> = HashMap::new();
//! item_map.insert("foo", 0);
//! item_map.insert("bar", 1);
//!
//! let multiset: Multiset<u16, 2> = Multiset::empty();
//!
//! // do a whole load of stuff to the multiset...
//!
//! let bar_count: &u16 = multiset.get(*item_map.get("bar").unwrap()).unwrap();
//! ```
//!
//! # SIMD and Generics
//!
//! Due to remaining rough edges in the const generic feature there is an extra
//! constraint required when using `Multiset` generically. The const values for
//! the number of lanes for the simd types of a counter type need to be
//! constrained. The constraint:
//! > `where [(); T::L128 * T::L256 * T::LF]: Sized`
//!
//! is the most simple to add.
//!
//!
//! # Cargo Features
//!
//! - __simd__: Requires nightly rust toolchain. Enables simd implementations
//! using the [__packed_simd__ crate](https://docs.rs/packed_simd) crate and
//! unsatble features: [const_generics](https://github.com/rust-lang/rust/issues/44580)
//! and [const_evaluatable_checked](https://github.com/rust-lang/rust/issues/76560).
//! - __rand__: Enables [`choose_random`](Multiset::choose_random) methods for
//! multiset structs using the [__rand__ crate](https://docs.rs/rand).
//!
//! # Performance
//!
//! The largest factor in multiset performance is the size of the multiset, the
//! larger the slower it is. The simplest way to improve performance is to keep
//! them as small as possible.
//!
//! #### Using SIMD
//!
//! The most simple way to improve performance is to use the simd
//! implementations by turning on the `simd` feature of Utote. If you can use
//! the nightly toolchain then this should be utilised.
#![cfg_attr(
feature = "simd",
feature(const_generics, const_evaluatable_checked),
allow(incomplete_features)
)]
mod multiset;
pub use multiset::*;
#[cfg(feature = "simd")]
mod chunks;
#[cfg(feature = "simd")]
mod simd;