Skip to content

Instantly share code, notes, and snippets.

@camsteffen
Last active August 12, 2020 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save camsteffen/776b939d8c1bd1d4c6a30291f518a01d to your computer and use it in GitHub Desktop.
Save camsteffen/776b939d8c1bd1d4c6a30291f518a01d to your computer and use it in GitHub Desktop.
Proposal hashmap! macro with options
macro_rules! hashmap {
(@opts nocap $hash:tt capacity: $cap:expr $(, $($tail:tt)*)?) => (hashmap!(@opts $cap $hash $($($tail)*)?));
(@opts $cap:tt nohash S: $hash:ty $(, $($tail:tt)*)?) => (hashmap!(@opts $cap (<$hash>::default()) $($($tail)*)?));
(@opts $cap:tt nohash hasher: $hash:expr $(, $($tail:tt)*)?) => (hashmap!(@opts $cap $hash $($($tail)*)?));
(@opts $cap:tt $hash:tt $name:ident: $($tail:tt)*) => (compile_error!(concat!("Invalid option: ", stringify!($name))));
(@opts $cap:tt $hash:tt) => (hashmap!(@init $cap $hash));
(@opts $cap:tt $hash:tt $($key:expr => $value:expr),+ $(,)?) => {
{
let mut map = hashmap!(@init $cap $hash $($key)*);
$(
let _ = map.insert($key, $value);
)*
map
}
};
(@opts $($tail:tt)*) => (compile_error!("Invalid syntax"));
(@init nocap nohash) => (::std::collections::HashMap::new());
(@init nocap $hash:tt) => (::std::collections::HashMap::with_hasher($hash));
(@init nocap $hash:tt $($t:expr)+) => {
{
let capacity = hashmap!(@count $($t)*);
hashmap!(@init capacity $hash)
}
};
(@init $cap:tt nohash $($tail:tt)*) => (::std::collections::HashMap::with_capacity($cap));
(@init $cap:tt $hash:tt $($tail:tt)*) => (::std::collections::HashMap::with_capacity_and_hasher($cap, $hash));
(@count $($t:tt)*) => (<[()]>::len(&[$(hashmap!(@unit $t)),*]));
(@unit $t:tt) => (());
($($t:tt)*) => (hashmap!(@opts nocap nohash $($t)*));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment