Import 'slotmap' crate

Request Document: go/android-rust-importing-crates
For CL Reviewers: go/android3p#cl-review
Bug: 395134064
Test: m libslotmap -j

Change-Id: I7111bf50d4b3eb2e01a6672d0252a508ee8e2251
diff --git a/crates/slotmap/.android-checksum.json b/crates/slotmap/.android-checksum.json
new file mode 100644
index 0000000..e10fe44
--- /dev/null
+++ b/crates/slotmap/.android-checksum.json
@@ -0,0 +1 @@
+{"package":null,"files":{".cargo-checksum.json":"57c08da436f0cdc3d537fc1c6366c6fe71dc7a1806cf3e4829910e7a89aa7798","Android.bp":"cc5edeec5900b26a48ce93c4c12f7136f3c2ecd59a3fefd797a0aacabe1404a7","Cargo.lock":"292f5c20184e103704e1231308b31dcf2610a0b5988fafe1a00ed9021267014c","Cargo.toml":"3d51c9b22ff16fd5823bf655f945ea43f51a11c06ac23352f3604ab657c79748","LICENSE":"d7f21f23ff9af7cb69e374346d5ef8d549ae3b6eac7143c27c4fa3556af7f1a5","METADATA":"a9bb42cf7c7c5207bba63f85520a86c5c505ad451d5803f3a8ae76a0371cec30","MODULE_LICENSE_ZLIB":"0d6f8afa3940b7f06bebee651376d43bc8b0d5b437337be2696d30377451e93a","README.md":"421d14e5812f85833ccf5526f2ba893b721e93c077f6a867b08d2c2365f31bba","RELEASES.md":"c3590781106a4703cbe6560ea88388bfe914398b06e729022442f54a349baeb3","build.rs":"7c69b23e7ff51ad6ce773344b3ab2c60a19dafb10606d01f27137c7ee210593f","cargo_embargo.json":"0be745f01ba4955b20f2cb5011168c4d8cd396af75c007035ec693c67b17bce7","examples/doubly_linked_list.rs":"48173f754bd384043571b44a08fa1a71b20e795f223838a5287286a611b13ba4","examples/rand_meld_heap.rs":"b23bf84b10bf5de8a66d9809dc08607c7bbc60becb69f0f580c99ba43e5bdaea","src/basic.rs":"82bbe03b66a7c9f0976b2ff8cefb34ba9007e102937861b9b60968e5bdfb8820","src/dense.rs":"a51402f8e3cce5e8deac1ea4fbb1bea2349dcc77b5c25173f5080edaf87f32cd","src/hop.rs":"1af7a3d8031bfc011e6880df71d6ca6a9b722a490359732592ea838c4ae2dede","src/lib.rs":"307bb3662808f842c2d3d2a0d58fb7090588a4223e8d1d77121f3ab4f03d8ddd","src/secondary.rs":"2b27366f63a69865b98f3198425816de1ad1c687d6757628442682e62ac3dc0f","src/sparse_secondary.rs":"f219de332f863921d42a4f7a61f0834fee72ea76ca7ab66aa2754d44f22ca9f2","src/util.rs":"a853ff0b0e7333cd18b04450416a529a5e9d7e0b12518625878d458aad72cca8"}}
\ No newline at end of file
diff --git a/crates/slotmap/.cargo-checksum.json b/crates/slotmap/.cargo-checksum.json
new file mode 100644
index 0000000..0435700
--- /dev/null
+++ b/crates/slotmap/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"94822af614b8763e4a8ea7fa8a4a76b793765e9a47ff28980584828be4ab0a3b","Cargo.toml":"ca8d3e1b9d2bc3de5e56718195aba29609f4b0a5ceb14811a55dfedef61566bc","LICENSE":"940d3c7339956aa9e8917518305b485ef2aed42df81adbf48ab3a97f0685849b","README.md":"bdce0b82cd3266b923a86f12b872caf66aa0cd5a563d8dc59004c0d73eff110a","RELEASES.md":"c0f3e7e1e54a3a1a2a699101dae4c1e5237294efc9baee8031fda5811863afc0","build.rs":"2ea8b8a95a2b88f845505c6d555dff45372b110d30f36d1ba2eb8d2ec0901839","examples/doubly_linked_list.rs":"aa3bca7a9351e8ae3d2b51de65288437ba5d1c838c7d741d9d10e753848793e8","examples/rand_meld_heap.rs":"a7ce796313981466e96ff471ad5c58b8af65b6cdc78806614c35d4d2bef85dbf","src/basic.rs":"e714da1358d7547d4fdb339f751328c09cdbbe3fa68ecc65dea5590b6895ee02","src/dense.rs":"c52218d1e35544f7a9f70a102e5e4df589eb73ea1c46aa31b1b3869c70cc53b2","src/hop.rs":"87bbb19f6bef1cd15ef9b42cdd5ff7a551541ad95aa743abc14ee037ef63b436","src/lib.rs":"f2784f1dca09ea8c2471921e3a04e7a00581dcb711b78e32025aa15142e9fe7e","src/secondary.rs":"7c86cf230a3f9efb2ad3daa99e2cf23eac90cb5d2d3dee1ceafa4151c5917345","src/sparse_secondary.rs":"2a0e8bc4c39dfc5ad4e8bc1f0eeea59de7681d8051832877644e36361f7303af","src/util.rs":"5023602a8c259d2506e087cf22dd2abb2602e77d4bb9cd39b0221c642d6f61f7"},"package":"dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"}
\ No newline at end of file
diff --git a/crates/slotmap/Android.bp b/crates/slotmap/Android.bp
new file mode 100644
index 0000000..0e9f998
--- /dev/null
+++ b/crates/slotmap/Android.bp
@@ -0,0 +1,38 @@
+// This file is generated by cargo_embargo.
+// Do not modify this file because the changes will be overridden on upgrade.
+
+package {
+    default_applicable_licenses: ["external_rust_crates_slotmap_license"],
+    default_team: "trendy_team_android_rust",
+}
+
+license {
+    name: "external_rust_crates_slotmap_license",
+    visibility: [":__subpackages__"],
+    license_kinds: ["SPDX-license-identifier-Zlib"],
+    license_text: ["LICENSE"],
+}
+
+rust_library {
+    name: "libslotmap",
+    host_supported: true,
+    crate_name: "slotmap",
+    cargo_env_compat: true,
+    cargo_pkg_version: "1.0.7",
+    crate_root: "src/lib.rs",
+    edition: "2018",
+    features: [
+        "default",
+        "std",
+    ],
+    cfgs: [
+        "has_min_const_generics",
+        "nightly",
+    ],
+    apex_available: [
+        "//apex_available:platform",
+        "//apex_available:anyapex",
+    ],
+    product_available: true,
+    vendor_available: true,
+}
diff --git a/crates/slotmap/Cargo.lock b/crates/slotmap/Cargo.lock
new file mode 100644
index 0000000..056c97a
--- /dev/null
+++ b/crates/slotmap/Cargo.lock
@@ -0,0 +1,275 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "0.7.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "env_logger"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+dependencies = [
+ "log",
+ "regex",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.1.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.82"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
+
+[[package]]
+name = "log"
+version = "0.4.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+dependencies = [
+ "cfg-if 0.1.10",
+]
+
+[[package]]
+name = "memchr"
+version = "2.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quickcheck"
+version = "0.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f"
+dependencies = [
+ "env_logger",
+ "log",
+ "rand",
+ "rand_core",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
+dependencies = [
+ "getrandom",
+ "libc",
+ "rand_chacha",
+ "rand_core",
+ "rand_hc",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "regex"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+ "thread_local",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
+
+[[package]]
+name = "ryu"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
+
+[[package]]
+name = "serde"
+version = "1.0.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.118"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "slotmap"
+version = "1.0.7"
+dependencies = [
+ "fxhash",
+ "quickcheck",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "version_check",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.58"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
+
+[[package]]
+name = "version_check"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
+
+[[package]]
+name = "wasi"
+version = "0.9.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
diff --git a/crates/slotmap/Cargo.toml b/crates/slotmap/Cargo.toml
new file mode 100644
index 0000000..fb6c010
--- /dev/null
+++ b/crates/slotmap/Cargo.toml
@@ -0,0 +1,64 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "slotmap"
+version = "1.0.7"
+authors = ["Orson Peters <orsonpeters@gmail.com>"]
+description = "Slotmap data structure"
+readme = "README.md"
+keywords = [
+    "slotmap",
+    "storage",
+    "allocator",
+    "arena",
+    "reference",
+]
+categories = [
+    "data-structures",
+    "memory-management",
+    "caching",
+]
+license = "Zlib"
+repository = "https://github.com/orlp/slotmap"
+
+[dependencies.serde]
+version = "1.0"
+features = [
+    "derive",
+    "alloc",
+]
+optional = true
+default-features = false
+
+[dev-dependencies.fxhash]
+version = "0.2.1"
+
+[dev-dependencies.quickcheck]
+version = "0.9"
+
+[dev-dependencies.serde]
+version = "1.0"
+
+[dev-dependencies.serde_derive]
+version = "1.0"
+
+[dev-dependencies.serde_json]
+version = "1.0"
+
+[build-dependencies.version_check]
+version = "0.9"
+
+[features]
+default = ["std"]
+std = []
+unstable = []
diff --git a/crates/slotmap/LICENSE b/crates/slotmap/LICENSE
new file mode 100644
index 0000000..238d3e6
--- /dev/null
+++ b/crates/slotmap/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2021 Orson Peters <orsonpeters@gmail.com>

+

+This software is provided 'as-is', without any express or implied warranty. In

+no event will the authors be held liable for any damages arising from the use of

+this software.

+

+Permission is granted to anyone to use this software for any purpose, including

+commercial applications, and to alter it and redistribute it freely, subject to

+the following restrictions:

+

+ 1. The origin of this software must not be misrepresented; you must not claim

+    that you wrote the original software. If you use this software in a product,

+    an acknowledgment in the product documentation would be appreciated but is

+    not required.

+

+ 2. Altered source versions must be plainly marked as such, and must not be

+    misrepresented as being the original software.

+

+ 3. This notice may not be removed or altered from any source distribution.

diff --git a/crates/slotmap/METADATA b/crates/slotmap/METADATA
new file mode 100644
index 0000000..b24a922
--- /dev/null
+++ b/crates/slotmap/METADATA
@@ -0,0 +1,17 @@
+name: "slotmap"
+description: "Slotmap data structure"
+third_party {
+  version: "1.0.7"
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2025
+    month: 2
+    day: 11
+  }
+  homepage: "https://crates.io/crates/slotmap"
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/slotmap/slotmap-1.0.7.crate"
+    version: "1.0.7"
+  }
+}
diff --git a/crates/slotmap/MODULE_LICENSE_ZLIB b/crates/slotmap/MODULE_LICENSE_ZLIB
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/crates/slotmap/MODULE_LICENSE_ZLIB
diff --git a/crates/slotmap/README.md b/crates/slotmap/README.md
new file mode 100644
index 0000000..6cba5f4
--- /dev/null
+++ b/crates/slotmap/README.md
@@ -0,0 +1,50 @@
+# slotmap

+

+A Rust library providing three containers with persistent unique keys to access

+stored values, `SlotMap`, `HopSlotMap` and `DenseSlotMap`. Upon insertion a key

+is returned that can be used to later access or remove the values. Insertion,

+deletion and access all take O(1) time with low overhead. Great for storing

+collections of objects that need stable, safe references but have no clear

+ownership otherwise, such as game entities or graph nodes. Two secondary maps,

+`SecondaryMap` and `SparseSecondaryMap` are also provided that allow you to map

+further objects to the keys created by one of the slot maps. Please refer to

+[**the documentation**](https://docs.rs/slotmap) for more information.

+

+The minimum required stable Rust version for `slotmap` is 1.49. To start using

+`slotmap` add the following to your `Cargo.toml`:

+

+```toml

+[dependencies]

+slotmap = "1.0"

+```

+

+# Example

+

+A short example:

+

+```rust

+use slotmap::{SlotMap, SecondaryMap};

+

+let mut sm = SlotMap::new();

+let foo = sm.insert("foo");  // Key generated on insert.

+let bar = sm.insert("bar");

+assert_eq!(sm[foo], "foo");

+assert_eq!(sm[bar], "bar");

+

+sm.remove(bar);

+let reuse = sm.insert("reuse");  // Space from bar reused.

+assert_eq!(sm.contains_key(bar), false);  // After deletion a key stays invalid.

+

+let mut sec = SecondaryMap::new();

+sec.insert(foo, "noun");  // We provide the key for secondary maps.

+sec.insert(reuse, "verb");

+

+for (key, val) in sm {

+    println!("{} is a {}", val, sec[key]);

+}

+```

+

+# License

+

+`slotmap` is released under the Zlib license, a permissive license. It is

+OSI and FSF approved and GPL compatible.

diff --git a/crates/slotmap/RELEASES.md b/crates/slotmap/RELEASES.md
new file mode 100644
index 0000000..29524d8
--- /dev/null
+++ b/crates/slotmap/RELEASES.md
@@ -0,0 +1,147 @@
+Version 1.0.7

+=============

+

+ - Added `clone_from` implementations for all slot maps.

+ - Added `try_insert_with_key` methods that accept a fallible closure.

+ - Improved performance of insertion and key hashing.

+ - Made `new_key_type` resistant to shadowing.

+ - Made iterators clonable regardless of item type clonability.

+

+

+Version 1.0.6

+=============

+

+ - Made `Key` trait unsafe, as it was erroneously safe to implement.

+

+

+Version 1.0.5

+=============

+

+ - Added fuzzing for extra testing.

+ - Fixed an issue that could cause a segfault when using `HopSlotMap::retain`

+   that had the same underlying cause as the fix in 1.0.4 but was missed.

+

+

+Version 1.0.4

+=============

+

+ - Fixed an issue that could cause a segfault when using `HopSlotMap::drain`.

+   All versions 0.3+ are affected, and thus yanked.

+

+

+Version 1.0.3

+=============

+

+ - Made `get_disjoint_mut` available on stable Rust 1.51 and up.

+ - Added unchecked variants for the getters on `SparseSecondaryMap`.

+

+

+Version 1.0.2

+=============

+

+ - Fixed the `new_key_type!` macro, it assumed the `Key` trait was in scope.

+ - Updated code base with more stringent (clippy) warnings, and many small code

+   quality and documentation changes.

+ - Documented the minimum required stable Rust version, which is 1.49.

+

+

+Version 1.0.1

+=============

+

+ - Fixed an instance where an uninitialized `[u32; N]` was created. The

+   uninitialized values were never read - the code always initialized them

+   before reading - but simply having the variable be uninitialized (despite all

+   bit patterns being valid) is technically undefined behavior.

+

+

+Version 1.0.0

+=============

+

+ - Removed all `Copy` trait restrictions of value types stable Rust! There are

+   no longer any restrictions on the types you can store in any of the

+   slot maps. For that reason `Slottable` was deprecated as well.

+

+ - `no_std` support was added, use it by opting out of the default feature `std`.

+

+ - Added `sm.get_disjoint_mut([k1, k2, ...])` which allows you to get mutable

+   references from multiple disjoint keys at the same time. This requires

+   `min-const-generics` to be stabilized, so until Rust 1.51 comes out this is

+   only available on nightly by setting the `unstable` feature.

+

+ - Added an `Entry` API to the secondary maps.

+

+ - Added `derive(Clone)` for iterators where possible.

+

+ - Replaced `Into<KeyData>` with `Key::data()`.

+

+ - `SecondaryMap` now uses minimal space overhead. Each slot now uses

+   `max(sizeof(T), 4)` bytes.

+ 

+ - Moved `SlotMap` to the `basic` module.

+

+

+Version 0.4.1

+=============

+

+ - Backport of fix made in 1.0.4.

+

+

+Version 0.4.0

+=============

+

+ - Codebase moved to 2018 Edition.

+

+ - Reintroduce `DenseSlotMap` - an overzealous removal in 0.3.0.

+ 

+ - Added support for `try_reserve`.

+

+ - Added support for custom hashers in `SparseSecondaryMap`.

+

+ - `SparseSecondaryMap` and `SecondaryMap` can now be cloned.

+

+ - Keys have a more terse debug output.

+

+ - Fixed a bug that caused an overflowing left shift on 32-bit targets.

+

+

+Version 0.3.0

+=============

+

+ - Massive rework, with a focus on secondary maps and custom keys to prevent

+   cross-slotmap key usage.

+

+ - Removed `DenseSlotMap` in favour of `HopSlotMap` as the latter performs

+   better when secondary maps are in use.

+   

+ - Unfortunately due to the redesign the first slot in a slot map must now

+   always be empty. This means some deserializations of slot maps serialized

+   with a version before 0.3.0 can fail.

+

+ - Added `SecondaryMap` and `SparseSecondaryMap`, which allows you to associate

+   extra data with keys given by a slot map. 

+

+ - Added `DefaultKey`, custom key types, and support for them on all slot maps

+   and secondary maps. You must now always specify the key type you're using

+   with a slot map, so `SlotMap<i32>` would be `SlotMap<DefaultKey, i32>`. It is

+   recommended to make a custom key type with `new_key_type!` for any slot map

+   you create, as this entirely prevents using the wrong key on the wrong slot

+   map.

+

+ - `KeyData` now has `as_ffi` and `from_ffi` functions that convert the data

+   that makes up a key to/from an `u64`. This allows you to use slot map keys

+   as opaque handles in FFI code.

+

+

+Version 0.2.1

+=============

+

+ - Fixed a potential uninitialized memory vulnerability. No uninitialized memory

+   was read or used directly, but Rust's assumptions could lead to it. Yanked

+   all previous versions as they were all vulnerable.

+

+ - Made a `Key` member non-zero so that `Option<Key>` is optimized.

+

+

+Version 0.2.0

+=============

+Start of version history.

diff --git a/crates/slotmap/build.rs b/crates/slotmap/build.rs
new file mode 100644
index 0000000..0de58a0
--- /dev/null
+++ b/crates/slotmap/build.rs
@@ -0,0 +1,17 @@
+fn main() {

+    let is_nightly = version_check::is_feature_flaggable() == Some(true);

+    let is_at_least_1_49 = version_check::is_min_version("1.49.0").unwrap_or(false);

+    let is_at_least_1_51 = version_check::is_min_version("1.51.0").unwrap_or(false);

+

+    if !is_at_least_1_49 {

+        println!("cargo:warning=slotmap requires rustc => 1.49.0");

+    }

+

+    if is_at_least_1_51 || is_nightly {

+        println!("cargo:rustc-cfg=has_min_const_generics");

+    }

+

+    if is_nightly {

+        println!("cargo:rustc-cfg=nightly");

+    }

+}

diff --git a/crates/slotmap/cargo_embargo.json b/crates/slotmap/cargo_embargo.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/crates/slotmap/cargo_embargo.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/crates/slotmap/examples/doubly_linked_list.rs b/crates/slotmap/examples/doubly_linked_list.rs
new file mode 100644
index 0000000..dc5bf7a
--- /dev/null
+++ b/crates/slotmap/examples/doubly_linked_list.rs
@@ -0,0 +1,135 @@
+// A simple doubly linked list example using slotmap.

+

+use slotmap::{new_key_type, Key, SlotMap};

+

+new_key_type! {

+    pub struct ListKey;

+}

+

+#[derive(Copy, Clone)]

+struct Node<T> {

+    value: T,

+    prev: ListKey,

+    next: ListKey,

+}

+

+pub struct List<T> {

+    sm: SlotMap<ListKey, Node<T>>,

+    head: ListKey,

+    tail: ListKey,

+}

+

+impl<T> List<T> {

+    pub fn new() -> Self {

+        Self {

+            sm: SlotMap::with_key(),

+            head: ListKey::null(),

+            tail: ListKey::null(),

+        }

+    }

+

+    pub fn len(&self) -> usize {

+        self.sm.len()

+    }

+

+    pub fn push_head(&mut self, value: T) -> ListKey {

+        let k = self.sm.insert(Node {

+            value,

+            prev: ListKey::null(),

+            next: self.head,

+        });

+

+        if let Some(old_head) = self.sm.get_mut(self.head) {

+            old_head.prev = k;

+        } else {

+            self.tail = k;

+        }

+        self.head = k;

+        k

+    }

+

+    pub fn push_tail(&mut self, value: T) -> ListKey {

+        let k = self.sm.insert(Node {

+            value,

+            prev: self.tail,

+            next: ListKey::null(),

+        });

+

+        if let Some(old_tail) = self.sm.get_mut(self.tail) {

+            old_tail.next = k;

+        } else {

+            self.head = k;

+        }

+        self.tail = k;

+        k

+    }

+

+    pub fn pop_head(&mut self) -> Option<T> {

+        self.sm.remove(self.head).map(|old_head| {

+            self.head = old_head.next;

+            old_head.value

+        })

+    }

+

+    pub fn pop_tail(&mut self) -> Option<T> {

+        self.sm.remove(self.tail).map(|old_tail| {

+            self.tail = old_tail.prev;

+            old_tail.value

+        })

+    }

+

+    pub fn remove(&mut self, key: ListKey) -> Option<T> {

+        self.sm.remove(key).map(|node| {

+            if let Some(prev_node) = self.sm.get_mut(node.prev) {

+                prev_node.next = node.next;

+            } else {

+                self.head = node.next;

+            }

+

+            if let Some(next_node) = self.sm.get_mut(node.next) {

+                next_node.prev = node.prev;

+            } else {

+                self.tail = node.prev;

+            }

+

+            node.value

+        })

+    }

+

+    pub fn head(&self) -> ListKey {

+        self.head

+    }

+

+    pub fn tail(&self) -> ListKey {

+        self.tail

+    }

+

+    pub fn get(&self, key: ListKey) -> Option<&T> {

+        self.sm.get(key).map(|node| &node.value)

+    }

+

+    pub fn get_mut(&mut self, key: ListKey) -> Option<&mut T> {

+        self.sm.get_mut(key).map(|node| &mut node.value)

+    }

+}

+

+fn main() {

+    let mut dll = List::new();

+    dll.push_head(5);

+    dll.push_tail(6);

+    let k = dll.push_head(3);

+    dll.push_tail(7);

+    dll.push_head(4);

+

+    assert_eq!(dll.len(), 4);

+    assert_eq!(dll.pop_head(), Some(4));

+    assert_eq!(dll.pop_head(), Some(5));

+    assert_eq!(dll.head(), k);

+    dll.push_head(10);

+    assert_eq!(dll.remove(k), Some(3));

+    assert_eq!(dll.pop_tail(), Some(7));

+    assert_eq!(dll.pop_tail(), Some(6));

+    assert_eq!(dll.pop_head(), Some(10));

+    assert_eq!(dll.pop_head(), None);

+    assert_eq!(dll.pop_tail(), None);

+}

diff --git a/crates/slotmap/examples/rand_meld_heap.rs b/crates/slotmap/examples/rand_meld_heap.rs
new file mode 100644
index 0000000..d0ab951
--- /dev/null
+++ b/crates/slotmap/examples/rand_meld_heap.rs
@@ -0,0 +1,174 @@
+// Randomized meldable heap.

+// https://en.wikipedia.org/wiki/Randomized_meldable_heap

+

+use slotmap::{new_key_type, Key, SlotMap};

+

+new_key_type! {

+    struct HeapKey;

+}

+

+#[derive(Copy, Clone)]

+struct NodeHandle(HeapKey);

+

+#[derive(Copy, Clone)]

+struct Node<T> {

+    value: T,

+    children: [HeapKey; 2],

+    parent: HeapKey,

+}

+

+struct RandMeldHeap<T: Ord> {

+    sm: SlotMap<HeapKey, Node<T>>,

+    rng: std::num::Wrapping<u32>,

+    root: HeapKey,

+}

+

+impl<T: Ord + std::fmt::Debug> RandMeldHeap<T> {

+    pub fn new() -> Self {

+        Self {

+            sm: SlotMap::with_key(),

+            rng: std::num::Wrapping(0xdead_beef),

+            root: HeapKey::null(),

+        }

+    }

+

+    pub fn coinflip(&mut self) -> bool {

+        // Simple LCG for top speed - random quality barely matters.

+        self.rng += (self.rng << 8) + std::num::Wrapping(1);

+        self.rng >> 31 > std::num::Wrapping(0)

+    }

+

+    pub fn insert(&mut self, value: T) -> NodeHandle {

+        let k = self.sm.insert(Node {

+            value,

+            children: [HeapKey::null(), HeapKey::null()],

+            parent: HeapKey::null(),

+        });

+

+        let root = self.root;

+        self.root = self.meld(k, root);

+

+        NodeHandle(k)

+    }

+

+    pub fn pop(&mut self) -> Option<T> {

+        self.sm.remove(self.root).map(|root| {

+            self.root = self.meld(root.children[0], root.children[1]);

+            if let Some(new_root) = self.sm.get_mut(self.root) {

+                new_root.parent = HeapKey::null();

+            }

+

+            root.value

+        })

+    }

+

+    pub fn remove_key(&mut self, node: NodeHandle) -> T {

+        let node = node.0;

+        self.unlink_node(node);

+        self.sm.remove(node).unwrap().value

+    }

+

+    pub fn update_key(&mut self, node: NodeHandle, value: T) {

+        let node = node.0;

+

+        // Unlink and re-insert.

+        self.unlink_node(node);

+        self.sm[node] = Node {

+            value,

+            children: [HeapKey::null(), HeapKey::null()],

+            parent: HeapKey::null(),

+        };

+        let root = self.root;

+        self.root = self.meld(node, root);

+    }

+

+    fn unlink_node(&mut self, node: HeapKey) {

+        // Remove node from heap by merging children and placing them where

+        // node used to be.

+        let children = self.sm[node].children;

+        let parent_key = self.sm[node].parent;

+

+        let melded_children = self.meld(children[0], children[1]);

+        if let Some(mc) = self.sm.get_mut(melded_children) {

+            mc.parent = parent_key;

+        }

+

+        if let Some(parent) = self.sm.get_mut(parent_key) {

+            if parent.children[0] == node {

+                parent.children[0] = melded_children;

+            } else {

+                parent.children[1] = melded_children;

+            }

+        } else {

+            self.root = melded_children;

+        }

+    }

+

+    fn meld(&mut self, mut a: HeapKey, mut b: HeapKey) -> HeapKey {

+        if a.is_null() {

+            return b;

+        }

+        if b.is_null() {

+            return a;

+        }

+

+        if self.sm[a].value > self.sm[b].value {

+            std::mem::swap(&mut a, &mut b);

+        }

+

+        let ret = a;

+

+        // From this point parent and trickle are assumed to be valid keys.

+        let mut parent = a;

+        let mut trickle = b;

+

+        loop {

+            // If a child spot is free, put our trickle there.

+            let children = self.sm[parent].children;

+            if children[0].is_null() {

+                self.sm[parent].children[0] = trickle;

+                self.sm[trickle].parent = parent;

+                break;

+            } else if children[1].is_null() {

+                self.sm[parent].children[1] = trickle;

+                self.sm[trickle].parent = parent;

+                break;

+            }

+

+            // No spot free, choose a random child.

+            let c = self.coinflip() as usize;

+            let child = children[c];

+            if self.sm[child].value > self.sm[trickle].value {

+                self.sm[parent].children[c] = trickle;

+                self.sm[trickle].parent = parent;

+                parent = trickle;

+                trickle = child;

+            } else {

+                parent = child;

+            }

+        }

+

+        ret

+    }

+

+    pub fn len(&self) -> usize {

+        self.sm.len()

+    }

+}

+

+fn main() {

+    let mut rhm = RandMeldHeap::new();

+    let the_answer = rhm.insert(-2);

+    let big = rhm.insert(999);

+

+    for k in (0..10).rev() {

+        rhm.insert(k * k);

+    }

+

+    rhm.update_key(the_answer, 42);

+    rhm.remove_key(big);

+

+    while rhm.len() > 0 {

+        println!("{}", rhm.pop().unwrap());

+    }

+}

diff --git a/crates/slotmap/src/basic.rs b/crates/slotmap/src/basic.rs
new file mode 100644
index 0000000..6eee5cc
--- /dev/null
+++ b/crates/slotmap/src/basic.rs
@@ -0,0 +1,1541 @@
+// Needed because assigning to non-Copy union is unsafe in stable but not in nightly.

+#![allow(unused_unsafe)]

+

+//! Contains the slot map implementation.

+

+#[cfg(all(nightly, any(doc, feature = "unstable")))]

+use alloc::collections::TryReserveError;

+use alloc::vec::Vec;

+use core::fmt;

+use core::iter::{Enumerate, FusedIterator};

+use core::marker::PhantomData;

+#[allow(unused_imports)] // MaybeUninit is only used on nightly at the moment.

+use core::mem::{ManuallyDrop, MaybeUninit};

+use core::ops::{Index, IndexMut};

+

+use crate::util::{Never, UnwrapUnchecked};

+use crate::{DefaultKey, Key, KeyData};

+

+// Storage inside a slot or metadata for the freelist when vacant.

+union SlotUnion<T> {

+    value: ManuallyDrop<T>,

+    next_free: u32,

+}

+

+// A slot, which represents storage for a value and a current version.

+// Can be occupied or vacant.

+struct Slot<T> {

+    u: SlotUnion<T>,

+    version: u32, // Even = vacant, odd = occupied.

+}

+

+// Safe API to read a slot.

+enum SlotContent<'a, T: 'a> {

+    Occupied(&'a T),

+    Vacant(&'a u32),

+}

+

+enum SlotContentMut<'a, T: 'a> {

+    OccupiedMut(&'a mut T),

+    VacantMut(&'a mut u32),

+}

+

+use self::SlotContent::{Occupied, Vacant};

+use self::SlotContentMut::{OccupiedMut, VacantMut};

+

+impl<T> Slot<T> {

+    // Is this slot occupied?

+    #[inline(always)]

+    pub fn occupied(&self) -> bool {

+        self.version % 2 > 0

+    }

+

+    pub fn get(&self) -> SlotContent<T> {

+        unsafe {

+            if self.occupied() {

+                Occupied(&*self.u.value)

+            } else {

+                Vacant(&self.u.next_free)

+            }

+        }

+    }

+

+    pub fn get_mut(&mut self) -> SlotContentMut<T> {

+        unsafe {

+            if self.occupied() {

+                OccupiedMut(&mut *self.u.value)

+            } else {

+                VacantMut(&mut self.u.next_free)

+            }

+        }

+    }

+}

+

+impl<T> Drop for Slot<T> {

+    fn drop(&mut self) {

+        if core::mem::needs_drop::<T>() && self.occupied() {

+            // This is safe because we checked that we're occupied.

+            unsafe {

+                ManuallyDrop::drop(&mut self.u.value);

+            }

+        }

+    }

+}

+

+impl<T: Clone> Clone for Slot<T> {

+    fn clone(&self) -> Self {

+        Self {

+            u: match self.get() {

+                Occupied(value) => SlotUnion {

+                    value: ManuallyDrop::new(value.clone()),

+                },

+                Vacant(&next_free) => SlotUnion { next_free },

+            },

+            version: self.version,

+        }

+    }

+

+    fn clone_from(&mut self, source: &Self) {

+        match (self.get_mut(), source.get()) {

+            (OccupiedMut(self_val), Occupied(source_val)) => self_val.clone_from(source_val),

+            (VacantMut(self_next_free), Vacant(&source_next_free)) => {

+                *self_next_free = source_next_free

+            },

+            (_, Occupied(value)) => {

+                self.u = SlotUnion {

+                    value: ManuallyDrop::new(value.clone()),

+                }

+            },

+            (_, Vacant(&next_free)) => self.u = SlotUnion { next_free },

+        }

+        self.version = source.version;

+    }

+}

+

+impl<T: fmt::Debug> fmt::Debug for Slot<T> {

+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {

+        let mut builder = fmt.debug_struct("Slot");

+        builder.field("version", &self.version);

+        match self.get() {

+            Occupied(value) => builder.field("value", value).finish(),

+            Vacant(next_free) => builder.field("next_free", next_free).finish(),

+        }

+    }

+}

+

+/// Slot map, storage with stable unique keys.

+///

+/// See [crate documentation](crate) for more details.

+#[derive(Debug)]

+pub struct SlotMap<K: Key, V> {

+    slots: Vec<Slot<V>>,

+    free_head: u32,

+    num_elems: u32,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<V> SlotMap<DefaultKey, V> {

+    /// Constructs a new, empty [`SlotMap`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: SlotMap<_, i32> = SlotMap::new();

+    /// ```

+    pub fn new() -> Self {

+        Self::with_capacity_and_key(0)

+    }

+

+    /// Creates an empty [`SlotMap`] with the given capacity.

+    ///

+    /// The slot map will not reallocate until it holds at least `capacity`

+    /// elements.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: SlotMap<_, i32> = SlotMap::with_capacity(10);

+    /// ```

+    pub fn with_capacity(capacity: usize) -> Self {

+        Self::with_capacity_and_key(capacity)

+    }

+}

+

+impl<K: Key, V> SlotMap<K, V> {

+    /// Constructs a new, empty [`SlotMap`] with a custom key type.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! {

+    ///     struct PositionKey;

+    /// }

+    /// let mut positions: SlotMap<PositionKey, i32> = SlotMap::with_key();

+    /// ```

+    pub fn with_key() -> Self {

+        Self::with_capacity_and_key(0)

+    }

+

+    /// Creates an empty [`SlotMap`] with the given capacity and a custom key

+    /// type.

+    ///

+    /// The slot map will not reallocate until it holds at least `capacity`

+    /// elements.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! {

+    ///     struct MessageKey;

+    /// }

+    /// let mut messages = SlotMap::with_capacity_and_key(3);

+    /// let welcome: MessageKey = messages.insert("Welcome");

+    /// let good_day = messages.insert("Good day");

+    /// let hello = messages.insert("Hello");

+    /// ```

+    pub fn with_capacity_and_key(capacity: usize) -> Self {

+        // Create slots with a sentinel at index 0.

+        // We don't actually use the sentinel for anything currently, but

+        // HopSlotMap does, and if we want keys to remain valid through

+        // conversion we have to have one as well.

+        let mut slots = Vec::with_capacity(capacity + 1);

+        slots.push(Slot {

+            u: SlotUnion { next_free: 0 },

+            version: 0,

+        });

+

+        Self {

+            slots,

+            free_head: 1,

+            num_elems: 0,

+            _k: PhantomData,

+        }

+    }

+

+    /// Returns the number of elements in the slot map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::with_capacity(10);

+    /// sm.insert("len() counts actual elements, not capacity");

+    /// let key = sm.insert("removed elements don't count either");

+    /// sm.remove(key);

+    /// assert_eq!(sm.len(), 1);

+    /// ```

+    pub fn len(&self) -> usize {

+        self.num_elems as usize

+    }

+

+    /// Returns if the slot map is empty.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("dummy");

+    /// assert_eq!(sm.is_empty(), false);

+    /// sm.remove(key);

+    /// assert_eq!(sm.is_empty(), true);

+    /// ```

+    pub fn is_empty(&self) -> bool {

+        self.num_elems == 0

+    }

+

+    /// Returns the number of elements the [`SlotMap`] can hold without

+    /// reallocating.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let sm: SlotMap<_, f64> = SlotMap::with_capacity(10);

+    /// assert_eq!(sm.capacity(), 10);

+    /// ```

+    pub fn capacity(&self) -> usize {

+        // One slot is reserved for the sentinel.

+        self.slots.capacity() - 1

+    }

+

+    /// Reserves capacity for at least `additional` more elements to be inserted

+    /// in the [`SlotMap`]. The collection may reserve more space to avoid

+    /// frequent reallocations.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the new allocation size overflows [`usize`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// sm.insert("foo");

+    /// sm.reserve(32);

+    /// assert!(sm.capacity() >= 33);

+    /// ```

+    pub fn reserve(&mut self, additional: usize) {

+        // One slot is reserved for the sentinel.

+        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);

+        self.slots.reserve(needed);

+    }

+

+    /// Tries to reserve capacity for at least `additional` more elements to be

+    /// inserted in the [`SlotMap`]. The collection may reserve more space to

+    /// avoid frequent reallocations.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// sm.insert("foo");

+    /// sm.try_reserve(32).unwrap();

+    /// assert!(sm.capacity() >= 33);

+    /// ```

+    #[cfg(all(nightly, any(doc, feature = "unstable")))]

+    #[cfg_attr(all(nightly, doc), doc(cfg(feature = "unstable")))]

+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {

+        // One slot is reserved for the sentinel.

+        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);

+        self.slots.try_reserve(needed)

+    }

+

+    /// Returns [`true`] if the slot map contains `key`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm.contains_key(key), true);

+    /// sm.remove(key);

+    /// assert_eq!(sm.contains_key(key), false);

+    /// ```

+    pub fn contains_key(&self, key: K) -> bool {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .map_or(false, |slot| slot.version == kd.version.get())

+    }

+

+    /// Inserts a value into the slot map. Returns a unique key that can be used

+    /// to access this value.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm[key], 42);

+    /// ```

+    #[inline(always)]

+    pub fn insert(&mut self, value: V) -> K {

+        unsafe { self.try_insert_with_key::<_, Never>(move |_| Ok(value)).unwrap_unchecked_() }

+    }

+

+    /// Inserts a value given by `f` into the slot map. The key where the

+    /// value will be stored is passed into `f`. This is useful to store values

+    /// that contain their own key.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert_with_key(|k| (k, 20));

+    /// assert_eq!(sm[key], (key, 20));

+    /// ```

+    #[inline(always)]

+    pub fn insert_with_key<F>(&mut self, f: F) -> K

+    where

+        F: FnOnce(K) -> V,

+    {

+        unsafe { self.try_insert_with_key::<_, Never>(move |k| Ok(f(k))).unwrap_unchecked_() }

+    }

+

+    /// Inserts a value given by `f` into the slot map. The key where the

+    /// value will be stored is passed into `f`. This is useful to store values

+    /// that contain their own key.

+    ///

+    /// If `f` returns `Err`, this method returns the error. The slotmap is untouched.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.try_insert_with_key::<_, ()>(|k| Ok((k, 20))).unwrap();

+    /// assert_eq!(sm[key], (key, 20));

+    ///

+    /// sm.try_insert_with_key::<_, ()>(|k| Err(())).unwrap_err();

+    /// ```

+    pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>

+    where

+        F: FnOnce(K) -> Result<V, E>,

+    {

+        // In case f panics, we don't make any changes until we have the value.

+        let new_num_elems = self.num_elems + 1;

+        if new_num_elems == core::u32::MAX {

+            panic!("SlotMap number of elements overflow");

+        }

+

+        if let Some(slot) = self.slots.get_mut(self.free_head as usize) {

+            let occupied_version = slot.version | 1;

+            let kd = KeyData::new(self.free_head, occupied_version);

+

+            // Get value first in case f panics or returns an error.

+            let value = f(kd.into())?;

+

+            // Update.

+            unsafe {

+                self.free_head = slot.u.next_free;

+                slot.u.value = ManuallyDrop::new(value);

+                slot.version = occupied_version;

+            }

+            self.num_elems = new_num_elems;

+            return Ok(kd.into());

+        }

+

+        let version = 1;

+        let kd = KeyData::new(self.slots.len() as u32, version);

+

+        // Create new slot before adjusting freelist in case f or the allocation panics or errors.

+        self.slots.push(Slot {

+            u: SlotUnion {

+                value: ManuallyDrop::new(f(kd.into())?),

+            },

+            version,

+        });

+

+        self.free_head = kd.idx + 1;

+        self.num_elems = new_num_elems;

+        Ok(kd.into())

+    }

+

+    // Helper function to remove a value from a slot. Safe iff the slot is

+    // occupied. Returns the value removed.

+    #[inline(always)]

+    unsafe fn remove_from_slot(&mut self, idx: usize) -> V {

+        // Remove value from slot before overwriting union.

+        let slot = self.slots.get_unchecked_mut(idx);

+        let value = ManuallyDrop::take(&mut slot.u.value);

+

+        // Maintain freelist.

+        slot.u.next_free = self.free_head;

+        self.free_head = idx as u32;

+        self.num_elems -= 1;

+        slot.version = slot.version.wrapping_add(1);

+

+        value

+    }

+

+    /// Removes a key from the slot map, returning the value at the key if the

+    /// key was not previously removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm.remove(key), Some(42));

+    /// assert_eq!(sm.remove(key), None);

+    /// ```

+    pub fn remove(&mut self, key: K) -> Option<V> {

+        let kd = key.data();

+        if self.contains_key(key) {

+            // This is safe because we know that the slot is occupied.

+            Some(unsafe { self.remove_from_slot(kd.idx as usize) })

+        } else {

+            None

+        }

+    }

+

+    /// Retains only the elements specified by the predicate.

+    ///

+    /// In other words, remove all key-value pairs `(k, v)` such that

+    /// `f(k, &mut v)` returns false. This method invalidates any removed keys.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    ///

+    /// let k1 = sm.insert(0);

+    /// let k2 = sm.insert(1);

+    /// let k3 = sm.insert(2);

+    ///

+    /// sm.retain(|key, val| key == k1 || *val == 1);

+    ///

+    /// assert!(sm.contains_key(k1));

+    /// assert!(sm.contains_key(k2));

+    /// assert!(!sm.contains_key(k3));

+    ///

+    /// assert_eq!(2, sm.len());

+    /// ```

+    pub fn retain<F>(&mut self, mut f: F)

+    where

+        F: FnMut(K, &mut V) -> bool,

+    {

+        for i in 1..self.slots.len() {

+            // This is safe because removing elements does not shrink slots.

+            let slot = unsafe { self.slots.get_unchecked_mut(i) };

+            let version = slot.version;

+

+            let should_remove = if let OccupiedMut(value) = slot.get_mut() {

+                let key = KeyData::new(i as u32, version).into();

+                !f(key, value)

+            } else {

+                false

+            };

+

+            if should_remove {

+                // This is safe because we know that the slot was occupied.

+                unsafe { self.remove_from_slot(i) };

+            }

+        }

+    }

+

+    /// Clears the slot map. Keeps the allocated memory for reuse.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// for i in 0..10 {

+    ///     sm.insert(i);

+    /// }

+    /// assert_eq!(sm.len(), 10);

+    /// sm.clear();

+    /// assert_eq!(sm.len(), 0);

+    /// ```

+    pub fn clear(&mut self) {

+        self.drain();

+    }

+

+    /// Clears the slot map, returning all key-value pairs in arbitrary order as

+    /// an iterator. Keeps the allocated memory for reuse.

+    ///

+    /// When the iterator is dropped all elements in the slot map are removed,

+    /// even if the iterator was not fully consumed. If the iterator is not

+    /// dropped (using e.g. [`std::mem::forget`]), only the elements that were

+    /// iterated over are removed.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(0);

+    /// let v: Vec<_> = sm.drain().collect();

+    /// assert_eq!(sm.len(), 0);

+    /// assert_eq!(v, vec![(k, 0)]);

+    /// ```

+    pub fn drain(&mut self) -> Drain<K, V> {

+        Drain { cur: 1, sm: self }

+    }

+

+    /// Returns a reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("bar");

+    /// assert_eq!(sm.get(key), Some(&"bar"));

+    /// sm.remove(key);

+    /// assert_eq!(sm.get(key), None);

+    /// ```

+    pub fn get(&self, key: K) -> Option<&V> {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| unsafe { &*slot.u.value })

+    }

+

+    /// Returns a reference to the value corresponding to the key without

+    /// version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("bar");

+    /// assert_eq!(unsafe { sm.get_unchecked(key) }, &"bar");

+    /// sm.remove(key);

+    /// // sm.get_unchecked(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked(&self, key: K) -> &V {

+        debug_assert!(self.contains_key(key));

+        &self.slots.get_unchecked(key.data().idx as usize).u.value

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert(3.5);

+    /// if let Some(x) = sm.get_mut(key) {

+    ///     *x += 3.0;

+    /// }

+    /// assert_eq!(sm[key], 6.5);

+    /// ```

+    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {

+        let kd = key.data();

+        self.slots

+            .get_mut(kd.idx as usize)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| unsafe { &mut *slot.u.value })

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key

+    /// without version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("foo");

+    /// unsafe { *sm.get_unchecked_mut(key) = "bar" };

+    /// assert_eq!(sm[key], "bar");

+    /// sm.remove(key);

+    /// // sm.get_unchecked_mut(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {

+        debug_assert!(self.contains_key(key));

+        &mut self.slots.get_unchecked_mut(key.data().idx as usize).u.value

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint, otherwise None is returned.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let ka = sm.insert("butter");

+    /// let kb = sm.insert("apples");

+    /// let kc = sm.insert("charlie");

+    /// sm.remove(kc); // Make key c invalid.

+    /// assert_eq!(sm.get_disjoint_mut([ka, kb, kc]), None); // Has invalid key.

+    /// assert_eq!(sm.get_disjoint_mut([ka, ka]), None); // Not disjoint.

+    /// let [a, b] = sm.get_disjoint_mut([ka, kb]).unwrap();

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sm[ka], "apples");

+    /// assert_eq!(sm[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {

+        // Create an uninitialized array of `MaybeUninit`. The `assume_init` is

+        // safe because the type we are claiming to have initialized here is a

+        // bunch of `MaybeUninit`s, which do not require initialization.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = unsafe { MaybeUninit::uninit().assume_init() };

+

+        let mut i = 0;

+        while i < N {

+            let kd = keys[i].data();

+            if !self.contains_key(kd.into()) {

+                break;

+            }

+

+            // This key is valid, and thus the slot is occupied. Temporarily

+            // mark it as unoccupied so duplicate keys would show up as invalid.

+            // This gives us a linear time disjointness check.

+            unsafe {

+                let slot = self.slots.get_unchecked_mut(kd.idx as usize);

+                slot.version ^= 1;

+                ptrs[i] = MaybeUninit::new(&mut *slot.u.value);

+            }

+            i += 1;

+        }

+

+        // Undo temporary unoccupied markings.

+        for k in &keys[..i] {

+            let idx = k.data().idx as usize;

+            unsafe {

+                self.slots.get_unchecked_mut(idx).version ^= 1;

+            }

+        }

+

+        if i == N {

+            // All were valid and disjoint.

+            Some(unsafe { core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs) })

+        } else {

+            None

+        }

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true for every given

+    /// key and no two keys are equal. Otherwise it is potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let ka = sm.insert("butter");

+    /// let kb = sm.insert("apples");

+    /// let [a, b] = unsafe { sm.get_disjoint_unchecked_mut([ka, kb]) };

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sm[ka], "apples");

+    /// assert_eq!(sm[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(

+        &mut self,

+        keys: [K; N],

+    ) -> [&mut V; N] {

+        // Safe, see get_disjoint_mut.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = MaybeUninit::uninit().assume_init();

+        for i in 0..N {

+            ptrs[i] = MaybeUninit::new(self.get_unchecked_mut(keys[i]));

+        }

+        core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs)

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order. The

+    /// iterator element type is `(K, &'a V)`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k0 = sm.insert(0);

+    /// let k1 = sm.insert(1);

+    /// let k2 = sm.insert(2);

+    ///

+    /// for (k, v) in sm.iter() {

+    ///     println!("key: {:?}, val: {}", k, v);

+    /// }

+    /// ```

+    pub fn iter(&self) -> Iter<K, V> {

+        let mut it = self.slots.iter().enumerate();

+        it.next(); // Skip sentinel.

+        Iter {

+            slots: it,

+            num_left: self.len(),

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order, with

+    /// mutable references to the values. The iterator element type is

+    /// `(K, &'a mut V)`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    ///

+    /// for (k, v) in sm.iter_mut() {

+    ///     if k != k1 {

+    ///         *v *= -1;

+    ///     }

+    /// }

+    ///

+    /// assert_eq!(sm[k0], -10);

+    /// assert_eq!(sm[k1], 20);

+    /// assert_eq!(sm[k2], -30);

+    /// ```

+    pub fn iter_mut(&mut self) -> IterMut<K, V> {

+        let len = self.len();

+        let mut it = self.slots.iter_mut().enumerate();

+        it.next(); // Skip sentinel.

+        IterMut {

+            num_left: len,

+            slots: it,

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all keys in arbitrary order. The iterator element

+    /// type is `K`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    /// let keys: HashSet<_> = sm.keys().collect();

+    /// let check: HashSet<_> = vec![k0, k1, k2].into_iter().collect();

+    /// assert_eq!(keys, check);

+    /// ```

+    pub fn keys(&self) -> Keys<K, V> {

+        Keys { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values in arbitrary order. The iterator element

+    /// type is `&'a V`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    /// let values: HashSet<_> = sm.values().collect();

+    /// let check: HashSet<_> = vec![&10, &20, &30].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values(&self) -> Values<K, V> {

+        Values { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values mutably in arbitrary order. The iterator

+    /// element type is `&'a mut V`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// sm.insert(1);

+    /// sm.insert(2);

+    /// sm.insert(3);

+    /// sm.values_mut().for_each(|n| { *n *= 3 });

+    /// let values: HashSet<_> = sm.into_iter().map(|(_k, v)| v).collect();

+    /// let check: HashSet<_> = vec![3, 6, 9].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values_mut(&mut self) -> ValuesMut<K, V> {

+        ValuesMut {

+            inner: self.iter_mut(),

+        }

+    }

+}

+

+impl<K: Key, V> Clone for SlotMap<K, V>

+where

+    V: Clone,

+{

+    fn clone(&self) -> Self {

+        Self {

+            slots: self.slots.clone(),

+            ..*self

+        }

+    }

+

+    fn clone_from(&mut self, source: &Self) {

+        self.slots.clone_from(&source.slots);

+        self.free_head = source.free_head;

+        self.num_elems = source.num_elems;

+    }

+}

+

+impl<K: Key, V> Default for SlotMap<K, V> {

+    fn default() -> Self {

+        Self::with_key()

+    }

+}

+

+impl<K: Key, V> Index<K> for SlotMap<K, V> {

+    type Output = V;

+

+    fn index(&self, key: K) -> &V {

+        match self.get(key) {

+            Some(r) => r,

+            None => panic!("invalid SlotMap key used"),

+        }

+    }

+}

+

+impl<K: Key, V> IndexMut<K> for SlotMap<K, V> {

+    fn index_mut(&mut self, key: K) -> &mut V {

+        match self.get_mut(key) {

+            Some(r) => r,

+            None => panic!("invalid SlotMap key used"),

+        }

+    }

+}

+

+// Iterators.

+/// A draining iterator for [`SlotMap`].

+///

+/// This iterator is created by [`SlotMap::drain`].

+#[derive(Debug)]

+pub struct Drain<'a, K: 'a + Key, V: 'a> {

+    sm: &'a mut SlotMap<K, V>,

+    cur: usize,

+}

+

+/// An iterator that moves key-value pairs out of a [`SlotMap`].

+///

+/// This iterator is created by calling the `into_iter` method on [`SlotMap`],

+/// provided by the [`IntoIterator`] trait.

+#[derive(Debug, Clone)]

+pub struct IntoIter<K: Key, V> {

+    num_left: usize,

+    slots: Enumerate<alloc::vec::IntoIter<Slot<V>>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the key-value pairs in a [`SlotMap`].

+///

+/// This iterator is created by [`SlotMap::iter`].

+#[derive(Debug)]

+pub struct Iter<'a, K: 'a + Key, V: 'a> {

+    num_left: usize,

+    slots: Enumerate<core::slice::Iter<'a, Slot<V>>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {

+    fn clone(&self) -> Self {

+        Iter {

+            num_left: self.num_left,

+            slots: self.slots.clone(),

+            _k: self._k,

+        }

+    }

+}

+

+/// A mutable iterator over the key-value pairs in a [`SlotMap`].

+///

+/// This iterator is created by [`SlotMap::iter_mut`].

+#[derive(Debug)]

+pub struct IterMut<'a, K: 'a + Key, V: 'a> {

+    num_left: usize,

+    slots: Enumerate<core::slice::IterMut<'a, Slot<V>>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the keys in a [`SlotMap`].

+///

+/// This iterator is created by [`SlotMap::keys`].

+#[derive(Debug)]

+pub struct Keys<'a, K: 'a + Key, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {

+    fn clone(&self) -> Self {

+        Keys {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// An iterator over the values in a [`SlotMap`].

+///

+/// This iterator is created by [`SlotMap::values`].

+#[derive(Debug)]

+pub struct Values<'a, K: 'a + Key, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {

+    fn clone(&self) -> Self {

+        Values {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// A mutable iterator over the values in a [`SlotMap`].

+///

+/// This iterator is created by [`SlotMap::values_mut`].

+#[derive(Debug)]

+pub struct ValuesMut<'a, K: 'a + Key, V: 'a> {

+    inner: IterMut<'a, K, V>,

+}

+

+impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        let len = self.sm.slots.len();

+        while self.cur < len {

+            let idx = self.cur;

+            self.cur += 1;

+

+            // This is safe because removing doesn't shrink slots.

+            unsafe {

+                let slot = self.sm.slots.get_unchecked(idx);

+                if slot.occupied() {

+                    let kd = KeyData::new(idx as u32, slot.version);

+                    return Some((kd.into(), self.sm.remove_from_slot(idx)));

+                }

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.sm.len(), Some(self.sm.len()))

+    }

+}

+

+impl<'a, K: Key, V> Drop for Drain<'a, K, V> {

+    fn drop(&mut self) {

+        self.for_each(|_drop| {});

+    }

+}

+

+impl<K: Key, V> Iterator for IntoIter<K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        while let Some((idx, mut slot)) = self.slots.next() {

+            if slot.occupied() {

+                let kd = KeyData::new(idx as u32, slot.version);

+

+                // Prevent dropping after extracting the value.

+                slot.version = 0;

+

+                // This is safe because we know the slot was occupied.

+                let value = unsafe { ManuallyDrop::take(&mut slot.u.value) };

+

+                self.num_left -= 1;

+                return Some((kd.into(), value));

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {

+    type Item = (K, &'a V);

+

+    fn next(&mut self) -> Option<(K, &'a V)> {

+        while let Some((idx, slot)) = self.slots.next() {

+            if let Occupied(value) = slot.get() {

+                let kd = KeyData::new(idx as u32, slot.version);

+                self.num_left -= 1;

+                return Some((kd.into(), value));

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {

+    type Item = (K, &'a mut V);

+

+    fn next(&mut self) -> Option<(K, &'a mut V)> {

+        while let Some((idx, slot)) = self.slots.next() {

+            let version = slot.version;

+            if let OccupiedMut(value) = slot.get_mut() {

+                let kd = KeyData::new(idx as u32, version);

+                self.num_left -= 1;

+                return Some((kd.into(), value));

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Keys<'a, K, V> {

+    type Item = K;

+

+    fn next(&mut self) -> Option<K> {

+        self.inner.next().map(|(key, _)| key)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Values<'a, K, V> {

+    type Item = &'a V;

+

+    fn next(&mut self) -> Option<&'a V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for ValuesMut<'a, K, V> {

+    type Item = &'a mut V;

+

+    fn next(&mut self) -> Option<&'a mut V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> IntoIterator for &'a SlotMap<K, V> {

+    type Item = (K, &'a V);

+    type IntoIter = Iter<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter()

+    }

+}

+

+impl<'a, K: Key, V> IntoIterator for &'a mut SlotMap<K, V> {

+    type Item = (K, &'a mut V);

+    type IntoIter = IterMut<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter_mut()

+    }

+}

+

+impl<K: Key, V> IntoIterator for SlotMap<K, V> {

+    type Item = (K, V);

+    type IntoIter = IntoIter<K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        let len = self.len();

+        let mut it = self.slots.into_iter().enumerate();

+        it.next(); // Skip sentinel.

+        IntoIter {

+            num_left: len,

+            slots: it,

+            _k: PhantomData,

+        }

+    }

+}

+

+impl<'a, K: Key, V> FusedIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Drain<'a, K, V> {}

+impl<K: Key, V> FusedIterator for IntoIter<K, V> {}

+

+impl<'a, K: Key, V> ExactSizeIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Drain<'a, K, V> {}

+impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}

+

+// Serialization with serde.

+#[cfg(feature = "serde")]

+mod serialize {

+    use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

+

+    use super::*;

+

+    #[derive(Serialize, Deserialize)]

+    struct SerdeSlot<T> {

+        value: Option<T>,

+        version: u32,

+    }

+

+    impl<T: Serialize> Serialize for Slot<T> {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            let serde_slot = SerdeSlot {

+                version: self.version,

+                value: match self.get() {

+                    Occupied(value) => Some(value),

+                    Vacant(_) => None,

+                },

+            };

+            serde_slot.serialize(serializer)

+        }

+    }

+

+    impl<'de, T> Deserialize<'de> for Slot<T>

+    where

+        T: Deserialize<'de>,

+    {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let serde_slot: SerdeSlot<T> = Deserialize::deserialize(deserializer)?;

+            let occupied = serde_slot.version % 2 == 1;

+            if occupied ^ serde_slot.value.is_some() {

+                return Err(de::Error::custom(&"inconsistent occupation in Slot"));

+            }

+

+            Ok(Self {

+                u: match serde_slot.value {

+                    Some(value) => SlotUnion {

+                        value: ManuallyDrop::new(value),

+                    },

+                    None => SlotUnion { next_free: 0 },

+                },

+                version: serde_slot.version,

+            })

+        }

+    }

+

+    impl<K: Key, V: Serialize> Serialize for SlotMap<K, V> {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            self.slots.serialize(serializer)

+        }

+    }

+

+    impl<'de, K, V> Deserialize<'de> for SlotMap<K, V>

+    where

+        K: Key,

+        V: Deserialize<'de>,

+    {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let mut slots: Vec<Slot<V>> = Deserialize::deserialize(deserializer)?;

+            if slots.len() >= u32::max_value() as usize {

+                return Err(de::Error::custom(&"too many slots"));

+            }

+

+            // Ensure the first slot exists and is empty for the sentinel.

+            if slots.get(0).map_or(true, |slot| slot.version % 2 == 1) {

+                return Err(de::Error::custom(&"first slot not empty"));

+            }

+

+            slots[0].version = 0;

+            slots[0].u.next_free = 0;

+

+            // We have our slots, rebuild freelist.

+            let mut num_elems = 0;

+            let mut next_free = slots.len();

+            for (i, slot) in slots[1..].iter_mut().enumerate() {

+                if slot.occupied() {

+                    num_elems += 1;

+                } else {

+                    slot.u.next_free = next_free as u32;

+                    next_free = i + 1;

+                }

+            }

+

+            Ok(Self {

+                num_elems,

+                slots,

+                free_head: next_free as u32,

+                _k: PhantomData,

+            })

+        }

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use std::collections::{HashMap, HashSet};

+

+    use quickcheck::quickcheck;

+

+    use super::*;

+

+    #[derive(Clone)]

+    struct CountDrop<'a>(&'a std::cell::RefCell<usize>);

+

+    impl<'a> Drop for CountDrop<'a> {

+        fn drop(&mut self) {

+            *self.0.borrow_mut() += 1;

+        }

+    }

+

+    #[cfg(all(nightly, feature = "unstable"))]

+    #[test]

+    fn check_drops() {

+        let drops = std::cell::RefCell::new(0usize);

+

+        {

+            let mut clone = {

+                // Insert 1000 items.

+                let mut sm = SlotMap::new();

+                let mut sm_keys = Vec::new();

+                for _ in 0..1000 {

+                    sm_keys.push(sm.insert(CountDrop(&drops)));

+                }

+

+                // Remove even keys.

+                for i in (0..1000).filter(|i| i % 2 == 0) {

+                    sm.remove(sm_keys[i]);

+                }

+

+                // Should only have dropped 500 so far.

+                assert_eq!(*drops.borrow(), 500);

+

+                // Let's clone ourselves and then die.

+                sm.clone()

+            };

+

+            // Now all original items should have been dropped exactly once.

+            assert_eq!(*drops.borrow(), 1000);

+

+            // Reuse some empty slots.

+            for _ in 0..250 {

+                clone.insert(CountDrop(&drops));

+            }

+        }

+

+        // 1000 + 750 drops in total should have happened.

+        assert_eq!(*drops.borrow(), 1750);

+    }

+

+    #[cfg(all(nightly, feature = "unstable"))]

+    #[test]

+    fn disjoint() {

+        // Intended to be run with miri to find any potential UB.

+        let mut sm = SlotMap::new();

+

+        // Some churn.

+        for i in 0..20usize {

+            sm.insert(i);

+        }

+        sm.retain(|_, i| *i % 2 == 0);

+

+        let keys: Vec<_> = sm.keys().collect();

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                if let Some([r0, r1]) = sm.get_disjoint_mut([keys[i], keys[j]]) {

+                    *r0 ^= *r1;

+                    *r1 = r1.wrapping_add(*r0);

+                } else {

+                    assert!(i == j);

+                }

+            }

+        }

+

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                for k in 0..keys.len() {

+                    if let Some([r0, r1, r2]) = sm.get_disjoint_mut([keys[i], keys[j], keys[k]]) {

+                        *r0 ^= *r1;

+                        *r0 = r0.wrapping_add(*r2);

+                        *r1 ^= *r0;

+                        *r1 = r1.wrapping_add(*r2);

+                        *r2 ^= *r0;

+                        *r2 = r2.wrapping_add(*r1);

+                    } else {

+                        assert!(i == j || j == k || i == k);

+                    }

+                }

+            }

+        }

+    }

+

+    quickcheck! {

+        fn qc_slotmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {

+            let mut hm = HashMap::new();

+            let mut hm_keys = Vec::new();

+            let mut unique_key = 0u32;

+            let mut sm = SlotMap::new();

+            let mut sm_keys = Vec::new();

+

+            #[cfg(not(feature = "serde"))]

+            let num_ops = 3;

+            #[cfg(feature = "serde")]

+            let num_ops = 4;

+

+            for (op, val) in operations {

+                match op % num_ops {

+                    // Insert.

+                    0 => {

+                        hm.insert(unique_key, val);

+                        hm_keys.push(unique_key);

+                        unique_key += 1;

+

+                        sm_keys.push(sm.insert(val));

+                    }

+

+                    // Delete.

+                    1 => {

+                        // 10% of the time test clear.

+                        if val % 10 == 0 {

+                            let hmvals: HashSet<_> = hm.drain().map(|(_, v)| v).collect();

+                            let smvals: HashSet<_> = sm.drain().map(|(_, v)| v).collect();

+                            if hmvals != smvals {

+                                return false;

+                            }

+                        }

+                        if hm_keys.is_empty() { continue; }

+

+                        let idx = val as usize % hm_keys.len();

+                        if hm.remove(&hm_keys[idx]) != sm.remove(sm_keys[idx]) {

+                            return false;

+                        }

+                    }

+

+                    // Access.

+                    2 => {

+                        if hm_keys.is_empty() { continue; }

+                        let idx = val as usize % hm_keys.len();

+                        let (hm_key, sm_key) = (&hm_keys[idx], sm_keys[idx]);

+

+                        if hm.contains_key(hm_key) != sm.contains_key(sm_key) ||

+                           hm.get(hm_key) != sm.get(sm_key) {

+                            return false;

+                        }

+                    }

+

+                    // Serde round-trip.

+                    #[cfg(feature = "serde")]

+                    3 => {

+                        let ser = serde_json::to_string(&sm).unwrap();

+                        sm = serde_json::from_str(&ser).unwrap();

+                    }

+

+                    _ => unreachable!(),

+                }

+            }

+

+            let mut smv: Vec<_> = sm.values().collect();

+            let mut hmv: Vec<_> = hm.values().collect();

+            smv.sort();

+            hmv.sort();

+            smv == hmv

+        }

+    }

+

+    #[cfg(feature = "serde")]

+    #[test]

+    fn slotmap_serde() {

+        let mut sm = SlotMap::new();

+        // Self-referential structure.

+        let first = sm.insert_with_key(|k| (k, 23i32));

+        let second = sm.insert((first, 42));

+

+        // Make some empty slots.

+        let empties = vec![sm.insert((first, 0)), sm.insert((first, 0))];

+        empties.iter().for_each(|k| {

+            sm.remove(*k);

+        });

+

+        let third = sm.insert((second, 0));

+        sm[first].0 = third;

+

+        let ser = serde_json::to_string(&sm).unwrap();

+        let de: SlotMap<DefaultKey, (DefaultKey, i32)> = serde_json::from_str(&ser).unwrap();

+        assert_eq!(de.len(), sm.len());

+

+        let mut smkv: Vec<_> = sm.iter().collect();

+        let mut dekv: Vec<_> = de.iter().collect();

+        smkv.sort();

+        dekv.sort();

+        assert_eq!(smkv, dekv);

+    }

+

+    #[cfg(feature = "serde")]

+    #[test]

+    fn slotmap_serde_freelist() {

+        let mut sm = SlotMap::new();

+        let k = sm.insert(5i32);

+        sm.remove(k);

+

+        let ser = serde_json::to_string(&sm).unwrap();

+        let mut de: SlotMap<DefaultKey, i32> = serde_json::from_str(&ser).unwrap();

+

+        de.insert(0);

+        de.insert(1);

+        de.insert(2);

+        assert_eq!(de.len(), 3);

+    }

+}

diff --git a/crates/slotmap/src/dense.rs b/crates/slotmap/src/dense.rs
new file mode 100644
index 0000000..b5f864f
--- /dev/null
+++ b/crates/slotmap/src/dense.rs
@@ -0,0 +1,1397 @@
+//! Contains the dense slot map implementation.

+

+// There is quite a lot of unsafe code in this implementation. To prevent the

+// same explanation over and over again, care must be taken that indices in

+// slots and keys from key-value pairs **that are stored inside the slot map**

+// are valid. Keys that are received from the user are not trusted (as they

+// might have come from a different slot map or malicious serde deseralization).

+

+#[cfg(all(nightly, any(doc, feature = "unstable")))]

+use alloc::collections::TryReserveError;

+use alloc::vec::Vec;

+use core::iter::FusedIterator;

+#[allow(unused_imports)] // MaybeUninit is only used on nightly at the moment.

+use core::mem::MaybeUninit;

+use core::ops::{Index, IndexMut};

+

+use crate::util::{Never, UnwrapUnchecked};

+use crate::{DefaultKey, Key, KeyData};

+

+// A slot, which represents storage for an index and a current version.

+// Can be occupied or vacant.

+#[derive(Debug, Clone)]

+struct Slot {

+    // Even = vacant, odd = occupied.

+    version: u32,

+

+    // An index when occupied, the next free slot otherwise.

+    idx_or_free: u32,

+}

+

+/// Dense slot map, storage with stable unique keys.

+///

+/// See [crate documentation](crate) for more details.

+#[derive(Debug)]

+pub struct DenseSlotMap<K: Key, V> {

+    keys: Vec<K>,

+    values: Vec<V>,

+    slots: Vec<Slot>,

+    free_head: u32,

+}

+

+impl<V> DenseSlotMap<DefaultKey, V> {

+    /// Construct a new, empty [`DenseSlotMap`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: DenseSlotMap<_, i32> = DenseSlotMap::new();

+    /// ```

+    pub fn new() -> Self {

+        Self::with_capacity_and_key(0)

+    }

+

+    /// Creates an empty [`DenseSlotMap`] with the given capacity.

+    ///

+    /// The slot map will not reallocate until it holds at least `capacity`

+    /// elements.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: DenseSlotMap<_, i32> = DenseSlotMap::with_capacity(10);

+    /// ```

+    pub fn with_capacity(capacity: usize) -> DenseSlotMap<DefaultKey, V> {

+        Self::with_capacity_and_key(capacity)

+    }

+}

+

+impl<K: Key, V> DenseSlotMap<K, V> {

+    /// Constructs a new, empty [`DenseSlotMap`] with a custom key type.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! {

+    ///     struct PositionKey;

+    /// }

+    /// let mut positions: DenseSlotMap<PositionKey, i32> = DenseSlotMap::with_key();

+    /// ```

+    pub fn with_key() -> Self {

+        Self::with_capacity_and_key(0)

+    }

+

+    /// Creates an empty [`DenseSlotMap`] with the given capacity and a custom key

+    /// type.

+    ///

+    /// The slot map will not reallocate until it holds at least `capacity`

+    /// elements.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! {

+    ///     struct MessageKey;

+    /// }

+    /// let mut messages = DenseSlotMap::with_capacity_and_key(3);

+    /// let welcome: MessageKey = messages.insert("Welcome");

+    /// let good_day = messages.insert("Good day");

+    /// let hello = messages.insert("Hello");

+    /// ```

+    pub fn with_capacity_and_key(capacity: usize) -> Self {

+        // Create slots with a sentinel at index 0.

+        // We don't actually use the sentinel for anything currently, but

+        // HopSlotMap does, and if we want keys to remain valid through

+        // conversion we have to have one as well.

+        let mut slots = Vec::with_capacity(capacity + 1);

+        slots.push(Slot {

+            idx_or_free: 0,

+            version: 0,

+        });

+

+        DenseSlotMap {

+            keys: Vec::with_capacity(capacity),

+            values: Vec::with_capacity(capacity),

+            slots,

+            free_head: 1,

+        }

+    }

+

+    /// Returns the number of elements in the slot map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::with_capacity(10);

+    /// sm.insert("len() counts actual elements, not capacity");

+    /// let key = sm.insert("removed elements don't count either");

+    /// sm.remove(key);

+    /// assert_eq!(sm.len(), 1);

+    /// ```

+    pub fn len(&self) -> usize {

+        self.keys.len()

+    }

+

+    /// Returns if the slot map is empty.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert("dummy");

+    /// assert_eq!(sm.is_empty(), false);

+    /// sm.remove(key);

+    /// assert_eq!(sm.is_empty(), true);

+    /// ```

+    pub fn is_empty(&self) -> bool {

+        self.keys.is_empty()

+    }

+

+    /// Returns the number of elements the [`DenseSlotMap`] can hold without

+    /// reallocating.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let sm: DenseSlotMap<_, f64> = DenseSlotMap::with_capacity(10);

+    /// assert_eq!(sm.capacity(), 10);

+    /// ```

+    pub fn capacity(&self) -> usize {

+        self.keys.capacity()

+    }

+

+    /// Reserves capacity for at least `additional` more elements to be inserted

+    /// in the [`DenseSlotMap`]. The collection may reserve more space to

+    /// avoid frequent reallocations.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the new allocation size overflows [`usize`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// sm.insert("foo");

+    /// sm.reserve(32);

+    /// assert!(sm.capacity() >= 33);

+    /// ```

+    pub fn reserve(&mut self, additional: usize) {

+        self.keys.reserve(additional);

+        self.values.reserve(additional);

+        // One slot is reserved for the sentinel.

+        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);

+        self.slots.reserve(needed);

+    }

+

+    /// Tries to reserve capacity for at least `additional` more elements to be

+    /// inserted in the [`DenseSlotMap`]. The collection may reserve more space to

+    /// avoid frequent reallocations.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// sm.insert("foo");

+    /// sm.try_reserve(32).unwrap();

+    /// assert!(sm.capacity() >= 33);

+    /// ```

+    #[cfg(all(nightly, any(doc, feature = "unstable")))]

+    #[cfg_attr(all(nightly, doc), doc(cfg(feature = "unstable")))]

+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {

+        self.keys.try_reserve(additional)?;

+        self.values.try_reserve(additional)?;

+        // One slot is reserved for the sentinel.

+        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);

+        self.slots.try_reserve(needed)

+    }

+

+    /// Returns [`true`] if the slot map contains `key`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm.contains_key(key), true);

+    /// sm.remove(key);

+    /// assert_eq!(sm.contains_key(key), false);

+    /// ```

+    pub fn contains_key(&self, key: K) -> bool {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .map_or(false, |slot| slot.version == kd.version.get())

+    }

+

+    /// Inserts a value into the slot map. Returns a unique key that can be used

+    /// to access this value.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm[key], 42);

+    /// ```

+    #[inline(always)]

+    pub fn insert(&mut self, value: V) -> K {

+        unsafe { self.try_insert_with_key::<_, Never>(move |_| Ok(value)).unwrap_unchecked_() }

+    }

+

+    /// Inserts a value given by `f` into the slot map. The key where the

+    /// value will be stored is passed into `f`. This is useful to store values

+    /// that contain their own key.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert_with_key(|k| (k, 20));

+    /// assert_eq!(sm[key], (key, 20));

+    /// ```

+    #[inline(always)]

+    pub fn insert_with_key<F>(&mut self, f: F) -> K

+    where

+        F: FnOnce(K) -> V,

+    {

+        unsafe { self.try_insert_with_key::<_, Never>(move |k| Ok(f(k))).unwrap_unchecked_() }

+    }

+

+    /// Inserts a value given by `f` into the slot map. The key where the

+    /// value will be stored is passed into `f`. This is useful to store values

+    /// that contain their own key.

+    ///

+    /// If `f` returns `Err`, this method returns the error. The slotmap is untouched.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.try_insert_with_key::<_, ()>(|k| Ok((k, 20))).unwrap();

+    /// assert_eq!(sm[key], (key, 20));

+    ///

+    /// sm.try_insert_with_key::<_, ()>(|k| Err(())).unwrap_err();

+    /// ```

+    pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>

+    where

+        F: FnOnce(K) -> Result<V, E>,

+    {

+        if self.len() >= (core::u32::MAX - 1) as usize {

+            panic!("DenseSlotMap number of elements overflow");

+        }

+

+        let idx = self.free_head;

+

+        if let Some(slot) = self.slots.get_mut(idx as usize) {

+            let occupied_version = slot.version | 1;

+            let key = KeyData::new(idx, occupied_version).into();

+

+            // Push value before adjusting slots/freelist in case f panics or returns an error.

+            self.values.push(f(key)?);

+            self.keys.push(key);

+            self.free_head = slot.idx_or_free;

+            slot.idx_or_free = self.keys.len() as u32 - 1;

+            slot.version = occupied_version;

+            return Ok(key);

+        }

+

+        // Push value before adjusting slots/freelist in case f panics or returns an error.

+        let key = KeyData::new(idx, 1).into();

+        self.values.push(f(key)?);

+        self.keys.push(key);

+        self.slots.push(Slot {

+            version: 1,

+            idx_or_free: self.keys.len() as u32 - 1,

+        });

+        self.free_head = self.slots.len() as u32;

+        Ok(key)

+    }

+

+    // Helper function to add a slot to the freelist. Returns the index that

+    // was stored in the slot.

+    #[inline(always)]

+    fn free_slot(&mut self, slot_idx: usize) -> u32 {

+        let slot = &mut self.slots[slot_idx];

+        let value_idx = slot.idx_or_free;

+        slot.version = slot.version.wrapping_add(1);

+        slot.idx_or_free = self.free_head;

+        self.free_head = slot_idx as u32;

+        value_idx

+    }

+

+    // Helper function to remove a value from a slot and make the slot free.

+    // Returns the value removed.

+    #[inline(always)]

+    fn remove_from_slot(&mut self, slot_idx: usize) -> V {

+        let value_idx = self.free_slot(slot_idx);

+

+        // Remove values/slot_indices by swapping to end.

+        let _ = self.keys.swap_remove(value_idx as usize);

+        let value = self.values.swap_remove(value_idx as usize);

+

+        // Did something take our place? Update its slot to new position.

+        if let Some(k) = self.keys.get(value_idx as usize) {

+            self.slots[k.data().idx as usize].idx_or_free = value_idx;

+        }

+

+        value

+    }

+

+    /// Removes a key from the slot map, returning the value at the key if the

+    /// key was not previously removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm.remove(key), Some(42));

+    /// assert_eq!(sm.remove(key), None);

+    /// ```

+    pub fn remove(&mut self, key: K) -> Option<V> {

+        let kd = key.data();

+        if self.contains_key(kd.into()) {

+            Some(self.remove_from_slot(kd.idx as usize))

+        } else {

+            None

+        }

+    }

+

+    /// Retains only the elements specified by the predicate.

+    ///

+    /// In other words, remove all key-value pairs `(k, v)` such that

+    /// `f(k, &mut v)` returns false. This method invalidates any removed keys.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    ///

+    /// let k3 = sm.insert(2);

+    /// let k1 = sm.insert(0);

+    /// let k2 = sm.insert(1);

+    ///

+    /// sm.retain(|key, val| key == k1 || *val == 1);

+    ///

+    /// assert!(sm.contains_key(k1));

+    /// assert!(sm.contains_key(k2));

+    /// assert!(!sm.contains_key(k3));

+    ///

+    /// assert_eq!(2, sm.len());

+    /// ```

+    pub fn retain<F>(&mut self, mut f: F)

+    where

+        F: FnMut(K, &mut V) -> bool,

+    {

+        let mut i = 0;

+        while i < self.keys.len() {

+            let (should_keep, slot_idx) = {

+                let (kd, mut value) = (self.keys[i].data(), &mut self.values[i]);

+                (f(kd.into(), &mut value), kd.idx as usize)

+            };

+

+            if should_keep {

+                i += 1;

+            } else {

+                // We do not increment i here intentionally. This index has just

+                // been replaced with a new value.

+                self.remove_from_slot(slot_idx);

+            }

+        }

+    }

+

+    /// Clears the slot map. Keeps the allocated memory for reuse.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// for i in 0..10 {

+    ///     sm.insert(i);

+    /// }

+    /// assert_eq!(sm.len(), 10);

+    /// sm.clear();

+    /// assert_eq!(sm.len(), 0);

+    /// ```

+    pub fn clear(&mut self) {

+        self.drain();

+    }

+

+    /// Clears the slot map, returning all key-value pairs in arbitrary order

+    /// as an iterator. Keeps the allocated memory for reuse.

+    ///

+    /// When the iterator is dropped all elements in the slot map are removed,

+    /// even if the iterator was not fully consumed. If the iterator is not

+    /// dropped (using e.g. [`std::mem::forget`]), only the elements that were

+    /// iterated over are removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let k = sm.insert(0);

+    /// let v: Vec<_> = sm.drain().collect();

+    /// assert_eq!(sm.len(), 0);

+    /// assert_eq!(v, vec![(k, 0)]);

+    /// ```

+    pub fn drain(&mut self) -> Drain<K, V> {

+        Drain { sm: self }

+    }

+

+    /// Returns a reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert("bar");

+    /// assert_eq!(sm.get(key), Some(&"bar"));

+    /// sm.remove(key);

+    /// assert_eq!(sm.get(key), None);

+    /// ```

+    pub fn get(&self, key: K) -> Option<&V> {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| unsafe {

+                // This is safe because we only store valid indices.

+                let idx = slot.idx_or_free as usize;

+                self.values.get_unchecked(idx)

+            })

+    }

+

+    /// Returns a reference to the value corresponding to the key without

+    /// version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert("bar");

+    /// assert_eq!(unsafe { sm.get_unchecked(key) }, &"bar");

+    /// sm.remove(key);

+    /// // sm.get_unchecked(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked(&self, key: K) -> &V {

+        debug_assert!(self.contains_key(key));

+        let idx = self.slots.get_unchecked(key.data().idx as usize).idx_or_free;

+        &self.values.get_unchecked(idx as usize)

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert(3.5);

+    /// if let Some(x) = sm.get_mut(key) {

+    ///     *x += 3.0;

+    /// }

+    /// assert_eq!(sm[key], 6.5);

+    /// ```

+    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| slot.idx_or_free as usize)

+            .map(move |idx| unsafe {

+                // This is safe because we only store valid indices.

+                self.values.get_unchecked_mut(idx)

+            })

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key

+    /// without version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let key = sm.insert("foo");

+    /// unsafe { *sm.get_unchecked_mut(key) = "bar" };

+    /// assert_eq!(sm[key], "bar");

+    /// sm.remove(key);

+    /// // sm.get_unchecked_mut(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {

+        debug_assert!(self.contains_key(key));

+        let idx = self.slots.get_unchecked(key.data().idx as usize).idx_or_free;

+        self.values.get_unchecked_mut(idx as usize)

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint, otherwise [`None`] is

+    /// returned.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let ka = sm.insert("butter");

+    /// let kb = sm.insert("apples");

+    /// let kc = sm.insert("charlie");

+    /// sm.remove(kc); // Make key c invalid.

+    /// assert_eq!(sm.get_disjoint_mut([ka, kb, kc]), None); // Has invalid key.

+    /// assert_eq!(sm.get_disjoint_mut([ka, ka]), None); // Not disjoint.

+    /// let [a, b] = sm.get_disjoint_mut([ka, kb]).unwrap();

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sm[ka], "apples");

+    /// assert_eq!(sm[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {

+        // Create an uninitialized array of `MaybeUninit`. The `assume_init` is

+        // safe because the type we are claiming to have initialized here is a

+        // bunch of `MaybeUninit`s, which do not require initialization.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = unsafe { MaybeUninit::uninit().assume_init() };

+

+        let mut i = 0;

+        while i < N {

+            // We can avoid this clone after min_const_generics and array_map.

+            let kd = keys[i].data();

+            if !self.contains_key(kd.into()) {

+                break;

+            }

+

+            // This key is valid, and thus the slot is occupied. Temporarily

+            // mark it as unoccupied so duplicate keys would show up as invalid.

+            // This gives us a linear time disjointness check.

+            unsafe {

+                let slot = self.slots.get_unchecked_mut(kd.idx as usize);

+                slot.version ^= 1;

+                let ptr = self.values.get_unchecked_mut(slot.idx_or_free as usize);

+                ptrs[i] = MaybeUninit::new(ptr);

+            }

+            i += 1;

+        }

+

+        // Undo temporary unoccupied markings.

+        for k in &keys[..i] {

+            let idx = k.data().idx as usize;

+            unsafe {

+                self.slots.get_unchecked_mut(idx).version ^= 1;

+            }

+        }

+

+        if i == N {

+            // All were valid and disjoint.

+            Some(unsafe { core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs) })

+        } else {

+            None

+        }

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true for every given

+    /// key and no two keys are equal. Otherwise it is potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let ka = sm.insert("butter");

+    /// let kb = sm.insert("apples");

+    /// let [a, b] = unsafe { sm.get_disjoint_unchecked_mut([ka, kb]) };

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sm[ka], "apples");

+    /// assert_eq!(sm[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(

+        &mut self,

+        keys: [K; N],

+    ) -> [&mut V; N] {

+        // Safe, see get_disjoint_mut.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = MaybeUninit::uninit().assume_init();

+        for i in 0..N {

+            ptrs[i] = MaybeUninit::new(self.get_unchecked_mut(keys[i]));

+        }

+        core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs)

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order. The

+    /// iterator element type is `(K, &'a V)`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let k0 = sm.insert(0);

+    /// let k1 = sm.insert(1);

+    /// let k2 = sm.insert(2);

+    ///

+    /// let mut it = sm.iter();

+    /// for (k, v) in sm.iter() {

+    ///     println!("key: {:?}, val: {}", k, v);

+    /// }

+    /// ```

+    pub fn iter(&self) -> Iter<K, V> {

+        Iter {

+            inner_keys: self.keys.iter(),

+            inner_values: self.values.iter(),

+        }

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order, with

+    /// mutable references to the values. The iterator element type is

+    /// `(K, &'a mut V)`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = DenseSlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    ///

+    /// for (k, v) in sm.iter_mut() {

+    ///     if k != k1 {

+    ///         *v *= -1;

+    ///     }

+    /// }

+    ///

+    /// assert_eq!(sm[k0], -10);

+    /// assert_eq!(sm[k1], 20);

+    /// assert_eq!(sm[k2], -30);

+    /// ```

+    pub fn iter_mut(&mut self) -> IterMut<K, V> {

+        IterMut {

+            inner_keys: self.keys.iter(),

+            inner_values: self.values.iter_mut(),

+        }

+    }

+

+    /// An iterator visiting all keys in arbitrary order. The iterator element

+    /// type is K.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = DenseSlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    /// let keys: HashSet<_> = sm.keys().collect();

+    /// let check: HashSet<_> = vec![k0, k1, k2].into_iter().collect();

+    /// assert_eq!(keys, check);

+    /// ```

+    pub fn keys(&self) -> Keys<K, V> {

+        Keys { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values in arbitrary order. The iterator element

+    /// type is `&'a V`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = DenseSlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    /// let values: HashSet<_> = sm.values().collect();

+    /// let check: HashSet<_> = vec![&10, &20, &30].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values(&self) -> Values<K, V> {

+        Values { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values mutably in arbitrary order. The iterator

+    /// element type is `&'a mut V`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = DenseSlotMap::new();

+    /// sm.insert(1);

+    /// sm.insert(2);

+    /// sm.insert(3);

+    /// sm.values_mut().for_each(|n| { *n *= 3 });

+    /// let values: HashSet<_> = sm.into_iter().map(|(_k, v)| v).collect();

+    /// let check: HashSet<_> = vec![3, 6, 9].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values_mut(&mut self) -> ValuesMut<K, V> {

+        ValuesMut {

+            inner: self.iter_mut(),

+        }

+    }

+}

+

+impl<K: Key, V> Clone for DenseSlotMap<K, V>

+where

+    V: Clone,

+{

+    fn clone(&self) -> Self {

+        Self {

+            keys: self.keys.clone(),

+            values: self.values.clone(),

+            slots: self.slots.clone(),

+            ..*self

+        }

+    }

+

+    fn clone_from(&mut self, source: &Self) {

+        self.keys.clone_from(&source.keys);

+        self.values.clone_from(&source.values);

+        self.slots.clone_from(&source.slots);

+        self.free_head = source.free_head;

+    }

+}

+

+impl<K: Key, V> Default for DenseSlotMap<K, V> {

+    fn default() -> Self {

+        Self::with_key()

+    }

+}

+

+impl<K: Key, V> Index<K> for DenseSlotMap<K, V> {

+    type Output = V;

+

+    fn index(&self, key: K) -> &V {

+        match self.get(key) {

+            Some(r) => r,

+            None => panic!("invalid DenseSlotMap key used"),

+        }

+    }

+}

+

+impl<K: Key, V> IndexMut<K> for DenseSlotMap<K, V> {

+    fn index_mut(&mut self, key: K) -> &mut V {

+        match self.get_mut(key) {

+            Some(r) => r,

+            None => panic!("invalid DenseSlotMap key used"),

+        }

+    }

+}

+

+// Iterators.

+/// A draining iterator for [`DenseSlotMap`].

+///

+/// This iterator is created by [`DenseSlotMap::drain`].

+#[derive(Debug)]

+pub struct Drain<'a, K: 'a + Key, V: 'a> {

+    sm: &'a mut DenseSlotMap<K, V>,

+}

+

+/// An iterator that moves key-value pairs out of a [`DenseSlotMap`].

+///

+/// This iterator is created by calling the `into_iter` method on [`DenseSlotMap`],

+/// provided by the [`IntoIterator`] trait.

+#[derive(Debug, Clone)]

+pub struct IntoIter<K, V> {

+    inner_keys: alloc::vec::IntoIter<K>,

+    inner_values: alloc::vec::IntoIter<V>,

+}

+

+/// An iterator over the key-value pairs in a [`DenseSlotMap`].

+///

+/// This iterator is created by [`DenseSlotMap::iter`].

+#[derive(Debug)]

+pub struct Iter<'a, K: 'a + Key, V: 'a> {

+    inner_keys: core::slice::Iter<'a, K>,

+    inner_values: core::slice::Iter<'a, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {

+    fn clone(&self) -> Self {

+        Iter {

+            inner_keys: self.inner_keys.clone(),

+            inner_values: self.inner_values.clone(),

+        }

+    }

+}

+

+/// A mutable iterator over the key-value pairs in a [`DenseSlotMap`].

+///

+/// This iterator is created by [`DenseSlotMap::iter_mut`].

+#[derive(Debug)]

+pub struct IterMut<'a, K: 'a + Key, V: 'a> {

+    inner_keys: core::slice::Iter<'a, K>,

+    inner_values: core::slice::IterMut<'a, V>,

+}

+

+/// An iterator over the keys in a [`DenseSlotMap`].

+///

+/// This iterator is created by [`DenseSlotMap::keys`].

+#[derive(Debug)]

+pub struct Keys<'a, K: 'a + Key, V> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {

+    fn clone(&self) -> Self {

+        Keys {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// An iterator over the values in a [`DenseSlotMap`].

+///

+/// This iterator is created by [`DenseSlotMap::values`].

+#[derive(Debug)]

+pub struct Values<'a, K: 'a + Key, V> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {

+    fn clone(&self) -> Self {

+        Values {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// A mutable iterator over the values in a [`DenseSlotMap`].

+///

+/// This iterator is created by [`DenseSlotMap::values_mut`].

+#[derive(Debug)]

+pub struct ValuesMut<'a, K: 'a + Key, V: 'a> {

+    inner: IterMut<'a, K, V>,

+}

+

+impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        // We make no iteration order guarantees, so we just repeatedly pop.

+        let key = self.sm.keys.pop();

+        let value = self.sm.values.pop();

+

+        if let (Some(k), Some(v)) = (key, value) {

+            self.sm.free_slot(k.data().idx as usize);

+            Some((k, v))

+        } else {

+            None

+        }

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        let len = self.sm.keys.len();

+        (len, Some(len))

+    }

+}

+

+impl<'a, K: Key, V> Drop for Drain<'a, K, V> {

+    fn drop(&mut self) {

+        self.for_each(|_drop| {});

+    }

+}

+

+impl<K: Key, V> Iterator for IntoIter<K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        let key = self.inner_keys.next();

+        let value = self.inner_values.next();

+

+        if let (Some(k), Some(v)) = (key, value) {

+            Some((k, v))

+        } else {

+            None

+        }

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner_keys.size_hint()

+    }

+}

+

+impl<'a, K: 'a + Key, V> Iterator for Iter<'a, K, V> {

+    type Item = (K, &'a V);

+

+    fn next(&mut self) -> Option<(K, &'a V)> {

+        let key = self.inner_keys.next();

+        let value = self.inner_values.next();

+

+        if let (Some(k), Some(v)) = (key, value) {

+            Some((*k, v))

+        } else {

+            None

+        }

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner_keys.size_hint()

+    }

+}

+

+impl<'a, K: 'a + Key, V> Iterator for IterMut<'a, K, V> {

+    type Item = (K, &'a mut V);

+

+    fn next(&mut self) -> Option<(K, &'a mut V)> {

+        let key = self.inner_keys.next();

+        let value = self.inner_values.next();

+

+        if let (Some(k), Some(v)) = (key, value) {

+            Some((*k, v))

+        } else {

+            None

+        }

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner_keys.size_hint()

+    }

+}

+

+impl<'a, K: 'a + Key, V> Iterator for Keys<'a, K, V> {

+    type Item = K;

+

+    fn next(&mut self) -> Option<K> {

+        self.inner.next().map(|(key, _)| key)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: 'a + Key, V> Iterator for Values<'a, K, V> {

+    type Item = &'a V;

+

+    fn next(&mut self) -> Option<&'a V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: 'a + Key, V> Iterator for ValuesMut<'a, K, V> {

+    type Item = &'a mut V;

+

+    fn next(&mut self) -> Option<&'a mut V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: 'a + Key, V> IntoIterator for &'a DenseSlotMap<K, V> {

+    type Item = (K, &'a V);

+    type IntoIter = Iter<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter()

+    }

+}

+

+impl<'a, K: 'a + Key, V> IntoIterator for &'a mut DenseSlotMap<K, V> {

+    type Item = (K, &'a mut V);

+    type IntoIter = IterMut<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter_mut()

+    }

+}

+

+impl<K: Key, V> IntoIterator for DenseSlotMap<K, V> {

+    type Item = (K, V);

+    type IntoIter = IntoIter<K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        IntoIter {

+            inner_keys: self.keys.into_iter(),

+            inner_values: self.values.into_iter(),

+        }

+    }

+}

+

+impl<'a, K: 'a + Key, V> FusedIterator for Iter<'a, K, V> {}

+impl<'a, K: 'a + Key, V> FusedIterator for IterMut<'a, K, V> {}

+impl<'a, K: 'a + Key, V> FusedIterator for Keys<'a, K, V> {}

+impl<'a, K: 'a + Key, V> FusedIterator for Values<'a, K, V> {}

+impl<'a, K: 'a + Key, V> FusedIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: 'a + Key, V> FusedIterator for Drain<'a, K, V> {}

+impl<K: Key, V> FusedIterator for IntoIter<K, V> {}

+

+impl<'a, K: 'a + Key, V> ExactSizeIterator for Iter<'a, K, V> {}

+impl<'a, K: 'a + Key, V> ExactSizeIterator for IterMut<'a, K, V> {}

+impl<'a, K: 'a + Key, V> ExactSizeIterator for Keys<'a, K, V> {}

+impl<'a, K: 'a + Key, V> ExactSizeIterator for Values<'a, K, V> {}

+impl<'a, K: 'a + Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: 'a + Key, V> ExactSizeIterator for Drain<'a, K, V> {}

+impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}

+

+// Serialization with serde.

+#[cfg(feature = "serde")]

+mod serialize {

+    use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

+

+    use super::*;

+

+    #[derive(Serialize, Deserialize)]

+    struct SerdeSlot<T> {

+        value: Option<T>,

+        version: u32,

+    }

+

+    impl<K: Key, V: Serialize> Serialize for DenseSlotMap<K, V> {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            let serde_slots: Vec<_> = self

+                .slots

+                .iter()

+                .map(|slot| SerdeSlot {

+                    value: if slot.version % 2 == 1 {

+                        self.values.get(slot.idx_or_free as usize)

+                    } else {

+                        None

+                    },

+                    version: slot.version,

+                })

+                .collect();

+            serde_slots.serialize(serializer)

+        }

+    }

+

+    impl<'de, K: Key, V: Deserialize<'de>> Deserialize<'de> for DenseSlotMap<K, V> {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let serde_slots: Vec<SerdeSlot<V>> = Deserialize::deserialize(deserializer)?;

+            if serde_slots.len() >= u32::max_value() as usize {

+                return Err(de::Error::custom(&"too many slots"));

+            }

+

+            // Ensure the first slot exists and is empty for the sentinel.

+            if serde_slots.get(0).map_or(true, |slot| slot.version % 2 == 1) {

+                return Err(de::Error::custom(&"first slot not empty"));

+            }

+

+            // Rebuild slots, key and values.

+            let mut keys = Vec::new();

+            let mut values = Vec::new();

+            let mut slots = Vec::new();

+            slots.push(Slot {

+                idx_or_free: 0,

+                version: 0,

+            });

+

+            let mut next_free = serde_slots.len();

+            for (i, serde_slot) in serde_slots.into_iter().enumerate().skip(1) {

+                let occupied = serde_slot.version % 2 == 1;

+                if occupied ^ serde_slot.value.is_some() {

+                    return Err(de::Error::custom(&"inconsistent occupation in Slot"));

+                }

+

+                if let Some(value) = serde_slot.value {

+                    let kd = KeyData::new(i as u32, serde_slot.version);

+                    keys.push(kd.into());

+                    values.push(value);

+                    slots.push(Slot {

+                        version: serde_slot.version,

+                        idx_or_free: (keys.len() - 1) as u32,

+                    });

+                } else {

+                    slots.push(Slot {

+                        version: serde_slot.version,

+                        idx_or_free: next_free as u32,

+                    });

+                    next_free = i;

+                }

+            }

+

+            Ok(DenseSlotMap {

+                keys,

+                values,

+                slots,

+                free_head: next_free as u32,

+            })

+        }

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use std::collections::{HashMap, HashSet};

+

+    use quickcheck::quickcheck;

+

+    use super::*;

+

+    #[derive(Clone)]

+    struct CountDrop<'a>(&'a core::cell::RefCell<usize>);

+

+    impl<'a> Drop for CountDrop<'a> {

+        fn drop(&mut self) {

+            *self.0.borrow_mut() += 1;

+        }

+    }

+

+    #[test]

+    fn check_drops() {

+        let drops = core::cell::RefCell::new(0usize);

+

+        {

+            let mut clone = {

+                // Insert 1000 items.

+                let mut sm = DenseSlotMap::new();

+                let mut sm_keys = Vec::new();

+                for _ in 0..1000 {

+                    sm_keys.push(sm.insert(CountDrop(&drops)));

+                }

+

+                // Remove even keys.

+                for i in (0..1000).filter(|i| i % 2 == 0) {

+                    sm.remove(sm_keys[i]);

+                }

+

+                // Should only have dropped 500 so far.

+                assert_eq!(*drops.borrow(), 500);

+

+                // Let's clone ourselves and then die.

+                sm.clone()

+            };

+

+            // Now all original items should have been dropped exactly once.

+            assert_eq!(*drops.borrow(), 1000);

+

+            // Re-use some empty slots.

+            for _ in 0..250 {

+                clone.insert(CountDrop(&drops));

+            }

+        }

+

+        // 1000 + 750 drops in total should have happened.

+        assert_eq!(*drops.borrow(), 1750);

+    }

+

+    #[cfg(all(nightly, feature = "unstable"))]

+    #[test]

+    fn disjoint() {

+        // Intended to be run with miri to find any potential UB.

+        let mut sm = DenseSlotMap::new();

+

+        // Some churn.

+        for i in 0..20usize {

+            sm.insert(i);

+        }

+        sm.retain(|_, i| *i % 2 == 0);

+

+        let keys: Vec<_> = sm.keys().collect();

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                if let Some([r0, r1]) = sm.get_disjoint_mut([keys[i], keys[j]]) {

+                    *r0 ^= *r1;

+                    *r1 = r1.wrapping_add(*r0);

+                } else {

+                    assert!(i == j);

+                }

+            }

+        }

+

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                for k in 0..keys.len() {

+                    if let Some([r0, r1, r2]) = sm.get_disjoint_mut([keys[i], keys[j], keys[k]]) {

+                        *r0 ^= *r1;

+                        *r0 = r0.wrapping_add(*r2);

+                        *r1 ^= *r0;

+                        *r1 = r1.wrapping_add(*r2);

+                        *r2 ^= *r0;

+                        *r2 = r2.wrapping_add(*r1);

+                    } else {

+                        assert!(i == j || j == k || i == k);

+                    }

+                }

+            }

+        }

+    }

+

+    quickcheck! {

+        fn qc_slotmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {

+            let mut hm = HashMap::new();

+            let mut hm_keys = Vec::new();

+            let mut unique_key = 0u32;

+            let mut sm = DenseSlotMap::new();

+            let mut sm_keys = Vec::new();

+

+            #[cfg(not(feature = "serde"))]

+            let num_ops = 3;

+            #[cfg(feature = "serde")]

+            let num_ops = 4;

+

+            for (op, val) in operations {

+                match op % num_ops {

+                    // Insert.

+                    0 => {

+                        hm.insert(unique_key, val);

+                        hm_keys.push(unique_key);

+                        unique_key += 1;

+

+                        sm_keys.push(sm.insert(val));

+                    }

+

+                    // Delete.

+                    1 => {

+                        // 10% of the time test clear.

+                        if val % 10 == 0 {

+                            let hmvals: HashSet<_> = hm.drain().map(|(_, v)| v).collect();

+                            let smvals: HashSet<_> = sm.drain().map(|(_, v)| v).collect();

+                            if hmvals != smvals {

+                                return false;

+                            }

+                        }

+                        if hm_keys.is_empty() { continue; }

+

+                        let idx = val as usize % hm_keys.len();

+                        if hm.remove(&hm_keys[idx]) != sm.remove(sm_keys[idx]) {

+                            return false;

+                        }

+                    }

+

+                    // Access.

+                    2 => {

+                        if hm_keys.is_empty() { continue; }

+                        let idx = val as usize % hm_keys.len();

+                        let (hm_key, sm_key) = (&hm_keys[idx], sm_keys[idx]);

+

+                        if hm.contains_key(hm_key) != sm.contains_key(sm_key) ||

+                           hm.get(hm_key) != sm.get(sm_key) {

+                            return false;

+                        }

+                    }

+

+                    // Serde round-trip.

+                    #[cfg(feature = "serde")]

+                    3 => {

+                        let ser = serde_json::to_string(&sm).unwrap();

+                        sm = serde_json::from_str(&ser).unwrap();

+                    }

+

+                    _ => unreachable!(),

+                }

+            }

+

+            let mut smv: Vec<_> = sm.values().collect();

+            let mut hmv: Vec<_> = hm.values().collect();

+            smv.sort();

+            hmv.sort();

+            smv == hmv

+        }

+    }

+

+    #[cfg(feature = "serde")]

+    #[test]

+    fn slotmap_serde() {

+        let mut sm = DenseSlotMap::new();

+        // Self-referential structure.

+        let first = sm.insert_with_key(|k| (k, 23i32));

+        let second = sm.insert((first, 42));

+

+        // Make some empty slots.

+        let empties = vec![sm.insert((first, 0)), sm.insert((first, 0))];

+        empties.iter().for_each(|k| {

+            sm.remove(*k);

+        });

+

+        let third = sm.insert((second, 0));

+        sm[first].0 = third;

+

+        let ser = serde_json::to_string(&sm).unwrap();

+        let de: DenseSlotMap<DefaultKey, (DefaultKey, i32)> = serde_json::from_str(&ser).unwrap();

+        assert_eq!(de.len(), sm.len());

+

+        let mut smkv: Vec<_> = sm.iter().collect();

+        let mut dekv: Vec<_> = de.iter().collect();

+        smkv.sort();

+        dekv.sort();

+        assert_eq!(smkv, dekv);

+    }

+

+    #[cfg(feature = "serde")]

+    #[test]

+    fn slotmap_serde_freelist() {

+        let mut sm = DenseSlotMap::new();

+        let k0 = sm.insert(5i32);

+        let k1 = sm.insert(5i32);

+        sm.remove(k0);

+        sm.remove(k1);

+

+        let ser = serde_json::to_string(&sm).unwrap();

+        let mut de: DenseSlotMap<DefaultKey, i32> = serde_json::from_str(&ser).unwrap();

+

+        de.insert(0);

+        de.insert(1);

+        de.insert(2);

+        assert_eq!(de.len(), 3);

+    }

+}

diff --git a/crates/slotmap/src/hop.rs b/crates/slotmap/src/hop.rs
new file mode 100644
index 0000000..d5cf8b3
--- /dev/null
+++ b/crates/slotmap/src/hop.rs
@@ -0,0 +1,1684 @@
+// Needed because assigning to non-Copy union is unsafe in stable but not in nightly.

+#![allow(unused_unsafe)]

+

+//! Contains the faster iteration, slower insertion/removal slot map

+//! implementation.

+//!

+//! This data structure is essentially the same as a regular [`SlotMap`], but

+//! maintains extra information when inserting/removing elements that allows it

+//! to 'hop over' vacant slots during iteration, making it potentially much

+//! faster for iteration.

+//!

+//! The trade-off is that compared to a regular [`SlotMap`] insertion/removal is

+//! roughly twice as slow. Random indexing has identical performance for both.

+//!

+//! [`SlotMap`]: crate::SlotMap

+

+#[cfg(all(nightly, any(doc, feature = "unstable")))]

+use alloc::collections::TryReserveError;

+use alloc::vec::Vec;

+use core::fmt;

+use core::iter::FusedIterator;

+use core::marker::PhantomData;

+use core::mem::ManuallyDrop;

+#[allow(unused_imports)] // MaybeUninit is only used on nightly at the moment.

+use core::mem::MaybeUninit;

+use core::ops::{Index, IndexMut};

+

+use crate::util::{Never, UnwrapUnchecked};

+use crate::{DefaultKey, Key, KeyData};

+

+// Metadata to maintain the freelist.

+#[derive(Clone, Copy, Debug)]

+struct FreeListEntry {

+    next: u32,

+    prev: u32,

+    other_end: u32,

+}

+

+// Storage inside a slot or metadata for the freelist when vacant.

+union SlotUnion<T> {

+    value: ManuallyDrop<T>,

+    free: FreeListEntry,

+}

+

+// A slot, which represents storage for a value and a current version.

+// Can be occupied or vacant.

+struct Slot<T> {

+    u: SlotUnion<T>,

+    version: u32, // Even = vacant, odd = occupied.

+}

+

+// Safe API to read a slot.

+enum SlotContent<'a, T: 'a> {

+    Occupied(&'a T),

+    Vacant(&'a FreeListEntry),

+}

+

+enum SlotContentMut<'a, T: 'a> {

+    OccupiedMut(&'a mut T),

+    VacantMut(&'a mut FreeListEntry),

+}

+

+use self::SlotContent::{Occupied, Vacant};

+use self::SlotContentMut::{OccupiedMut, VacantMut};

+

+impl<T> Slot<T> {

+    // Is this slot occupied?

+    #[inline(always)]

+    pub fn occupied(&self) -> bool {

+        self.version % 2 == 1

+    }

+

+    pub fn get(&self) -> SlotContent<T> {

+        unsafe {

+            if self.occupied() {

+                Occupied(&*self.u.value)

+            } else {

+                Vacant(&self.u.free)

+            }

+        }

+    }

+

+    pub fn get_mut(&mut self) -> SlotContentMut<T> {

+        unsafe {

+            if self.occupied() {

+                OccupiedMut(&mut *self.u.value)

+            } else {

+                VacantMut(&mut self.u.free)

+            }

+        }

+    }

+}

+

+impl<T> Drop for Slot<T> {

+    fn drop(&mut self) {

+        if core::mem::needs_drop::<T>() && self.occupied() {

+            // This is safe because we checked that we're occupied.

+            unsafe {

+                ManuallyDrop::drop(&mut self.u.value);

+            }

+        }

+    }

+}

+

+impl<T: Clone> Clone for Slot<T> {

+    fn clone(&self) -> Self {

+        Self {

+            u: match self.get() {

+                Occupied(value) => SlotUnion {

+                    value: ManuallyDrop::new(value.clone()),

+                },

+                Vacant(&free) => SlotUnion { free },

+            },

+            version: self.version,

+        }

+    }

+

+    fn clone_from(&mut self, source: &Self) {

+        match (self.get_mut(), source.get()) {

+            (OccupiedMut(self_val), Occupied(source_val)) => self_val.clone_from(source_val),

+            (VacantMut(self_free), Vacant(&source_free)) => *self_free = source_free,

+            (_, Occupied(value)) => {

+                self.u = SlotUnion {

+                    value: ManuallyDrop::new(value.clone()),

+                }

+            },

+            (_, Vacant(&free)) => self.u = SlotUnion { free },

+        }

+        self.version = source.version;

+    }

+}

+

+impl<T: fmt::Debug> fmt::Debug for Slot<T> {

+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {

+        let mut builder = fmt.debug_struct("Slot");

+        builder.field("version", &self.version);

+        match self.get() {

+            Occupied(value) => builder.field("value", value).finish(),

+            Vacant(free) => builder.field("free", free).finish(),

+        }

+    }

+}

+

+/// Hop slot map, storage with stable unique keys.

+///

+/// See [crate documentation](crate) for more details.

+#[derive(Debug)]

+pub struct HopSlotMap<K: Key, V> {

+    slots: Vec<Slot<V>>,

+    num_elems: u32,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<V> HopSlotMap<DefaultKey, V> {

+    /// Constructs a new, empty [`HopSlotMap`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: HopSlotMap<_, i32> = HopSlotMap::new();

+    /// ```

+    pub fn new() -> Self {

+        Self::with_capacity_and_key(0)

+    }

+

+    /// Creates an empty [`HopSlotMap`] with the given capacity.

+    ///

+    /// The slot map will not reallocate until it holds at least `capacity`

+    /// elements.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: HopSlotMap<_, i32> = HopSlotMap::with_capacity(10);

+    /// ```

+    pub fn with_capacity(capacity: usize) -> Self {

+        Self::with_capacity_and_key(capacity)

+    }

+}

+

+impl<K: Key, V> HopSlotMap<K, V> {

+    /// Constructs a new, empty [`HopSlotMap`] with a custom key type.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! {

+    ///     struct PositionKey;

+    /// }

+    /// let mut positions: HopSlotMap<PositionKey, i32> = HopSlotMap::with_key();

+    /// ```

+    pub fn with_key() -> Self {

+        Self::with_capacity_and_key(0)

+    }

+

+    /// Creates an empty [`HopSlotMap`] with the given capacity and a custom key

+    /// type.

+    ///

+    /// The slot map will not reallocate until it holds at least `capacity`

+    /// elements.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! {

+    ///     struct MessageKey;

+    /// }

+    /// let mut messages = HopSlotMap::with_capacity_and_key(3);

+    /// let welcome: MessageKey = messages.insert("Welcome");

+    /// let good_day = messages.insert("Good day");

+    /// let hello = messages.insert("Hello");

+    /// ```

+    pub fn with_capacity_and_key(capacity: usize) -> Self {

+        // Create slots with sentinel at index 0.

+        let mut slots = Vec::with_capacity(capacity + 1);

+        slots.push(Slot {

+            u: SlotUnion {

+                free: FreeListEntry {

+                    next: 0,

+                    prev: 0,

+                    other_end: 0,

+                },

+            },

+            version: 0,

+        });

+

+        Self {

+            slots,

+            num_elems: 0,

+            _k: PhantomData,

+        }

+    }

+

+    /// Returns the number of elements in the slot map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::with_capacity(10);

+    /// sm.insert("len() counts actual elements, not capacity");

+    /// let key = sm.insert("removed elements don't count either");

+    /// sm.remove(key);

+    /// assert_eq!(sm.len(), 1);

+    /// ```

+    pub fn len(&self) -> usize {

+        self.num_elems as usize

+    }

+

+    /// Returns if the slot map is empty.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert("dummy");

+    /// assert_eq!(sm.is_empty(), false);

+    /// sm.remove(key);

+    /// assert_eq!(sm.is_empty(), true);

+    /// ```

+    pub fn is_empty(&self) -> bool {

+        self.num_elems == 0

+    }

+

+    /// Returns the number of elements the [`HopSlotMap`] can hold without

+    /// reallocating.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let sm: HopSlotMap<_, f64> = HopSlotMap::with_capacity(10);

+    /// assert_eq!(sm.capacity(), 10);

+    /// ```

+    pub fn capacity(&self) -> usize {

+        // One slot is reserved for the freelist sentinel.

+        self.slots.capacity() - 1

+    }

+

+    /// Reserves capacity for at least `additional` more elements to be inserted

+    /// in the [`HopSlotMap`]. The collection may reserve more space to

+    /// avoid frequent reallocations.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the new allocation size overflows [`usize`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// sm.insert("foo");

+    /// sm.reserve(32);

+    /// assert!(sm.capacity() >= 33);

+    /// ```

+    pub fn reserve(&mut self, additional: usize) {

+        // One slot is reserved for the freelist sentinel.

+        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);

+        self.slots.reserve(needed);

+    }

+

+    /// Tries to reserve capacity for at least `additional` more elements to be

+    /// inserted in the [`HopSlotMap`]. The collection may reserve more space to

+    /// avoid frequent reallocations.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// sm.insert("foo");

+    /// sm.try_reserve(32).unwrap();

+    /// assert!(sm.capacity() >= 33);

+    /// ```

+    #[cfg(all(nightly, any(doc, feature = "unstable")))]

+    #[cfg_attr(all(nightly, doc), doc(cfg(feature = "unstable")))]

+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {

+        // One slot is reserved for the freelist sentinel.

+        let needed = (self.len() + additional).saturating_sub(self.slots.len() - 1);

+        self.slots.try_reserve(needed)

+    }

+

+    /// Returns [`true`] if the slot map contains `key`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm.contains_key(key), true);

+    /// sm.remove(key);

+    /// assert_eq!(sm.contains_key(key), false);

+    /// ```

+    pub fn contains_key(&self, key: K) -> bool {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .map_or(false, |slot| slot.version == kd.version.get())

+    }

+

+    /// Inserts a value into the slot map. Returns a unique key that can be

+    /// used to access this value.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm[key], 42);

+    /// ```

+    #[inline(always)]

+    pub fn insert(&mut self, value: V) -> K {

+        unsafe { self.try_insert_with_key::<_, Never>(move |_| Ok(value)).unwrap_unchecked_() }

+    }

+

+    // Helper function to make using the freelist painless.

+    // For that same ergonomy it uses u32, not usize as index.

+    // Safe iff idx is a valid index and the slot at that index is vacant.

+    unsafe fn freelist(&mut self, idx: u32) -> &mut FreeListEntry {

+        &mut self.slots.get_unchecked_mut(idx as usize).u.free

+    }

+

+    /// Inserts a value given by `f` into the slot map. The key where the

+    /// value will be stored is passed into `f`. This is useful to store values

+    /// that contain their own key.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert_with_key(|k| (k, 20));

+    /// assert_eq!(sm[key], (key, 20));

+    /// ```

+    #[inline(always)]

+    pub fn insert_with_key<F>(&mut self, f: F) -> K

+    where

+        F: FnOnce(K) -> V,

+    {

+        unsafe { self.try_insert_with_key::<_, Never>(move |k| Ok(f(k))).unwrap_unchecked_() }

+    }

+

+    /// Inserts a value given by `f` into the slot map. The key where the

+    /// value will be stored is passed into `f`. This is useful to store values

+    /// that contain their own key.

+    ///

+    /// If `f` returns `Err`, this method returns the error. The slotmap is untouched.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the number of elements in the slot map equals

+    /// 2<sup>32</sup> - 2.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.try_insert_with_key::<_, ()>(|k| Ok((k, 20))).unwrap();

+    /// assert_eq!(sm[key], (key, 20));

+    ///

+    /// sm.try_insert_with_key::<_, ()>(|k| Err(())).unwrap_err();

+    /// ```

+    pub fn try_insert_with_key<F, E>(&mut self, f: F) -> Result<K, E>

+    where

+        F: FnOnce(K) -> Result<V, E>,

+    {

+        // In case f panics, we don't make any changes until we have the value.

+        let new_num_elems = self.num_elems + 1;

+        if new_num_elems == core::u32::MAX {

+            panic!("HopSlotMap number of elements overflow");

+        }

+

+        // All unsafe accesses here are safe due to the invariants of the slot

+        // map freelist.

+        unsafe {

+            let head = self.freelist(0).next;

+

+            // We have a contiguous block of vacant slots starting at head.

+            // Put our new element at the back slot.

+            let front = head;

+            let back = self.freelist(front).other_end;

+            let slot_idx = back as usize;

+

+            // Freelist is empty.

+            if slot_idx == 0 {

+                let version = 1;

+                let key = KeyData::new(self.slots.len() as u32, version).into();

+

+                self.slots.push(Slot {

+                    u: SlotUnion {

+                        value: ManuallyDrop::new(f(key)?),

+                    },

+                    version,

+                });

+                self.num_elems = new_num_elems;

+                return Ok(key);

+            }

+

+            // Compute value first in case f panics or returns an error.

+            let occupied_version = self.slots[slot_idx].version | 1;

+            let key = KeyData::new(slot_idx as u32, occupied_version).into();

+            let value = f(key)?;

+

+            // Update freelist.

+            if front == back {

+                // Used last slot in this block, move next one to head.

+                let new_head = self.freelist(front).next;

+                self.freelist(0).next = new_head;

+                self.freelist(new_head).prev = 0;

+            } else {

+                // Continue using this block, only need to update other_ends.

+                let new_back = back - 1;

+                self.freelist(new_back).other_end = front;

+                self.freelist(front).other_end = new_back;

+            }

+

+            // And finally insert the value.

+            let slot = &mut self.slots[slot_idx];

+            slot.version = occupied_version;

+            slot.u.value = ManuallyDrop::new(value);

+            self.num_elems = new_num_elems;

+            Ok(key)

+        }

+    }

+

+    // Helper function to remove a value from a slot. Safe iff the slot is

+    // occupied. Returns the value removed.

+    #[inline(always)]

+    unsafe fn remove_from_slot(&mut self, idx: usize) -> V {

+        // Remove value from slot.

+        let slot = self.slots.get_unchecked_mut(idx);

+        slot.version = slot.version.wrapping_add(1);

+        let value = ManuallyDrop::take(&mut slot.u.value);

+

+        // This is safe and can't underflow because of the sentinel element at

+        // the start.

+        let left_vacant = !self.slots.get_unchecked(idx - 1).occupied();

+        let right_vacant = self.slots.get(idx + 1).map_or(false, |s| !s.occupied());

+

+        // Maintain freelist by either appending/prepending this slot to a

+        // contiguous block to the left or right, merging the two blocks to the

+        // left and right or inserting a new block.

+        let i = idx as u32;

+        match (left_vacant, right_vacant) {

+            (false, false) => {

+                // New block, insert it at the tail.

+                let old_tail = self.freelist(0).prev;

+                self.freelist(0).prev = i;

+                self.freelist(old_tail).next = i;

+                *self.freelist(i) = FreeListEntry {

+                    other_end: i,

+                    next: 0,

+                    prev: old_tail,

+                };

+            },

+

+            (false, true) => {

+                // Prepend to vacant block on right.

+                let front_data = *self.freelist(i + 1);

+

+                // Since the start of this block moved we must update the pointers to it.

+                self.freelist(front_data.other_end).other_end = i;

+                self.freelist(front_data.prev).next = i;

+                self.freelist(front_data.next).prev = i;

+                *self.freelist(i) = front_data;

+            },

+

+            (true, false) => {

+                // Append to vacant block on left.

+                let front = self.freelist(i - 1).other_end;

+                self.freelist(i).other_end = front;

+                self.freelist(front).other_end = i;

+            },

+

+            (true, true) => {

+                // We must merge left and right.

+                // First snip right out of the freelist.

+                let right = *self.freelist(i + 1);

+                self.freelist(right.prev).next = right.next;

+                self.freelist(right.next).prev = right.prev;

+

+                // Now update endpoints.

+                let front = self.freelist(i - 1).other_end;

+                let back = right.other_end;

+                self.freelist(front).other_end = back;

+                self.freelist(back).other_end = front;

+            },

+        }

+

+        self.num_elems -= 1;

+

+        value

+    }

+

+    /// Removes a key from the slot map, returning the value at the key if the

+    /// key was not previously removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert(42);

+    /// assert_eq!(sm.remove(key), Some(42));

+    /// assert_eq!(sm.remove(key), None);

+    /// ```

+    pub fn remove(&mut self, key: K) -> Option<V> {

+        let kd = key.data();

+        if self.contains_key(key) {

+            // This is safe because we know that the slot is occupied.

+            Some(unsafe { self.remove_from_slot(kd.idx as usize) })

+        } else {

+            None

+        }

+    }

+

+    /// Retains only the elements specified by the predicate.

+    ///

+    /// In other words, remove all key-value pairs `(k, v)` such that

+    /// `f(k, &mut v)` returns false. This method invalidates any removed keys.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    ///

+    /// let k1 = sm.insert(0);

+    /// let k2 = sm.insert(1);

+    /// let k3 = sm.insert(2);

+    ///

+    /// sm.retain(|key, val| key == k1 || *val == 1);

+    ///

+    /// assert!(sm.contains_key(k1));

+    /// assert!(sm.contains_key(k2));

+    /// assert!(!sm.contains_key(k3));

+    ///

+    /// assert_eq!(2, sm.len());

+    /// ```

+    pub fn retain<F>(&mut self, mut f: F)

+    where

+        F: FnMut(K, &mut V) -> bool,

+    {

+        let mut elems_left_to_scan = self.len();

+        let mut cur = unsafe { self.slots.get_unchecked(0).u.free.other_end as usize + 1 };

+        while elems_left_to_scan > 0 {

+            // This is safe because removing elements does not shrink slots, cur always

+            // points to an occupied slot.

+            let idx = cur;

+            let slot = unsafe { self.slots.get_unchecked_mut(cur) };

+            let version = slot.version;

+            let key = KeyData::new(cur as u32, version).into();

+            let should_remove = !f(key, unsafe { &mut *slot.u.value });

+

+            cur = match self.slots.get(cur + 1).map(|s| s.get()) {

+                Some(Occupied(_)) => cur + 1,

+                Some(Vacant(free)) => free.other_end as usize + 1,

+                None => 0,

+            };

+

+            if should_remove {

+                // This must happen after getting the next index.

+                unsafe { self.remove_from_slot(idx) };

+            }

+

+            elems_left_to_scan -= 1;

+        }

+    }

+

+    /// Clears the slot map. Keeps the allocated memory for reuse.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// for i in 0..10 {

+    ///     sm.insert(i);

+    /// }

+    /// assert_eq!(sm.len(), 10);

+    /// sm.clear();

+    /// assert_eq!(sm.len(), 0);

+    /// ```

+    pub fn clear(&mut self) {

+        self.drain();

+    }

+

+    /// Clears the slot map, returning all key-value pairs in arbitrary order as

+    /// an iterator. Keeps the allocated memory for reuse.

+    ///

+    /// When the iterator is dropped all elements in the slot map are removed,

+    /// even if the iterator was not fully consumed. If the iterator is not

+    /// dropped (using e.g. [`std::mem::forget`]), only the elements that were

+    /// iterated over are removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let k = sm.insert(0);

+    /// let v: Vec<_> = sm.drain().collect();

+    /// assert_eq!(sm.len(), 0);

+    /// assert_eq!(v, vec![(k, 0)]);

+    /// ```

+    pub fn drain(&mut self) -> Drain<K, V> {

+        Drain {

+            cur: unsafe { self.slots.get_unchecked(0).u.free.other_end as usize + 1 },

+            sm: self,

+        }

+    }

+

+    /// Returns a reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert("bar");

+    /// assert_eq!(sm.get(key), Some(&"bar"));

+    /// sm.remove(key);

+    /// assert_eq!(sm.get(key), None);

+    /// ```

+    pub fn get(&self, key: K) -> Option<&V> {

+        let kd = key.data();

+        // This is safe because we check version first and a key always contains

+        // an odd version, thus we are occupied.

+        self.slots

+            .get(kd.idx as usize)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| unsafe { &*slot.u.value })

+    }

+

+    /// Returns a reference to the value corresponding to the key without

+    /// version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// dangerous undefined behavior.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert("bar");

+    /// assert_eq!(unsafe { sm.get_unchecked(key) }, &"bar");

+    /// sm.remove(key);

+    /// // sm.get_unchecked(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked(&self, key: K) -> &V {

+        debug_assert!(self.contains_key(key));

+        &self.slots.get_unchecked(key.data().idx as usize).u.value

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert(3.5);

+    /// if let Some(x) = sm.get_mut(key) {

+    ///     *x += 3.0;

+    /// }

+    /// assert_eq!(sm[key], 6.5);

+    /// ```

+    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {

+        let kd = key.data();

+        // This is safe because we check version first and a key always contains

+        // an odd version, thus we are occupied.

+        self.slots

+            .get_mut(kd.idx as usize)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| unsafe { &mut *slot.u.value })

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key

+    /// without version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// dangerous undefined behavior.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let key = sm.insert("foo");

+    /// unsafe { *sm.get_unchecked_mut(key) = "bar" };

+    /// assert_eq!(sm[key], "bar");

+    /// sm.remove(key);

+    /// // sm.get_unchecked_mut(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {

+        debug_assert!(self.contains_key(key));

+        &mut self.slots.get_unchecked_mut(key.data().idx as usize).u.value

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint, otherwise [`None`] is

+    /// returned.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let ka = sm.insert("butter");

+    /// let kb = sm.insert("apples");

+    /// let kc = sm.insert("charlie");

+    /// sm.remove(kc); // Make key c invalid.

+    /// assert_eq!(sm.get_disjoint_mut([ka, kb, kc]), None); // Has invalid key.

+    /// assert_eq!(sm.get_disjoint_mut([ka, ka]), None); // Not disjoint.

+    /// let [a, b] = sm.get_disjoint_mut([ka, kb]).unwrap();

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sm[ka], "apples");

+    /// assert_eq!(sm[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {

+        // Create an uninitialized array of `MaybeUninit`. The `assume_init` is

+        // safe because the type we are claiming to have initialized here is a

+        // bunch of `MaybeUninit`s, which do not require initialization.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = unsafe { MaybeUninit::uninit().assume_init() };

+

+        let mut i = 0;

+        while i < N {

+            // We can avoid this clone after min_const_generics and array_map.

+            let kd = keys[i].data();

+            if !self.contains_key(kd.into()) {

+                break;

+            }

+

+            // This key is valid, and thus the slot is occupied. Temporarily

+            // mark it as unoccupied so duplicate keys would show up as invalid.

+            // This gives us a linear time disjointness check.

+            unsafe {

+                let slot = self.slots.get_unchecked_mut(kd.idx as usize);

+                slot.version ^= 1;

+                ptrs[i] = MaybeUninit::new(&mut *slot.u.value);

+            }

+            i += 1;

+        }

+

+        // Undo temporary unoccupied markings.

+        for k in &keys[..i] {

+            let idx = k.data().idx as usize;

+            unsafe {

+                self.slots.get_unchecked_mut(idx).version ^= 1;

+            }

+        }

+

+        if i == N {

+            // All were valid and disjoint.

+            Some(unsafe { core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs) })

+        } else {

+            None

+        }

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true for every given

+    /// key and no two keys are equal. Otherwise it is potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let ka = sm.insert("butter");

+    /// let kb = sm.insert("apples");

+    /// let [a, b] = unsafe { sm.get_disjoint_unchecked_mut([ka, kb]) };

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sm[ka], "apples");

+    /// assert_eq!(sm[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(

+        &mut self,

+        keys: [K; N],

+    ) -> [&mut V; N] {

+        // Safe, see get_disjoint_mut.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = MaybeUninit::uninit().assume_init();

+        for i in 0..N {

+            ptrs[i] = MaybeUninit::new(self.get_unchecked_mut(keys[i]));

+        }

+        core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs)

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order. The

+    /// iterator element type is `(K, &'a V)`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let k0 = sm.insert(0);

+    /// let k1 = sm.insert(1);

+    /// let k2 = sm.insert(2);

+    ///

+    /// for (k, v) in sm.iter() {

+    ///     println!("key: {:?}, val: {}", k, v);

+    /// }

+    /// ```

+    pub fn iter(&self) -> Iter<K, V> {

+        Iter {

+            cur: unsafe { self.slots.get_unchecked(0).u.free.other_end as usize + 1 },

+            num_left: self.len(),

+            slots: &self.slots[..],

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order, with

+    /// mutable references to the values. The iterator element type is

+    /// `(K, &'a mut V)`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = HopSlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    ///

+    /// for (k, v) in sm.iter_mut() {

+    ///     if k != k1 {

+    ///         *v *= -1;

+    ///     }

+    /// }

+    ///

+    /// assert_eq!(sm[k0], -10);

+    /// assert_eq!(sm[k1], 20);

+    /// assert_eq!(sm[k2], -30);

+    /// ```

+    pub fn iter_mut(&mut self) -> IterMut<K, V> {

+        IterMut {

+            cur: 0,

+            num_left: self.len(),

+            slots: &mut self.slots[..],

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all keys in arbitrary order. The iterator element

+    /// type is `K`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = HopSlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    /// let keys: HashSet<_> = sm.keys().collect();

+    /// let check: HashSet<_> = vec![k0, k1, k2].into_iter().collect();

+    /// assert_eq!(keys, check);

+    /// ```

+    pub fn keys(&self) -> Keys<K, V> {

+        Keys { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values in arbitrary order. The iterator element

+    /// type is `&'a V`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = HopSlotMap::new();

+    /// let k0 = sm.insert(10);

+    /// let k1 = sm.insert(20);

+    /// let k2 = sm.insert(30);

+    /// let values: HashSet<_> = sm.values().collect();

+    /// let check: HashSet<_> = vec![&10, &20, &30].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values(&self) -> Values<K, V> {

+        Values { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values mutably in arbitrary order. The iterator

+    /// element type is `&'a mut V`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = HopSlotMap::new();

+    /// sm.insert(1);

+    /// sm.insert(2);

+    /// sm.insert(3);

+    /// sm.values_mut().for_each(|n| { *n *= 3 });

+    /// let values: HashSet<_> = sm.into_iter().map(|(_k, v)| v).collect();

+    /// let check: HashSet<_> = vec![3, 6, 9].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values_mut(&mut self) -> ValuesMut<K, V> {

+        ValuesMut {

+            inner: self.iter_mut(),

+        }

+    }

+}

+

+impl<K: Key, V> Clone for HopSlotMap<K, V>

+where

+    V: Clone,

+{

+    fn clone(&self) -> Self {

+        Self {

+            slots: self.slots.clone(),

+            ..*self

+        }

+    }

+

+    fn clone_from(&mut self, source: &Self) {

+        self.slots.clone_from(&source.slots);

+        self.num_elems = source.num_elems;

+    }

+}

+

+impl<K: Key, V> Default for HopSlotMap<K, V> {

+    fn default() -> Self {

+        Self::with_key()

+    }

+}

+

+impl<K: Key, V> Index<K> for HopSlotMap<K, V> {

+    type Output = V;

+

+    fn index(&self, key: K) -> &V {

+        match self.get(key) {

+            Some(r) => r,

+            None => panic!("invalid HopSlotMap key used"),

+        }

+    }

+}

+

+impl<K: Key, V> IndexMut<K> for HopSlotMap<K, V> {

+    fn index_mut(&mut self, key: K) -> &mut V {

+        match self.get_mut(key) {

+            Some(r) => r,

+            None => panic!("invalid HopSlotMap key used"),

+        }

+    }

+}

+

+// Iterators.

+/// A draining iterator for [`HopSlotMap`].

+///

+/// This iterator is created by [`HopSlotMap::drain`].

+#[derive(Debug)]

+pub struct Drain<'a, K: Key + 'a, V: 'a> {

+    cur: usize,

+    sm: &'a mut HopSlotMap<K, V>,

+}

+

+/// An iterator that moves key-value pairs out of a [`HopSlotMap`].

+///

+/// This iterator is created by calling the `into_iter` method on [`HopSlotMap`],

+/// provided by the [`IntoIterator`] trait.

+#[derive(Debug, Clone)]

+pub struct IntoIter<K: Key, V> {

+    cur: usize,

+    num_left: usize,

+    slots: Vec<Slot<V>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the key-value pairs in a [`HopSlotMap`].

+///

+/// This iterator is created by [`HopSlotMap::iter`].

+#[derive(Debug)]

+pub struct Iter<'a, K: Key + 'a, V: 'a> {

+    cur: usize,

+    num_left: usize,

+    slots: &'a [Slot<V>],

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {

+    fn clone(&self) -> Self {

+        Iter {

+            cur: self.cur,

+            num_left: self.num_left,

+            slots: self.slots,

+            _k: self._k.clone(),

+        }

+    }

+}

+

+/// A mutable iterator over the key-value pairs in a [`HopSlotMap`].

+///

+/// This iterator is created by [`HopSlotMap::iter_mut`].

+#[derive(Debug)]

+pub struct IterMut<'a, K: Key + 'a, V: 'a> {

+    cur: usize,

+    num_left: usize,

+    slots: &'a mut [Slot<V>],

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the keys in a [`HopSlotMap`].

+///

+/// This iterator is created by [`HopSlotMap::keys`].

+#[derive(Debug)]

+pub struct Keys<'a, K: Key + 'a, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {

+    fn clone(&self) -> Self {

+        Keys {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// An iterator over the values in a [`HopSlotMap`].

+///

+/// This iterator is created by [`HopSlotMap::values`].

+#[derive(Debug)]

+pub struct Values<'a, K: Key + 'a, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {

+    fn clone(&self) -> Self {

+        Values {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// A mutable iterator over the values in a [`HopSlotMap`].

+///

+/// This iterator is created by [`HopSlotMap::values_mut`].

+#[derive(Debug)]

+pub struct ValuesMut<'a, K: Key + 'a, V: 'a> {

+    inner: IterMut<'a, K, V>,

+}

+

+impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        // All unchecked indices are safe due to the invariants of the freelist

+        // and that self.sm.len() guarantees there is another element.

+        if self.sm.len() == 0 {

+            return None;

+        }

+

+        // Skip ahead to next element. Must do this before removing.

+        let idx = self.cur;

+        self.cur = match self.sm.slots.get(idx + 1).map(|s| s.get()) {

+            Some(Occupied(_)) => idx + 1,

+            Some(Vacant(free)) => free.other_end as usize + 1,

+            None => 0,

+        };

+

+        let key = KeyData::new(idx as u32, unsafe { self.sm.slots.get_unchecked(idx).version });

+        Some((key.into(), unsafe { self.sm.remove_from_slot(idx) }))

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.sm.len(), Some(self.sm.len()))

+    }

+}

+

+impl<'a, K: Key, V> Drop for Drain<'a, K, V> {

+    fn drop(&mut self) {

+        self.for_each(|_drop| {});

+    }

+}

+

+impl<K: Key, V> Iterator for IntoIter<K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        if self.cur >= self.slots.len() {

+            return None;

+        }

+

+        let idx = match self.slots[self.cur].get() {

+            Occupied(_) => self.cur,

+            Vacant(free) => {

+                // Skip block of contiguous vacant slots.

+                let idx = free.other_end as usize + 1;

+                if idx >= self.slots.len() {

+                    return None;

+                }

+                idx

+            },

+        };

+

+        self.cur = idx + 1;

+        self.num_left -= 1;

+        let slot = &mut self.slots[idx];

+        let key = KeyData::new(idx as u32, slot.version).into();

+        slot.version = 0; // Prevent dropping after extracting the value.

+        Some((key, unsafe { ManuallyDrop::take(&mut slot.u.value) }))

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {

+    type Item = (K, &'a V);

+

+    fn next(&mut self) -> Option<(K, &'a V)> {

+        // All unchecked indices are safe due to the invariants of the freelist

+        // and that num_left guarantees there is another element.

+        if self.num_left == 0 {

+            return None;

+        }

+        self.num_left -= 1;

+

+        let idx = match unsafe { self.slots.get_unchecked(self.cur).get() } {

+            Occupied(_) => self.cur,

+            Vacant(free) => free.other_end as usize + 1,

+        };

+

+        self.cur = idx + 1;

+        let slot = unsafe { self.slots.get_unchecked(idx) };

+        let key = KeyData::new(idx as u32, slot.version).into();

+        Some((key, unsafe { &*slot.u.value }))

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {

+    type Item = (K, &'a mut V);

+

+    fn next(&mut self) -> Option<(K, &'a mut V)> {

+        if self.cur >= self.slots.len() {

+            return None;

+        }

+

+        let idx = match self.slots[self.cur].get() {

+            Occupied(_) => self.cur,

+            Vacant(free) => {

+                // Skip block of contiguous vacant slots.

+                let idx = free.other_end as usize + 1;

+                if idx >= self.slots.len() {

+                    return None;

+                }

+                idx

+            },

+        };

+

+        self.cur = idx + 1;

+        self.num_left -= 1;

+

+        // Unsafe necessary because Rust can't deduce that we won't

+        // return multiple references to the same value.

+        let slot = &mut self.slots[idx];

+        let version = slot.version;

+        let value_ref = unsafe {

+            let ptr: *mut V = &mut *slot.u.value;

+            &mut *ptr

+        };

+        Some((KeyData::new(idx as u32, version).into(), value_ref))

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Keys<'a, K, V> {

+    type Item = K;

+

+    fn next(&mut self) -> Option<K> {

+        self.inner.next().map(|(key, _)| key)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Values<'a, K, V> {

+    type Item = &'a V;

+

+    fn next(&mut self) -> Option<&'a V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for ValuesMut<'a, K, V> {

+    type Item = &'a mut V;

+

+    fn next(&mut self) -> Option<&'a mut V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> IntoIterator for &'a HopSlotMap<K, V> {

+    type Item = (K, &'a V);

+    type IntoIter = Iter<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter()

+    }

+}

+

+impl<'a, K: Key, V> IntoIterator for &'a mut HopSlotMap<K, V> {

+    type Item = (K, &'a mut V);

+    type IntoIter = IterMut<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter_mut()

+    }

+}

+

+impl<K: Key, V> IntoIterator for HopSlotMap<K, V> {

+    type Item = (K, V);

+    type IntoIter = IntoIter<K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        IntoIter {

+            cur: 0,

+            num_left: self.len(),

+            slots: self.slots,

+            _k: PhantomData,

+        }

+    }

+}

+

+impl<'a, K: Key, V> FusedIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Drain<'a, K, V> {}

+impl<K: Key, V> FusedIterator for IntoIter<K, V> {}

+

+impl<'a, K: Key, V> ExactSizeIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Drain<'a, K, V> {}

+impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}

+

+// Serialization with serde.

+#[cfg(feature = "serde")]

+mod serialize {

+    use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

+

+    use super::*;

+

+    #[derive(Serialize, Deserialize)]

+    struct SerdeSlot<T> {

+        value: Option<T>,

+        version: u32,

+    }

+

+    impl<T: Serialize> Serialize for Slot<T> {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            let serde_slot = SerdeSlot {

+                version: self.version,

+                value: match self.get() {

+                    Occupied(value) => Some(value),

+                    Vacant(_) => None,

+                },

+            };

+            serde_slot.serialize(serializer)

+        }

+    }

+

+    impl<'de, T> Deserialize<'de> for Slot<T>

+    where

+        T: Deserialize<'de>,

+    {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let serde_slot: SerdeSlot<T> = Deserialize::deserialize(deserializer)?;

+            let occupied = serde_slot.version % 2 == 1;

+            if occupied ^ serde_slot.value.is_some() {

+                return Err(de::Error::custom(&"inconsistent occupation in Slot"));

+            }

+

+            Ok(Self {

+                u: match serde_slot.value {

+                    Some(value) => SlotUnion {

+                        value: ManuallyDrop::new(value),

+                    },

+                    None => SlotUnion {

+                        free: FreeListEntry {

+                            next: 0,

+                            prev: 0,

+                            other_end: 0,

+                        },

+                    },

+                },

+                version: serde_slot.version,

+            })

+        }

+    }

+

+    impl<K: Key, V: Serialize> Serialize for HopSlotMap<K, V> {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            self.slots.serialize(serializer)

+        }

+    }

+

+    impl<'de, K: Key, V: Deserialize<'de>> Deserialize<'de> for HopSlotMap<K, V> {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let mut slots: Vec<Slot<V>> = Deserialize::deserialize(deserializer)?;

+            if slots.len() >= u32::max_value() as usize {

+                return Err(de::Error::custom(&"too many slots"));

+            }

+

+            // Ensure the first slot exists and is empty for the sentinel.

+            if slots.get(0).map_or(true, |slot| slot.version % 2 == 1) {

+                return Err(de::Error::custom(&"first slot not empty"));

+            }

+

+            slots[0].u.free = FreeListEntry {

+                next: 0,

+                prev: 0,

+                other_end: 0,

+            };

+

+            // We have our slots, rebuild freelist.

+            let mut num_elems = 0;

+            let mut prev = 0;

+            let mut i = 0;

+            while i < slots.len() {

+                // i is the start of a contiguous block of vacant slots.

+                let front = i;

+                while i < slots.len() && !slots[i].occupied() {

+                    i += 1;

+                }

+                let back = i - 1;

+

+                // Update freelist.

+                unsafe {

+                    slots[back].u.free.other_end = front as u32;

+                    slots[prev].u.free.next = front as u32;

+                    slots[front].u.free = FreeListEntry {

+                        next: 0,

+                        prev: prev as u32,

+                        other_end: back as u32,

+                    };

+                }

+

+                prev = front;

+

+                // Skip occupied slots.

+                while i < slots.len() && slots[i].occupied() {

+                    num_elems += 1;

+                    i += 1;

+                }

+            }

+

+            Ok(Self {

+                num_elems,

+                slots,

+                _k: PhantomData,

+            })

+        }

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use std::collections::{HashMap, HashSet};

+

+    use quickcheck::quickcheck;

+

+    use super::*;

+

+    #[derive(Clone)]

+    struct CountDrop<'a>(&'a std::cell::RefCell<usize>);

+

+    impl<'a> Drop for CountDrop<'a> {

+        fn drop(&mut self) {

+            *self.0.borrow_mut() += 1;

+        }

+    }

+

+    #[cfg(all(nightly, feature = "unstable"))]

+    #[test]

+    fn check_drops() {

+        let drops = std::cell::RefCell::new(0usize);

+

+        {

+            let mut clone = {

+                // Insert 1000 items.

+                let mut sm = HopSlotMap::new();

+                let mut sm_keys = Vec::new();

+                for _ in 0..1000 {

+                    sm_keys.push(sm.insert(CountDrop(&drops)));

+                }

+

+                // Remove even keys.

+                for i in (0..1000).filter(|i| i % 2 == 0) {

+                    sm.remove(sm_keys[i]);

+                }

+

+                // Should only have dropped 500 so far.

+                assert_eq!(*drops.borrow(), 500);

+

+                // Let's clone ourselves and then die.

+                sm.clone()

+            };

+

+            // Now all original items should have been dropped exactly once.

+            assert_eq!(*drops.borrow(), 1000);

+

+            // Reuse some empty slots.

+            for _ in 0..250 {

+                clone.insert(CountDrop(&drops));

+            }

+        }

+

+        // 1000 + 750 drops in total should have happened.

+        assert_eq!(*drops.borrow(), 1750);

+    }

+

+    #[cfg(all(nightly, feature = "unstable"))]

+    #[test]

+    fn disjoint() {

+        // Intended to be run with miri to find any potential UB.

+        let mut sm = HopSlotMap::new();

+

+        // Some churn.

+        for i in 0..20usize {

+            sm.insert(i);

+        }

+        sm.retain(|_, i| *i % 2 == 0);

+

+        let keys: Vec<_> = sm.keys().collect();

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                if let Some([r0, r1]) = sm.get_disjoint_mut([keys[i], keys[j]]) {

+                    *r0 ^= *r1;

+                    *r1 = r1.wrapping_add(*r0);

+                } else {

+                    assert!(i == j);

+                }

+            }

+        }

+

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                for k in 0..keys.len() {

+                    if let Some([r0, r1, r2]) = sm.get_disjoint_mut([keys[i], keys[j], keys[k]]) {

+                        *r0 ^= *r1;

+                        *r0 = r0.wrapping_add(*r2);

+                        *r1 ^= *r0;

+                        *r1 = r1.wrapping_add(*r2);

+                        *r2 ^= *r0;

+                        *r2 = r2.wrapping_add(*r1);

+                    } else {

+                        assert!(i == j || j == k || i == k);

+                    }

+                }

+            }

+        }

+    }

+

+    quickcheck! {

+        fn qc_slotmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {

+            let mut hm = HashMap::new();

+            let mut hm_keys = Vec::new();

+            let mut unique_key = 0u32;

+            let mut sm = HopSlotMap::new();

+            let mut sm_keys = Vec::new();

+

+            #[cfg(not(feature = "serde"))]

+            let num_ops = 3;

+            #[cfg(feature = "serde")]

+            let num_ops = 4;

+

+            for (op, val) in operations {

+                match op % num_ops {

+                    // Insert.

+                    0 => {

+                        hm.insert(unique_key, val);

+                        hm_keys.push(unique_key);

+                        unique_key += 1;

+

+                        sm_keys.push(sm.insert(val));

+                    }

+

+                    // Delete.

+                    1 => {

+                        // 10% of the time test clear.

+                        if val % 10 == 0 {

+                            let hmvals: HashSet<_> = hm.drain().map(|(_, v)| v).collect();

+                            let smvals: HashSet<_> = sm.drain().map(|(_, v)| v).collect();

+                            if hmvals != smvals {

+                                return false;

+                            }

+                        }

+                        if hm_keys.is_empty() { continue; }

+

+                        let idx = val as usize % hm_keys.len();

+                        if hm.remove(&hm_keys[idx]) != sm.remove(sm_keys[idx]) {

+                            return false;

+                        }

+                    }

+

+                    // Access.

+                    2 => {

+                        if hm_keys.is_empty() { continue; }

+                        let idx = val as usize % hm_keys.len();

+                        let (hm_key, sm_key) = (&hm_keys[idx], sm_keys[idx]);

+

+                        if hm.contains_key(hm_key) != sm.contains_key(sm_key) ||

+                           hm.get(hm_key) != sm.get(sm_key) {

+                            return false;

+                        }

+                    }

+

+                    // Serde round-trip.

+                    #[cfg(feature = "serde")]

+                    3 => {

+                        let ser = serde_json::to_string(&sm).unwrap();

+                        sm = serde_json::from_str(&ser).unwrap();

+                    }

+

+                    _ => unreachable!(),

+                }

+            }

+

+            let mut smv: Vec<_> = sm.values().collect();

+            let mut hmv: Vec<_> = hm.values().collect();

+            smv.sort();

+            hmv.sort();

+            smv == hmv

+        }

+    }

+

+    #[cfg(feature = "serde")]

+    #[test]

+    fn slotmap_serde() {

+        let mut sm = HopSlotMap::new();

+        // Self-referential structure.

+        let first = sm.insert_with_key(|k| (k, 23i32));

+        let second = sm.insert((first, 42));

+

+        // Make some empty slots.

+        let empties = vec![sm.insert((first, 0)), sm.insert((first, 0))];

+        empties.iter().for_each(|k| {

+            sm.remove(*k);

+        });

+

+        let third = sm.insert((second, 0));

+        sm[first].0 = third;

+

+        let ser = serde_json::to_string(&sm).unwrap();

+        let de: HopSlotMap<DefaultKey, (DefaultKey, i32)> = serde_json::from_str(&ser).unwrap();

+        assert_eq!(de.len(), sm.len());

+

+        let mut smkv: Vec<_> = sm.iter().collect();

+        let mut dekv: Vec<_> = de.iter().collect();

+        smkv.sort();

+        dekv.sort();

+        assert_eq!(smkv, dekv);

+    }

+

+    #[cfg(feature = "serde")]

+    #[test]

+    fn slotmap_serde_freelist() {

+        let mut sm = HopSlotMap::new();

+        let k = sm.insert(5i32);

+        sm.remove(k);

+

+        let ser = serde_json::to_string(&sm).unwrap();

+        let mut de: HopSlotMap<DefaultKey, i32> = serde_json::from_str(&ser).unwrap();

+

+        de.insert(0);

+        de.insert(1);

+        de.insert(2);

+        assert_eq!(de.len(), 3);

+    }

+}

diff --git a/crates/slotmap/src/lib.rs b/crates/slotmap/src/lib.rs
new file mode 100644
index 0000000..fb3d24d
--- /dev/null
+++ b/crates/slotmap/src/lib.rs
@@ -0,0 +1,652 @@
+#![doc(html_root_url = "https://docs.rs/slotmap/1.0.7")]

+#![crate_name = "slotmap"]

+#![cfg_attr(all(nightly, feature = "unstable"), feature(try_reserve))]

+#![cfg_attr(all(not(test), not(feature = "std")), no_std)]

+#![cfg_attr(all(nightly, doc), feature(doc_cfg))]

+#![warn(

+    missing_debug_implementations,

+    trivial_casts,

+    trivial_numeric_casts,

+    unused_lifetimes,

+    unused_import_braces

+)]

+#![deny(missing_docs, unaligned_references)]

+#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]

+#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]

+#![cfg_attr(

+    feature = "cargo-clippy",

+    allow(

+        // Style differences.

+        module_name_repetitions,

+        redundant_closure_for_method_calls,

+        unseparated_literal_suffix,

+

+        // I know what I'm doing and want these.

+        wildcard_imports,

+        inline_always,

+        cast_possible_truncation,

+        needless_pass_by_value,

+

+        // Very noisy.

+        missing_errors_doc,

+        must_use_candidate

+    ))]

+

+//! # slotmap

+//!

+//! This library provides a container with persistent unique keys to access

+//! stored values, [`SlotMap`]. Upon insertion a key is returned that can be

+//! used to later access or remove the values. Insertion, removal and access all

+//! take O(1) time with low overhead. Great for storing collections of objects

+//! that need stable, safe references but have no clear ownership otherwise,

+//! such as game entities or graph nodes.

+//!

+//! The difference between a [`BTreeMap`] or [`HashMap`] and a slot map is

+//! that the slot map generates and returns the key when inserting a value. A

+//! key is always unique and will only refer to the value that was inserted.

+//! A slot map's main purpose is to simply own things in a safe and efficient

+//! manner.

+//!

+//! You can also create (multiple) secondary maps that can map the keys returned

+//! by [`SlotMap`] to other values, to associate arbitrary data with objects

+//! stored in slot maps, without hashing required - it's direct indexing under

+//! the hood.

+//!

+//! The minimum required stable Rust version for this crate is 1.49.

+//!

+//! # Examples

+//!

+//! ```

+//! # use slotmap::*;

+//! let mut sm = SlotMap::new();

+//! let foo = sm.insert("foo");  // Key generated on insert.

+//! let bar = sm.insert("bar");

+//! assert_eq!(sm[foo], "foo");

+//! assert_eq!(sm[bar], "bar");

+//!

+//! sm.remove(bar);

+//! let reuse = sm.insert("reuse");  // Space from bar reused.

+//! assert_eq!(sm.contains_key(bar), false);  // After deletion a key stays invalid.

+//!

+//! let mut sec = SecondaryMap::new();

+//! sec.insert(foo, "noun");  // We provide the key for secondary maps.

+//! sec.insert(reuse, "verb");

+//!

+//! for (key, val) in sm {

+//!     println!("{} is a {}", val, sec[key]);

+//! }

+//! ```

+//!

+//! # Serialization through [`serde`], [`no_std`] support and unstable features

+//!

+//! Both keys and the slot maps have full (de)seralization support through

+//! the [`serde`] library. A key remains valid for a slot map even after one or

+//! both have been serialized and deserialized! This makes storing or

+//! transferring complicated referential structures and graphs a breeze. Care has

+//! been taken such that deserializing keys and slot maps from untrusted sources

+//! is safe. If you wish to use these features you must enable the `serde`

+//! feature flag for `slotmap` in your `Cargo.toml`.

+//!

+//! ```text

+//! slotmap = { version = "1.0", features = ["serde"] }

+//! ```

+//!

+//! This crate also supports [`no_std`] environments, but does require the

+//! [`alloc`] crate to be available. To enable this you have to disable the

+//! `std` feature that is enabled by default:

+//!

+//! ```text

+//! slotmap = { version = "1.0", default-features = false }

+//! ```

+//!

+//! Unfortunately [`SparseSecondaryMap`] is not available in [`no_std`], because

+//! it relies on [`HashMap`]. Finally the `unstable` feature can be defined to

+//! enable the parts of `slotmap` that only work on nightly Rust.

+//!

+//! # Why not index a [`Vec`], or use [`slab`], [`stable-vec`], etc?

+//!

+//! Those solutions either can not reclaim memory from deleted elements or

+//! suffer from the ABA problem. The keys returned by `slotmap` are versioned.

+//! This means that once a key is removed, it stays removed, even if the

+//! physical storage inside the slotmap is reused for new elements. The key is a

+//! permanently unique<sup>*</sup> reference to the inserted value. Despite

+//! supporting versioning, a [`SlotMap`] is often not (much) slower than the

+//! alternative, by internally using carefully checked unsafe code. Finally,

+//! `slotmap` simply has a lot of features that make your life easy.

+//!

+//! # Performance characteristics and implementation details

+//!

+//! Insertion, access and deletion is all O(1) with low overhead by storing the

+//! elements inside a [`Vec`]. Unlike references or indices into a vector,

+//! unless you remove a key it is never invalidated. Behind the scenes each

+//! slot in the vector is a `(value, version)` tuple. After insertion the

+//! returned key also contains a version. Only when the stored version and

+//! version in a key match is a key valid. This allows us to reuse space in the

+//! vector after deletion without letting removed keys point to spurious new

+//! elements. <sup>*</sup>After 2<sup>31</sup> deletions and insertions to the

+//! same underlying slot the version wraps around and such a spurious reference

+//! could potentially occur. It is incredibly unlikely however, and in all

+//! circumstances is the behavior safe. A slot map can hold up to

+//! 2<sup>32</sup> - 2 elements at a time.

+//!

+//! The memory usage for each slot in [`SlotMap`] is `4 + max(sizeof(T), 4)`

+//! rounded up to the alignment of `T`. Similarly it is `4 + max(sizeof(T), 12)`

+//! for [`HopSlotMap`]. [`DenseSlotMap`] has an overhead of 8 bytes per element

+//! and 8 bytes per slot.

+//!

+//! # Choosing [`SlotMap`], [`HopSlotMap`] or [`DenseSlotMap`]

+//!

+//! A [`SlotMap`] is the fastest for most operations, except iteration. It can

+//! never shrink the size of its underlying storage, because it must remember

+//! for each storage slot what the latest stored version was, even if the slot

+//! is empty now. This means that iteration can be slow as it must iterate over

+//! potentially a lot of empty slots.

+//!

+//! [`HopSlotMap`] solves this by maintaining more information on

+//! insertion/removal, allowing it to iterate only over filled slots by 'hopping

+//! over' contiguous blocks of vacant slots. This can give it significantly

+//! better iteration speed.  If you expect to iterate over all elements in a

+//! [`SlotMap`] a lot, and potentially have a lot of deleted elements, choose

+//! [`HopSlotMap`]. The downside is that insertion and removal is roughly twice

+//! as slow. Random access is the same speed for both.

+//!

+//! [`DenseSlotMap`] goes even further and stores all elements on a contiguous

+//! block of memory. It uses two indirections per random access; the slots

+//! contain indices used to access the contiguous memory. This means random

+//! access is slower than both [`SlotMap`] and [`HopSlotMap`], but iteration is

+//! significantly faster, as fast as a normal [`Vec`].

+//!

+//! # Choosing [`SecondaryMap`] or [`SparseSecondaryMap`]

+//!

+//! You want to associate extra data with objects stored in a slot map, so you

+//! use (multiple) secondary maps to map keys to that data.

+//!

+//! A [`SecondaryMap`] is simply a [`Vec`] of slots like slot map is, and

+//! essentially provides all the same guarantees as [`SlotMap`] does for its

+//! operations (with the exception that you provide the keys as produced by the

+//! primary slot map). This does mean that even if you associate data to only

+//! a single element from the primary slot map, you could need and have to

+//! initialize as much memory as the original.

+//!

+//! A [`SparseSecondaryMap`] is like a [`HashMap`] from keys to objects, however

+//! it automatically removes outdated keys for slots that had their space

+//! reused. You should use this variant if you expect to store some associated

+//! data for only a small portion of the primary slot map.

+//!

+//! # Custom key types

+//!

+//! If you have multiple slot maps it's an error to use the key of one slot map

+//! on another slot map. The result is safe, but unspecified, and can not be

+//! detected at runtime, so it can lead to a hard to find bug.

+//!

+//! To prevent this, slot maps allow you to specify what the type is of the key

+//! they return. You can construct new key types using the [`new_key_type!`]

+//! macro. The resulting type behaves exactly like [`DefaultKey`], but is a

+//! distinct type. So instead of simply using `SlotMap<DefaultKey, Player>` you

+//! would use:

+//!

+//! ```

+//! # use slotmap::*;

+//! # #[derive(Copy, Clone)]

+//! # struct Player;

+//! new_key_type! { struct PlayerKey; }

+//! let sm: SlotMap<PlayerKey, Player> = SlotMap::with_key();

+//! ```

+//!

+//! You can write code generic over any key type using the [`Key`] trait.

+//!

+//! [`Vec`]: std::vec::Vec

+//! [`BTreeMap`]: std::collections::BTreeMap

+//! [`HashMap`]: std::collections::HashMap

+//! [`serde`]: https://github.com/serde-rs/serde

+//! [`slab`]: https://crates.io/crates/slab

+//! [`stable-vec`]: https://crates.io/crates/stable-vec

+//! [`no_std`]: https://doc.rust-lang.org/1.7.0/book/no-stdlib.html

+

+extern crate alloc;

+

+// So our macros can refer to these.

+#[doc(hidden)]

+pub mod __impl {

+    #[cfg(feature = "serde")]

+    pub use serde::{Deserialize, Deserializer, Serialize, Serializer};

+    pub use core::convert::From;

+    pub use core::result::Result;

+}

+

+pub mod basic;

+pub mod dense;

+pub mod hop;

+pub mod secondary;

+#[cfg(feature = "std")]

+pub mod sparse_secondary;

+pub(crate) mod util;

+

+use core::fmt::{self, Debug, Formatter};

+use core::hash::{Hash, Hasher};

+use core::num::NonZeroU32;

+

+#[doc(inline)]

+pub use crate::basic::SlotMap;

+#[doc(inline)]

+pub use crate::dense::DenseSlotMap;

+#[doc(inline)]

+pub use crate::hop::HopSlotMap;

+#[doc(inline)]

+pub use crate::secondary::SecondaryMap;

+#[cfg(feature = "std")]

+#[doc(inline)]

+pub use crate::sparse_secondary::SparseSecondaryMap;

+

+// Keep Slottable for backwards compatibility, but warn about deprecation

+// and hide from documentation.

+#[doc(hidden)]

+#[deprecated(

+    since = "1.0.0",

+    note = "Slottable is not necessary anymore, slotmap now supports all types on stable."

+)]

+pub trait Slottable {}

+

+#[doc(hidden)]

+#[allow(deprecated)]

+impl<T> Slottable for T {}

+

+/// The actual data stored in a [`Key`].

+///

+/// This implements [`Ord`](std::cmp::Ord) so keys can be stored in e.g.

+/// [`BTreeMap`](std::collections::BTreeMap), but the order of keys is

+/// unspecified.

+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]

+pub struct KeyData {

+    idx: u32,

+    version: NonZeroU32,

+}

+

+impl KeyData {

+    fn new(idx: u32, version: u32) -> Self {

+        debug_assert!(version > 0);

+

+        Self {

+            idx,

+            version: unsafe { NonZeroU32::new_unchecked(version | 1) },

+        }

+    }

+

+    fn null() -> Self {

+        Self::new(core::u32::MAX, 1)

+    }

+

+    fn is_null(self) -> bool {

+        self.idx == core::u32::MAX

+    }

+

+    /// Returns the key data as a 64-bit integer. No guarantees about its value

+    /// are made other than that passing it to [`from_ffi`](Self::from_ffi)

+    /// will return a key equal to the original.

+    ///

+    /// With this you can easily pass slot map keys as opaque handles to foreign

+    /// code. After you get them back you can confidently use them in your slot

+    /// map without worrying about unsafe behavior as you would with passing and

+    /// receiving back references or pointers.

+    ///

+    /// This is not a substitute for proper serialization, use [`serde`] for

+    /// that. If you are not doing FFI, you almost surely do not need this

+    /// function.

+    ///

+    /// [`serde`]: crate#serialization-through-serde-no_std-support-and-unstable-features

+    pub fn as_ffi(self) -> u64 {

+        (u64::from(self.version.get()) << 32) | u64::from(self.idx)

+    }

+

+    /// Iff `value` is a value received from `k.as_ffi()`, returns a key equal

+    /// to `k`. Otherwise the behavior is safe but unspecified.

+    pub fn from_ffi(value: u64) -> Self {

+        let idx = value & 0xffff_ffff;

+        let version = (value >> 32) | 1; // Ensure version is odd.

+        Self::new(idx as u32, version as u32)

+    }

+}

+

+impl Debug for KeyData {

+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {

+        write!(f, "{}v{}", self.idx, self.version.get())

+    }

+}

+

+impl Default for KeyData {

+    fn default() -> Self {

+        Self::null()

+    }

+}

+

+impl Hash for KeyData

+{

+    fn hash<H: Hasher>(&self, state: &mut H) {

+        // A derived Hash impl would call write_u32 twice. We call write_u64

+        // once, which is beneficial if the hasher implements write_u64

+        // explicitly.

+        state.write_u64(self.as_ffi())

+    }

+}

+

+/// Key used to access stored values in a slot map.

+///

+/// Do not use a key from one slot map in another. The behavior is safe but

+/// non-sensical (and might panic in case of out-of-bounds).

+///

+/// To prevent this, it is suggested to have a unique key type for each slot

+/// map. You can create new key types using [`new_key_type!`], which makes a

+/// new type identical to [`DefaultKey`], just with a different name.

+///

+/// This trait is intended to be a thin wrapper around [`KeyData`], and all

+/// methods must behave exactly as if we're operating on a [`KeyData`] directly.

+/// The internal unsafe code relies on this, therefore this trait is `unsafe` to

+/// implement. It is strongly suggested to simply use [`new_key_type!`] instead

+/// of implementing this trait yourself.

+pub unsafe trait Key:

+    From<KeyData>

+    + Copy

+    + Clone

+    + Default

+    + Eq

+    + PartialEq

+    + Ord

+    + PartialOrd

+    + core::hash::Hash

+    + core::fmt::Debug

+{

+    /// Creates a new key that is always invalid and distinct from any non-null

+    /// key. A null key can only be created through this method (or default

+    /// initialization of keys made with [`new_key_type!`], which calls this

+    /// method).

+    ///

+    /// A null key is always invalid, but an invalid key (that is, a key that

+    /// has been removed from the slot map) does not become a null key. A null

+    /// is safe to use with any safe method of any slot map instance.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(42);

+    /// let nk = DefaultKey::null();

+    /// assert!(nk.is_null());

+    /// assert!(k != nk);

+    /// assert_eq!(sm.get(nk), None);

+    /// ```

+    fn null() -> Self {

+        KeyData::null().into()

+    }

+

+    /// Checks if a key is null. There is only a single null key, that is

+    /// `a.is_null() && b.is_null()` implies `a == b`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! { struct MyKey; }

+    /// let a = MyKey::null();

+    /// let b = MyKey::default();

+    /// assert_eq!(a, b);

+    /// assert!(a.is_null());

+    /// ```

+    fn is_null(&self) -> bool {

+        self.data().is_null()

+    }

+

+    /// Gets the [`KeyData`] stored in this key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// new_key_type! { struct MyKey; }

+    /// let dk = DefaultKey::null();

+    /// let mk = MyKey::null();

+    /// assert_eq!(dk.data(), mk.data());

+    /// ```

+    fn data(&self) -> KeyData;

+}

+

+/// A helper macro to create new key types. If you use a new key type for each

+/// slot map you create you can entirely prevent using the wrong key on the

+/// wrong slot map.

+///

+/// The type constructed by this macro is defined exactly as [`DefaultKey`],

+/// but is a distinct type for the type checker and does not implicitly convert.

+///

+/// # Examples

+///

+/// ```

+/// # extern crate slotmap;

+/// # use slotmap::*;

+/// new_key_type! {

+///     // A private key type.

+///     struct RocketKey;

+///

+///     // A public key type with a doc comment.

+///     /// Key for the user slot map.

+///     pub struct UserKey;

+/// }

+///

+/// fn main() {

+///     let mut users = SlotMap::with_key();

+///     let mut rockets = SlotMap::with_key();

+///     let bob: UserKey = users.insert("bobby");

+///     let apollo: RocketKey = rockets.insert("apollo");

+///     // Now this is a type error because rockets.get expects an RocketKey:

+///     // rockets.get(bob);

+///

+///     // If for some reason you do end up needing to convert (e.g. storing

+///     // keys of multiple slot maps in the same data structure without

+///     // boxing), you can use KeyData as an intermediate representation. This

+///     // does mean that once again you are responsible for not using the wrong

+///     // key on the wrong slot map.

+///     let keys = vec![bob.data(), apollo.data()];

+///     println!("{} likes rocket {}",

+///              users[keys[0].into()], rockets[keys[1].into()]);

+/// }

+/// ```

+#[macro_export(local_inner_macros)]

+macro_rules! new_key_type {

+    ( $(#[$outer:meta])* $vis:vis struct $name:ident; $($rest:tt)* ) => {

+        $(#[$outer])*

+        #[derive(Copy, Clone, Default,

+                 Eq, PartialEq, Ord, PartialOrd,

+                 Hash, Debug)]

+        #[repr(transparent)]

+        $vis struct $name($crate::KeyData);

+

+        impl $crate::__impl::From<$crate::KeyData> for $name {

+            fn from(k: $crate::KeyData) -> Self {

+                $name(k)

+            }

+        }

+

+        unsafe impl $crate::Key for $name {

+            fn data(&self) -> $crate::KeyData {

+                self.0

+            }

+        }

+

+        $crate::__serialize_key!($name);

+

+        $crate::new_key_type!($($rest)*);

+    };

+

+    () => {}

+}

+

+#[cfg(feature = "serde")]

+#[doc(hidden)]

+#[macro_export]

+macro_rules! __serialize_key {

+    ( $name:ty ) => {

+        impl $crate::__impl::Serialize for $name {

+            fn serialize<S>(&self, serializer: S) -> $crate::__impl::Result<S::Ok, S::Error>

+            where

+                S: $crate::__impl::Serializer,

+            {

+                $crate::Key::data(self).serialize(serializer)

+            }

+        }

+

+        impl<'de> $crate::__impl::Deserialize<'de> for $name {

+            fn deserialize<D>(deserializer: D) -> $crate::__impl::Result<Self, D::Error>

+            where

+                D: $crate::__impl::Deserializer<'de>,

+            {

+                let key_data: $crate::KeyData =

+                    $crate::__impl::Deserialize::deserialize(deserializer)?;

+                Ok(key_data.into())

+            }

+        }

+    };

+}

+

+#[cfg(not(feature = "serde"))]

+#[doc(hidden)]

+#[macro_export]

+macro_rules! __serialize_key {

+    ( $name:ty ) => {};

+}

+

+new_key_type! {

+    /// The default slot map key type.

+    pub struct DefaultKey;

+}

+

+// Serialization with serde.

+#[cfg(feature = "serde")]

+mod serialize {

+    use serde::{Deserialize, Deserializer, Serialize, Serializer};

+

+    use super::*;

+

+    #[derive(Serialize, Deserialize)]

+    pub struct SerKey {

+        idx: u32,

+        version: u32,

+    }

+

+    impl Serialize for KeyData {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            let ser_key = SerKey {

+                idx: self.idx,

+                version: self.version.get(),

+            };

+            ser_key.serialize(serializer)

+        }

+    }

+

+    impl<'de> Deserialize<'de> for KeyData {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let mut ser_key: SerKey = Deserialize::deserialize(deserializer)?;

+

+            // Ensure a.is_null() && b.is_null() implies a == b.

+            if ser_key.idx == core::u32::MAX {

+                ser_key.version = 1;

+            }

+

+            ser_key.version |= 1; // Ensure version is odd.

+            Ok(Self::new(ser_key.idx, ser_key.version))

+        }

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    // Intentionally no `use super::*;` because we want to test macro expansion

+    // in the *users* scope, which might not have that.

+    #[test]

+    fn macro_expansion() {

+        #![allow(dead_code)]

+        use super::new_key_type;

+

+        // Clobber namespace with clashing names - should still work.

+        trait Serialize { }

+        trait Deserialize { }

+        trait Serializer { }

+        trait Deserializer { }

+        trait Key { }

+        trait From { }

+        struct Result;

+        struct KeyData;

+

+        new_key_type! {

+            struct A;

+            pub(crate) struct B;

+            pub struct C;

+        }

+    }

+

+    #[test]

+    fn check_is_older_version() {

+        use super::util::is_older_version;

+

+        let is_older = |a, b| is_older_version(a, b);

+        assert!(!is_older(42, 42));

+        assert!(is_older(0, 1));

+        assert!(is_older(0, 1 << 31));

+        assert!(!is_older(0, (1 << 31) + 1));

+        assert!(is_older(u32::MAX, 0));

+    }

+

+    #[test]

+    fn iters_cloneable() {

+        use super::*;

+

+        struct NoClone;

+

+        let mut sm = SlotMap::new();

+        let mut hsm = HopSlotMap::new();

+        let mut dsm = DenseSlotMap::new();

+        let mut scm = SecondaryMap::new();

+        let mut sscm = SparseSecondaryMap::new();

+        scm.insert(sm.insert(NoClone), NoClone);

+        sscm.insert(hsm.insert(NoClone), NoClone);

+        dsm.insert(NoClone);

+

+        let _ = sm.keys().clone();

+        let _ = sm.values().clone();

+        let _ = sm.iter().clone();

+        let _ = hsm.keys().clone();

+        let _ = hsm.values().clone();

+        let _ = hsm.iter().clone();

+        let _ = dsm.keys().clone();

+        let _ = dsm.values().clone();

+        let _ = dsm.iter().clone();

+        let _ = scm.keys().clone();

+        let _ = scm.values().clone();

+        let _ = scm.iter().clone();

+        let _ = sscm.keys().clone();

+        let _ = sscm.values().clone();

+        let _ = sscm.iter().clone();

+    }

+

+    #[cfg(feature = "serde")]

+    #[test]

+    fn key_serde() {

+        use super::*;

+

+        // Check round-trip through serde.

+        let mut sm = SlotMap::new();

+        let k = sm.insert(42);

+        let ser = serde_json::to_string(&k).unwrap();

+        let de: DefaultKey = serde_json::from_str(&ser).unwrap();

+        assert_eq!(k, de);

+

+        // Even if a malicious entity sends up even (unoccupied) versions in the

+        // key, we make the version point to the occupied version.

+        let malicious: KeyData = serde_json::from_str(&r#"{"idx":0,"version":4}"#).unwrap();

+        assert_eq!(malicious.version.get(), 5);

+    }

+}

diff --git a/crates/slotmap/src/secondary.rs b/crates/slotmap/src/secondary.rs
new file mode 100644
index 0000000..29d5032
--- /dev/null
+++ b/crates/slotmap/src/secondary.rs
@@ -0,0 +1,1767 @@
+//! Contains the secondary map implementation.

+

+#[cfg(all(nightly, any(doc, feature = "unstable")))]

+use alloc::collections::TryReserveError;

+use alloc::vec::Vec;

+use core::hint::unreachable_unchecked;

+use core::iter::{Enumerate, Extend, FromIterator, FusedIterator};

+use core::marker::PhantomData;

+use core::mem::replace;

+#[allow(unused_imports)] // MaybeUninit is only used on nightly at the moment.

+use core::mem::MaybeUninit;

+use core::num::NonZeroU32;

+use core::ops::{Index, IndexMut};

+

+use super::{Key, KeyData};

+use crate::util::is_older_version;

+

+// This representation works because we don't have to store the versions

+// of removed elements.

+#[derive(Debug, Clone)]

+enum Slot<T> {

+    Occupied { value: T, version: NonZeroU32 },

+

+    Vacant,

+}

+

+use self::Slot::{Occupied, Vacant};

+

+impl<T> Slot<T> {

+    pub fn new_occupied(version: u32, value: T) -> Self {

+        Occupied {

+            value,

+            version: unsafe { NonZeroU32::new_unchecked(version | 1u32) },

+        }

+    }

+

+    pub fn new_vacant() -> Self {

+        Vacant

+    }

+

+    // Is this slot occupied?

+    #[inline(always)]

+    pub fn occupied(&self) -> bool {

+        match self {

+            Occupied { .. } => true,

+            Vacant => false,

+        }

+    }

+

+    #[inline(always)]

+    pub fn version(&self) -> u32 {

+        match self {

+            Occupied { version, .. } => version.get(),

+            Vacant => 0,

+        }

+    }

+

+    pub unsafe fn get_unchecked(&self) -> &T {

+        match self {

+            Occupied { value, .. } => value,

+            Vacant => unreachable_unchecked(),

+        }

+    }

+

+    pub unsafe fn get_unchecked_mut(&mut self) -> &mut T {

+        match self {

+            Occupied { value, .. } => value,

+            Vacant => unreachable_unchecked(),

+        }

+    }

+

+    pub fn into_option(self) -> Option<T> {

+        match self {

+            Occupied { value, .. } => Some(value),

+            Vacant => None,

+        }

+    }

+}

+

+/// Secondary map, associate data with previously stored elements in a slot map.

+///

+/// A [`SecondaryMap`] allows you to efficiently store additional information

+/// for each element in a slot map. You can have multiple secondary maps per

+/// slot map, but not multiple slot maps per secondary map. It is safe but

+/// unspecified behavior if you use keys from multiple different slot maps in

+/// the same [`SecondaryMap`].

+///

+/// A [`SecondaryMap`] does not leak memory even if you never remove elements.

+/// In return, when you remove a key from the primary slot map, after any insert

+/// the space associated with the removed element may be reclaimed. Don't expect

+/// the values associated with a removed key to stick around after an insertion

+/// has happened!

+///

+/// Finally a note on memory complexity, the [`SecondaryMap`] can use memory for

+/// each slot in the primary slot map, and has to iterate over every slot during

+/// iteration, regardless of whether you have inserted an associative value at

+/// that key or not. If you have some property that you only expect to set for a

+/// minority of keys, use a [`SparseSecondaryMap`](crate::SparseSecondaryMap),

+/// which is backed by a [`HashMap`](std::collections::HashMap).

+///

+/// Example usage:

+///

+/// ```

+/// # use slotmap::*;

+/// let mut players = SlotMap::new();

+/// let mut health = SecondaryMap::new();

+/// let mut ammo = SecondaryMap::new();

+///

+/// let alice = players.insert("alice");

+/// let bob = players.insert("bob");

+///

+/// for p in players.keys() {

+///     health.insert(p, 100);

+///     ammo.insert(p, 30);

+/// }

+///

+/// // Alice attacks Bob with all her ammo!

+/// health[bob] -= ammo[alice] * 3;

+/// ammo[alice] = 0;

+/// ```

+#[derive(Debug, Clone)]

+pub struct SecondaryMap<K: Key, V> {

+    slots: Vec<Slot<V>>,

+    num_elems: usize,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<K: Key, V> SecondaryMap<K, V> {

+    /// Constructs a new, empty [`SecondaryMap`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SecondaryMap<DefaultKey, i32> = SecondaryMap::new();

+    /// ```

+    pub fn new() -> Self {

+        Self::with_capacity(0)

+    }

+

+    /// Creates an empty [`SecondaryMap`] with the given capacity of slots.

+    ///

+    /// The secondary map will not reallocate until it holds at least `capacity`

+    /// slots. Even inserting a single key-value pair might require as many

+    /// slots as the slot map the key comes from, so it's recommended to match

+    /// the capacity of a secondary map to its corresponding slot map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: SlotMap<_, i32> = SlotMap::with_capacity(10);

+    /// let mut sec: SecondaryMap<DefaultKey, i32> = SecondaryMap::with_capacity(sm.capacity());

+    /// ```

+    pub fn with_capacity(capacity: usize) -> Self {

+        let mut slots = Vec::with_capacity(capacity + 1); // Sentinel.

+        slots.push(Slot::new_vacant());

+        Self {

+            slots,

+            num_elems: 0,

+            _k: PhantomData,

+        }

+    }

+

+    /// Returns the number of elements in the secondary map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(4);

+    /// let mut squared = SecondaryMap::new();

+    /// assert_eq!(squared.len(), 0);

+    /// squared.insert(k, 16);

+    /// assert_eq!(squared.len(), 1);

+    /// ```

+    pub fn len(&self) -> usize {

+        self.num_elems

+    }

+

+    /// Returns if the secondary map is empty.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SecondaryMap<DefaultKey, i32> = SecondaryMap::new();

+    /// assert!(sec.is_empty());

+    /// ```

+    pub fn is_empty(&self) -> bool {

+        self.num_elems == 0

+    }

+

+    /// Returns the number of elements the [`SecondaryMap`] can hold without

+    /// reallocating.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SecondaryMap<DefaultKey, i32> = SecondaryMap::with_capacity(10);

+    /// assert!(sec.capacity() >= 10);

+    /// ```

+    pub fn capacity(&self) -> usize {

+        self.slots.capacity() - 1 // Sentinel.

+    }

+

+    /// Sets the capacity of the [`SecondaryMap`] to `new_capacity`, if it is

+    /// bigger than the current capacity.

+    ///

+    /// It is recommended to set the capacity of a [`SecondaryMap`] to the

+    /// capacity of its corresponding slot map before inserting many new

+    /// elements to prevent frequent reallocations. The collection may reserve

+    /// more space than requested.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the new allocation size overflows [`usize`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SecondaryMap<DefaultKey, i32> = SecondaryMap::with_capacity(10);

+    /// assert!(sec.capacity() >= 10);

+    /// sec.set_capacity(1000);

+    /// assert!(sec.capacity() >= 1000);

+    /// ```

+    pub fn set_capacity(&mut self, new_capacity: usize) {

+        let new_capacity = new_capacity + 1; // Sentinel.

+        if new_capacity > self.slots.capacity() {

+            let needed = new_capacity - self.slots.len();

+            self.slots.reserve(needed);

+        }

+    }

+

+    /// Tries to set the capacity of the [`SecondaryMap`] to `new_capacity`, if it

+    /// is bigger than the current capacity.

+    ///

+    /// It is recommended to set the capacity of a [`SecondaryMap`] to the

+    /// capacity of its corresponding slot map before inserting many new

+    /// elements to prevent frequent reallocations. The collection may reserve

+    /// more space than requested.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SecondaryMap<DefaultKey, i32> = SecondaryMap::with_capacity(10);

+    /// assert!(sec.capacity() >= 10);

+    /// sec.try_set_capacity(1000).unwrap();

+    /// assert!(sec.capacity() >= 1000);

+    /// ```

+    #[cfg(all(nightly, any(doc, feature = "unstable")))]

+    #[cfg_attr(all(nightly, doc), doc(cfg(feature = "unstable")))]

+    pub fn try_set_capacity(&mut self, new_capacity: usize) -> Result<(), TryReserveError> {

+        let new_capacity = new_capacity + 1; // Sentinel.

+        if new_capacity > self.slots.capacity() {

+            let needed = new_capacity - self.slots.len();

+            self.slots.try_reserve(needed)

+        } else {

+            Ok(())

+        }

+    }

+

+    /// Returns [`true`] if the secondary map contains `key`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(4);

+    /// let mut squared = SecondaryMap::new();

+    /// assert!(!squared.contains_key(k));

+    /// squared.insert(k, 16);

+    /// assert!(squared.contains_key(k));

+    /// ```

+    pub fn contains_key(&self, key: K) -> bool {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .map_or(false, |slot| slot.version() == kd.version.get())

+    }

+

+    /// Inserts a value into the secondary map at the given `key`. Can silently

+    /// fail and return `None` if `key` was removed from the originating slot

+    /// map.

+    ///

+    /// Returns [`None`] if this key was not present in the map, the old value

+    /// otherwise.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(4);

+    /// let mut squared = SecondaryMap::new();

+    /// assert_eq!(squared.insert(k, 0), None);

+    /// assert_eq!(squared.insert(k, 4), Some(0));

+    /// // You don't have to use insert if the key is already in the secondary map.

+    /// squared[k] *= squared[k];

+    /// assert_eq!(squared[k], 16);

+    /// ```

+    pub fn insert(&mut self, key: K, value: V) -> Option<V> {

+        if key.is_null() {

+            return None;

+        }

+

+        let kd = key.data();

+        self.slots

+            .extend((self.slots.len()..=kd.idx as usize).map(|_| Slot::new_vacant()));

+

+        let slot = &mut self.slots[kd.idx as usize];

+        if slot.version() == kd.version.get() {

+            // Is always occupied.

+            return Some(replace(unsafe { slot.get_unchecked_mut() }, value));

+        }

+

+        if slot.occupied() {

+            // Don't replace existing newer values.

+            if is_older_version(kd.version.get(), slot.version()) {

+                return None;

+            }

+        } else {

+            self.num_elems += 1;

+        }

+

+        *slot = Slot::new_occupied(kd.version.get(), value);

+        None

+    }

+

+    /// Removes a key from the secondary map, returning the value at the key if

+    /// the key was not previously removed. If `key` was removed from the

+    /// originating slot map, its corresponding entry in the secondary map may

+    /// or may not already be removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut squared = SecondaryMap::new();

+    /// let k = sm.insert(4);

+    /// squared.insert(k, 16);

+    /// squared.remove(k);

+    /// assert!(!squared.contains_key(k));

+    ///

+    /// // It's not necessary to remove keys deleted from the primary slot map, they

+    /// // get deleted automatically when their slots are reused on a subsequent insert.

+    /// squared.insert(k, 16);

+    /// sm.remove(k); // Remove k from the slot map, making an empty slot.

+    /// let new_k = sm.insert(2); // Since sm only has one empty slot, this reuses it.

+    /// assert!(!squared.contains_key(new_k)); // Space reuse does not mean equal keys.

+    /// assert!(squared.contains_key(k)); // Slot has not been reused in squared yet.

+    /// squared.insert(new_k, 4);

+    /// assert!(!squared.contains_key(k)); // Old key is no longer available.

+    /// ```

+    pub fn remove(&mut self, key: K) -> Option<V> {

+        let kd = key.data();

+        if let Some(slot) = self.slots.get_mut(kd.idx as usize) {

+            if slot.version() == kd.version.get() {

+                self.num_elems -= 1;

+                return replace(slot, Slot::new_vacant()).into_option();

+            }

+        }

+

+        None

+    }

+

+    /// Retains only the elements specified by the predicate.

+    ///

+    /// In other words, remove all key-value pairs `(k, v)` such that

+    /// `f(k, &mut v)` returns false. This method invalidates any removed keys.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k1 = sm.insert(0); sec.insert(k1, 10);

+    /// let k2 = sm.insert(1); sec.insert(k2, 11);

+    /// let k3 = sm.insert(2); sec.insert(k3, 12);

+    ///

+    /// sec.retain(|key, val| key == k1 || *val == 11);

+    ///

+    /// assert!(sec.contains_key(k1));

+    /// assert!(sec.contains_key(k2));

+    /// assert!(!sec.contains_key(k3));

+    /// assert_eq!(sec.len(), 2);

+    /// ```

+    pub fn retain<F>(&mut self, mut f: F)

+    where

+        F: FnMut(K, &mut V) -> bool,

+    {

+        for (i, slot) in self.slots.iter_mut().enumerate() {

+            if let Occupied { value, version } = slot {

+                let key = KeyData::new(i as u32, version.get()).into();

+                if !f(key, value) {

+                    self.num_elems -= 1;

+                    *slot = Slot::new_vacant();

+                }

+            }

+        }

+    }

+

+    /// Clears the secondary map. Keeps the allocated memory for reuse.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// for i in 0..10 {

+    ///     sec.insert(sm.insert(i), i);

+    /// }

+    /// assert_eq!(sec.len(), 10);

+    /// sec.clear();

+    /// assert_eq!(sec.len(), 0);

+    /// ```

+    pub fn clear(&mut self) {

+        self.drain();

+    }

+

+    /// Clears the slot map, returning all key-value pairs in arbitrary order as

+    /// an iterator. Keeps the allocated memory for reuse.

+    ///

+    /// When the iterator is dropped all elements in the slot map are removed,

+    /// even if the iterator was not fully consumed. If the iterator is not

+    /// dropped (using e.g. [`std::mem::forget`]), only the elements that were

+    /// iterated over are removed.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::iter::FromIterator;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(0);

+    /// let mut sec = SecondaryMap::new();

+    /// sec.insert(k, 1);

+    /// let v: Vec<_> = sec.drain().collect();

+    /// assert_eq!(sec.len(), 0);

+    /// assert_eq!(v, vec![(k, 1)]);

+    /// ```

+    pub fn drain(&mut self) -> Drain<K, V> {

+        Drain { cur: 1, sm: self }

+    }

+

+    /// Returns a reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("foo");

+    /// let mut sec = SecondaryMap::new();

+    /// sec.insert(key, "bar");

+    /// assert_eq!(sec.get(key), Some(&"bar"));

+    /// sec.remove(key);

+    /// assert_eq!(sec.get(key), None);

+    /// ```

+    pub fn get(&self, key: K) -> Option<&V> {

+        let kd = key.data();

+        self.slots

+            .get(kd.idx as usize)

+            .filter(|slot| slot.version() == kd.version.get())

+            .map(|slot| unsafe { slot.get_unchecked() })

+    }

+

+    /// Returns a reference to the value corresponding to the key without

+    /// version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("foo");

+    /// let mut sec = SecondaryMap::new();

+    /// sec.insert(key, "bar");

+    /// assert_eq!(unsafe { sec.get_unchecked(key) }, &"bar");

+    /// sec.remove(key);

+    /// // sec.get_unchecked(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked(&self, key: K) -> &V {

+        debug_assert!(self.contains_key(key));

+        let slot = self.slots.get_unchecked(key.data().idx as usize);

+        slot.get_unchecked()

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("test");

+    /// let mut sec = SecondaryMap::new();

+    /// sec.insert(key, 3.5);

+    /// if let Some(x) = sec.get_mut(key) {

+    ///     *x += 3.0;

+    /// }

+    /// assert_eq!(sec[key], 6.5);

+    /// ```

+    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {

+        let kd = key.data();

+        self.slots

+            .get_mut(kd.idx as usize)

+            .filter(|slot| slot.version() == kd.version.get())

+            .map(|slot| unsafe { slot.get_unchecked_mut() })

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key

+    /// without version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("foo");

+    /// let mut sec = SecondaryMap::new();

+    /// sec.insert(key, "bar");

+    /// unsafe { *sec.get_unchecked_mut(key) = "baz" };

+    /// assert_eq!(sec[key], "baz");

+    /// sec.remove(key);

+    /// // sec.get_unchecked_mut(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {

+        debug_assert!(self.contains_key(key));

+        let slot = self.slots.get_unchecked_mut(key.data().idx as usize);

+        slot.get_unchecked_mut()

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint, otherwise None is returned.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// let ka = sm.insert(()); sec.insert(ka, "butter");

+    /// let kb = sm.insert(()); sec.insert(kb, "apples");

+    /// let kc = sm.insert(()); sec.insert(kc, "charlie");

+    /// sec.remove(kc); // Make key c invalid.

+    /// assert_eq!(sec.get_disjoint_mut([ka, kb, kc]), None); // Has invalid key.

+    /// assert_eq!(sec.get_disjoint_mut([ka, ka]), None); // Not disjoint.

+    /// let [a, b] = sec.get_disjoint_mut([ka, kb]).unwrap();

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sec[ka], "apples");

+    /// assert_eq!(sec[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {

+        // Create an uninitialized array of `MaybeUninit`. The `assume_init` is

+        // safe because the type we are claiming to have initialized here is a

+        // bunch of `MaybeUninit`s, which do not require initialization.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = unsafe { MaybeUninit::uninit().assume_init() };

+        let mut slot_versions: [MaybeUninit<u32>; N] =

+            unsafe { MaybeUninit::uninit().assume_init() };

+

+        let mut i = 0;

+        while i < N {

+            let kd = keys[i].data();

+

+            match self.slots.get_mut(kd.idx as usize) {

+                Some(Occupied { version, value }) if *version == kd.version => {

+                    // This key is valid, and the slot is occupied. Temporarily

+                    // set the version to 2 so duplicate keys would show up as

+                    // invalid, since keys always have an odd version. This

+                    // gives us a linear time disjointness check.

+                    ptrs[i] = MaybeUninit::new(&mut *value);

+                    slot_versions[i] = MaybeUninit::new(version.get());

+                    *version = NonZeroU32::new(2).unwrap();

+                },

+

+                _ => break,

+            }

+

+            i += 1;

+        }

+

+        // Undo temporary unoccupied markings.

+        for j in 0..i {

+            let idx = keys[j].data().idx as usize;

+            unsafe {

+                match self.slots.get_mut(idx) {

+                    Some(Occupied { version, .. }) => {

+                        *version = NonZeroU32::new_unchecked(slot_versions[j].assume_init());

+                    },

+                    _ => unreachable_unchecked(),

+                }

+            }

+        }

+

+        if i == N {

+            // All were valid and disjoint.

+            Some(unsafe { core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs) })

+        } else {

+            None

+        }

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true for every given

+    /// key and no two keys are equal. Otherwise it is potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// let ka = sm.insert(()); sec.insert(ka, "butter");

+    /// let kb = sm.insert(()); sec.insert(kb, "apples");

+    /// let [a, b] = unsafe { sec.get_disjoint_unchecked_mut([ka, kb]) };

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sec[ka], "apples");

+    /// assert_eq!(sec[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(

+        &mut self,

+        keys: [K; N],

+    ) -> [&mut V; N] {

+        // Safe, see get_disjoint_mut.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = MaybeUninit::uninit().assume_init();

+        for i in 0..N {

+            ptrs[i] = MaybeUninit::new(self.get_unchecked_mut(keys[i]));

+        }

+        core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs)

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order. The

+    /// iterator element type is `(K, &'a V)`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// let k0 = sm.insert(0); sec.insert(k0, 10);

+    /// let k1 = sm.insert(1); sec.insert(k1, 11);

+    /// let k2 = sm.insert(2); sec.insert(k2, 12);

+    ///

+    /// for (k, v) in sm.iter() {

+    ///     println!("key: {:?}, val: {}", k, v);

+    /// }

+    /// ```

+    pub fn iter(&self) -> Iter<K, V> {

+        Iter {

+            num_left: self.num_elems,

+            slots: self.slots.iter().enumerate(),

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order, with

+    /// mutable references to the values. The iterator element type is

+    /// `(K, &'a mut V)`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// let k0 = sm.insert(1); sec.insert(k0, 10);

+    /// let k1 = sm.insert(2); sec.insert(k1, 20);

+    /// let k2 = sm.insert(3); sec.insert(k2, 30);

+    ///

+    /// for (k, v) in sec.iter_mut() {

+    ///     if k != k1 {

+    ///         *v *= -1;

+    ///     }

+    /// }

+    ///

+    /// assert_eq!(sec[k0], -10);

+    /// assert_eq!(sec[k1], 20);

+    /// assert_eq!(sec[k2], -30);

+    /// ```

+    pub fn iter_mut(&mut self) -> IterMut<K, V> {

+        IterMut {

+            num_left: self.num_elems,

+            slots: self.slots.iter_mut().enumerate(),

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all keys in arbitrary order. The iterator element

+    /// type is `K`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// let k0 = sm.insert(1); sec.insert(k0, 10);

+    /// let k1 = sm.insert(2); sec.insert(k1, 20);

+    /// let k2 = sm.insert(3); sec.insert(k2, 30);

+    /// let keys: HashSet<_> = sec.keys().collect();

+    /// let check: HashSet<_> = vec![k0, k1, k2].into_iter().collect();

+    /// assert_eq!(keys, check);

+    /// ```

+    pub fn keys(&self) -> Keys<K, V> {

+        Keys { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values in arbitrary order. The iterator element

+    /// type is `&'a V`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// let k0 = sm.insert(1); sec.insert(k0, 10);

+    /// let k1 = sm.insert(2); sec.insert(k1, 20);

+    /// let k2 = sm.insert(3); sec.insert(k2, 30);

+    /// let values: HashSet<_> = sec.values().collect();

+    /// let check: HashSet<_> = vec![&10, &20, &30].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values(&self) -> Values<K, V> {

+        Values { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values mutably in arbitrary order. The iterator

+    /// element type is `&'a mut V`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// sec.insert(sm.insert(1), 10);

+    /// sec.insert(sm.insert(2), 20);

+    /// sec.insert(sm.insert(3), 30);

+    /// sec.values_mut().for_each(|n| { *n *= 3 });

+    /// let values: HashSet<_> = sec.into_iter().map(|(_k, v)| v).collect();

+    /// let check: HashSet<_> = vec![30, 60, 90].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values_mut(&mut self) -> ValuesMut<K, V> {

+        ValuesMut {

+            inner: self.iter_mut(),

+        }

+    }

+

+    /// Gets the given key's corresponding [`Entry`] in the map for in-place

+    /// manipulation. May return [`None`] if the key was removed from the

+    /// originating slot map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    /// let k = sm.insert(1);

+    /// let v = sec.entry(k).unwrap().or_insert(10);

+    /// assert_eq!(*v, 10);

+    /// ```

+    pub fn entry(&mut self, key: K) -> Option<Entry<K, V>> {

+        if key.is_null() {

+            return None;

+        }

+

+        let kd = key.data();

+

+        // Ensure the slot exists so the Entry implementation can safely assume

+        // the slot always exists without checking.

+        self.slots

+            .extend((self.slots.len()..=kd.idx as usize).map(|_| Slot::new_vacant()));

+

+        let slot = unsafe { self.slots.get_unchecked(kd.idx as usize) };

+        if kd.version.get() == slot.version() {

+            Some(Entry::Occupied(OccupiedEntry {

+                map: self,

+                kd,

+                _k: PhantomData,

+            }))

+        } else if is_older_version(kd.version.get(), slot.version()) {

+            None

+        } else {

+            Some(Entry::Vacant(VacantEntry {

+                map: self,

+                kd,

+                _k: PhantomData,

+            }))

+        }

+    }

+}

+

+impl<K: Key, V> Default for SecondaryMap<K, V> {

+    fn default() -> Self {

+        Self::new()

+    }

+}

+

+impl<K: Key, V> Index<K> for SecondaryMap<K, V> {

+    type Output = V;

+

+    fn index(&self, key: K) -> &V {

+        match self.get(key) {

+            Some(r) => r,

+            None => panic!("invalid SecondaryMap key used"),

+        }

+    }

+}

+

+impl<K: Key, V> IndexMut<K> for SecondaryMap<K, V> {

+    fn index_mut(&mut self, key: K) -> &mut V {

+        match self.get_mut(key) {

+            Some(r) => r,

+            None => panic!("invalid SecondaryMap key used"),

+        }

+    }

+}

+

+impl<K: Key, V: PartialEq> PartialEq for SecondaryMap<K, V> {

+    fn eq(&self, other: &Self) -> bool {

+        if self.len() != other.len() {

+            return false;

+        }

+

+        self.iter()

+            .all(|(key, value)| other.get(key).map_or(false, |other_value| *value == *other_value))

+    }

+}

+

+impl<K: Key, V: Eq> Eq for SecondaryMap<K, V> {}

+

+impl<K: Key, V> FromIterator<(K, V)> for SecondaryMap<K, V> {

+    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {

+        let mut sec = Self::new();

+        sec.extend(iter);

+        sec

+    }

+}

+

+impl<K: Key, V> Extend<(K, V)> for SecondaryMap<K, V> {

+    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {

+        let iter = iter.into_iter();

+        for (k, v) in iter {

+            self.insert(k, v);

+        }

+    }

+}

+

+impl<'a, K: Key, V: 'a + Copy> Extend<(K, &'a V)> for SecondaryMap<K, V> {

+    fn extend<I: IntoIterator<Item = (K, &'a V)>>(&mut self, iter: I) {

+        let iter = iter.into_iter();

+        for (k, v) in iter {

+            self.insert(k, *v);

+        }

+    }

+}

+

+/// A view into a occupied entry in a [`SecondaryMap`]. It is part of the

+/// [`Entry`] enum.

+#[derive(Debug)]

+pub struct OccupiedEntry<'a, K: Key, V> {

+    map: &'a mut SecondaryMap<K, V>,

+    kd: KeyData,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// A view into a vacant entry in a [`SecondaryMap`]. It is part of the

+/// [`Entry`] enum.

+#[derive(Debug)]

+pub struct VacantEntry<'a, K: Key, V> {

+    map: &'a mut SecondaryMap<K, V>,

+    kd: KeyData,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// A view into a single entry in a [`SecondaryMap`], which may either be

+/// vacant or occupied.

+///

+/// This `enum` is constructed using [`SecondaryMap::entry`].

+#[derive(Debug)]

+pub enum Entry<'a, K: Key, V> {

+    /// An occupied entry.

+    Occupied(OccupiedEntry<'a, K, V>),

+

+    /// A vacant entry.

+    Vacant(VacantEntry<'a, K, V>),

+}

+

+impl<'a, K: Key, V> Entry<'a, K, V> {

+    /// Ensures a value is in the entry by inserting the default if empty, and

+    /// returns a mutable reference to the value in the entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert("poneyland");

+    /// let v = sec.entry(k).unwrap().or_insert(10);

+    /// assert_eq!(*v, 10);

+    /// *sec.entry(k).unwrap().or_insert(1) *= 2;

+    /// assert_eq!(sec[k], 20);

+    /// ```

+    pub fn or_insert(self, default: V) -> &'a mut V {

+        self.or_insert_with(|| default)

+    }

+

+    /// Ensures a value is in the entry by inserting the result of the default

+    /// function if empty, and returns a mutable reference to the value in the

+    /// entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// let v = sec.entry(k).unwrap().or_insert_with(|| "foobar".to_string());

+    /// assert_eq!(v, &"foobar");

+    /// ```

+    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {

+        match self {

+            Entry::Occupied(x) => x.into_mut(),

+            Entry::Vacant(x) => x.insert(default()),

+        }

+    }

+

+    /// Returns this entry's key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec: SecondaryMap<_, ()> = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// let entry = sec.entry(k).unwrap();

+    /// assert_eq!(entry.key(), k);

+    /// ```

+    pub fn key(&self) -> K {

+        match self {

+            Entry::Occupied(entry) => entry.kd.into(),

+            Entry::Vacant(entry) => entry.kd.into(),

+        }

+    }

+

+    /// Provides in-place mutable access to an occupied entry before any

+    /// potential inserts into the map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 0);

+    /// sec.entry(k).unwrap().and_modify(|x| *x = 1);

+    ///

+    /// assert_eq!(sec[k], 1)

+    /// ```

+    pub fn and_modify<F>(self, f: F) -> Self

+    where

+        F: FnOnce(&mut V),

+    {

+        match self {

+            Entry::Occupied(mut entry) => {

+                f(entry.get_mut());

+                Entry::Occupied(entry)

+            },

+            Entry::Vacant(entry) => Entry::Vacant(entry),

+        }

+    }

+}

+

+impl<'a, K: Key, V: Default> Entry<'a, K, V> {

+    /// Ensures a value is in the entry by inserting the default value if empty,

+    /// and returns a mutable reference to the value in the entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec: SecondaryMap<_, Option<i32>> = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.entry(k).unwrap().or_default();

+    /// assert_eq!(sec[k], None)

+    /// ```

+    pub fn or_default(self) -> &'a mut V {

+        self.or_insert_with(Default::default)

+    }

+}

+

+impl<'a, K: Key, V> OccupiedEntry<'a, K, V> {

+    /// Returns this entry's key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    /// assert_eq!(sec.entry(k).unwrap().key(), k);

+    /// ```

+    pub fn key(&self) -> K {

+        self.kd.into()

+    }

+

+    /// Removes the entry from the slot map and returns the key and value.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let foo = sm.insert("foo");

+    /// sec.entry(foo).unwrap().or_insert("bar");

+    ///

+    /// if let Some(Entry::Occupied(o)) = sec.entry(foo) {

+    ///     assert_eq!(o.remove_entry(), (foo, "bar"));

+    /// }

+    /// assert_eq!(sec.contains_key(foo), false);

+    /// ```

+    pub fn remove_entry(self) -> (K, V) {

+        (self.kd.into(), self.remove())

+    }

+

+    /// Gets a reference to the value in the entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    ///

+    /// if let Entry::Occupied(o) = sec.entry(k).unwrap() {

+    ///     assert_eq!(*o.get(), 10);

+    /// }

+    /// ```

+    pub fn get(&self) -> &V {

+        unsafe { self.map.get_unchecked(self.kd.into()) }

+    }

+

+    /// Gets a mutable reference to the value in the entry.

+    ///

+    /// If you need a reference to the [`OccupiedEntry`] which may outlive the

+    /// destruction of the [`Entry`] value, see [`into_mut`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    /// if let Entry::Occupied(mut o) = sec.entry(k).unwrap() {

+    ///     *o.get_mut() = 20;

+    /// }

+    /// assert_eq!(sec[k], 20);

+    /// ```

+    ///

+    /// [`into_mut`]: Self::into_mut

+    pub fn get_mut(&mut self) -> &mut V {

+        unsafe { self.map.get_unchecked_mut(self.kd.into()) }

+    }

+

+    /// Converts the [`OccupiedEntry`] into a mutable reference to the value in

+    /// the entry with a lifetime bound to the map itself.

+    ///

+    /// If you need multiple references to the [`OccupiedEntry`], see

+    /// [`get_mut`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(0);

+    /// sec.insert(k, 0);

+    ///

+    /// let r;

+    /// if let Entry::Occupied(o) = sec.entry(k).unwrap() {

+    ///     r = o.into_mut(); // v outlives the entry.

+    /// } else {

+    ///     r = sm.get_mut(k).unwrap();

+    /// }

+    /// *r = 1;

+    /// assert_eq!((sm[k], sec[k]), (0, 1));

+    /// ```

+    ///

+    /// [`get_mut`]: Self::get_mut

+    pub fn into_mut(self) -> &'a mut V {

+        unsafe { self.map.get_unchecked_mut(self.kd.into()) }

+    }

+

+    /// Sets the value of the entry, and returns the entry's old value.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    ///

+    /// if let Entry::Occupied(mut o) = sec.entry(k).unwrap() {

+    ///     let v = o.insert(20);

+    ///     assert_eq!(v, 10);

+    ///     assert_eq!(*o.get(), 20);

+    /// }

+    /// ```

+    pub fn insert(&mut self, value: V) -> V {

+        replace(self.get_mut(), value)

+    }

+

+    /// Takes the value out of the entry, and returns it.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    ///

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    ///

+    /// if let Entry::Occupied(mut o) = sec.entry(k).unwrap() {

+    ///     assert_eq!(o.remove(), 10);

+    ///     assert_eq!(sec.contains_key(k), false);

+    /// }

+    /// ```

+    pub fn remove(self) -> V {

+        let slot = unsafe { self.map.slots.get_unchecked_mut(self.kd.idx as usize) };

+        self.map.num_elems -= 1;

+        match replace(slot, Slot::new_vacant()) {

+            Occupied { value, .. } => value,

+            Vacant => unsafe { unreachable_unchecked() },

+        }

+    }

+}

+

+impl<'a, K: Key, V> VacantEntry<'a, K, V> {

+    /// Gets the key that would be used when inserting a value through the

+    /// [`VacantEntry`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    ///

+    /// let mut sm = SlotMap::new();

+    /// let mut sec: SecondaryMap<_, ()> = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    ///

+    /// if let Entry::Vacant(v) = sec.entry(k).unwrap() {

+    ///     assert_eq!(v.key(), k);

+    /// }

+    /// ```

+    pub fn key(&self) -> K {

+        self.kd.into()

+    }

+

+    /// Sets the value of the entry with the [`VacantEntry`]'s key, and returns

+    /// a mutable reference to it.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::secondary::Entry;

+    ///

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    ///

+    /// if let Entry::Vacant(v) = sec.entry(k).unwrap() {

+    ///     let new_val = v.insert(3);

+    ///     assert_eq!(new_val, &mut 3);

+    /// }

+    /// ```

+    pub fn insert(self, value: V) -> &'a mut V {

+        let slot = unsafe { self.map.slots.get_unchecked_mut(self.kd.idx as usize) };

+        // Despite the slot being considered Vacant for this entry, it might be occupied

+        // with an outdated element.

+        match replace(slot, Slot::new_occupied(self.kd.version.get(), value)) {

+            Occupied { .. } => {},

+            Vacant => self.map.num_elems += 1,

+        }

+        unsafe { slot.get_unchecked_mut() }

+    }

+}

+

+// Iterators.

+/// A draining iterator for [`SecondaryMap`].

+///

+/// This iterator is created by [`SecondaryMap::drain`].

+#[derive(Debug)]

+pub struct Drain<'a, K: Key + 'a, V: 'a> {

+    sm: &'a mut SecondaryMap<K, V>,

+    cur: usize,

+}

+

+/// An iterator that moves key-value pairs out of a [`SecondaryMap`].

+///

+/// This iterator is created by calling the `into_iter` method on [`SecondaryMap`],

+/// provided by the [`IntoIterator`] trait.

+#[derive(Debug)]

+pub struct IntoIter<K: Key, V> {

+    num_left: usize,

+    slots: Enumerate<alloc::vec::IntoIter<Slot<V>>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the key-value pairs in a [`SecondaryMap`].

+///

+/// This iterator is created by [`SecondaryMap::iter`].

+#[derive(Debug)]

+pub struct Iter<'a, K: Key + 'a, V: 'a> {

+    num_left: usize,

+    slots: Enumerate<core::slice::Iter<'a, Slot<V>>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {

+    fn clone(&self) -> Self {

+        Iter {

+            num_left: self.num_left,

+            slots: self.slots.clone(),

+            _k: self._k,

+        }

+    }

+}

+

+/// A mutable iterator over the key-value pairs in a [`SecondaryMap`].

+///

+/// This iterator is created by [`SecondaryMap::iter_mut`].

+#[derive(Debug)]

+pub struct IterMut<'a, K: Key + 'a, V: 'a> {

+    num_left: usize,

+    slots: Enumerate<core::slice::IterMut<'a, Slot<V>>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the keys in a [`SecondaryMap`].

+///

+/// This iterator is created by [`SecondaryMap::keys`].

+#[derive(Debug)]

+pub struct Keys<'a, K: Key + 'a, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {

+    fn clone(&self) -> Self {

+        Keys {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// An iterator over the values in a [`SecondaryMap`].

+///

+/// This iterator is created by [`SecondaryMap::values`].

+#[derive(Debug)]

+pub struct Values<'a, K: Key + 'a, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {

+    fn clone(&self) -> Self {

+        Values {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// A mutable iterator over the values in a [`SecondaryMap`].

+///

+/// This iterator is created by [`SecondaryMap::values_mut`].

+#[derive(Debug)]

+pub struct ValuesMut<'a, K: Key + 'a, V: 'a> {

+    inner: IterMut<'a, K, V>,

+}

+

+impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        while let Some(slot) = self.sm.slots.get_mut(self.cur) {

+            let idx = self.cur;

+            self.cur += 1;

+            if let Occupied { value, version } = replace(slot, Slot::new_vacant()) {

+                self.sm.num_elems -= 1;

+                let key = KeyData::new(idx as u32, version.get()).into();

+                return Some((key, value));

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.sm.len(), Some(self.sm.len()))

+    }

+}

+

+impl<'a, K: Key, V> Drop for Drain<'a, K, V> {

+    fn drop(&mut self) {

+        self.for_each(|_drop| {});

+    }

+}

+

+impl<K: Key, V> Iterator for IntoIter<K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        while let Some((idx, mut slot)) = self.slots.next() {

+            if let Occupied { value, version } = replace(&mut slot, Slot::new_vacant()) {

+                self.num_left -= 1;

+                let key = KeyData::new(idx as u32, version.get()).into();

+                return Some((key, value));

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {

+    type Item = (K, &'a V);

+

+    fn next(&mut self) -> Option<(K, &'a V)> {

+        while let Some((idx, slot)) = self.slots.next() {

+            if let Occupied { value, version } = slot {

+                self.num_left -= 1;

+                let key = KeyData::new(idx as u32, version.get()).into();

+                return Some((key, value));

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {

+    type Item = (K, &'a mut V);

+

+    fn next(&mut self) -> Option<(K, &'a mut V)> {

+        while let Some((idx, slot)) = self.slots.next() {

+            if let Occupied { value, version } = slot {

+                let key = KeyData::new(idx as u32, version.get()).into();

+                self.num_left -= 1;

+                return Some((key, value));

+            }

+        }

+

+        None

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        (self.num_left, Some(self.num_left))

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Keys<'a, K, V> {

+    type Item = K;

+

+    fn next(&mut self) -> Option<K> {

+        self.inner.next().map(|(key, _)| key)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Values<'a, K, V> {

+    type Item = &'a V;

+

+    fn next(&mut self) -> Option<&'a V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for ValuesMut<'a, K, V> {

+    type Item = &'a mut V;

+

+    fn next(&mut self) -> Option<&'a mut V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> IntoIterator for &'a SecondaryMap<K, V> {

+    type Item = (K, &'a V);

+    type IntoIter = Iter<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter()

+    }

+}

+

+impl<'a, K: Key, V> IntoIterator for &'a mut SecondaryMap<K, V> {

+    type Item = (K, &'a mut V);

+    type IntoIter = IterMut<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter_mut()

+    }

+}

+

+impl<K: Key, V> IntoIterator for SecondaryMap<K, V> {

+    type Item = (K, V);

+    type IntoIter = IntoIter<K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        let len = self.len();

+        let mut it = self.slots.into_iter().enumerate();

+        it.next(); // Skip sentinel.

+        IntoIter {

+            num_left: len,

+            slots: it,

+            _k: PhantomData,

+        }

+    }

+}

+

+impl<'a, K: Key, V> FusedIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Drain<'a, K, V> {}

+impl<K: Key, V> FusedIterator for IntoIter<K, V> {}

+

+impl<'a, K: Key, V> ExactSizeIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Drain<'a, K, V> {}

+impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}

+

+// Serialization with serde.

+#[cfg(feature = "serde")]

+mod serialize {

+    use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

+

+    use super::*;

+

+    #[derive(Serialize, Deserialize)]

+    struct SerdeSlot<T> {

+        value: Option<T>,

+        version: u32,

+    }

+

+    impl<T: Serialize> Serialize for Slot<T> {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            let serde_slot = SerdeSlot {

+                version: self.version(),

+                value: match self {

+                    Occupied { value, .. } => Some(value),

+                    Vacant => None,

+                },

+            };

+            serde_slot.serialize(serializer)

+        }

+    }

+

+    impl<'de, T> Deserialize<'de> for Slot<T>

+    where

+        T: Deserialize<'de>,

+    {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let serde_slot: SerdeSlot<T> = Deserialize::deserialize(deserializer)?;

+            let occupied = serde_slot.version % 2 == 1;

+            if occupied ^ serde_slot.value.is_some() {

+                return Err(de::Error::custom(&"inconsistent occupation in Slot"));

+            }

+

+            Ok(match serde_slot.value {

+                Some(value) => Self::new_occupied(serde_slot.version, value),

+                None => Self::new_vacant(),

+            })

+        }

+    }

+

+    impl<K: Key, V: Serialize> Serialize for SecondaryMap<K, V> {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            self.slots.serialize(serializer)

+        }

+    }

+

+    impl<'de, K: Key, V: Deserialize<'de>> Deserialize<'de> for SecondaryMap<K, V> {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let mut slots: Vec<Slot<V>> = Deserialize::deserialize(deserializer)?;

+            if slots.len() >= (u32::max_value() - 1) as usize {

+                return Err(de::Error::custom(&"too many slots"));

+            }

+

+            // Ensure the first slot exists and is empty for the sentinel.

+            if slots.get(0).map_or(true, |slot| slot.occupied()) {

+                return Err(de::Error::custom(&"first slot not empty"));

+            }

+

+            slots[0] = Slot::new_vacant();

+            let num_elems = slots.iter().map(|s| s.occupied() as usize).sum();

+

+            Ok(Self {

+                num_elems,

+                slots,

+                _k: PhantomData,

+            })

+        }

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use std::collections::HashMap;

+

+    use quickcheck::quickcheck;

+

+    use crate::*;

+

+    #[cfg(all(nightly, feature = "unstable"))]

+    #[test]

+    fn disjoint() {

+        // Intended to be run with miri to find any potential UB.

+        let mut sm = SlotMap::new();

+        let mut sec = SecondaryMap::new();

+

+        // Some churn.

+        for i in 0..20usize {

+            sm.insert(i);

+        }

+        sm.retain(|_, i| *i % 2 == 0);

+

+        for (i, k) in sm.keys().enumerate() {

+            sec.insert(k, i);

+        }

+

+        let keys: Vec<_> = sm.keys().collect();

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                if let Some([r0, r1]) = sec.get_disjoint_mut([keys[i], keys[j]]) {

+                    *r0 ^= *r1;

+                    *r1 = r1.wrapping_add(*r0);

+                } else {

+                    assert!(i == j);

+                }

+            }

+        }

+

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                for k in 0..keys.len() {

+                    if let Some([r0, r1, r2]) = sec.get_disjoint_mut([keys[i], keys[j], keys[k]]) {

+                        *r0 ^= *r1;

+                        *r0 = r0.wrapping_add(*r2);

+                        *r1 ^= *r0;

+                        *r1 = r1.wrapping_add(*r2);

+                        *r2 ^= *r0;

+                        *r2 = r2.wrapping_add(*r1);

+                    } else {

+                        assert!(i == j || j == k || i == k);

+                    }

+                }

+            }

+        }

+    }

+

+    quickcheck! {

+        fn qc_secmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {

+            let mut hm = HashMap::new();

+            let mut hm_keys = Vec::new();

+            let mut unique_key = 0u32;

+            let mut sm = SlotMap::new();

+            let mut sec = SecondaryMap::new();

+            let mut sm_keys = Vec::new();

+

+            #[cfg(not(feature = "serde"))]

+            let num_ops = 4;

+            #[cfg(feature = "serde")]

+            let num_ops = 5;

+

+            for (op, val) in operations {

+                match op % num_ops {

+                    // Insert.

+                    0 => {

+                        hm.insert(unique_key, val);

+                        hm_keys.push(unique_key);

+                        unique_key += 1;

+

+                        let k = sm.insert(val);

+                        sec.insert(k, val);

+                        sm_keys.push(k);

+                    }

+

+                    // Delete.

+                    1 => {

+                        if hm_keys.is_empty() { continue; }

+

+                        let idx = val as usize % hm_keys.len();

+                        sm.remove(sm_keys[idx]);

+                        if hm.remove(&hm_keys[idx]) != sec.remove(sm_keys[idx]) {

+                            return false;

+                        }

+                    }

+

+                    // Access.

+                    2 => {

+                        if hm_keys.is_empty() { continue; }

+                        let idx = val as usize % hm_keys.len();

+                        let (hm_key, sm_key) = (&hm_keys[idx], sm_keys[idx]);

+

+                        if hm.contains_key(hm_key) != sec.contains_key(sm_key) ||

+                           hm.get(hm_key) != sec.get(sm_key) {

+                            return false;

+                        }

+                    }

+

+                    // Clone.

+                    3 => {

+                        sec = sec.clone();

+                    }

+

+                    // Serde round-trip.

+                    #[cfg(feature = "serde")]

+                    4 => {

+                        let ser = serde_json::to_string(&sec).unwrap();

+                        sec = serde_json::from_str(&ser).unwrap();

+                    }

+

+                    _ => unreachable!(),

+                }

+            }

+

+            let mut secv: Vec<_> = sec.values().collect();

+            let mut hmv: Vec<_> = hm.values().collect();

+            secv.sort();

+            hmv.sort();

+            secv == hmv

+        }

+    }

+}

diff --git a/crates/slotmap/src/sparse_secondary.rs b/crates/slotmap/src/sparse_secondary.rs
new file mode 100644
index 0000000..0365fef
--- /dev/null
+++ b/crates/slotmap/src/sparse_secondary.rs
@@ -0,0 +1,1715 @@
+//! Contains the sparse secondary map implementation.

+

+#[cfg(all(nightly, any(doc, feature = "unstable")))]

+use alloc::collections::TryReserveError;

+#[allow(unused_imports)] // MaybeUninit is only used on nightly at the moment.

+use core::mem::MaybeUninit;

+use std::collections::hash_map::{self, HashMap};

+use std::hash;

+use std::iter::{Extend, FromIterator, FusedIterator};

+use std::marker::PhantomData;

+use std::ops::{Index, IndexMut};

+

+use super::{Key, KeyData};

+use crate::util::{is_older_version, UnwrapUnchecked};

+

+#[derive(Debug, Clone)]

+struct Slot<T> {

+    version: u32,

+    value: T,

+}

+

+/// Sparse secondary map, associate data with previously stored elements in a

+/// slot map.

+///

+/// A [`SparseSecondaryMap`] allows you to efficiently store additional

+/// information for each element in a slot map. You can have multiple secondary

+/// maps per slot map, but not multiple slot maps per secondary map. It is safe

+/// but unspecified behavior if you use keys from multiple different slot maps

+/// in the same [`SparseSecondaryMap`].

+///

+/// A [`SparseSecondaryMap`] does not leak memory even if you never remove

+/// elements. In return, when you remove a key from the primary slot map, after

+/// any insert the space associated with the removed element may be reclaimed.

+/// Don't expect the values associated with a removed key to stick around after

+/// an insertion has happened!

+///

+/// Unlike [`SecondaryMap`], the [`SparseSecondaryMap`] is backed by a

+/// [`HashMap`]. This means its access times are higher, but it uses less memory

+/// and iterates faster if there are only a few elements of the slot map in the

+/// secondary map. If most or all of the elements in a slot map are also found

+/// in the secondary map, use a [`SecondaryMap`] instead.

+///

+/// The current implementation of [`SparseSecondaryMap`] requires [`std`] and is

+/// thus not available in `no_std` environments.

+///

+/// [`SecondaryMap`]: crate::SecondaryMap

+/// [`HashMap`]: std::collections::HashMap

+///

+/// Example usage:

+///

+/// ```

+/// # use slotmap::*;

+/// let mut players = SlotMap::new();

+/// let mut health = SparseSecondaryMap::new();

+/// let mut ammo = SparseSecondaryMap::new();

+///

+/// let alice = players.insert("alice");

+/// let bob = players.insert("bob");

+///

+/// for p in players.keys() {

+///     health.insert(p, 100);

+///     ammo.insert(p, 30);

+/// }

+///

+/// // Alice attacks Bob with all her ammo!

+/// health[bob] -= ammo[alice] * 3;

+/// ammo[alice] = 0;

+/// ```

+

+#[derive(Debug, Clone)]

+pub struct SparseSecondaryMap<K: Key, V, S: hash::BuildHasher = hash_map::RandomState> {

+    slots: HashMap<u32, Slot<V>, S>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<K: Key, V> SparseSecondaryMap<K, V, hash_map::RandomState> {

+    /// Constructs a new, empty [`SparseSecondaryMap`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32> = SparseSecondaryMap::new();

+    /// ```

+    pub fn new() -> Self {

+        Self::with_capacity(0)

+    }

+

+    /// Creates an empty [`SparseSecondaryMap`] with the given capacity of slots.

+    ///

+    /// The secondary map will not reallocate until it holds at least `capacity`

+    /// slots.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm: SlotMap<_, i32> = SlotMap::with_capacity(10);

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32> =

+    ///     SparseSecondaryMap::with_capacity(sm.capacity());

+    /// ```

+    pub fn with_capacity(capacity: usize) -> Self {

+        Self {

+            slots: HashMap::with_capacity(capacity),

+            _k: PhantomData,

+        }

+    }

+}

+

+impl<K: Key, V, S: hash::BuildHasher> SparseSecondaryMap<K, V, S> {

+    /// Creates an empty [`SparseSecondaryMap`] which will use the given hash

+    /// builder to hash keys.

+    ///

+    /// The secondary map will not reallocate until it holds at least `capacity`

+    /// slots.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use std::collections::hash_map::RandomState;

+    /// # use slotmap::*;

+    /// let mut sm: SlotMap<_, i32> = SlotMap::with_capacity(10);

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32, _> =

+    ///     SparseSecondaryMap::with_hasher(RandomState::new());

+    /// ```

+    pub fn with_hasher(hash_builder: S) -> Self {

+        Self {

+            slots: HashMap::with_hasher(hash_builder),

+            _k: PhantomData,

+        }

+    }

+

+    /// Creates an empty [`SparseSecondaryMap`] with the given capacity of slots,

+    /// using `hash_builder` to hash the keys.

+    ///

+    /// The secondary map will not reallocate until it holds at least `capacity`

+    /// slots.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use std::collections::hash_map::RandomState;

+    /// # use slotmap::*;

+    /// let mut sm: SlotMap<_, i32> = SlotMap::with_capacity(10);

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32, _> =

+    ///     SparseSecondaryMap::with_capacity_and_hasher(10, RandomState::new());

+    /// ```

+    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {

+        Self {

+            slots: HashMap::with_capacity_and_hasher(capacity, hash_builder),

+            _k: PhantomData,

+        }

+    }

+

+    /// Returns the number of elements in the secondary map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(4);

+    /// let mut squared = SparseSecondaryMap::new();

+    /// assert_eq!(squared.len(), 0);

+    /// squared.insert(k, 16);

+    /// assert_eq!(squared.len(), 1);

+    /// ```

+    pub fn len(&self) -> usize {

+        self.slots.len()

+    }

+

+    /// Returns if the secondary map is empty.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32> = SparseSecondaryMap::new();

+    /// assert!(sec.is_empty());

+    /// ```

+    pub fn is_empty(&self) -> bool {

+        self.slots.is_empty()

+    }

+

+    /// Returns the number of elements the [`SparseSecondaryMap`] can hold without

+    /// reallocating.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32> = SparseSecondaryMap::with_capacity(10);

+    /// assert!(sec.capacity() >= 10);

+    /// ```

+    pub fn capacity(&self) -> usize {

+        self.slots.capacity()

+    }

+

+    /// Reserves capacity for at least `additional` more slots in the

+    /// [`SparseSecondaryMap`]. The collection may reserve more space to avoid

+    /// frequent reallocations.

+    ///

+    /// # Panics

+    ///

+    /// Panics if the new allocation size overflows [`usize`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32> = SparseSecondaryMap::new();

+    /// sec.reserve(10);

+    /// assert!(sec.capacity() >= 10);

+    /// ```

+    pub fn reserve(&mut self, additional: usize) {

+        self.slots.reserve(additional);

+    }

+

+    /// Tries to reserve capacity for at least `additional` more slots in the

+    /// [`SparseSecondaryMap`].  The collection may reserve more space to avoid

+    /// frequent reallocations.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sec: SparseSecondaryMap<DefaultKey, i32> = SparseSecondaryMap::new();

+    /// sec.try_reserve(10).unwrap();

+    /// assert!(sec.capacity() >= 10);

+    /// ```

+    #[cfg(all(nightly, any(doc, feature = "unstable")))]

+    #[cfg_attr(all(nightly, doc), doc(cfg(feature = "unstable")))]

+    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {

+        self.slots.try_reserve(additional)

+    }

+

+    /// Returns [`true`] if the secondary map contains `key`.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(4);

+    /// let mut squared = SparseSecondaryMap::new();

+    /// assert!(!squared.contains_key(k));

+    /// squared.insert(k, 16);

+    /// assert!(squared.contains_key(k));

+    /// ```

+    pub fn contains_key(&self, key: K) -> bool {

+        let kd = key.data();

+        self.slots.get(&kd.idx).map_or(false, |slot| slot.version == kd.version.get())

+    }

+

+    /// Inserts a value into the secondary map at the given `key`. Can silently

+    /// fail if `key` was removed from the originating slot map.

+    ///

+    /// Returns [`None`] if this key was not present in the map, the old value

+    /// otherwise.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(4);

+    /// let mut squared = SparseSecondaryMap::new();

+    /// assert_eq!(squared.insert(k, 0), None);

+    /// assert_eq!(squared.insert(k, 4), Some(0));

+    /// // You don't have to use insert if the key is already in the secondary map.

+    /// squared[k] *= squared[k];

+    /// assert_eq!(squared[k], 16);

+    /// ```

+    pub fn insert(&mut self, key: K, value: V) -> Option<V> {

+        if key.is_null() {

+            return None;

+        }

+

+        let kd = key.data();

+

+        if let Some(slot) = self.slots.get_mut(&kd.idx) {

+            if slot.version == kd.version.get() {

+                return Some(std::mem::replace(&mut slot.value, value));

+            }

+

+            // Don't replace existing newer values.

+            if is_older_version(kd.version.get(), slot.version) {

+                return None;

+            }

+

+            *slot = Slot {

+                version: kd.version.get(),

+                value,

+            };

+

+            return None;

+        }

+

+        self.slots.insert(kd.idx, Slot {

+            version: kd.version.get(),

+            value,

+        });

+

+        None

+    }

+

+    /// Removes a key from the secondary map, returning the value at the key if

+    /// the key was not previously removed. If `key` was removed from the

+    /// originating slot map, its corresponding entry in the secondary map may

+    /// or may not already be removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut squared = SparseSecondaryMap::new();

+    /// let k = sm.insert(4);

+    /// squared.insert(k, 16);

+    /// squared.remove(k);

+    /// assert!(!squared.contains_key(k));

+    ///

+    /// // It's not necessary to remove keys deleted from the primary slot map, they

+    /// // get deleted automatically when their slots are reused on a subsequent insert.

+    /// squared.insert(k, 16);

+    /// sm.remove(k); // Remove k from the slot map, making an empty slot.

+    /// let new_k = sm.insert(2); // Since sm only has one empty slot, this reuses it.

+    /// assert!(!squared.contains_key(new_k)); // Space reuse does not mean equal keys.

+    /// assert!(squared.contains_key(k)); // Slot has not been reused in squared yet.

+    /// squared.insert(new_k, 4);

+    /// assert!(!squared.contains_key(k)); // Old key is no longer available.

+    /// ```

+    pub fn remove(&mut self, key: K) -> Option<V> {

+        let kd = key.data();

+

+        if let hash_map::Entry::Occupied(entry) = self.slots.entry(kd.idx) {

+            if entry.get().version == kd.version.get() {

+                return Some(entry.remove_entry().1.value);

+            }

+        }

+

+        None

+    }

+

+    /// Retains only the elements specified by the predicate.

+    ///

+    /// In other words, remove all key-value pairs `(k, v)` such that

+    /// `f(k, &mut v)` returns false. This method invalidates any removed keys.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k1 = sm.insert(0); sec.insert(k1, 10);

+    /// let k2 = sm.insert(1); sec.insert(k2, 11);

+    /// let k3 = sm.insert(2); sec.insert(k3, 12);

+    ///

+    /// sec.retain(|key, val| key == k1 || *val == 11);

+    ///

+    /// assert!(sec.contains_key(k1));

+    /// assert!(sec.contains_key(k2));

+    /// assert!(!sec.contains_key(k3));

+    ///

+    /// assert_eq!(2, sec.len());

+    /// ```

+    pub fn retain<F>(&mut self, mut f: F)

+    where

+        F: FnMut(K, &mut V) -> bool,

+    {

+        self.slots.retain(|&idx, slot| {

+            let key = KeyData::new(idx, slot.version).into();

+            f(key, &mut slot.value)

+        })

+    }

+

+    /// Clears the secondary map. Keeps the allocated memory for reuse.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// for i in 0..10 {

+    ///     sec.insert(sm.insert(i), i);

+    /// }

+    /// assert_eq!(sec.len(), 10);

+    /// sec.clear();

+    /// assert_eq!(sec.len(), 0);

+    /// ```

+    pub fn clear(&mut self) {

+        self.slots.clear();

+    }

+

+    /// Clears the slot map, returning all key-value pairs in arbitrary order as

+    /// an iterator. Keeps the allocated memory for reuse.

+    ///

+    /// When the iterator is dropped all elements in the slot map are removed,

+    /// even if the iterator was not fully consumed. If the iterator is not

+    /// dropped (using e.g. [`std::mem::forget`]), only the elements that were

+    /// iterated over are removed.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::iter::FromIterator;

+    /// let mut sm = SlotMap::new();

+    /// let k = sm.insert(0);

+    /// let mut sec = SparseSecondaryMap::new();

+    /// sec.insert(k, 1);

+    /// let v: Vec<_> = sec.drain().collect();

+    /// assert_eq!(sec.len(), 0);

+    /// assert_eq!(v, vec![(k, 1)]);

+    /// ```

+    pub fn drain(&mut self) -> Drain<K, V> {

+        Drain {

+            inner: self.slots.drain(),

+            _k: PhantomData,

+        }

+    }

+

+    /// Returns a reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("foo");

+    /// let mut sec = SparseSecondaryMap::new();

+    /// sec.insert(key, "bar");

+    /// assert_eq!(sec.get(key), Some(&"bar"));

+    /// sec.remove(key);

+    /// assert_eq!(sec.get(key), None);

+    /// ```

+    pub fn get(&self, key: K) -> Option<&V> {

+        let kd = key.data();

+        self.slots

+            .get(&kd.idx)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| &slot.value)

+    }

+

+    /// Returns a reference to the value corresponding to the key without

+    /// version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("foo");

+    /// let mut sec = SparseSecondaryMap::new();

+    /// sec.insert(key, "bar");

+    /// assert_eq!(unsafe { sec.get_unchecked(key) }, &"bar");

+    /// sec.remove(key);

+    /// // sec.get_unchecked(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked(&self, key: K) -> &V {

+        debug_assert!(self.contains_key(key));

+        self.get(key).unwrap_unchecked_()

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("test");

+    /// let mut sec = SparseSecondaryMap::new();

+    /// sec.insert(key, 3.5);

+    /// if let Some(x) = sec.get_mut(key) {

+    ///     *x += 3.0;

+    /// }

+    /// assert_eq!(sec[key], 6.5);

+    /// ```

+    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {

+        let kd = key.data();

+        self.slots

+            .get_mut(&kd.idx)

+            .filter(|slot| slot.version == kd.version.get())

+            .map(|slot| &mut slot.value)

+    }

+

+    /// Returns a mutable reference to the value corresponding to the key

+    /// without version or bounds checking.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true. Otherwise it is

+    /// potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let key = sm.insert("foo");

+    /// let mut sec = SparseSecondaryMap::new();

+    /// sec.insert(key, "bar");

+    /// unsafe { *sec.get_unchecked_mut(key) = "baz" };

+    /// assert_eq!(sec[key], "baz");

+    /// sec.remove(key);

+    /// // sec.get_unchecked_mut(key) is now dangerous!

+    /// ```

+    pub unsafe fn get_unchecked_mut(&mut self, key: K) -> &mut V {

+        debug_assert!(self.contains_key(key));

+        self.get_mut(key).unwrap_unchecked_()

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint, otherwise None is returned.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// let ka = sm.insert(()); sec.insert(ka, "butter");

+    /// let kb = sm.insert(()); sec.insert(kb, "apples");

+    /// let kc = sm.insert(()); sec.insert(kc, "charlie");

+    /// sec.remove(kc); // Make key c invalid.

+    /// assert_eq!(sec.get_disjoint_mut([ka, kb, kc]), None); // Has invalid key.

+    /// assert_eq!(sec.get_disjoint_mut([ka, ka]), None); // Not disjoint.

+    /// let [a, b] = sec.get_disjoint_mut([ka, kb]).unwrap();

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sec[ka], "apples");

+    /// assert_eq!(sec[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub fn get_disjoint_mut<const N: usize>(&mut self, keys: [K; N]) -> Option<[&mut V; N]> {

+        // Create an uninitialized array of `MaybeUninit`. The `assume_init` is

+        // safe because the type we are claiming to have initialized here is a

+        // bunch of `MaybeUninit`s, which do not require initialization.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = unsafe { MaybeUninit::uninit().assume_init() };

+

+        let mut i = 0;

+        while i < N {

+            let kd = keys[i].data();

+

+            match self.slots.get_mut(&kd.idx) {

+                Some(Slot { version, value }) if *version == kd.version.get() => {

+                    // This key is valid, and the slot is occupied. Temporarily

+                    // make the version even so duplicate keys would show up as

+                    // invalid, since keys always have an odd version. This

+                    // gives us a linear time disjointness check.

+                    ptrs[i] = MaybeUninit::new(&mut *value);

+                    *version ^= 1;

+                },

+

+                _ => break,

+            }

+

+            i += 1;

+        }

+

+        // Undo temporary even versions.

+        for k in &keys[0..i] {

+            match self.slots.get_mut(&k.data().idx) {

+                Some(Slot { version, .. }) => {

+                    *version ^= 1;

+                },

+                _ => unsafe { core::hint::unreachable_unchecked() },

+            }

+        }

+

+        if i == N {

+            // All were valid and disjoint.

+            Some(unsafe { core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs) })

+        } else {

+            None

+        }

+    }

+

+    /// Returns mutable references to the values corresponding to the given

+    /// keys. All keys must be valid and disjoint.

+    ///

+    /// Requires at least stable Rust version 1.51.

+    ///

+    /// # Safety

+    ///

+    /// This should only be used if `contains_key(key)` is true for every given

+    /// key and no two keys are equal. Otherwise it is potentially unsafe.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// let ka = sm.insert(()); sec.insert(ka, "butter");

+    /// let kb = sm.insert(()); sec.insert(kb, "apples");

+    /// let [a, b] = unsafe { sec.get_disjoint_unchecked_mut([ka, kb]) };

+    /// std::mem::swap(a, b);

+    /// assert_eq!(sec[ka], "apples");

+    /// assert_eq!(sec[kb], "butter");

+    /// ```

+    #[cfg(has_min_const_generics)]

+    pub unsafe fn get_disjoint_unchecked_mut<const N: usize>(

+        &mut self,

+        keys: [K; N],

+    ) -> [&mut V; N] {

+        // Safe, see get_disjoint_mut.

+        let mut ptrs: [MaybeUninit<*mut V>; N] = MaybeUninit::uninit().assume_init();

+        for i in 0..N {

+            ptrs[i] = MaybeUninit::new(self.get_unchecked_mut(keys[i]));

+        }

+        core::mem::transmute_copy::<_, [&mut V; N]>(&ptrs)

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order. The

+    /// iterator element type is `(K, &'a V)`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// let k0 = sm.insert(0); sec.insert(k0, 10);

+    /// let k1 = sm.insert(1); sec.insert(k1, 11);

+    /// let k2 = sm.insert(2); sec.insert(k2, 12);

+    ///

+    /// for (k, v) in sec.iter() {

+    ///     println!("key: {:?}, val: {}", k, v);

+    /// }

+    /// ```

+    pub fn iter(&self) -> Iter<K, V> {

+        Iter {

+            inner: self.slots.iter(),

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all key-value pairs in arbitrary order, with

+    /// mutable references to the values. The iterator element type is

+    /// `(K, &'a mut V)`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// let k0 = sm.insert(1); sec.insert(k0, 10);

+    /// let k1 = sm.insert(2); sec.insert(k1, 20);

+    /// let k2 = sm.insert(3); sec.insert(k2, 30);

+    ///

+    /// for (k, v) in sec.iter_mut() {

+    ///     if k != k1 {

+    ///         *v *= -1;

+    ///     }

+    /// }

+    ///

+    /// assert_eq!(sec[k0], -10);

+    /// assert_eq!(sec[k1], 20);

+    /// assert_eq!(sec[k2], -30);

+    /// ```

+    pub fn iter_mut(&mut self) -> IterMut<K, V> {

+        IterMut {

+            inner: self.slots.iter_mut(),

+            _k: PhantomData,

+        }

+    }

+

+    /// An iterator visiting all keys in arbitrary order. The iterator element

+    /// type is `K`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// let k0 = sm.insert(1); sec.insert(k0, 10);

+    /// let k1 = sm.insert(2); sec.insert(k1, 20);

+    /// let k2 = sm.insert(3); sec.insert(k2, 30);

+    /// let keys: HashSet<_> = sec.keys().collect();

+    /// let check: HashSet<_> = vec![k0, k1, k2].into_iter().collect();

+    /// assert_eq!(keys, check);

+    /// ```

+    pub fn keys(&self) -> Keys<K, V> {

+        Keys { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values in arbitrary order. The iterator element

+    /// type is `&'a V`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// let k0 = sm.insert(1); sec.insert(k0, 10);

+    /// let k1 = sm.insert(2); sec.insert(k1, 20);

+    /// let k2 = sm.insert(3); sec.insert(k2, 30);

+    /// let values: HashSet<_> = sec.values().collect();

+    /// let check: HashSet<_> = vec![&10, &20, &30].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values(&self) -> Values<K, V> {

+        Values { inner: self.iter() }

+    }

+

+    /// An iterator visiting all values mutably in arbitrary order. The iterator

+    /// element type is `&'a mut V`.

+    ///

+    /// This function must iterate over all slots, empty or not. In the face of

+    /// many deleted elements it can be inefficient.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use std::collections::HashSet;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// sec.insert(sm.insert(1), 10);

+    /// sec.insert(sm.insert(2), 20);

+    /// sec.insert(sm.insert(3), 30);

+    /// sec.values_mut().for_each(|n| { *n *= 3 });

+    /// let values: HashSet<_> = sec.into_iter().map(|(_k, v)| v).collect();

+    /// let check: HashSet<_> = vec![30, 60, 90].into_iter().collect();

+    /// assert_eq!(values, check);

+    /// ```

+    pub fn values_mut(&mut self) -> ValuesMut<K, V> {

+        ValuesMut {

+            inner: self.iter_mut(),

+        }

+    }

+

+    /// Gets the given key's corresponding [`Entry`] in the map for in-place

+    /// manipulation. May return [`None`] if the key was removed from the

+    /// originating slot map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    /// let k = sm.insert(1);

+    /// let v = sec.entry(k).unwrap().or_insert(10);

+    /// assert_eq!(*v, 10);

+    /// ```

+    pub fn entry(&mut self, key: K) -> Option<Entry<K, V>> {

+        if key.is_null() {

+            return None;

+        }

+

+        let kd = key.data();

+

+        // Until we can map an OccupiedEntry to a VacantEntry I don't think

+        // there is a way to avoid this extra lookup.

+        if let hash_map::Entry::Occupied(o) = self.slots.entry(kd.idx) {

+            if o.get().version != kd.version.get() {

+                // Which is outdated, our key or the slot?

+                if is_older_version(o.get().version, kd.version.get()) {

+                    o.remove();

+                } else {

+                    return None;

+                }

+            }

+        }

+

+        Some(match self.slots.entry(kd.idx) {

+            hash_map::Entry::Occupied(inner) => {

+                // We know for certain that this entry's key matches ours due

+                // to the previous if block.

+                Entry::Occupied(OccupiedEntry {

+                    inner,

+                    kd,

+                    _k: PhantomData,

+                })

+            },

+            hash_map::Entry::Vacant(inner) => Entry::Vacant(VacantEntry {

+                inner,

+                kd,

+                _k: PhantomData,

+            }),

+        })

+    }

+}

+

+impl<K, V, S> Default for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher + Default,

+{

+    fn default() -> Self {

+        Self::with_hasher(Default::default())

+    }

+}

+

+impl<K, V, S> Index<K> for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher,

+{

+    type Output = V;

+

+    fn index(&self, key: K) -> &V {

+        match self.get(key) {

+            Some(r) => r,

+            None => panic!("invalid SparseSecondaryMap key used"),

+        }

+    }

+}

+

+impl<K, V, S> IndexMut<K> for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher,

+{

+    fn index_mut(&mut self, key: K) -> &mut V {

+        match self.get_mut(key) {

+            Some(r) => r,

+            None => panic!("invalid SparseSecondaryMap key used"),

+        }

+    }

+}

+

+impl<K, V, S> PartialEq for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    V: PartialEq,

+    S: hash::BuildHasher,

+{

+    fn eq(&self, other: &Self) -> bool {

+        if self.len() != other.len() {

+            return false;

+        }

+

+        self.iter()

+            .all(|(key, value)| other.get(key).map_or(false, |other_value| *value == *other_value))

+    }

+}

+

+impl<K, V, S> Eq for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    V: Eq,

+    S: hash::BuildHasher,

+{

+}

+

+impl<K, V, S> FromIterator<(K, V)> for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher + Default,

+{

+    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {

+        let mut sec = Self::default();

+        sec.extend(iter);

+        sec

+    }

+}

+

+impl<K, V, S> Extend<(K, V)> for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher,

+{

+    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {

+        let iter = iter.into_iter();

+        for (k, v) in iter {

+            self.insert(k, v);

+        }

+    }

+}

+

+impl<'a, K, V, S> Extend<(K, &'a V)> for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    V: 'a + Copy,

+    S: hash::BuildHasher,

+{

+    fn extend<I: IntoIterator<Item = (K, &'a V)>>(&mut self, iter: I) {

+        let iter = iter.into_iter();

+        for (k, v) in iter {

+            self.insert(k, *v);

+        }

+    }

+}

+

+/// A view into a occupied entry in a [`SparseSecondaryMap`]. It is part of the

+/// [`Entry`] enum.

+#[derive(Debug)]

+pub struct OccupiedEntry<'a, K: Key, V> {

+    inner: hash_map::OccupiedEntry<'a, u32, Slot<V>>,

+    kd: KeyData,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// A view into a vacant entry in a [`SparseSecondaryMap`]. It is part of the

+/// [`Entry`] enum.

+#[derive(Debug)]

+pub struct VacantEntry<'a, K: Key, V> {

+    inner: hash_map::VacantEntry<'a, u32, Slot<V>>,

+    kd: KeyData,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// A view into a single entry in a [`SparseSecondaryMap`], which may either be

+/// vacant or occupied.

+///

+/// This `enum` is constructed using [`SparseSecondaryMap::entry`].

+#[derive(Debug)]

+pub enum Entry<'a, K: Key, V> {

+    /// An occupied entry.

+    Occupied(OccupiedEntry<'a, K, V>),

+

+    /// A vacant entry.

+    Vacant(VacantEntry<'a, K, V>),

+}

+

+impl<'a, K: Key, V> Entry<'a, K, V> {

+    /// Ensures a value is in the entry by inserting the default if empty, and

+    /// returns a mutable reference to the value in the entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert("poneyland");

+    /// let v = sec.entry(k).unwrap().or_insert(10);

+    /// assert_eq!(*v, 10);

+    /// *sec.entry(k).unwrap().or_insert(1) *= 2;

+    /// assert_eq!(sec[k], 20);

+    /// ```

+    pub fn or_insert(self, default: V) -> &'a mut V {

+        self.or_insert_with(|| default)

+    }

+

+    /// Ensures a value is in the entry by inserting the result of the default

+    /// function if empty, and returns a mutable reference to the value in the

+    /// entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// let v = sec.entry(k).unwrap().or_insert_with(|| "foobar".to_string());

+    /// assert_eq!(v, &"foobar");

+    /// ```

+    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {

+        match self {

+            Entry::Occupied(x) => x.into_mut(),

+            Entry::Vacant(x) => x.insert(default()),

+        }

+    }

+

+    /// Returns this entry's key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec: SparseSecondaryMap<_, ()> = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// let entry = sec.entry(k).unwrap();

+    /// assert_eq!(entry.key(), k);

+    /// ```

+    pub fn key(&self) -> K {

+        match self {

+            Entry::Occupied(entry) => entry.kd.into(),

+            Entry::Vacant(entry) => entry.kd.into(),

+        }

+    }

+

+    /// Provides in-place mutable access to an occupied entry before any

+    /// potential inserts into the map.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 0);

+    /// sec.entry(k).unwrap().and_modify(|x| *x = 1);

+    ///

+    /// assert_eq!(sec[k], 1)

+    /// ```

+    pub fn and_modify<F>(self, f: F) -> Self

+    where

+        F: FnOnce(&mut V),

+    {

+        match self {

+            Entry::Occupied(mut entry) => {

+                f(entry.get_mut());

+                Entry::Occupied(entry)

+            },

+            Entry::Vacant(entry) => Entry::Vacant(entry),

+        }

+    }

+}

+

+impl<'a, K: Key, V: Default> Entry<'a, K, V> {

+    /// Ensures a value is in the entry by inserting the default value if empty,

+    /// and returns a mutable reference to the value in the entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec: SparseSecondaryMap<_, Option<i32>> = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.entry(k).unwrap().or_default();

+    /// assert_eq!(sec[k], None)

+    /// ```

+    pub fn or_default(self) -> &'a mut V {

+        self.or_insert_with(Default::default)

+    }

+}

+

+impl<'a, K: Key, V> OccupiedEntry<'a, K, V> {

+    /// Returns this entry's key.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    /// assert_eq!(sec.entry(k).unwrap().key(), k);

+    /// ```

+    pub fn key(&self) -> K {

+        self.kd.into()

+    }

+

+    /// Removes the entry from the slot map and returns the key and value.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let foo = sm.insert("foo");

+    /// sec.entry(foo).unwrap().or_insert("bar");

+    ///

+    /// if let Some(Entry::Occupied(o)) = sec.entry(foo) {

+    ///     assert_eq!(o.remove_entry(), (foo, "bar"));

+    /// }

+    /// assert_eq!(sec.contains_key(foo), false);

+    /// ```

+    pub fn remove_entry(self) -> (K, V) {

+        (self.kd.into(), self.remove())

+    }

+

+    /// Gets a reference to the value in the entry.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    ///

+    /// if let Entry::Occupied(o) = sec.entry(k).unwrap() {

+    ///     assert_eq!(*o.get(), 10);

+    /// }

+    /// ```

+    pub fn get(&self) -> &V {

+        &self.inner.get().value

+    }

+

+    /// Gets a mutable reference to the value in the entry.

+    ///

+    /// If you need a reference to the [`OccupiedEntry`] which may outlive the

+    /// destruction of the [`Entry`] value, see [`into_mut`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    /// if let Entry::Occupied(mut o) = sec.entry(k).unwrap() {

+    ///     *o.get_mut() = 20;

+    /// }

+    /// assert_eq!(sec[k], 20);

+    /// ```

+    ///

+    /// [`into_mut`]: Self::into_mut

+    pub fn get_mut(&mut self) -> &mut V {

+        &mut self.inner.get_mut().value

+    }

+

+    /// Converts the [`OccupiedEntry`] into a mutable reference to the value in

+    /// the entry with a lifetime bound to the map itself.

+    ///

+    /// If you need multiple references to the [`OccupiedEntry`], see

+    /// [`get_mut`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(0);

+    /// sec.insert(k, 0);

+    ///

+    /// let r;

+    /// if let Entry::Occupied(o) = sec.entry(k).unwrap() {

+    ///     r = o.into_mut(); // v outlives the entry.

+    /// } else {

+    ///     r = sm.get_mut(k).unwrap();

+    /// }

+    /// *r = 1;

+    /// assert_eq!((sm[k], sec[k]), (0, 1));

+    /// ```

+    ///

+    /// [`get_mut`]: Self::get_mut

+    pub fn into_mut(self) -> &'a mut V {

+        &mut self.inner.into_mut().value

+    }

+

+    /// Sets the value of the entry, and returns the entry's old value.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    ///

+    /// if let Entry::Occupied(mut o) = sec.entry(k).unwrap() {

+    ///     let v = o.insert(20);

+    ///     assert_eq!(v, 10);

+    ///     assert_eq!(*o.get(), 20);

+    /// }

+    /// ```

+    pub fn insert(&mut self, value: V) -> V {

+        std::mem::replace(self.get_mut(), value)

+    }

+

+    /// Takes the value out of the entry, and returns it.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    ///

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    /// sec.insert(k, 10);

+    ///

+    /// if let Entry::Occupied(mut o) = sec.entry(k).unwrap() {

+    ///     assert_eq!(o.remove(), 10);

+    ///     assert_eq!(sec.contains_key(k), false);

+    /// }

+    /// ```

+    pub fn remove(self) -> V {

+        self.inner.remove().value

+    }

+}

+

+impl<'a, K: Key, V> VacantEntry<'a, K, V> {

+    /// Gets the key that would be used when inserting a value through the

+    /// [`VacantEntry`].

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    ///

+    /// let mut sm = SlotMap::new();

+    /// let mut sec: SparseSecondaryMap<_, ()> = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    ///

+    /// if let Entry::Vacant(v) = sec.entry(k).unwrap() {

+    ///     assert_eq!(v.key(), k);

+    /// }

+    /// ```

+    pub fn key(&self) -> K {

+        self.kd.into()

+    }

+

+    /// Sets the value of the entry with the [`VacantEntry`]'s key, and returns

+    /// a mutable reference to it.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// # use slotmap::*;

+    /// # use slotmap::sparse_secondary::Entry;

+    ///

+    /// let mut sm = SlotMap::new();

+    /// let mut sec = SparseSecondaryMap::new();

+    ///

+    /// let k = sm.insert(1);

+    ///

+    /// if let Entry::Vacant(v) = sec.entry(k).unwrap() {

+    ///     let new_val = v.insert(3);

+    ///     assert_eq!(new_val, &mut 3);

+    /// }

+    /// ```

+    pub fn insert(self, value: V) -> &'a mut V {

+        &mut self

+            .inner

+            .insert(Slot {

+                version: self.kd.version.get(),

+                value,

+            })

+            .value

+    }

+}

+

+// Iterators.

+/// A draining iterator for [`SparseSecondaryMap`].

+///

+/// This iterator is created by [`SparseSecondaryMap::drain`].

+#[derive(Debug)]

+pub struct Drain<'a, K: Key + 'a, V: 'a> {

+    inner: hash_map::Drain<'a, u32, Slot<V>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator that moves key-value pairs out of a [`SparseSecondaryMap`].

+///

+/// This iterator is created by calling the `into_iter` method on [`SparseSecondaryMap`],

+/// provided by the [`IntoIterator`] trait.

+#[derive(Debug)]

+pub struct IntoIter<K: Key, V> {

+    inner: hash_map::IntoIter<u32, Slot<V>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the key-value pairs in a [`SparseSecondaryMap`].

+///

+/// This iterator is created by [`SparseSecondaryMap::iter`].

+#[derive(Debug)]

+pub struct Iter<'a, K: Key + 'a, V: 'a> {

+    inner: hash_map::Iter<'a, u32, Slot<V>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Iter<'a, K, V> {

+    fn clone(&self) -> Self {

+        Iter {

+            inner: self.inner.clone(),

+            _k: self._k,

+        }

+    }

+}

+

+/// A mutable iterator over the key-value pairs in a [`SparseSecondaryMap`].

+///

+/// This iterator is created by [`SparseSecondaryMap::iter_mut`].

+#[derive(Debug)]

+pub struct IterMut<'a, K: Key + 'a, V: 'a> {

+    inner: hash_map::IterMut<'a, u32, Slot<V>>,

+    _k: PhantomData<fn(K) -> K>,

+}

+

+/// An iterator over the keys in a [`SparseSecondaryMap`].

+///

+/// This iterator is created by [`SparseSecondaryMap::keys`].

+#[derive(Debug)]

+pub struct Keys<'a, K: Key + 'a, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Keys<'a, K, V> {

+    fn clone(&self) -> Self {

+        Keys {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// An iterator over the values in a [`SparseSecondaryMap`].

+///

+/// This iterator is created by [`SparseSecondaryMap::values`].

+#[derive(Debug)]

+pub struct Values<'a, K: Key + 'a, V: 'a> {

+    inner: Iter<'a, K, V>,

+}

+

+impl<'a, K: 'a + Key, V: 'a> Clone for Values<'a, K, V> {

+    fn clone(&self) -> Self {

+        Values {

+            inner: self.inner.clone(),

+        }

+    }

+}

+

+/// A mutable iterator over the values in a [`SparseSecondaryMap`].

+///

+/// This iterator is created by [`SparseSecondaryMap::values_mut`].

+#[derive(Debug)]

+pub struct ValuesMut<'a, K: Key + 'a, V: 'a> {

+    inner: IterMut<'a, K, V>,

+}

+

+impl<'a, K: Key, V> Iterator for Drain<'a, K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        self.inner.next().map(|(idx, slot)| {

+            let key = KeyData::new(idx, slot.version).into();

+            (key, slot.value)

+        })

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Drop for Drain<'a, K, V> {

+    fn drop(&mut self) {

+        self.for_each(|_drop| {});

+    }

+}

+

+impl<K: Key, V> Iterator for IntoIter<K, V> {

+    type Item = (K, V);

+

+    fn next(&mut self) -> Option<(K, V)> {

+        self.inner.next().map(|(idx, slot)| {

+            let key = KeyData::new(idx, slot.version).into();

+            (key, slot.value)

+        })

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Iter<'a, K, V> {

+    type Item = (K, &'a V);

+

+    fn next(&mut self) -> Option<(K, &'a V)> {

+        self.inner.next().map(|(&idx, slot)| {

+            let key = KeyData::new(idx, slot.version).into();

+            (key, &slot.value)

+        })

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for IterMut<'a, K, V> {

+    type Item = (K, &'a mut V);

+

+    fn next(&mut self) -> Option<(K, &'a mut V)> {

+        self.inner.next().map(|(&idx, slot)| {

+            let key = KeyData::new(idx, slot.version).into();

+            (key, &mut slot.value)

+        })

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Keys<'a, K, V> {

+    type Item = K;

+

+    fn next(&mut self) -> Option<K> {

+        self.inner.next().map(|(key, _)| key)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for Values<'a, K, V> {

+    type Item = &'a V;

+

+    fn next(&mut self) -> Option<&'a V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K: Key, V> Iterator for ValuesMut<'a, K, V> {

+    type Item = &'a mut V;

+

+    fn next(&mut self) -> Option<&'a mut V> {

+        self.inner.next().map(|(_, value)| value)

+    }

+

+    fn size_hint(&self) -> (usize, Option<usize>) {

+        self.inner.size_hint()

+    }

+}

+

+impl<'a, K, V, S> IntoIterator for &'a SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher,

+{

+    type Item = (K, &'a V);

+    type IntoIter = Iter<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter()

+    }

+}

+

+impl<'a, K, V, S> IntoIterator for &'a mut SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher,

+{

+    type Item = (K, &'a mut V);

+    type IntoIter = IterMut<'a, K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        self.iter_mut()

+    }

+}

+

+impl<K, V, S> IntoIterator for SparseSecondaryMap<K, V, S>

+where

+    K: Key,

+    S: hash::BuildHasher,

+{

+    type Item = (K, V);

+    type IntoIter = IntoIter<K, V>;

+

+    fn into_iter(self) -> Self::IntoIter {

+        IntoIter {

+            inner: self.slots.into_iter(),

+            _k: PhantomData,

+        }

+    }

+}

+

+impl<'a, K: Key, V> FusedIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> FusedIterator for Drain<'a, K, V> {}

+impl<K: Key, V> FusedIterator for IntoIter<K, V> {}

+

+impl<'a, K: Key, V> ExactSizeIterator for Iter<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for IterMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Keys<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Values<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for ValuesMut<'a, K, V> {}

+impl<'a, K: Key, V> ExactSizeIterator for Drain<'a, K, V> {}

+impl<K: Key, V> ExactSizeIterator for IntoIter<K, V> {}

+

+// Serialization with serde.

+#[cfg(feature = "serde")]

+mod serialize {

+    use serde::{Deserialize, Deserializer, Serialize, Serializer};

+

+    use super::*;

+    use crate::SecondaryMap;

+

+    impl<K, V, H> Serialize for SparseSecondaryMap<K, V, H>

+    where

+        K: Key,

+        V: Serialize,

+        H: hash::BuildHasher,

+    {

+        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>

+        where

+            S: Serializer,

+        {

+            let mut serde_sec = SecondaryMap::new();

+            for (k, v) in self {

+                serde_sec.insert(k, v);

+            }

+

+            serde_sec.serialize(serializer)

+        }

+    }

+

+    impl<'de, K, V, S> Deserialize<'de> for SparseSecondaryMap<K, V, S>

+    where

+        K: Key,

+        V: Deserialize<'de>,

+        S: hash::BuildHasher + Default,

+    {

+        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>

+        where

+            D: Deserializer<'de>,

+        {

+            let serde_sec: SecondaryMap<K, V> = Deserialize::deserialize(deserializer)?;

+            let mut sec = Self::default();

+

+            for (k, v) in serde_sec {

+                sec.insert(k, v);

+            }

+

+            Ok(sec)

+        }

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use std::collections::HashMap;

+

+    use quickcheck::quickcheck;

+

+    use crate::*;

+

+    #[test]

+    fn custom_hasher() {

+        type FastSparseSecondaryMap<K, V> = SparseSecondaryMap<K, V, fxhash::FxBuildHasher>;

+        let mut sm = SlotMap::new();

+        let mut sec = FastSparseSecondaryMap::default();

+        let key1 = sm.insert(42);

+        sec.insert(key1, 1234);

+        assert_eq!(sec[key1], 1234);

+        assert_eq!(sec.len(), 1);

+        let sec2 = sec.iter().map(|(k, &v)| (k, v)).collect::<FastSparseSecondaryMap<_, _>>();

+        assert_eq!(sec, sec2);

+    }

+

+    #[cfg(all(nightly, feature = "unstable"))]

+    #[test]

+    fn disjoint() {

+        // Intended to be run with miri to find any potential UB.

+        let mut sm = SlotMap::new();

+        let mut sec = SparseSecondaryMap::new();

+

+        // Some churn.

+        for i in 0..20usize {

+            sm.insert(i);

+        }

+        sm.retain(|_, i| *i % 2 == 0);

+

+        for (i, k) in sm.keys().enumerate() {

+            sec.insert(k, i);

+        }

+

+        let keys: Vec<_> = sm.keys().collect();

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                if let Some([r0, r1]) = sec.get_disjoint_mut([keys[i], keys[j]]) {

+                    *r0 ^= *r1;

+                    *r1 = r1.wrapping_add(*r0);

+                } else {

+                    assert!(i == j);

+                }

+            }

+        }

+

+        for i in 0..keys.len() {

+            for j in 0..keys.len() {

+                for k in 0..keys.len() {

+                    if let Some([r0, r1, r2]) = sec.get_disjoint_mut([keys[i], keys[j], keys[k]]) {

+                        *r0 ^= *r1;

+                        *r0 = r0.wrapping_add(*r2);

+                        *r1 ^= *r0;

+                        *r1 = r1.wrapping_add(*r2);

+                        *r2 ^= *r0;

+                        *r2 = r2.wrapping_add(*r1);

+                    } else {

+                        assert!(i == j || j == k || i == k);

+                    }

+                }

+            }

+        }

+    }

+

+    quickcheck! {

+        fn qc_secmap_equiv_hashmap(operations: Vec<(u8, u32)>) -> bool {

+            let mut hm = HashMap::new();

+            let mut hm_keys = Vec::new();

+            let mut unique_key = 0u32;

+            let mut sm = SlotMap::new();

+            let mut sec = SparseSecondaryMap::new();

+            let mut sm_keys = Vec::new();

+

+            #[cfg(not(feature = "serde"))]

+            let num_ops = 4;

+            #[cfg(feature = "serde")]

+            let num_ops = 5;

+

+            for (op, val) in operations {

+                match op % num_ops {

+                    // Insert.

+                    0 => {

+                        hm.insert(unique_key, val);

+                        hm_keys.push(unique_key);

+                        unique_key += 1;

+

+                        let k = sm.insert(val);

+                        sec.insert(k, val);

+                        sm_keys.push(k);

+                    }

+

+                    // Delete.

+                    1 => {

+                        if hm_keys.is_empty() { continue; }

+

+                        let idx = val as usize % hm_keys.len();

+                        sm.remove(sm_keys[idx]);

+                        if hm.remove(&hm_keys[idx]) != sec.remove(sm_keys[idx]) {

+                            return false;

+                        }

+                    }

+

+                    // Access.

+                    2 => {

+                        if hm_keys.is_empty() { continue; }

+                        let idx = val as usize % hm_keys.len();

+                        let (hm_key, sm_key) = (&hm_keys[idx], sm_keys[idx]);

+

+                        if hm.contains_key(hm_key) != sec.contains_key(sm_key) ||

+                           hm.get(hm_key) != sec.get(sm_key) {

+                            return false;

+                        }

+                    }

+

+                    // Clone.

+                    3 => {

+                        sec = sec.clone();

+                    }

+

+                    // Serde round-trip.

+                    #[cfg(feature = "serde")]

+                    4 => {

+                        let ser = serde_json::to_string(&sec).unwrap();

+                        sec = serde_json::from_str(&ser).unwrap();

+                    }

+

+                    _ => unreachable!(),

+                }

+            }

+

+            let mut secv: Vec<_> = sec.values().collect();

+            let mut hmv: Vec<_> = hm.values().collect();

+            secv.sort();

+            hmv.sort();

+            secv == hmv

+        }

+    }

+}

diff --git a/crates/slotmap/src/util.rs b/crates/slotmap/src/util.rs
new file mode 100644
index 0000000..193552c
--- /dev/null
+++ b/crates/slotmap/src/util.rs
@@ -0,0 +1,46 @@
+use core::fmt::Debug;

+use core::hint::unreachable_unchecked;

+

+/// Internal stable replacement for !.

+#[derive(Debug)]

+pub enum Never {}

+

+/// Returns if a is an older version than b, taking into account wrapping of

+/// versions.

+pub fn is_older_version(a: u32, b: u32) -> bool {

+    let diff = a.wrapping_sub(b);

+    diff >= (1 << 31)

+}

+

+/// An unwrapper that checks on debug, doesn't check on release.

+/// UB if unwrapped on release mode when unwrap would panic.

+pub trait UnwrapUnchecked<T> {

+    // Extra underscore because unwrap_unchecked is planned to be added to the stdlib.

+    unsafe fn unwrap_unchecked_(self) -> T;

+}

+

+impl<T> UnwrapUnchecked<T> for Option<T> {

+    unsafe fn unwrap_unchecked_(self) -> T {

+        if cfg!(debug_assertions) {

+            self.unwrap()

+        } else {

+            match self {

+                Some(x) => x,

+                None => unreachable_unchecked(),

+            }

+        }

+    }

+}

+

+impl<T, E: Debug> UnwrapUnchecked<T> for Result<T, E> {

+    unsafe fn unwrap_unchecked_(self) -> T {

+        if cfg!(debug_assertions) {

+            self.unwrap()

+        } else {

+            match self {

+                Ok(x) => x,

+                Err(_) => unreachable_unchecked(),

+            }

+        }

+    }

+}

diff --git a/pseudo_crate/Cargo.lock b/pseudo_crate/Cargo.lock
index efb217e..6fc1d93 100644
--- a/pseudo_crate/Cargo.lock
+++ b/pseudo_crate/Cargo.lock
@@ -421,6 +421,7 @@
  "signal-hook-registry",
  "siphasher",
  "slab",
+ "slotmap",
  "smallvec",
  "smccc",
  "socket2",
@@ -5706,6 +5707,15 @@
 ]
 
 [[package]]
+name = "slotmap"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
 name = "smallvec"
 version = "1.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/pseudo_crate/Cargo.toml b/pseudo_crate/Cargo.toml
index 040c107..84d616a 100644
--- a/pseudo_crate/Cargo.toml
+++ b/pseudo_crate/Cargo.toml
@@ -330,6 +330,7 @@
 signal-hook-registry = "=1.4.2"
 siphasher = "=1.0.1"
 slab = "=0.4.9"
+slotmap = "=1.0.7"
 smallvec = "=1.14.0"
 smccc = "=0.1.1"
 socket2 = "=0.5.8"
diff --git a/pseudo_crate/crate-list.txt b/pseudo_crate/crate-list.txt
index 5dd23a3..0f86736 100644
--- a/pseudo_crate/crate-list.txt
+++ b/pseudo_crate/crate-list.txt
@@ -324,6 +324,7 @@
 signal-hook-registry
 siphasher
 slab
+slotmap
 smallvec
 smccc
 socket2