├── .github └── workflows │ └── rust.yml ├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── benches └── bench.rs ├── deploy-docs.sh ├── src ├── lib.rs ├── serde.rs └── set.rs └── tests ├── serde.rs ├── set.rs └── test.rs /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v2 17 | - name: Build 18 | run: cargo build --verbose 19 | - name: Run tests 20 | run: cargo test --verbose 21 | - name: Run tests (gecko-ffi) 22 | run: cargo test --tests --verbose 23 | 24 | miri: 25 | name: "Miri" 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v2 29 | - name: Install Miri 30 | run: | 31 | rustup toolchain install nightly --component miri 32 | rustup override set nightly 33 | cargo miri setup 34 | - name: Test with Miri 35 | run: MIRIFLAGS=-Zmiri-strict-provenance cargo miri test 36 | 37 | fmt: 38 | runs-on: ubuntu-latest 39 | steps: 40 | - uses: actions/checkout@v2 41 | - uses: actions-rs/toolchain@v1 42 | with: 43 | toolchain: stable 44 | profile: minimal 45 | components: rustfmt 46 | override: true 47 | - uses: actions-rs/cargo@v1 48 | with: 49 | command: fmt 50 | args: --all -- --check 51 | 52 | 53 | clippy: 54 | runs-on: ubuntu-latest 55 | steps: 56 | - uses: actions/checkout@v2 57 | - uses: actions-rs/toolchain@v1 58 | with: 59 | toolchain: stable 60 | profile: minimal 61 | components: clippy 62 | override: true 63 | - uses: actions-rs/clippy-check@v1 64 | env: 65 | PWD: ${{ env.GITHUB_WORKSPACE }} 66 | with: 67 | token: ${{ secrets.GITHUB_TOKEN }} 68 | args: --workspace --tests --examples 69 | 70 | 71 | docs: 72 | runs-on: ubuntu-latest 73 | env: 74 | RUSTDOCFLAGS: -Dwarnings 75 | steps: 76 | - uses: actions/checkout@v2 77 | - uses: actions-rs/toolchain@v1 78 | with: 79 | toolchain: stable 80 | profile: minimal 81 | components: rust-docs 82 | override: true 83 | - uses: swatinem/rust-cache@v1 84 | - uses: actions-rs/cargo@v1 85 | with: 86 | command: doc 87 | args: --workspace --no-deps 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | matrix: 4 | include: 5 | - rust: stable 6 | env: FEATURES="serde_impl" 7 | - rust: nightly 8 | env: FEATURES="serde_impl nightly" 9 | script: 10 | - cargo build --features "$FEATURES" 11 | - cargo test --features "$FEATURES" 12 | - cargo doc --no-deps 13 | after_success: | 14 | [ "$TRAVIS_RUST_VERSION" = nightly ] && 15 | [ "$TRAVIS_BRANCH" = master ] && 16 | [ "$TRAVIS_PULL_REQUEST" = false ] && 17 | bash deploy-docs.sh 18 | notifications: 19 | webhooks: http://huon.me:54857/travis 20 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "linear-map" 3 | version = "1.2.0" 4 | license = "MIT/Apache-2.0" 5 | description = "A map implemented by searching linearly in a vector." 6 | authors = [ 7 | "Andrew Paseltiner ", 8 | "Tobias Bucher ", 9 | ] 10 | repository = "https://github.com/contain-rs/linear-map" 11 | documentation = "https://contain-rs.github.io/linear-map/linear_map" 12 | keywords = ["data-structures"] 13 | readme = "README.md" 14 | 15 | [features] 16 | nightly = [] 17 | serde_impl = ["serde", "serde_test"] 18 | 19 | [dependencies] 20 | serde = { version = "1.0", optional = true } 21 | serde_test = { version = "1.0", optional = true } 22 | 23 | [lib] 24 | test = false 25 | bench = false 26 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Rust CI](https://github.com/contain-rs/linear-map/workflows/Rust/badge.svg?branch=master) [![crates.io](https://img.shields.io/crates/v/linear-map.svg)](https://crates.io/crates/linear-map) [![](https://docs.rs/linear-map/badge.svg)](https://docs.rs/linear-map) 2 | 3 | **WARNING: THIS PROJECT IS IN MAINTENANCE MODE, DUE TO INSUFFICIENT MAINTAINER RESOURCES** 4 | 5 | It works fine, but will generally no longer be improved. 6 | 7 | We are currently only accepting changes which: 8 | 9 | * keep this compiling with the latest versions of Rust or its dependencies. 10 | * have minimal review requirements, such as documentation changes (so not totally new APIs). 11 | 12 | ------ 13 | 14 | 15 | A map implemented by searching linearly in a vector. 16 | 17 | -------------------------------------------------------------------------------- /benches/bench.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | 3 | extern crate linear_map; 4 | extern crate test; 5 | 6 | use linear_map::LinearMap; 7 | 8 | const SMALL: u32 = 10; 9 | const MEDIUM: u32 = 100; 10 | const BIG: u32 = 1000; 11 | 12 | fn insert(b: &mut test::Bencher, num: u32) { 13 | b.iter(|| { 14 | let mut map = LinearMap::new(); 15 | for i in 0..num { 16 | map.insert(i, i); 17 | } 18 | }) 19 | } 20 | 21 | fn remove_insert(b: &mut test::Bencher, num: u32) { 22 | b.iter(|| { 23 | let mut map = LinearMap::new(); 24 | for i in 0..num { 25 | map.insert(i, i); 26 | } 27 | for i in 0..num { 28 | map.remove(&i); 29 | } 30 | }) 31 | } 32 | 33 | fn remove_rev_insert(b: &mut test::Bencher, num: u32) { 34 | b.iter(|| { 35 | let mut map = LinearMap::new(); 36 | for i in 0..num { 37 | map.insert(i, i); 38 | } 39 | for i in 0..num { 40 | map.remove(&(num - i - 1)); 41 | } 42 | }) 43 | } 44 | 45 | fn get_middle(b: &mut test::Bencher, num: u32) { 46 | let mut map = LinearMap::new(); 47 | for i in 0..num { 48 | map.insert(i, i); 49 | } 50 | let middle = num / 2; 51 | b.iter(|| { 52 | test::black_box(map.get(&middle)); 53 | test::black_box(map.get_mut(&middle)); 54 | }) 55 | } 56 | 57 | fn get_none(b: &mut test::Bencher, num: u32) { 58 | let mut map = LinearMap::new(); 59 | for i in 0..num { 60 | map.insert(i, i); 61 | } 62 | let none = num + 1; 63 | b.iter(|| { 64 | test::black_box(map.get(&none)); 65 | test::black_box(map.get_mut(&none)); 66 | }) 67 | } 68 | 69 | #[bench] 70 | fn bench_insert_small(b: &mut test::Bencher) { 71 | insert(b, SMALL); 72 | } 73 | #[bench] 74 | fn bench_insert_medium(b: &mut test::Bencher) { 75 | insert(b, MEDIUM); 76 | } 77 | #[bench] 78 | fn bench_insert_big(b: &mut test::Bencher) { 79 | insert(b, BIG); 80 | } 81 | 82 | #[bench] 83 | fn bench_remove_insert_small(b: &mut test::Bencher) { 84 | remove_insert(b, SMALL); 85 | } 86 | #[bench] 87 | fn bench_remove_insert_medium(b: &mut test::Bencher) { 88 | remove_insert(b, MEDIUM); 89 | } 90 | #[bench] 91 | fn bench_remove_insert_big(b: &mut test::Bencher) { 92 | remove_insert(b, BIG); 93 | } 94 | 95 | #[bench] 96 | fn bench_remove_rev_insert_small(b: &mut test::Bencher) { 97 | remove_rev_insert(b, SMALL); 98 | } 99 | #[bench] 100 | fn bench_remove_rev_insert_medium(b: &mut test::Bencher) { 101 | remove_rev_insert(b, MEDIUM); 102 | } 103 | #[bench] 104 | fn bench_remove_rev_insert_big(b: &mut test::Bencher) { 105 | remove_rev_insert(b, BIG); 106 | } 107 | 108 | #[bench] 109 | fn bench_get_middle_small(b: &mut test::Bencher) { 110 | get_middle(b, SMALL); 111 | } 112 | #[bench] 113 | fn bench_get_middle_medium(b: &mut test::Bencher) { 114 | get_middle(b, MEDIUM); 115 | } 116 | #[bench] 117 | fn bench_get_middle_big(b: &mut test::Bencher) { 118 | get_middle(b, BIG); 119 | } 120 | 121 | #[bench] 122 | fn bench_get_none_small(b: &mut test::Bencher) { 123 | get_none(b, SMALL); 124 | } 125 | #[bench] 126 | fn bench_get_none_medium(b: &mut test::Bencher) { 127 | get_none(b, MEDIUM); 128 | } 129 | #[bench] 130 | fn bench_get_none_big(b: &mut test::Bencher) { 131 | get_none(b, BIG); 132 | } 133 | -------------------------------------------------------------------------------- /deploy-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit -o nounset 4 | 5 | rev=$(git rev-parse --short HEAD) 6 | 7 | cd target/doc 8 | 9 | git init 10 | git config user.email 'FlashCat@users.noreply.github.com' 11 | git config user.name 'FlashCat' 12 | git remote add upstream "https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git" 13 | git fetch upstream gh-pages 14 | git reset upstream/gh-pages 15 | 16 | touch . 17 | 18 | git add -A . 19 | git commit -m "rebuild pages at ${rev}" 20 | git push -q upstream HEAD:gh-pages 21 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! A map implemented by searching linearly in a vector. 2 | //! 3 | //! See the [`LinearMap`](struct.LinearMap.html) type for details. 4 | 5 | #![deny(missing_docs)] 6 | 7 | // Optional Serde support 8 | #[cfg(feature = "serde_impl")] 9 | pub mod serde; 10 | pub mod set; 11 | 12 | use std::borrow::Borrow; 13 | use std::fmt::{self, Debug}; 14 | use std::iter; 15 | use std::mem; 16 | use std::ops; 17 | use std::slice; 18 | use std::vec; 19 | 20 | use self::Entry::{Occupied, Vacant}; 21 | 22 | /// A map implemented by searching linearly in a vector. 23 | /// 24 | /// `LinearMap`'s keys are compared using the [`Eq`][eq] trait. All search operations 25 | /// (`contains_key`, `get`, `get_mut`, `insert`, and `remove`) run in `O(n)` time, making this 26 | /// implementation suitable only for small numbers of keys. The ordering of the keys in the 27 | /// underlying vector is arbitrary. 28 | /// 29 | /// It is a logic error for a key to be modified in such a way that the key's equality, as 30 | /// determined by the [`Eq`][eq] trait, changes while it is in the map. This is normally only 31 | /// possible through [`Cell`][cell], [`RefCell`][ref_cell], global state, I/O, or unsafe code. 32 | /// 33 | /// [cell]: https://doc.rust-lang.org/nightly/std/cell/struct.Cell.html 34 | /// [eq]: https://doc.rust-lang.org/nightly/std/cmp/trait.Eq.html 35 | /// [ref_cell]: https://doc.rust-lang.org/nightly/std/cell/struct.RefCell.html 36 | /// 37 | /// # Example 38 | /// 39 | /// ``` 40 | /// use linear_map::LinearMap; 41 | /// 42 | /// // type inference lets us omit an explicit type signature (which 43 | /// // would be `LinearMap<&str, &str>` in this example). 44 | /// let mut book_reviews = LinearMap::new(); 45 | /// 46 | /// // review some books. 47 | /// book_reviews.insert("Adventures of Huckleberry Finn", "My favorite book."); 48 | /// book_reviews.insert("Grimms' Fairy Tales", "Masterpiece."); 49 | /// book_reviews.insert("Pride and Prejudice", "Very enjoyable."); 50 | /// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot."); 51 | /// 52 | /// // check for a specific one. 53 | /// if !book_reviews.contains_key("Les Misérables") { 54 | /// println!("We've got {} reviews, but Les Misérables ain't one.", 55 | /// book_reviews.len()); 56 | /// } 57 | /// 58 | /// // oops, this review has a lot of spelling mistakes. let's delete it. 59 | /// book_reviews.remove("The Adventures of Sherlock Holmes"); 60 | /// 61 | /// // look up the values associated with some keys. 62 | /// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]; 63 | /// for book in &to_find { 64 | /// match book_reviews.get(book) { 65 | /// Some(review) => println!("{}: {}", book, review), 66 | /// None => println!("{} is unreviewed.", book) 67 | /// } 68 | /// } 69 | /// 70 | /// // iterate over everything. 71 | /// for (book, review) in &book_reviews { 72 | /// println!("{}: \"{}\"", book, review); 73 | /// } 74 | /// ``` 75 | pub struct LinearMap { 76 | storage: Vec<(K, V)>, 77 | } 78 | 79 | impl LinearMap { 80 | /// Creates an empty map. This method does not allocate. 81 | pub fn new() -> Self { 82 | LinearMap { storage: vec![] } 83 | } 84 | 85 | /// Creates an empty map with the given initial capacity. 86 | pub fn with_capacity(capacity: usize) -> Self { 87 | LinearMap { 88 | storage: Vec::with_capacity(capacity), 89 | } 90 | } 91 | 92 | /// Returns the number of elements the map can hold without reallocating. 93 | pub fn capacity(&self) -> usize { 94 | self.storage.capacity() 95 | } 96 | 97 | /// Reserves capacity for at least `additional` more to be inserted in the 98 | /// map. The collection may reserve more space to avoid frequent 99 | /// reallocations. 100 | /// 101 | /// # Panics 102 | /// 103 | /// Panics if the new allocation size overflows `usize`. 104 | pub fn reserve(&mut self, additional: usize) { 105 | self.storage.reserve(additional); 106 | } 107 | 108 | /// Reserves the minimum capacity for exactly `additional` more elemnnts to 109 | /// be inserted in the map. 110 | /// 111 | /// Note that the allocator may give the collection more space than it 112 | /// requests. Therefore capacity cannot be relied upon to be precisely 113 | /// minimal. Prefer `reserve` if future insertions are expected. 114 | /// 115 | /// # Panics 116 | /// 117 | /// Panics if the new capacity overflows `usize`. 118 | pub fn reserve_exact(&mut self, additional: usize) { 119 | self.storage.reserve_exact(additional); 120 | } 121 | 122 | /// Shrinks the capacity of the map as much as possible. 123 | /// 124 | /// It will drop down as close as possible to the current length but the 125 | /// allocator may still inform the map that there is more space than 126 | /// necessary. Therefore capacity cannot be relid upon to be minimal. 127 | pub fn shrink_to_fit(&mut self) { 128 | self.storage.shrink_to_fit(); 129 | } 130 | 131 | /// Returns the number of elements in the map. 132 | pub fn len(&self) -> usize { 133 | self.storage.len() 134 | } 135 | 136 | /// Returns true if the map contains no elements. 137 | pub fn is_empty(&self) -> bool { 138 | self.storage.is_empty() 139 | } 140 | 141 | /// Clears the map, removing all elements. Keeps the allocated memory for 142 | /// reuse. 143 | pub fn clear(&mut self) { 144 | self.storage.clear(); 145 | } 146 | 147 | /// Scan through the map and keep those key-value pairs where the 148 | /// closure returns `true`. 149 | /// 150 | /// The order the elements are visited is not specified. 151 | pub fn retain(&mut self, mut keep_fn: F) 152 | where 153 | F: FnMut(&K, &mut V) -> bool, 154 | { 155 | let mut del = 0; 156 | { 157 | let v = &mut *self.storage; 158 | for i in 0..v.len() { 159 | if !keep_fn(&v[i].0, &mut v[i].1) { 160 | del += 1; 161 | } else if del > 0 { 162 | v.swap(i - del, i); 163 | } 164 | } 165 | } 166 | if del > 0 { 167 | let len = self.storage.len(); 168 | self.storage.truncate(len - del); 169 | } 170 | } 171 | 172 | /// Removes all key-value pairs from the map and returns an iterator that yields them in 173 | /// arbitrary order. 174 | /// 175 | /// All key-value pairs are removed even if the iterator is not exhausted. However, the 176 | /// behavior of this method is unspecified if the iterator is leaked. 177 | /// 178 | /// The iterator's item type is `(K, V)`. 179 | pub fn drain(&mut self) -> Drain { 180 | Drain { 181 | iter: self.storage.drain(..), 182 | } 183 | } 184 | 185 | /// Returns an iterator yielding references to the map's keys and their corresponding values in 186 | /// arbitrary order. 187 | /// 188 | /// The iterator's item type is `(&K, &V)`. 189 | pub fn iter(&self) -> Iter { 190 | Iter { 191 | iter: self.storage.iter(), 192 | } 193 | } 194 | 195 | /// Returns an iterator yielding references to the map's keys and mutable references to their 196 | /// corresponding values in arbitrary order. 197 | /// 198 | /// The iterator's item type is `(&K, &mut V)`. 199 | pub fn iter_mut(&mut self) -> IterMut { 200 | IterMut { 201 | iter: self.storage.iter_mut(), 202 | } 203 | } 204 | 205 | /// Returns an iterator yielding references to the map's keys in arbitrary order. 206 | /// 207 | /// The iterator's item type is `&K`. 208 | pub fn keys(&self) -> Keys { 209 | Keys { iter: self.iter() } 210 | } 211 | 212 | /// Returns an iterator yielding references to the map's values in arbitrary order. 213 | /// 214 | /// The iterator's item type is `&V`. 215 | pub fn values(&self) -> Values { 216 | Values { iter: self.iter() } 217 | } 218 | 219 | /// Returns a reference to the value in the map whose key is equal to the given key. 220 | /// 221 | /// Returns `None` if the map contains no such key. 222 | /// 223 | /// The given key may be any borrowed form of the map's key type, but `Eq` on the borrowed form 224 | /// *must* match that of the key type. 225 | pub fn get(&self, key: &Q) -> Option<&V> 226 | where 227 | K: Borrow, 228 | { 229 | for (k, v) in self { 230 | if key == k.borrow() { 231 | return Some(v); 232 | } 233 | } 234 | None 235 | } 236 | 237 | /// Returns a mutable reference to the value in the map whose key is equal to the given key. 238 | /// 239 | /// Returns `None` if the map contains no such key. 240 | /// 241 | /// The given key may be any borrowed form of the map's key type, but `Eq` on the borrowed form 242 | /// *must* match that of the key type. 243 | pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> 244 | where 245 | K: Borrow, 246 | { 247 | for (k, v) in self { 248 | if key == k.borrow() { 249 | return Some(v); 250 | } 251 | } 252 | None 253 | } 254 | 255 | /// Checks if the map contains a key that is equal to the given key. 256 | /// 257 | /// The given key may be any borrowed form of the map's key type, but `Eq` on the borrowed form 258 | /// *must* match that of the key type. 259 | pub fn contains_key(&self, key: &Q) -> bool 260 | where 261 | K: Borrow, 262 | { 263 | self.get(key).is_some() 264 | } 265 | 266 | /// Inserts a key-value pair into the map. 267 | /// 268 | /// Returns `None` if the map did not contain a key that is equal to the given key. 269 | /// 270 | /// If the map did contain such a key, its corresponding value is replaced with the given 271 | /// value, and the old value is returned. The key is not updated, though. This matters for 272 | /// values that can be `==` without being identical. See the [standard library's documentation] 273 | /// [std] for more details. 274 | /// 275 | /// [std]: https://doc.rust-lang.org/nightly/std/collections/index.html#insert-and-complex-keys 276 | pub fn insert(&mut self, key: K, value: V) -> Option { 277 | match self.entry(key) { 278 | Occupied(mut e) => Some(e.insert(value)), 279 | Vacant(e) => { 280 | e.insert(value); 281 | None 282 | } 283 | } 284 | } 285 | 286 | /// Removes the key in the map that is equal to the given key and returns its corresponding 287 | /// value. 288 | /// 289 | /// Returns `None` if the map contained no such key. 290 | /// 291 | /// The given key may be any borrowed form of the map's key type, but `Eq` on the borrowed form 292 | /// *must* match that of the key type. 293 | pub fn remove(&mut self, key: &Q) -> Option 294 | where 295 | K: Borrow, 296 | { 297 | for i in 0..self.storage.len() { 298 | if self.storage[i].0.borrow() == key { 299 | return Some(self.storage.swap_remove(i).1); 300 | } 301 | } 302 | None 303 | } 304 | 305 | /// Returns the given key's corresponding entry in the map for in-place manipulation. 306 | pub fn entry(&mut self, key: K) -> Entry { 307 | match self.storage.iter().position(|&(ref k, _)| key == *k) { 308 | None => Vacant(VacantEntry { map: self, key }), 309 | Some(index) => Occupied(OccupiedEntry { map: self, index }), 310 | } 311 | } 312 | } 313 | 314 | impl Clone for LinearMap { 315 | fn clone(&self) -> Self { 316 | LinearMap { 317 | storage: self.storage.clone(), 318 | } 319 | } 320 | 321 | fn clone_from(&mut self, other: &Self) { 322 | self.storage.clone_from(&other.storage); 323 | } 324 | } 325 | 326 | impl Debug for LinearMap { 327 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 328 | f.debug_map().entries(self).finish() 329 | } 330 | } 331 | 332 | impl Default for LinearMap { 333 | fn default() -> Self { 334 | Self::new() 335 | } 336 | } 337 | 338 | impl Extend<(K, V)> for LinearMap { 339 | fn extend>(&mut self, key_values: I) { 340 | for (key, value) in key_values { 341 | self.insert(key, value); 342 | } 343 | } 344 | } 345 | 346 | impl iter::FromIterator<(K, V)> for LinearMap { 347 | fn from_iter>(key_values: I) -> Self { 348 | let mut map = Self::new(); 349 | map.extend(key_values); 350 | map 351 | } 352 | } 353 | 354 | impl<'a, K: Eq + Borrow, V, Q: ?Sized + Eq> ops::Index<&'a Q> for LinearMap { 355 | type Output = V; 356 | 357 | fn index(&self, key: &'a Q) -> &V { 358 | self.get(key).expect("key not found") 359 | } 360 | } 361 | 362 | impl PartialEq for LinearMap { 363 | fn eq(&self, other: &Self) -> bool { 364 | if self.len() != other.len() { 365 | return false; 366 | } 367 | 368 | for (key, value) in self { 369 | if other.get(key) != Some(value) { 370 | return false; 371 | } 372 | } 373 | 374 | true 375 | } 376 | } 377 | 378 | impl Eq for LinearMap {} 379 | 380 | impl From> for Vec<(K, V)> { 381 | fn from(other: LinearMap) -> Self { 382 | other.storage 383 | } 384 | } 385 | 386 | impl From> for LinearMap { 387 | fn from(other: Vec<(K, V)>) -> Self { 388 | Self { storage: other } 389 | } 390 | } 391 | 392 | /// Creates a `LinearMap` from a list of key-value pairs. 393 | /// 394 | /// The created `LinearMap` has a capacity set to the number of entries provided. 395 | /// 396 | /// # Example 397 | /// 398 | /// ``` 399 | /// #[macro_use] extern crate linear_map; 400 | /// # fn main() { 401 | /// 402 | /// let map = linear_map!{ 403 | /// "a" => 1, 404 | /// "b" => 2, 405 | /// }; 406 | /// assert_eq!(map["a"], 1); 407 | /// assert_eq!(map["b"], 2); 408 | /// assert_eq!(map.get("c"), None); 409 | /// # } 410 | /// ``` 411 | #[macro_export] 412 | macro_rules! linear_map { 413 | ($($key:expr => $value:expr,)+) => { linear_map!($($key => $value),+) }; 414 | ($($key:expr => $value:expr),*) => { 415 | { 416 | let _cap = <[&str]>::len(&[$(stringify!($key)),*]); 417 | let mut _map = $crate::LinearMap::with_capacity(_cap); 418 | $( 419 | _map.insert($key, $value); 420 | )* 421 | _map 422 | } 423 | }; 424 | } 425 | 426 | /// A view into a single occupied location in a `LinearMap`. 427 | /// 428 | /// See [`LinearMap::entry`](struct.LinearMap.html#method.entry) for details. 429 | pub struct OccupiedEntry<'a, K: 'a, V: 'a> { 430 | map: &'a mut LinearMap, 431 | index: usize, 432 | } 433 | 434 | /// A view into a single vacant location in a `LinearMap`. 435 | /// 436 | /// See [`LinearMap::entry`](struct.LinearMap.html#method.entry) for details. 437 | pub struct VacantEntry<'a, K: 'a, V: 'a> { 438 | map: &'a mut LinearMap, 439 | key: K, 440 | } 441 | 442 | /// A view into a single entry in a `LinearMap`. 443 | /// 444 | /// See [`LinearMap::entry`](struct.LinearMap.html#method.entry) for details. 445 | pub enum Entry<'a, K: 'a, V: 'a> { 446 | /// An occupied entry. 447 | Occupied(OccupiedEntry<'a, K, V>), 448 | 449 | /// A vacant entry. 450 | Vacant(VacantEntry<'a, K, V>), 451 | } 452 | 453 | impl<'a, K, V> Entry<'a, K, V> { 454 | /// Ensures that the entry is occupied by inserting the given value if it is vacant. 455 | /// 456 | /// Returns a mutable reference to the entry's value. 457 | pub fn or_insert(self, default: V) -> &'a mut V { 458 | match self { 459 | Occupied(entry) => entry.into_mut(), 460 | Vacant(entry) => entry.insert(default), 461 | } 462 | } 463 | 464 | /// Ensures that the entry is occupied by inserting the the result of the given function if it 465 | /// is vacant. 466 | /// 467 | /// Returns a mutable reference to the entry's value. 468 | pub fn or_insert_with V>(self, default: F) -> &'a mut V { 469 | match self { 470 | Occupied(entry) => entry.into_mut(), 471 | Vacant(entry) => entry.insert(default()), 472 | } 473 | } 474 | } 475 | 476 | impl<'a, K, V> OccupiedEntry<'a, K, V> { 477 | /// Returns a reference to the entry's value. 478 | pub fn get(&self) -> &V { 479 | &self.map.storage[self.index].1 480 | } 481 | 482 | /// Returns a mutable reference to the entry's value. 483 | pub fn get_mut(&mut self) -> &mut V { 484 | &mut self.map.storage[self.index].1 485 | } 486 | 487 | /// Returns a mutable reference to the entry's value with the same lifetime as the map. 488 | pub fn into_mut(self) -> &'a mut V { 489 | &mut self.map.storage[self.index].1 490 | } 491 | 492 | /// Replaces the entry's value with the given one and returns the previous value. 493 | pub fn insert(&mut self, value: V) -> V { 494 | mem::replace(self.get_mut(), value) 495 | } 496 | 497 | /// Removes the entry from the map and returns its value. 498 | pub fn remove(self) -> V { 499 | self.map.storage.swap_remove(self.index).1 500 | } 501 | } 502 | 503 | impl<'a, K, V> VacantEntry<'a, K, V> { 504 | /// Inserts the entry into the map with the given value. 505 | /// 506 | /// Returns a mutable reference to the entry's value with the same lifetime as the map. 507 | pub fn insert(self, value: V) -> &'a mut V { 508 | self.map.storage.push((self.key, value)); 509 | &mut self.map.storage.last_mut().unwrap().1 510 | } 511 | } 512 | 513 | /// A consuming iterator over a `LinearMap`. 514 | /// 515 | /// The iterator's order is arbitrary. 516 | /// 517 | /// Acquire through [`IntoIterator`](struct.LinearMap.html#method.into_iter). 518 | pub struct IntoIter { 519 | iter: vec::IntoIter<(K, V)>, 520 | } 521 | 522 | impl Iterator for IntoIter { 523 | type Item = (K, V); 524 | 525 | fn next(&mut self) -> Option<(K, V)> { 526 | self.iter.next() 527 | } 528 | 529 | fn size_hint(&self) -> (usize, Option) { 530 | self.iter.size_hint() 531 | } 532 | } 533 | 534 | impl DoubleEndedIterator for IntoIter { 535 | fn next_back(&mut self) -> Option<(K, V)> { 536 | self.iter.next_back() 537 | } 538 | } 539 | 540 | impl ExactSizeIterator for IntoIter { 541 | fn len(&self) -> usize { 542 | self.iter.len() 543 | } 544 | } 545 | 546 | /// A draining iterator over a `LinearMap`. 547 | /// 548 | /// See [`LinearMap::drain`](struct.LinearMap.html#method.drain) for details. 549 | pub struct Drain<'a, K: 'a, V: 'a> { 550 | iter: vec::Drain<'a, (K, V)>, 551 | } 552 | 553 | /// An iterator yielding references to a `LinearMap`'s keys and their corresponding values. 554 | /// 555 | /// See [`LinearMap::iter`](struct.LinearMap.html#method.iter) for details. 556 | pub struct Iter<'a, K: 'a, V: 'a> { 557 | iter: slice::Iter<'a, (K, V)>, 558 | } 559 | 560 | /// An iterator yielding references to a `LinearMap`'s keys and mutable references to their 561 | /// corresponding values. 562 | /// 563 | /// See [`LinearMap::iter_mut`](struct.LinearMap.html#method.iter_mut) for details. 564 | pub struct IterMut<'a, K: 'a, V: 'a> { 565 | iter: slice::IterMut<'a, (K, V)>, 566 | } 567 | 568 | /// An iterator yielding references to a `LinearMap`'s keys in arbitrary order. 569 | /// 570 | /// See [`LinearMap::keys`](struct.LinearMap.html#method.keys) for details. 571 | pub struct Keys<'a, K: 'a, V: 'a> { 572 | iter: Iter<'a, K, V>, 573 | } 574 | 575 | /// An iterator yielding references to a `LinearMap`'s values in arbitrary order. 576 | /// 577 | /// See [`LinearMap::values`](struct.LinearMap.html#method.values) for details. 578 | pub struct Values<'a, K: 'a, V: 'a> { 579 | iter: Iter<'a, K, V>, 580 | } 581 | 582 | macro_rules! impl_iter { 583 | ($typ:ty, $item:ty, $map:expr) => { 584 | impl<'a, K, V> Iterator for $typ { 585 | type Item = $item; 586 | 587 | fn next(&mut self) -> Option { 588 | self.iter.next().map($map) 589 | } 590 | 591 | fn size_hint(&self) -> (usize, Option) { 592 | self.iter.size_hint() 593 | } 594 | } 595 | 596 | impl<'a, K, V> DoubleEndedIterator for $typ { 597 | fn next_back(&mut self) -> Option { 598 | self.iter.next_back().map($map) 599 | } 600 | } 601 | 602 | impl<'a, K, V> ExactSizeIterator for $typ { 603 | fn len(&self) -> usize { 604 | self.iter.len() 605 | } 606 | } 607 | }; 608 | } 609 | impl_iter! {Drain<'a,K,V>, (K,V), |e| e } 610 | impl_iter! {Iter<'a,K,V>, (&'a K, &'a V), |e| (&e.0, &e.1) } 611 | impl_iter! {IterMut<'a,K,V>, (&'a K, &'a mut V), |e| (&e.0, &mut e.1) } 612 | impl_iter! {Keys<'a,K,V>, &'a K, |e| e.0 } 613 | impl_iter! {Values<'a,K,V>, &'a V, |e| e.1 } 614 | 615 | impl<'a, K, V> Clone for Iter<'a, K, V> { 616 | fn clone(&self) -> Self { 617 | Iter { 618 | iter: self.iter.clone(), 619 | } 620 | } 621 | } 622 | 623 | impl<'a, K, V> Clone for Keys<'a, K, V> { 624 | fn clone(&self) -> Self { 625 | Keys { 626 | iter: self.iter.clone(), 627 | } 628 | } 629 | } 630 | 631 | impl<'a, K, V> Clone for Values<'a, K, V> { 632 | fn clone(&self) -> Self { 633 | Values { 634 | iter: self.iter.clone(), 635 | } 636 | } 637 | } 638 | 639 | impl IntoIterator for LinearMap { 640 | type Item = (K, V); 641 | type IntoIter = IntoIter; 642 | 643 | fn into_iter(self) -> IntoIter { 644 | IntoIter { 645 | iter: self.storage.into_iter(), 646 | } 647 | } 648 | } 649 | 650 | impl<'a, K: Eq, V> IntoIterator for &'a LinearMap { 651 | type Item = (&'a K, &'a V); 652 | type IntoIter = Iter<'a, K, V>; 653 | 654 | fn into_iter(self) -> Iter<'a, K, V> { 655 | self.iter() 656 | } 657 | } 658 | 659 | impl<'a, K: Eq, V> IntoIterator for &'a mut LinearMap { 660 | type Item = (&'a K, &'a mut V); 661 | type IntoIter = IterMut<'a, K, V>; 662 | 663 | fn into_iter(self) -> IterMut<'a, K, V> { 664 | self.iter_mut() 665 | } 666 | } 667 | 668 | #[allow(dead_code)] 669 | fn assert_covariance() { 670 | fn a<'a, K, V>(x: LinearMap<&'static K, &'static V>) -> LinearMap<&'a K, &'a V> { 671 | x 672 | } 673 | 674 | fn b<'a, K, V>(x: IntoIter<&'static K, &'static V>) -> IntoIter<&'a K, &'a V> { 675 | x 676 | } 677 | 678 | fn c<'i, 'a, K, V>(x: Iter<'i, &'static K, &'static V>) -> Iter<'i, &'a K, &'a V> { 679 | x 680 | } 681 | 682 | fn d<'i, 'a, K, V>(x: Keys<'i, &'static K, &'static V>) -> Keys<'i, &'a K, &'a V> { 683 | x 684 | } 685 | 686 | fn e<'i, 'a, K, V>(x: Values<'i, &'static K, &'static V>) -> Values<'i, &'a K, &'a V> { 687 | x 688 | } 689 | } 690 | -------------------------------------------------------------------------------- /src/serde.rs: -------------------------------------------------------------------------------- 1 | //! An optional implementation of serialization/deserialization. Reference 2 | //! implementations used: 3 | //! 4 | //! - [Serialize][1]. 5 | //! - [Deserialize][2]. 6 | //! 7 | //! [1]: https://github.com/serde-rs/serde/blob/97856462467db2e90cf368e407c7ebcc726a01a9/serde/src/ser/impls.rs#L601-L611 8 | //! [2]: https://github.com/serde-rs/serde/blob/97856462467db2e90cf368e407c7ebcc726a01a9/serde/src/de/impls.rs#L694-L746 9 | 10 | extern crate serde; 11 | 12 | use super::set::LinearSet; 13 | use super::LinearMap; 14 | 15 | use self::serde::de::{Error, MapAccess, SeqAccess, Visitor}; 16 | use self::serde::ser::{SerializeMap, SerializeSeq}; 17 | use self::serde::{Deserialize, Deserializer, Serialize, Serializer}; 18 | 19 | use std::fmt; 20 | use std::marker::PhantomData; 21 | 22 | impl Serialize for LinearMap 23 | where 24 | K: Serialize + Eq, 25 | V: Serialize, 26 | { 27 | #[inline] 28 | fn serialize(&self, serializer: S) -> Result 29 | where 30 | S: Serializer, 31 | { 32 | let mut state = try!(serializer.serialize_map(Some(self.len()))); 33 | for (k, v) in self { 34 | try!(state.serialize_entry(k, v)); 35 | } 36 | state.end() 37 | } 38 | } 39 | 40 | #[allow(missing_docs)] 41 | pub struct LinearMapVisitor { 42 | marker: PhantomData>, 43 | } 44 | 45 | impl LinearMapVisitor { 46 | #[allow(missing_docs)] 47 | pub fn new() -> Self { 48 | LinearMapVisitor { 49 | marker: PhantomData, 50 | } 51 | } 52 | } 53 | 54 | impl<'de, K, V> Visitor<'de> for LinearMapVisitor 55 | where 56 | K: Deserialize<'de> + Eq, 57 | V: Deserialize<'de>, 58 | { 59 | type Value = LinearMap; 60 | 61 | fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { 62 | write!(f, "a LinearMap") 63 | } 64 | 65 | #[inline] 66 | fn visit_unit(self) -> Result 67 | where 68 | E: Error, 69 | { 70 | Ok(LinearMap::new()) 71 | } 72 | 73 | #[inline] 74 | fn visit_map(self, mut visitor: Visitor) -> Result 75 | where 76 | Visitor: MapAccess<'de>, 77 | { 78 | let mut values = LinearMap::with_capacity(visitor.size_hint().unwrap_or(0)); 79 | 80 | while let Some((key, value)) = try!(visitor.next_entry()) { 81 | values.insert(key, value); 82 | } 83 | 84 | Ok(values) 85 | } 86 | } 87 | 88 | impl<'de, K, V> Deserialize<'de> for LinearMap 89 | where 90 | K: Deserialize<'de> + Eq, 91 | V: Deserialize<'de>, 92 | { 93 | fn deserialize(deserializer: D) -> Result, D::Error> 94 | where 95 | D: Deserializer<'de>, 96 | { 97 | deserializer.deserialize_map(LinearMapVisitor::new()) 98 | } 99 | } 100 | 101 | impl Serialize for LinearSet 102 | where 103 | K: Serialize + Eq, 104 | { 105 | #[inline] 106 | fn serialize(&self, serializer: S) -> Result 107 | where 108 | S: Serializer, 109 | { 110 | let mut state = try!(serializer.serialize_seq(Some(self.len()))); 111 | for k in self { 112 | try!(state.serialize_element(k)); 113 | } 114 | state.end() 115 | } 116 | } 117 | 118 | #[allow(missing_docs)] 119 | pub struct LinearSetVisitor { 120 | marker: PhantomData>, 121 | } 122 | 123 | impl LinearSetVisitor { 124 | #[allow(missing_docs)] 125 | pub fn new() -> Self { 126 | LinearSetVisitor { 127 | marker: PhantomData, 128 | } 129 | } 130 | } 131 | 132 | impl<'de, K> Visitor<'de> for LinearSetVisitor 133 | where 134 | K: Deserialize<'de> + Eq, 135 | { 136 | type Value = LinearSet; 137 | 138 | fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { 139 | write!(f, "a LinearSet") 140 | } 141 | 142 | #[inline] 143 | fn visit_unit(self) -> Result 144 | where 145 | E: Error, 146 | { 147 | Ok(LinearSet::new()) 148 | } 149 | 150 | #[inline] 151 | fn visit_seq(self, mut visitor: Visitor) -> Result 152 | where 153 | Visitor: SeqAccess<'de>, 154 | { 155 | let mut values = LinearSet::with_capacity(visitor.size_hint().unwrap_or(0)); 156 | 157 | while let Some(key) = try!(visitor.next_element()) { 158 | values.insert(key); 159 | } 160 | 161 | Ok(values) 162 | } 163 | } 164 | 165 | impl<'de, K> Deserialize<'de> for LinearSet 166 | where 167 | K: Deserialize<'de> + Eq, 168 | { 169 | fn deserialize(deserializer: D) -> Result, D::Error> 170 | where 171 | D: Deserializer<'de>, 172 | { 173 | deserializer.deserialize_seq(LinearSetVisitor::new()) 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /src/set.rs: -------------------------------------------------------------------------------- 1 | //! A set implemented by searching linearly in a vector. 2 | //! 3 | //! See the [`LinearSet`](struct.LinearSet.html) type for details. 4 | 5 | use std::borrow::Borrow; 6 | use std::fmt; 7 | use std::iter::{Chain, FromIterator}; 8 | use std::ops::{BitAnd, BitOr, BitXor, Sub}; 9 | 10 | use super::{Keys, LinearMap}; 11 | 12 | /// An implementation of a set using the underlying representation of a 13 | /// LinearMap where the value is (). 14 | /// 15 | /// # Examples 16 | /// 17 | /// ``` 18 | /// use linear_map::set::LinearSet;; 19 | /// // Type inference lets us omit an explicit type signature (which 20 | /// // would be `LinearSet<&str>` in this example). 21 | /// let mut books = LinearSet::new(); 22 | /// 23 | /// // Add some books. 24 | /// books.insert("A Dance With Dragons"); 25 | /// books.insert("To Kill a Mockingbird"); 26 | /// books.insert("The Odyssey"); 27 | /// books.insert("The Great Gatsby"); 28 | /// 29 | /// // Check for a specific one. 30 | /// if !books.contains("The Winds of Winter") { 31 | /// println!("We have {} books, but The Winds of Winter ain't one.", 32 | /// books.len()); 33 | /// } 34 | /// 35 | /// // Remove a book. 36 | /// books.remove("The Odyssey"); 37 | /// 38 | /// // Iterate over everything. 39 | /// for book in &books { 40 | /// println!("{}", book); 41 | /// } 42 | /// ``` 43 | /// 44 | /// The easiest way to use `LinearSet` with a custom type is to derive 45 | /// `Eq`. We must also derive `PartialEq`, this will in the 46 | /// future be implied by `Eq`. 47 | /// 48 | /// ``` 49 | /// use linear_map::set::LinearSet;; 50 | /// #[derive(Eq, PartialEq, Debug)] 51 | /// struct Viking<'a> { 52 | /// name: &'a str, 53 | /// power: usize, 54 | /// } 55 | /// 56 | /// let mut vikings = LinearSet::new(); 57 | /// 58 | /// vikings.insert(Viking { name: "Einar", power: 9 }); 59 | /// vikings.insert(Viking { name: "Einar", power: 9 }); 60 | /// vikings.insert(Viking { name: "Olaf", power: 4 }); 61 | /// vikings.insert(Viking { name: "Harald", power: 8 }); 62 | /// 63 | /// // Use derived implementation to print the vikings. 64 | /// for x in &vikings { 65 | /// println!("{:?}", x); 66 | /// } 67 | /// ``` 68 | #[derive(Clone)] 69 | pub struct LinearSet { 70 | map: LinearMap, 71 | } 72 | 73 | impl LinearSet { 74 | /// Creates an empty LinearSet. 75 | /// 76 | /// # Examples 77 | /// 78 | /// ``` 79 | /// use linear_map::set::LinearSet;; 80 | /// let mut set: LinearSet = LinearSet::new(); 81 | /// ``` 82 | #[inline] 83 | 84 | pub fn new() -> LinearSet { 85 | LinearSet { 86 | map: LinearMap::new(), 87 | } 88 | } 89 | 90 | /// Creates an empty LinearSet with space for at least `n` elements in 91 | /// the map. 92 | /// 93 | /// # Examples 94 | /// 95 | /// ``` 96 | /// use linear_map::set::LinearSet;; 97 | /// let mut set: LinearSet = LinearSet::with_capacity(10); 98 | /// ``` 99 | #[inline] 100 | pub fn with_capacity(capacity: usize) -> LinearSet { 101 | LinearSet { 102 | map: LinearMap::with_capacity(capacity), 103 | } 104 | } 105 | } 106 | 107 | impl LinearSet 108 | where 109 | T: Eq, 110 | { 111 | /// Returns the number of elements the set can hold without reallocating. 112 | /// 113 | /// # Examples 114 | /// 115 | /// ``` 116 | /// use linear_map::set::LinearSet;; 117 | /// let set: LinearSet = LinearSet::with_capacity(100); 118 | /// assert!(set.capacity() >= 100); 119 | /// ``` 120 | #[inline] 121 | 122 | pub fn capacity(&self) -> usize { 123 | self.map.capacity() 124 | } 125 | 126 | /// Reserves capacity for at least `additional` more elements to be inserted 127 | /// in the `LinearSet`. The collection may reserve more space to avoid 128 | /// frequent reallocations. 129 | /// 130 | /// # Panics 131 | /// 132 | /// Panics if the new allocation size overflows `usize`. 133 | /// 134 | /// # Examples 135 | /// 136 | /// ``` 137 | /// use linear_map::set::LinearSet;; 138 | /// let mut set: LinearSet = LinearSet::new(); 139 | /// set.reserve(10); 140 | /// ``` 141 | 142 | pub fn reserve(&mut self, additional: usize) { 143 | self.map.reserve(additional) 144 | } 145 | 146 | /// Shrinks the capacity of the set as much as possible. It will drop 147 | /// down as much as possible while maintaining the internal rules 148 | /// and possibly leaving some space in accordance with the resize policy. 149 | /// 150 | /// # Examples 151 | /// 152 | /// ``` 153 | /// use linear_map::set::LinearSet;; 154 | /// 155 | /// let mut set = LinearSet::with_capacity(100); 156 | /// set.insert(1); 157 | /// set.insert(2); 158 | /// assert!(set.capacity() >= 100); 159 | /// set.shrink_to_fit(); 160 | /// assert!(set.capacity() >= 2); 161 | /// ``` 162 | 163 | pub fn shrink_to_fit(&mut self) { 164 | self.map.shrink_to_fit() 165 | } 166 | 167 | /// An iterator visiting all elements in arbitrary order. 168 | /// Iterator element type is &'a T. 169 | /// 170 | /// # Examples 171 | /// 172 | /// ``` 173 | /// use linear_map::set::LinearSet;; 174 | /// let mut set = LinearSet::new(); 175 | /// set.insert("a"); 176 | /// set.insert("b"); 177 | /// 178 | /// // Will print in an arbitrary order. 179 | /// for x in set.iter() { 180 | /// println!("{}", x); 181 | /// } 182 | /// ``` 183 | 184 | pub fn iter(&self) -> Iter { 185 | Iter { 186 | iter: self.map.keys(), 187 | } 188 | } 189 | 190 | /// Visit the values representing the difference. 191 | /// 192 | /// # Examples 193 | /// 194 | /// ``` 195 | /// use linear_map::set::LinearSet;; 196 | /// let a: LinearSet<_> = [1, 2, 3].iter().cloned().collect(); 197 | /// let b: LinearSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 198 | /// 199 | /// // Can be seen as `a - b`. 200 | /// for x in a.difference(&b) { 201 | /// println!("{}", x); // Print 1 202 | /// } 203 | /// 204 | /// let diff: LinearSet<_> = a.difference(&b).cloned().collect(); 205 | /// assert_eq!(diff, [1].iter().cloned().collect()); 206 | /// 207 | /// // Note that difference is not symmetric, 208 | /// // and `b - a` means something else: 209 | /// let diff: LinearSet<_> = b.difference(&a).cloned().collect(); 210 | /// assert_eq!(diff, [4].iter().cloned().collect()); 211 | /// ``` 212 | 213 | pub fn difference<'a>(&'a self, other: &'a LinearSet) -> Difference<'a, T> { 214 | Difference { 215 | iter: self.iter(), 216 | other, 217 | } 218 | } 219 | 220 | /// Visit the values representing the symmetric difference. 221 | /// 222 | /// # Examples 223 | /// 224 | /// ``` 225 | /// use linear_map::set::LinearSet;; 226 | /// let a: LinearSet<_> = [1, 2, 3].iter().cloned().collect(); 227 | /// let b: LinearSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 228 | /// 229 | /// // Print 1, 4 in arbitrary order. 230 | /// for x in a.symmetric_difference(&b) { 231 | /// println!("{}", x); 232 | /// } 233 | /// 234 | /// let diff1: LinearSet<_> = a.symmetric_difference(&b).cloned().collect(); 235 | /// let diff2: LinearSet<_> = b.symmetric_difference(&a).cloned().collect(); 236 | /// 237 | /// assert_eq!(diff1, diff2); 238 | /// assert_eq!(diff1, [1, 4].iter().cloned().collect()); 239 | /// ``` 240 | 241 | pub fn symmetric_difference<'a>( 242 | &'a self, 243 | other: &'a LinearSet, 244 | ) -> SymmetricDifference<'a, T> { 245 | SymmetricDifference { 246 | iter: self.difference(other).chain(other.difference(self)), 247 | } 248 | } 249 | 250 | /// Visit the values representing the intersection. 251 | /// 252 | /// # Examples 253 | /// 254 | /// ``` 255 | /// use linear_map::set::LinearSet;; 256 | /// let a: LinearSet<_> = [1, 2, 3].iter().cloned().collect(); 257 | /// let b: LinearSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 258 | /// 259 | /// // Print 2, 3 in arbitrary order. 260 | /// for x in a.intersection(&b) { 261 | /// println!("{}", x); 262 | /// } 263 | /// 264 | /// let intersection: LinearSet<_> = a.intersection(&b).cloned().collect(); 265 | /// assert_eq!(intersection, [2, 3].iter().cloned().collect()); 266 | /// ``` 267 | 268 | pub fn intersection<'a>(&'a self, other: &'a LinearSet) -> Intersection<'a, T> { 269 | Intersection { 270 | iter: self.iter(), 271 | other, 272 | } 273 | } 274 | 275 | /// Visit the values representing the union. 276 | /// 277 | /// # Examples 278 | /// 279 | /// ``` 280 | /// use linear_map::set::LinearSet;; 281 | /// let a: LinearSet<_> = [1, 2, 3].iter().cloned().collect(); 282 | /// let b: LinearSet<_> = [4, 2, 3, 4].iter().cloned().collect(); 283 | /// 284 | /// // Print 1, 2, 3, 4 in arbitrary order. 285 | /// for x in a.union(&b) { 286 | /// println!("{}", x); 287 | /// } 288 | /// 289 | /// let union: LinearSet<_> = a.union(&b).cloned().collect(); 290 | /// assert_eq!(union, [1, 2, 3, 4].iter().cloned().collect()); 291 | /// ``` 292 | 293 | pub fn union<'a>(&'a self, other: &'a LinearSet) -> Union<'a, T> { 294 | Union { 295 | iter: self.iter().chain(other.difference(self)), 296 | } 297 | } 298 | 299 | /// Returns the number of elements in the set. 300 | /// 301 | /// # Examples 302 | /// 303 | /// ``` 304 | /// use linear_map::set::LinearSet;; 305 | /// 306 | /// let mut v = LinearSet::new(); 307 | /// assert_eq!(v.len(), 0); 308 | /// v.insert(1); 309 | /// assert_eq!(v.len(), 1); 310 | /// ``` 311 | 312 | pub fn len(&self) -> usize { 313 | self.map.len() 314 | } 315 | 316 | /// Returns true if the set contains no elements. 317 | /// 318 | /// # Examples 319 | /// 320 | /// ``` 321 | /// use linear_map::set::LinearSet;; 322 | /// 323 | /// let mut v = LinearSet::new(); 324 | /// assert!(v.is_empty()); 325 | /// v.insert(1); 326 | /// assert!(!v.is_empty()); 327 | /// ``` 328 | 329 | pub fn is_empty(&self) -> bool { 330 | self.map.is_empty() 331 | } 332 | 333 | /// Clears the set, returning all elements in an iterator. 334 | #[inline] 335 | pub fn drain(&mut self) -> Drain { 336 | Drain { 337 | iter: self.map.drain(), 338 | } 339 | } 340 | 341 | /// Clears the set, removing all values. 342 | /// 343 | /// # Examples 344 | /// 345 | /// ``` 346 | /// use linear_map::set::LinearSet;; 347 | /// 348 | /// let mut v = LinearSet::new(); 349 | /// v.insert(1); 350 | /// v.clear(); 351 | /// assert!(v.is_empty()); 352 | /// ``` 353 | pub fn clear(&mut self) { 354 | self.map.clear() 355 | } 356 | 357 | /// Retains only the elements specified by the predicate. 358 | /// 359 | /// In other words, remove all elements `e` such that `f(&e)` returns `false`. 360 | /// 361 | pub fn retain(&mut self, mut f: F) 362 | where 363 | F: FnMut(&T) -> bool, 364 | { 365 | self.map.retain(|k, _| f(k)); 366 | } 367 | 368 | /// Returns `true` if the set contains a value. 369 | /// 370 | /// The value may be any borrowed form of the set's value type, but 371 | /// `Eq` on the borrowed form *must* match those for 372 | /// the value type. 373 | /// 374 | /// # Examples 375 | /// 376 | /// ``` 377 | /// use linear_map::set::LinearSet;; 378 | /// 379 | /// let set: LinearSet<_> = [1, 2, 3].iter().cloned().collect(); 380 | /// assert_eq!(set.contains(&1), true); 381 | /// assert_eq!(set.contains(&4), false); 382 | /// ``` 383 | pub fn contains(&self, value: &Q) -> bool 384 | where 385 | T: Borrow, 386 | Q: Eq, 387 | { 388 | self.map.contains_key(value) 389 | } 390 | 391 | /// Returns `true` if the set has no elements in common with `other`. 392 | /// This is equivalent to checking for an empty intersection. 393 | /// 394 | /// # Examples 395 | /// 396 | /// ``` 397 | /// use linear_map::set::LinearSet;; 398 | /// 399 | /// let a: LinearSet<_> = [1, 2, 3].iter().cloned().collect(); 400 | /// let mut b = LinearSet::new(); 401 | /// 402 | /// assert_eq!(a.is_disjoint(&b), true); 403 | /// b.insert(4); 404 | /// assert_eq!(a.is_disjoint(&b), true); 405 | /// b.insert(1); 406 | /// assert_eq!(a.is_disjoint(&b), false); 407 | /// ``` 408 | 409 | pub fn is_disjoint(&self, other: &LinearSet) -> bool { 410 | self.iter().all(|v| !other.contains(v)) 411 | } 412 | 413 | /// Returns `true` if the set is a subset of another. 414 | /// 415 | /// # Examples 416 | /// 417 | /// ``` 418 | /// use linear_map::set::LinearSet;; 419 | /// 420 | /// let sup: LinearSet<_> = [1, 2, 3].iter().cloned().collect(); 421 | /// let mut set = LinearSet::new(); 422 | /// 423 | /// assert_eq!(set.is_subset(&sup), true); 424 | /// set.insert(2); 425 | /// assert_eq!(set.is_subset(&sup), true); 426 | /// set.insert(4); 427 | /// assert_eq!(set.is_subset(&sup), false); 428 | /// ``` 429 | 430 | pub fn is_subset(&self, other: &LinearSet) -> bool { 431 | self.iter().all(|v| other.contains(v)) 432 | } 433 | 434 | /// Returns `true` if the set is a superset of another. 435 | /// 436 | /// # Examples 437 | /// 438 | /// ``` 439 | /// use linear_map::set::LinearSet;; 440 | /// 441 | /// let sub: LinearSet<_> = [1, 2].iter().cloned().collect(); 442 | /// let mut set = LinearSet::new(); 443 | /// 444 | /// assert_eq!(set.is_superset(&sub), false); 445 | /// 446 | /// set.insert(0); 447 | /// set.insert(1); 448 | /// assert_eq!(set.is_superset(&sub), false); 449 | /// 450 | /// set.insert(2); 451 | /// assert_eq!(set.is_superset(&sub), true); 452 | /// ``` 453 | #[inline] 454 | 455 | pub fn is_superset(&self, other: &LinearSet) -> bool { 456 | other.is_subset(self) 457 | } 458 | 459 | /// Adds a value to the set. 460 | /// 461 | /// If the set did not have a value present, `true` is returned. 462 | /// 463 | /// If the set did have this key present, `false` is returned. 464 | /// 465 | /// # Examples 466 | /// 467 | /// ``` 468 | /// use linear_map::set::LinearSet;; 469 | /// 470 | /// let mut set = LinearSet::new(); 471 | /// 472 | /// assert_eq!(set.insert(2), true); 473 | /// assert_eq!(set.insert(2), false); 474 | /// assert_eq!(set.len(), 1); 475 | /// ``` 476 | 477 | pub fn insert(&mut self, value: T) -> bool { 478 | self.map.insert(value, ()).is_none() 479 | } 480 | 481 | /// Removes a value from the set. Returns `true` if the value was 482 | /// present in the set. 483 | /// 484 | /// The value may be any borrowed form of the set's value type, but 485 | /// `Eq` on the borrowed form *must* match those for 486 | /// the value type. 487 | /// 488 | /// # Examples 489 | /// 490 | /// ``` 491 | /// use linear_map::set::LinearSet;; 492 | /// 493 | /// let mut set = LinearSet::new(); 494 | /// 495 | /// set.insert(2); 496 | /// assert_eq!(set.remove(&2), true); 497 | /// assert_eq!(set.remove(&2), false); 498 | /// ``` 499 | 500 | pub fn remove(&mut self, value: &Q) -> bool 501 | where 502 | T: Borrow, 503 | Q: Eq, 504 | { 505 | self.map.remove(value).is_some() 506 | } 507 | } 508 | 509 | impl PartialEq for LinearSet 510 | where 511 | T: Eq, 512 | { 513 | fn eq(&self, other: &LinearSet) -> bool { 514 | if self.len() != other.len() { 515 | return false; 516 | } 517 | 518 | self.iter().all(|key| other.contains(key)) 519 | } 520 | } 521 | 522 | impl Eq for LinearSet where T: Eq {} 523 | 524 | impl fmt::Debug for LinearSet 525 | where 526 | T: Eq + fmt::Debug, 527 | { 528 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 529 | f.debug_set().entries(self.iter()).finish() 530 | } 531 | } 532 | 533 | impl FromIterator for LinearSet 534 | where 535 | T: Eq, 536 | { 537 | fn from_iter>(iter: I) -> LinearSet { 538 | let iterator = iter.into_iter(); 539 | let lower = iterator.size_hint().0; 540 | let mut set = LinearSet::with_capacity(lower); 541 | set.extend(iterator); 542 | set 543 | } 544 | } 545 | 546 | impl Extend for LinearSet 547 | where 548 | T: Eq, 549 | { 550 | fn extend>(&mut self, iter: I) { 551 | for k in iter { 552 | self.insert(k); 553 | } 554 | } 555 | } 556 | 557 | impl<'a, T> Extend<&'a T> for LinearSet 558 | where 559 | T: 'a + Eq + Copy, 560 | { 561 | fn extend>(&mut self, iter: I) { 562 | self.extend(iter.into_iter().cloned()); 563 | } 564 | } 565 | 566 | impl Default for LinearSet 567 | where 568 | T: Eq, 569 | { 570 | fn default() -> LinearSet { 571 | LinearSet::new() 572 | } 573 | } 574 | 575 | impl From> for Vec { 576 | fn from(other: LinearSet) -> Self { 577 | unsafe { std::mem::transmute(other) } 578 | } 579 | } 580 | 581 | impl From> for LinearSet { 582 | fn from(other: Vec) -> Self { 583 | unsafe { std::mem::transmute(other) } 584 | } 585 | } 586 | 587 | impl<'a, 'b, T> BitOr<&'b LinearSet> for &'a LinearSet 588 | where 589 | T: Eq + Clone, 590 | { 591 | type Output = LinearSet; 592 | 593 | /// Returns the union of `self` and `rhs` as a new `LinearSet`. 594 | /// 595 | /// # Examples 596 | /// 597 | /// ``` 598 | /// use linear_map::set::LinearSet;; 599 | /// 600 | /// let a: LinearSet<_> = vec![1, 2, 3].into_iter().collect(); 601 | /// let b: LinearSet<_> = vec![3, 4, 5].into_iter().collect(); 602 | /// 603 | /// let set = &a | &b; 604 | /// 605 | /// let mut i = 0; 606 | /// let expected = [1, 2, 3, 4, 5]; 607 | /// for x in &set { 608 | /// assert!(expected.contains(x)); 609 | /// i += 1; 610 | /// } 611 | /// assert_eq!(i, expected.len()); 612 | /// ``` 613 | fn bitor(self, rhs: &LinearSet) -> LinearSet { 614 | self.union(rhs).cloned().collect() 615 | } 616 | } 617 | 618 | impl<'a, 'b, T> BitAnd<&'b LinearSet> for &'a LinearSet 619 | where 620 | T: Eq + Clone, 621 | { 622 | type Output = LinearSet; 623 | 624 | /// Returns the intersection of `self` and `rhs` as a new `LinearSet`. 625 | /// 626 | /// # Examples 627 | /// 628 | /// ``` 629 | /// use linear_map::set::LinearSet;; 630 | /// 631 | /// let a: LinearSet<_> = vec![1, 2, 3].into_iter().collect(); 632 | /// let b: LinearSet<_> = vec![2, 3, 4].into_iter().collect(); 633 | /// 634 | /// let set = &a & &b; 635 | /// 636 | /// let mut i = 0; 637 | /// let expected = [2, 3]; 638 | /// for x in &set { 639 | /// assert!(expected.contains(x)); 640 | /// i += 1; 641 | /// } 642 | /// assert_eq!(i, expected.len()); 643 | /// ``` 644 | fn bitand(self, rhs: &LinearSet) -> LinearSet { 645 | self.intersection(rhs).cloned().collect() 646 | } 647 | } 648 | 649 | impl<'a, 'b, T> BitXor<&'b LinearSet> for &'a LinearSet 650 | where 651 | T: Eq + Clone, 652 | { 653 | type Output = LinearSet; 654 | 655 | /// Returns the symmetric difference of `self` and `rhs` as a new `LinearSet`. 656 | /// 657 | /// # Examples 658 | /// 659 | /// ``` 660 | /// use linear_map::set::LinearSet;; 661 | /// 662 | /// let a: LinearSet<_> = vec![1, 2, 3].into_iter().collect(); 663 | /// let b: LinearSet<_> = vec![3, 4, 5].into_iter().collect(); 664 | /// 665 | /// let set = &a ^ &b; 666 | /// 667 | /// let mut i = 0; 668 | /// let expected = [1, 2, 4, 5]; 669 | /// for x in &set { 670 | /// assert!(expected.contains(x)); 671 | /// i += 1; 672 | /// } 673 | /// assert_eq!(i, expected.len()); 674 | /// ``` 675 | fn bitxor(self, rhs: &LinearSet) -> LinearSet { 676 | self.symmetric_difference(rhs).cloned().collect() 677 | } 678 | } 679 | 680 | impl<'a, 'b, T> Sub<&'b LinearSet> for &'a LinearSet 681 | where 682 | T: Eq + Clone, 683 | { 684 | type Output = LinearSet; 685 | 686 | /// Returns the difference of `self` and `rhs` as a new `LinearSet`. 687 | /// 688 | /// # Examples 689 | /// 690 | /// ``` 691 | /// use linear_map::set::LinearSet;; 692 | /// 693 | /// let a: LinearSet<_> = vec![1, 2, 3].into_iter().collect(); 694 | /// let b: LinearSet<_> = vec![3, 4, 5].into_iter().collect(); 695 | /// 696 | /// let set = &a - &b; 697 | /// 698 | /// let mut i = 0; 699 | /// let expected = [1, 2]; 700 | /// for x in &set { 701 | /// assert!(expected.contains(x)); 702 | /// i += 1; 703 | /// } 704 | /// assert_eq!(i, expected.len()); 705 | /// ``` 706 | fn sub(self, rhs: &LinearSet) -> LinearSet { 707 | self.difference(rhs).cloned().collect() 708 | } 709 | } 710 | 711 | /// LinearSet iterator 712 | pub struct Iter<'a, K: 'a> { 713 | iter: Keys<'a, K, ()>, 714 | } 715 | 716 | /// LinearSet move iterator 717 | pub struct IntoIter { 718 | iter: super::IntoIter, 719 | } 720 | 721 | /// LinearSet drain iterator 722 | pub struct Drain<'a, K: 'a> { 723 | iter: super::Drain<'a, K, ()>, 724 | } 725 | 726 | /// Intersection iterator 727 | pub struct Intersection<'a, T: 'a> { 728 | // iterator of the first set 729 | iter: Iter<'a, T>, 730 | // the second set 731 | other: &'a LinearSet, 732 | } 733 | 734 | /// Difference iterator 735 | pub struct Difference<'a, T: 'a> { 736 | // iterator of the first set 737 | iter: Iter<'a, T>, 738 | // the second set 739 | other: &'a LinearSet, 740 | } 741 | 742 | /// Symmetric difference iterator. 743 | pub struct SymmetricDifference<'a, T: 'a> { 744 | iter: Chain, Difference<'a, T>>, 745 | } 746 | 747 | /// Set union iterator. 748 | pub struct Union<'a, T: 'a> { 749 | iter: Chain, Difference<'a, T>>, 750 | } 751 | 752 | impl<'a, T> IntoIterator for &'a LinearSet 753 | where 754 | T: Eq, 755 | { 756 | type Item = &'a T; 757 | type IntoIter = Iter<'a, T>; 758 | 759 | fn into_iter(self) -> Iter<'a, T> { 760 | self.iter() 761 | } 762 | } 763 | 764 | impl IntoIterator for LinearSet 765 | where 766 | T: Eq, 767 | { 768 | type Item = T; 769 | type IntoIter = IntoIter; 770 | 771 | /// Creates a consuming iterator, that is, one that moves each value out 772 | /// of the set in arbitrary order. The set cannot be used after calling 773 | /// this. 774 | /// 775 | /// # Examples 776 | /// 777 | /// ``` 778 | /// use linear_map::set::LinearSet;; 779 | /// let mut set = LinearSet::new(); 780 | /// set.insert("a".to_string()); 781 | /// set.insert("b".to_string()); 782 | /// 783 | /// // Not possible to collect to a Vec with a regular `.iter()`. 784 | /// let v: Vec = set.into_iter().collect(); 785 | /// 786 | /// // Will print in an arbitrary order. 787 | /// for x in &v { 788 | /// println!("{}", x); 789 | /// } 790 | /// ``` 791 | fn into_iter(self) -> IntoIter { 792 | IntoIter { 793 | iter: self.map.into_iter(), 794 | } 795 | } 796 | } 797 | 798 | impl<'a, K> Clone for Iter<'a, K> { 799 | fn clone(&self) -> Iter<'a, K> { 800 | Iter { 801 | iter: self.iter.clone(), 802 | } 803 | } 804 | } 805 | impl<'a, K> Iterator for Iter<'a, K> { 806 | type Item = &'a K; 807 | 808 | fn next(&mut self) -> Option<&'a K> { 809 | self.iter.next() 810 | } 811 | fn size_hint(&self) -> (usize, Option) { 812 | self.iter.size_hint() 813 | } 814 | } 815 | impl<'a, K> ExactSizeIterator for Iter<'a, K> { 816 | fn len(&self) -> usize { 817 | self.iter.len() 818 | } 819 | } 820 | 821 | impl Iterator for IntoIter { 822 | type Item = K; 823 | 824 | fn next(&mut self) -> Option { 825 | self.iter.next().map(|(k, _)| k) 826 | } 827 | fn size_hint(&self) -> (usize, Option) { 828 | self.iter.size_hint() 829 | } 830 | } 831 | impl ExactSizeIterator for IntoIter { 832 | fn len(&self) -> usize { 833 | self.iter.len() 834 | } 835 | } 836 | 837 | impl<'a, K> Iterator for Drain<'a, K> { 838 | type Item = K; 839 | 840 | fn next(&mut self) -> Option { 841 | self.iter.next().map(|(k, _)| k) 842 | } 843 | fn size_hint(&self) -> (usize, Option) { 844 | self.iter.size_hint() 845 | } 846 | } 847 | impl<'a, K> ExactSizeIterator for Drain<'a, K> { 848 | fn len(&self) -> usize { 849 | self.iter.len() 850 | } 851 | } 852 | 853 | impl<'a, T> Clone for Intersection<'a, T> { 854 | fn clone(&self) -> Intersection<'a, T> { 855 | Intersection { 856 | iter: self.iter.clone(), 857 | ..*self 858 | } 859 | } 860 | } 861 | 862 | impl<'a, T> Iterator for Intersection<'a, T> 863 | where 864 | T: Eq, 865 | { 866 | type Item = &'a T; 867 | 868 | fn next(&mut self) -> Option<&'a T> { 869 | loop { 870 | match self.iter.next() { 871 | None => return None, 872 | Some(elt) => { 873 | if self.other.contains(elt) { 874 | return Some(elt); 875 | } 876 | } 877 | } 878 | } 879 | } 880 | 881 | fn size_hint(&self) -> (usize, Option) { 882 | let (_, upper) = self.iter.size_hint(); 883 | (0, upper) 884 | } 885 | } 886 | 887 | impl<'a, T> Clone for Difference<'a, T> { 888 | fn clone(&self) -> Difference<'a, T> { 889 | Difference { 890 | iter: self.iter.clone(), 891 | ..*self 892 | } 893 | } 894 | } 895 | 896 | impl<'a, T> Iterator for Difference<'a, T> 897 | where 898 | T: Eq, 899 | { 900 | type Item = &'a T; 901 | 902 | fn next(&mut self) -> Option<&'a T> { 903 | loop { 904 | match self.iter.next() { 905 | None => return None, 906 | Some(elt) => { 907 | if !self.other.contains(elt) { 908 | return Some(elt); 909 | } 910 | } 911 | } 912 | } 913 | } 914 | 915 | fn size_hint(&self) -> (usize, Option) { 916 | let (_, upper) = self.iter.size_hint(); 917 | (0, upper) 918 | } 919 | } 920 | 921 | impl<'a, T> Clone for SymmetricDifference<'a, T> { 922 | fn clone(&self) -> SymmetricDifference<'a, T> { 923 | SymmetricDifference { 924 | iter: self.iter.clone(), 925 | } 926 | } 927 | } 928 | 929 | impl<'a, T> Iterator for SymmetricDifference<'a, T> 930 | where 931 | T: Eq, 932 | { 933 | type Item = &'a T; 934 | 935 | fn next(&mut self) -> Option<&'a T> { 936 | self.iter.next() 937 | } 938 | fn size_hint(&self) -> (usize, Option) { 939 | self.iter.size_hint() 940 | } 941 | } 942 | 943 | impl<'a, T> Clone for Union<'a, T> { 944 | fn clone(&self) -> Union<'a, T> { 945 | Union { 946 | iter: self.iter.clone(), 947 | } 948 | } 949 | } 950 | 951 | impl<'a, T> Iterator for Union<'a, T> 952 | where 953 | T: Eq, 954 | { 955 | type Item = &'a T; 956 | 957 | fn next(&mut self) -> Option<&'a T> { 958 | self.iter.next() 959 | } 960 | fn size_hint(&self) -> (usize, Option) { 961 | self.iter.size_hint() 962 | } 963 | } 964 | 965 | #[allow(dead_code)] 966 | fn assert_covariance() { 967 | fn set<'new>(v: LinearSet<&'static str>) -> LinearSet<&'new str> { 968 | v 969 | } 970 | fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { 971 | v 972 | } 973 | fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { 974 | v 975 | } 976 | fn difference<'a, 'new>(v: Difference<'a, &'static str>) -> Difference<'a, &'new str> { 977 | v 978 | } 979 | fn symmetric_difference<'a, 'new>( 980 | v: SymmetricDifference<'a, &'static str>, 981 | ) -> SymmetricDifference<'a, &'new str> { 982 | v 983 | } 984 | fn intersection<'a, 'new>(v: Intersection<'a, &'static str>) -> Intersection<'a, &'new str> { 985 | v 986 | } 987 | fn union<'a, 'new>(v: Union<'a, &'static str>) -> Union<'a, &'new str> { 988 | v 989 | } 990 | } 991 | -------------------------------------------------------------------------------- /tests/serde.rs: -------------------------------------------------------------------------------- 1 | #![cfg(feature = "serde_impl")] 2 | 3 | extern crate linear_map; 4 | use linear_map::LinearMap; 5 | 6 | extern crate serde_test; 7 | use serde_test::{assert_tokens, Token}; 8 | 9 | #[test] 10 | fn test_ser_de_empty() { 11 | let map = LinearMap::::new(); 12 | 13 | assert_tokens(&map, &[Token::Map { len: Some(0) }, Token::MapEnd]); 14 | } 15 | 16 | #[test] 17 | fn test_ser_de() { 18 | let mut map = LinearMap::new(); 19 | map.insert('b', 20); 20 | map.insert('a', 10); 21 | map.insert('c', 30); 22 | 23 | assert_tokens( 24 | &map, 25 | &[ 26 | Token::Map { len: Some(3) }, 27 | Token::Char('b'), 28 | Token::I32(20), 29 | Token::Char('a'), 30 | Token::I32(10), 31 | Token::Char('c'), 32 | Token::I32(30), 33 | Token::MapEnd, 34 | ], 35 | ); 36 | } 37 | 38 | mod set { 39 | use linear_map::set::LinearSet; 40 | use serde_test::{assert_tokens, Token}; 41 | 42 | #[test] 43 | fn test_ser_de_empty() { 44 | let set = LinearSet::::new(); 45 | assert_tokens(&set, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); 46 | } 47 | 48 | #[test] 49 | fn test_ser_de() { 50 | let mut set = LinearSet::new(); 51 | set.insert('b'); 52 | set.insert('a'); 53 | set.insert('c'); 54 | 55 | assert_tokens( 56 | &set, 57 | &[ 58 | Token::Seq { len: Some(3) }, 59 | Token::Char('b'), 60 | Token::Char('a'), 61 | Token::Char('c'), 62 | Token::SeqEnd, 63 | ], 64 | ); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tests/set.rs: -------------------------------------------------------------------------------- 1 | extern crate linear_map; 2 | 3 | use linear_map::set::LinearSet; 4 | 5 | #[test] 6 | fn test_disjoint() { 7 | let mut xs = LinearSet::new(); 8 | let mut ys = LinearSet::new(); 9 | assert!(xs.is_disjoint(&ys)); 10 | assert!(ys.is_disjoint(&xs)); 11 | assert!(xs.insert(5)); 12 | assert!(ys.insert(11)); 13 | assert!(xs.is_disjoint(&ys)); 14 | assert!(ys.is_disjoint(&xs)); 15 | assert!(xs.insert(7)); 16 | assert!(xs.insert(19)); 17 | assert!(xs.insert(4)); 18 | assert!(ys.insert(2)); 19 | assert!(ys.insert(-11)); 20 | assert!(xs.is_disjoint(&ys)); 21 | assert!(ys.is_disjoint(&xs)); 22 | assert!(ys.insert(7)); 23 | assert!(!xs.is_disjoint(&ys)); 24 | assert!(!ys.is_disjoint(&xs)); 25 | } 26 | 27 | #[test] 28 | fn test_subset_and_superset() { 29 | let mut a = LinearSet::new(); 30 | assert!(a.insert(0)); 31 | assert!(a.insert(5)); 32 | assert!(a.insert(11)); 33 | assert!(a.insert(7)); 34 | 35 | let mut b = LinearSet::new(); 36 | assert!(b.insert(0)); 37 | assert!(b.insert(7)); 38 | assert!(b.insert(19)); 39 | assert!(b.insert(250)); 40 | assert!(b.insert(11)); 41 | assert!(b.insert(200)); 42 | 43 | assert!(!a.is_subset(&b)); 44 | assert!(!a.is_superset(&b)); 45 | assert!(!b.is_subset(&a)); 46 | assert!(!b.is_superset(&a)); 47 | 48 | assert!(b.insert(5)); 49 | 50 | assert!(a.is_subset(&b)); 51 | assert!(!a.is_superset(&b)); 52 | assert!(!b.is_subset(&a)); 53 | assert!(b.is_superset(&a)); 54 | } 55 | 56 | #[test] 57 | fn test_iterate() { 58 | let mut a = LinearSet::new(); 59 | for i in 0..32 { 60 | assert!(a.insert(i)); 61 | } 62 | let mut observed: u32 = 0; 63 | for k in &a { 64 | observed |= 1 << *k; 65 | } 66 | assert_eq!(observed, 0xFFFF_FFFF); 67 | } 68 | 69 | #[test] 70 | fn test_intersection() { 71 | let mut a = LinearSet::new(); 72 | let mut b = LinearSet::new(); 73 | 74 | assert!(a.insert(11)); 75 | assert!(a.insert(1)); 76 | assert!(a.insert(3)); 77 | assert!(a.insert(77)); 78 | assert!(a.insert(103)); 79 | assert!(a.insert(5)); 80 | assert!(a.insert(-5)); 81 | 82 | assert!(b.insert(2)); 83 | assert!(b.insert(11)); 84 | assert!(b.insert(77)); 85 | assert!(b.insert(-9)); 86 | assert!(b.insert(-42)); 87 | assert!(b.insert(5)); 88 | assert!(b.insert(3)); 89 | 90 | let mut i = 0; 91 | let expected = [3, 5, 11, 77]; 92 | for x in a.intersection(&b) { 93 | assert!(expected.contains(x)); 94 | i += 1 95 | } 96 | assert_eq!(i, expected.len()); 97 | } 98 | 99 | #[test] 100 | fn test_difference() { 101 | let mut a = LinearSet::new(); 102 | let mut b = LinearSet::new(); 103 | 104 | assert!(a.insert(1)); 105 | assert!(a.insert(3)); 106 | assert!(a.insert(5)); 107 | assert!(a.insert(9)); 108 | assert!(a.insert(11)); 109 | 110 | assert!(b.insert(3)); 111 | assert!(b.insert(9)); 112 | 113 | let mut i = 0; 114 | let expected = [1, 5, 11]; 115 | for x in a.difference(&b) { 116 | assert!(expected.contains(x)); 117 | i += 1 118 | } 119 | assert_eq!(i, expected.len()); 120 | } 121 | 122 | #[test] 123 | fn test_symmetric_difference() { 124 | let mut a = LinearSet::new(); 125 | let mut b = LinearSet::new(); 126 | 127 | assert!(a.insert(1)); 128 | assert!(a.insert(3)); 129 | assert!(a.insert(5)); 130 | assert!(a.insert(9)); 131 | assert!(a.insert(11)); 132 | 133 | assert!(b.insert(-2)); 134 | assert!(b.insert(3)); 135 | assert!(b.insert(9)); 136 | assert!(b.insert(14)); 137 | assert!(b.insert(22)); 138 | 139 | let mut i = 0; 140 | let expected = [-2, 1, 5, 11, 14, 22]; 141 | for x in a.symmetric_difference(&b) { 142 | assert!(expected.contains(x)); 143 | i += 1 144 | } 145 | assert_eq!(i, expected.len()); 146 | } 147 | 148 | #[test] 149 | fn test_union() { 150 | let mut a = LinearSet::new(); 151 | let mut b = LinearSet::new(); 152 | 153 | assert!(a.insert(1)); 154 | assert!(a.insert(3)); 155 | assert!(a.insert(5)); 156 | assert!(a.insert(9)); 157 | assert!(a.insert(11)); 158 | assert!(a.insert(16)); 159 | assert!(a.insert(19)); 160 | assert!(a.insert(24)); 161 | 162 | assert!(b.insert(-2)); 163 | assert!(b.insert(1)); 164 | assert!(b.insert(5)); 165 | assert!(b.insert(9)); 166 | assert!(b.insert(13)); 167 | assert!(b.insert(19)); 168 | 169 | let mut i = 0; 170 | let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]; 171 | for x in a.union(&b) { 172 | assert!(expected.contains(x)); 173 | i += 1 174 | } 175 | assert_eq!(i, expected.len()); 176 | } 177 | 178 | #[test] 179 | fn test_from_iter() { 180 | let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9]; 181 | 182 | let set: LinearSet<_> = xs.iter().cloned().collect(); 183 | 184 | for x in &xs { 185 | assert!(set.contains(x)); 186 | } 187 | } 188 | 189 | #[test] 190 | fn test_move_iter() { 191 | let hs = { 192 | let mut hs = LinearSet::new(); 193 | 194 | hs.insert('a'); 195 | hs.insert('b'); 196 | 197 | hs 198 | }; 199 | 200 | let v = hs.into_iter().collect::>(); 201 | assert!(v == ['a', 'b'] || v == ['b', 'a']); 202 | } 203 | 204 | #[test] 205 | fn test_eq() { 206 | // These constants once happened to expose a bug in insert(). 207 | // I'm keeping them around to prevent a regression. 208 | let mut s1 = LinearSet::new(); 209 | 210 | s1.insert(1); 211 | s1.insert(2); 212 | s1.insert(3); 213 | 214 | let mut s2 = LinearSet::new(); 215 | 216 | s2.insert(1); 217 | s2.insert(2); 218 | 219 | assert!(s1 != s2); 220 | 221 | s2.insert(3); 222 | 223 | assert_eq!(s1, s2); 224 | } 225 | 226 | #[test] 227 | fn test_show() { 228 | let mut set = LinearSet::new(); 229 | let empty = LinearSet::::new(); 230 | 231 | set.insert(1); 232 | set.insert(2); 233 | 234 | let set_str = format!("{:?}", set); 235 | 236 | assert!(set_str == "{1, 2}" || set_str == "{2, 1}"); 237 | assert_eq!(format!("{:?}", empty), "{}"); 238 | } 239 | 240 | #[test] 241 | fn test_trivial_drain() { 242 | let mut s = LinearSet::::new(); 243 | for _ in s.drain() {} 244 | assert!(s.is_empty()); 245 | drop(s); 246 | 247 | let mut s = LinearSet::::new(); 248 | drop(s.drain()); 249 | assert!(s.is_empty()); 250 | } 251 | 252 | #[test] 253 | fn test_drain() { 254 | let mut s: LinearSet<_> = (1..100).collect(); 255 | 256 | // try this a bunch of times to make sure we don't screw up internal state. 257 | for _ in 0..20 { 258 | assert_eq!(s.len(), 99); 259 | 260 | { 261 | let mut last_i = 0; 262 | let mut d = s.drain(); 263 | for (i, x) in d.by_ref().take(50).enumerate() { 264 | last_i = i; 265 | assert!(x != 0); 266 | } 267 | assert_eq!(last_i, 49); 268 | } 269 | 270 | for _ in &s { 271 | panic!("s should be empty!"); 272 | } 273 | 274 | // reset to try again. 275 | s.extend(1..100); 276 | } 277 | } 278 | 279 | #[test] 280 | fn test_extend_ref() { 281 | let mut a = LinearSet::new(); 282 | a.insert(1); 283 | 284 | a.extend(&[2, 3, 4]); 285 | 286 | assert_eq!(a.len(), 4); 287 | assert!(a.contains(&1)); 288 | assert!(a.contains(&2)); 289 | assert!(a.contains(&3)); 290 | assert!(a.contains(&4)); 291 | 292 | let mut b = LinearSet::new(); 293 | b.insert(5); 294 | b.insert(6); 295 | 296 | a.extend(&b); 297 | 298 | assert_eq!(a.len(), 6); 299 | assert!(a.contains(&1)); 300 | assert!(a.contains(&2)); 301 | assert!(a.contains(&3)); 302 | assert!(a.contains(&4)); 303 | assert!(a.contains(&5)); 304 | assert!(a.contains(&6)); 305 | } 306 | 307 | #[test] 308 | fn test_into_vec() { 309 | let mut a = LinearSet::new(); 310 | assert!(a.insert(0)); 311 | assert!(a.insert(5)); 312 | assert!(a.insert(11)); 313 | assert!(a.insert(7)); 314 | let set_as_vec: Vec<_> = a.into(); 315 | assert_eq!(set_as_vec, vec![0, 5, 11, 7]); 316 | } 317 | 318 | #[test] 319 | fn test_retain() { 320 | let xs = [1, 2, 3, 4, 5, 6]; 321 | let mut set: LinearSet = xs.iter().cloned().collect(); 322 | set.retain(|&k| k % 2 == 0); 323 | assert_eq!(set.len(), 3); 324 | assert!(set.contains(&2)); 325 | assert!(set.contains(&4)); 326 | assert!(set.contains(&6)); 327 | } 328 | -------------------------------------------------------------------------------- /tests/test.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate linear_map; 3 | 4 | use linear_map::Entry::{Occupied, Vacant}; 5 | use linear_map::LinearMap; 6 | 7 | const TEST_CAPACITY: usize = 10; 8 | 9 | #[test] 10 | fn test_new() { 11 | let map: LinearMap = LinearMap::new(); 12 | assert_eq!(map.capacity(), 0); 13 | assert_eq!(map.len(), 0); 14 | assert!(map.is_empty()); 15 | } 16 | 17 | #[test] 18 | fn test_with_capacity() { 19 | let map: LinearMap = LinearMap::with_capacity(TEST_CAPACITY); 20 | assert!(map.capacity() >= TEST_CAPACITY); 21 | } 22 | 23 | #[test] 24 | fn test_capacity() { 25 | let mut map = LinearMap::new(); 26 | map.insert(1, 2); 27 | assert!(map.capacity() >= 1); 28 | map.remove(&1); 29 | assert!(map.capacity() >= 1); 30 | map.reserve(TEST_CAPACITY); 31 | let capacity = map.capacity(); 32 | assert!(capacity >= TEST_CAPACITY); 33 | for i in 0..TEST_CAPACITY as i32 { 34 | assert!(map.insert(i, i).is_none()); 35 | } 36 | assert_eq!(capacity, map.capacity()); 37 | } 38 | 39 | #[test] 40 | fn test_reserve() { 41 | let mut map = LinearMap::new(); 42 | map.reserve(TEST_CAPACITY); 43 | assert!(map.capacity() >= TEST_CAPACITY); 44 | for i in 0..TEST_CAPACITY as i32 { 45 | assert!(map.insert(i, i).is_none()); 46 | } 47 | map.reserve(TEST_CAPACITY); 48 | assert!(map.capacity() >= 2 * TEST_CAPACITY); 49 | 50 | let mut map = LinearMap::new(); 51 | map.reserve(TEST_CAPACITY); 52 | assert!(map.capacity() >= TEST_CAPACITY); 53 | for i in 0..TEST_CAPACITY as i32 { 54 | assert!(map.insert(i, i).is_none()); 55 | } 56 | map.reserve(TEST_CAPACITY); 57 | assert!(map.capacity() >= 2 * TEST_CAPACITY); 58 | } 59 | 60 | #[test] 61 | fn test_shrink_to_fit() { 62 | let mut map = LinearMap::new(); 63 | map.shrink_to_fit(); 64 | assert_eq!(map.capacity(), 0); 65 | map.reserve(TEST_CAPACITY); 66 | map.shrink_to_fit(); 67 | assert_eq!(map.capacity(), 0); 68 | for i in 0..TEST_CAPACITY as i32 { 69 | assert!(map.insert(i, i).is_none()); 70 | } 71 | map.shrink_to_fit(); 72 | assert_eq!(map.len(), TEST_CAPACITY); 73 | assert!(map.capacity() >= TEST_CAPACITY); 74 | } 75 | 76 | #[test] 77 | fn test_len_and_is_empty() { 78 | let mut map = LinearMap::new(); 79 | assert_eq!(map.len(), 0); 80 | assert!(map.is_empty()); 81 | map.insert(100, 100); 82 | assert_eq!(map.len(), 1); 83 | assert!(!map.is_empty()); 84 | for i in 0..TEST_CAPACITY as i32 { 85 | assert!(map.insert(i, i).is_none()); 86 | } 87 | assert_eq!(map.len(), 1 + TEST_CAPACITY); 88 | assert!(!map.is_empty()); 89 | assert!(map.remove(&100).is_some()); 90 | assert_eq!(map.len(), TEST_CAPACITY); 91 | assert!(!map.is_empty()); 92 | } 93 | 94 | #[test] 95 | fn test_clear() { 96 | let mut map = LinearMap::new(); 97 | map.clear(); 98 | assert_eq!(map.len(), 0); 99 | for i in 0..TEST_CAPACITY as i32 { 100 | assert!(map.insert(i, i).is_none()); 101 | } 102 | map.clear(); 103 | assert_eq!(map.len(), 0); 104 | assert!(map.capacity() > 0); 105 | } 106 | 107 | #[test] 108 | fn test_iterators() { 109 | const ONE: i32 = 0b0001; 110 | const TWO: i32 = 0b0010; 111 | const THREE: i32 = 0b0100; 112 | const FOUR: i32 = 0b1000; 113 | const ALL: i32 = 0b1111; 114 | let mut map = LinearMap::new(); 115 | assert!(map.insert(ONE, TWO).is_none()); 116 | assert!(map.insert(TWO, THREE).is_none()); 117 | assert!(map.insert(THREE, FOUR).is_none()); 118 | assert!(map.insert(FOUR, ONE).is_none()); 119 | 120 | { 121 | let mut result_k = 0; 122 | let mut result_v = 0; 123 | for (&k, &v) in map.iter() { 124 | result_k ^= k; 125 | result_v ^= v; 126 | assert_eq!(((k << 1) & ALL) | ((k >> 3) & ALL), v); 127 | } 128 | assert_eq!(result_k, ALL); 129 | assert_eq!(result_v, ALL); 130 | } 131 | { 132 | let mut result_k = 0; 133 | let mut result_v = 0; 134 | for (&k, &mut v) in map.iter_mut() { 135 | result_k ^= k; 136 | result_v ^= v; 137 | assert_eq!(((k << 1) & ALL) | ((k >> 3) & ALL), v); 138 | } 139 | assert_eq!(result_k, ALL); 140 | assert_eq!(result_v, ALL); 141 | } 142 | { 143 | let mut result = 0; 144 | for &k in map.keys() { 145 | result ^= k; 146 | } 147 | assert_eq!(result, ALL); 148 | } 149 | { 150 | let mut result = 0; 151 | for &v in map.values() { 152 | result ^= v; 153 | } 154 | assert_eq!(result, ALL); 155 | } 156 | } 157 | 158 | #[test] 159 | fn test_insert_remove_get() { 160 | let mut map = LinearMap::new(); 161 | assert!(map.insert(100, 101).is_none()); 162 | assert!(map.contains_key(&100)); 163 | assert_eq!(map.get(&100), Some(&101)); 164 | assert_eq!(map.get_mut(&100), Some(&mut 101)); 165 | for i in 0..TEST_CAPACITY as i32 { 166 | assert!(map.insert(i, i).is_none()); 167 | } 168 | assert_eq!(map.insert(100, 102), Some(101)); 169 | assert_eq!(map.remove(&100), Some(102)); 170 | assert_eq!(map.remove(&100), None); 171 | assert_eq!(map.remove(&1000), None); 172 | } 173 | 174 | #[test] 175 | fn test_entry() { 176 | let xs = [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)]; 177 | 178 | let mut map = LinearMap::new(); 179 | 180 | for &(k, v) in &xs { 181 | map.insert(k, v); 182 | } 183 | 184 | // Existing key (insert) 185 | match map.entry(1) { 186 | Vacant(_) => unreachable!(), 187 | Occupied(mut view) => { 188 | assert_eq!(view.get(), &10); 189 | assert_eq!(view.insert(100), 10); 190 | } 191 | } 192 | assert_eq!(map.get(&1).unwrap(), &100); 193 | assert_eq!(map.len(), 6); 194 | 195 | // Existing key (update) 196 | match map.entry(2) { 197 | Vacant(_) => unreachable!(), 198 | Occupied(mut view) => { 199 | let v = view.get_mut(); 200 | let new_v = (*v) * 10; 201 | *v = new_v; 202 | } 203 | } 204 | assert_eq!(map.get(&2).unwrap(), &200); 205 | assert_eq!(map.len(), 6); 206 | 207 | // Existing key (take) 208 | match map.entry(3) { 209 | Vacant(_) => unreachable!(), 210 | Occupied(view) => { 211 | assert_eq!(view.remove(), 30); 212 | } 213 | } 214 | assert_eq!(map.get(&3), None); 215 | assert_eq!(map.len(), 5); 216 | 217 | // Inexistent key (insert) 218 | match map.entry(10) { 219 | Occupied(_) => unreachable!(), 220 | Vacant(view) => { 221 | assert_eq!(*view.insert(1000), 1000); 222 | } 223 | } 224 | assert_eq!(map.get(&10).unwrap(), &1000); 225 | assert_eq!(map.len(), 6); 226 | } 227 | 228 | #[test] 229 | fn test_eq() { 230 | let kvs = vec![('a', 1), ('b', 2), ('c', 3)]; 231 | 232 | let mut m1: LinearMap<_, _> = kvs.clone().into_iter().collect(); 233 | let m2: LinearMap<_, _> = kvs.into_iter().rev().collect(); 234 | assert_eq!(m1, m2); 235 | 236 | m1.insert('a', 11); 237 | assert!(m1 != m2); 238 | 239 | m1.insert('a', 1); 240 | assert_eq!(m1, m2); 241 | 242 | m1.remove(&'a'); 243 | assert!(m1 != m2); 244 | } 245 | 246 | #[test] 247 | fn test_macro() { 248 | let names = linear_map! { 249 | 1 => "one", 250 | 2 => "two", 251 | }; 252 | assert_eq!(names.len(), 2); 253 | assert_eq!(names.capacity(), 2); 254 | assert_eq!(names[&1], "one"); 255 | assert_eq!(names[&2], "two"); 256 | assert_eq!(names.get(&3), None); 257 | 258 | let empty: LinearMap = linear_map! {}; 259 | assert_eq!(empty.len(), 0); 260 | assert_eq!(empty.capacity(), 0); 261 | 262 | let _nested_compiles = linear_map! { 263 | 1 => linear_map!{0 => 1 + 2,}, 264 | 2 => linear_map!{1 => 1,}, 265 | }; 266 | } 267 | 268 | #[test] 269 | fn test_retain() { 270 | let mut map: LinearMap = (0..100).map(|x| (x, x * 10)).collect(); 271 | map.retain(|&k, _| k % 2 == 0); 272 | assert_eq!(map.len(), 50); 273 | assert_eq!(map[&2], 20); 274 | assert_eq!(map[&4], 40); 275 | assert_eq!(map[&6], 60); 276 | } 277 | --------------------------------------------------------------------------------