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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
// Copyright 2018 Mohammad Rezaei.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//
//! # Thin Collections for Rust
//! Alternative implementations for vector, map and set that are faster/smaller for some use cases.
//!
//! `ThinVec` is a general vector replacement that only uses a single `usize`.
//! `std::collections::Vec` uses 3. This makes `ThinVec` a much better choice when it's used
//! inside another data structure, such as a vector of vectors or a map of vectors, etc.
//!
//! `ThinMap` is a specialized map replacement for small key values. It uses less memory than `HashMap`
//! if `mem::size_of::<(K, V)>() < 18`. It's also 2x to 5x faster (see the benchmarks). It's perfect
//! for all the primitives, or your own keys, but for custom keys, you must implement the `ThinSentinel`
//! trait.
//!
//! `ThinSet` uses `ThinMap` underneath, so it's great for elements up to 18 bytes.
//!
//! `V64` is a specialized vector replacement that uses a single 64bit value to represent itself.
//! It can store up to 7 bytes in that, and then uses heap memory. It's ideal for small vectors,
//! especially if those vectors are used inside other data structures.
//!
//! ## Usage
//!
//! Add this to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! thincollections = "0.5.0"
//! ```
//!
//! and this to your crate root:
//!
//! ```rust
//! #[macro_use] extern crate thincollections;
//! # fn main() {
//! # }
//! ```
//!
pub mod thin_sentinel;
pub mod thin_map;
pub mod thin_set;
pub mod thin_v64;
pub mod thin_vec;
pub mod thin_hasher;
#[doc(hidden)]
pub mod cla_map;
#[doc(hidden)]
pub mod util;
/// Creates a [`V64`] containing the arguments.
///
/// `v64!` allows `V64`s to be defined with the same syntax as array expressions.
/// There are two forms of this macro:
///
/// - Create a [`V64`] containing a given list of elements:
///
/// ```
/// # #[macro_use] extern crate thincollections;
/// # use thincollections::thin_v64::V64;
/// # fn main() {
/// let v: V64<i32> = v64![1, 2, 3];
/// assert_eq!(v[0], 1);
/// assert_eq!(v[1], 2);
/// assert_eq!(v[2], 3);
/// # }
/// ```
///
/// - Create a [`V64`] from a given element and size:
///
/// ```
/// # #[macro_use] extern crate thincollections;
/// # use thincollections::thin_v64::V64;
/// # fn main() {
/// let v: V64<u64> = v64![1; 3];
/// assert_eq!(3, v.len());
/// // assert_eq!(v, V64::from_buf([1, 1, 1]));
/// # }
/// ```
///
/// Note that unlike array expressions this syntax supports all elements
/// which implement [`Clone`] and the number of elements doesn't have to be
/// a constant.
///
/// This will use `clone` to duplicate an expression, so one should be careful
/// using this with types having a nonstandard `Clone` implementation. For
/// example, `v64![Rc::new(1); 5]` will create a vector of five references
/// to the same boxed integer value, not five references pointing to independently
/// boxed integers.
#[macro_export]
macro_rules! v64 {
// count helper: transform any expression into 1
(@one $x:expr) => (1usize);
($elem:expr; $n:expr) => ({
$crate::thin_v64::V64::from_elem($elem, $n)
});
($($x:expr),*$(,)*) => ({
let count = 0usize $(+ v64!(@one $x))*;
let mut vec = $crate::thin_v64::V64::with_capacity(count);
$(vec.push($x);)*
vec
});
}
/// Creates a [`ThinVec`] containing the arguments.
///
/// `thinvec!` allows `ThinVec`s to be defined with the same syntax as array expressions.
/// There are two forms of this macro:
///
/// - Create a [`ThinVec`] containing a given list of elements:
///
/// ```
/// # #[macro_use] extern crate thincollections;
/// # use thincollections::thin_vec::ThinVec;
/// # fn main() {
/// let v: ThinVec<i32> = thinvec![1, 2, 3];
/// assert_eq!(v[0], 1);
/// assert_eq!(v[1], 2);
/// assert_eq!(v[2], 3);
/// # }
/// ```
///
/// - Create a [`ThinVec`] from a given element and size:
///
/// ```
/// # #[macro_use] extern crate thincollections;
/// # use thincollections::thin_vec::ThinVec;
/// # fn main() {
/// let v: ThinVec<u64> = thinvec![1; 3];
/// assert_eq!(3, v.len());
/// // assert_eq!(v, ThinVec::from_buf([1, 1, 1]));
/// # }
/// ```
///
/// Note that unlike array expressions this syntax supports all elements
/// which implement [`Clone`] and the number of elements doesn't have to be
/// a constant.
///
/// This will use `clone` to duplicate an expression, so one should be careful
/// using this with types having a nonstandard `Clone` implementation. For
/// example, `thinvec![Rc::new(1); 5]` will create a vector of five references
/// to the same boxed integer value, not five references pointing to independently
/// boxed integers.
#[macro_export]
macro_rules! thinvec {
// count helper: transform any expression into 1
(@one $x:expr) => (1usize);
($elem:expr; $n:expr) => ({
$crate::thin_vec::ThinVec::from_elem($elem, $n)
});
($($x:expr),*$(,)*) => ({
let count = 0usize $(+ thinvec!(@one $x))*;
let mut vec = $crate::thin_vec::ThinVec::with_capacity(count);
$(vec.push($x);)*
vec
});
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}