├── .cargo-rdme.toml ├── .github └── workflows │ └── rust.yml ├── .gitignore ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── RELEASES.md ├── benches └── bench.rs └── src └── lib.rs /.cargo-rdme.toml: -------------------------------------------------------------------------------- 1 | line-terminator = "lf" 2 | -------------------------------------------------------------------------------- /.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@v4 17 | - name: Build 18 | run: cargo build --verbose 19 | - name: Run tests 20 | run: cargo test --verbose 21 | - name: Run tests on no_std 22 | run: cargo test --no-default-features --verbose 23 | - name: Run tests for serde 24 | run: cargo test --features serde --verbose 25 | - run: cargo test --no-default-features --features serde_no_std 26 | - run: cargo test --features borsh 27 | - run: cargo test --features miniserde 28 | - run: cargo test --features nanoserde 29 | - run: cargo test --features nanoserde --no-default-features 30 | 31 | miri: 32 | name: "Miri" 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: actions/checkout@v4 36 | - name: Install Miri 37 | run: | 38 | rustup toolchain install nightly --component miri 39 | rustup override set nightly 40 | cargo miri setup 41 | - name: Test with Miri 42 | run: MIRIFLAGS=-Zmiri-strict-provenance cargo miri test 43 | 44 | fmt: 45 | runs-on: ubuntu-latest 46 | steps: 47 | - uses: actions/checkout@v4 48 | - uses: dtolnay/rust-toolchain@master 49 | with: 50 | toolchain: stable 51 | components: rustfmt 52 | - run: cargo fmt --all -- --check 53 | 54 | msrv: 55 | name: Rust ${{matrix.rust}} 56 | runs-on: ubuntu-latest 57 | strategy: 58 | fail-fast: false 59 | matrix: 60 | rust: [1.63.0, 1.64.0] 61 | timeout-minutes: 45 62 | steps: 63 | - uses: actions/checkout@v4 64 | - uses: dtolnay/rust-toolchain@master 65 | with: 66 | toolchain: ${{matrix.rust}} 67 | - run: cargo build 68 | - run: cargo test 69 | - run: cargo test --no-default-features 70 | - run: cargo test --no-default-features --features serde_no_std 71 | - run: cargo test --features serde 72 | - run: cargo test --features miniserde 73 | 74 | msrv-borsh: 75 | name: Rust ${{matrix.rust}} 76 | runs-on: ubuntu-latest 77 | strategy: 78 | fail-fast: false 79 | matrix: 80 | rust: [1.67.0, 1.68.0] 81 | timeout-minutes: 45 82 | steps: 83 | - uses: actions/checkout@v4 84 | - uses: dtolnay/rust-toolchain@master 85 | with: 86 | toolchain: ${{matrix.rust}} 87 | - run: cargo test 88 | - run: cargo test --features borsh 89 | - run: cargo test --features nanoserde 90 | - run: cargo test --features nanoserde --no-default-features 91 | 92 | clippy: 93 | runs-on: ubuntu-latest 94 | steps: 95 | - uses: actions/checkout@v4 96 | - uses: dtolnay/rust-toolchain@master 97 | with: 98 | toolchain: stable 99 | components: clippy 100 | - run: cargo clippy --workspace --tests --examples 101 | 102 | docs: 103 | runs-on: ubuntu-latest 104 | env: 105 | RUSTDOCFLAGS: -Dwarnings 106 | steps: 107 | - uses: actions/checkout@v4 108 | - uses: dtolnay/rust-toolchain@master 109 | with: 110 | toolchain: stable 111 | - uses: swatinem/rust-cache@v2 112 | - run: cargo doc --workspace --no-deps 113 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | # this is a library 3 | /Cargo.lock 4 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bit-set" 3 | version = "0.8.0" 4 | authors = ["Alexis Beingessner "] 5 | license = "Apache-2.0 OR MIT" 6 | description = "A set of bits" 7 | repository = "https://github.com/contain-rs/bit-set" 8 | homepage = "https://github.com/contain-rs/bit-set" 9 | documentation = "https://docs.rs/bit-set/" 10 | keywords = ["data-structures", "bitset"] 11 | readme = "README.md" 12 | edition = "2021" 13 | rust-version = "1.63" 14 | 15 | [dependencies] 16 | borsh = { version = "1.5", default-features = false, features = ["derive"], optional = true } 17 | serde = { version = "1.0", default-features = false, features = ["derive"], optional = true } 18 | miniserde = { version = "0.1", optional = true } 19 | nanoserde = { version = "0.1", optional = true } 20 | 21 | [dependencies.bit-vec] 22 | version = "0.8.0" 23 | default-features = false 24 | 25 | [dev-dependencies] 26 | rand = "0.8" 27 | serde_json = "1.0" 28 | 29 | [features] 30 | default = ["std"] 31 | std = ["bit-vec/std"] 32 | 33 | borsh = ["dep:borsh", "bit-vec/borsh"] 34 | serde = ["dep:serde", "bit-vec/serde"] 35 | miniserde = ["dep:miniserde", "bit-vec/miniserde"] 36 | nanoserde = ["dep:nanoserde", "bit-vec/nanoserde"] 37 | 38 | serde_std = ["std", "serde/std"] 39 | serde_no_std = ["serde/alloc"] 40 | borsh_std = ["borsh/std"] 41 | 42 | [package.metadata.docs.rs] 43 | features = ["borsh", "serde", "miniserde", "nanoserde"] 44 | -------------------------------------------------------------------------------- /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) 2023 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 |
2 |

bit-set

3 |

4 | A compact set of bits. 5 |

6 |

7 | 8 | [![crates.io][crates.io shield]][crates.io link] 9 | [![Documentation][docs.rs badge]][docs.rs link] 10 | ![Rust CI][github ci badge] 11 | ![rustc 1.63+] 12 | ![borsh: rustc 1.67+] 13 | ![nanoserde: rustc 1.67+] 14 |
15 |
16 | [![Dependency Status][deps.rs status]][deps.rs link] 17 | [![Download Status][shields.io download count]][crates.io link] 18 | 19 |

20 |
21 | 22 | [crates.io shield]: https://img.shields.io/crates/v/bit-set?label=latest 23 | [crates.io link]: https://crates.io/crates/bit-set 24 | [docs.rs badge]: https://docs.rs/bit-set/badge.svg?version=0.8.0 25 | [docs.rs link]: https://docs.rs/bit-set/0.8.0/bit_set/ 26 | [github ci badge]: https://github.com/contain-rs/bit-set/workflows/Rust/badge.svg?branch=master 27 | [rustc 1.63+]: https://img.shields.io/badge/rustc-1.63%2B-blue.svg 28 | [borsh: rustc 1.67+]: https://img.shields.io/badge/borsh:%20rustc-1.67%2B-blue.svg 29 | [nanoserde: rustc 1.67+]: https://img.shields.io/badge/nanoserde:%20rustc-1.67%2B-blue.svg 30 | [deps.rs status]: https://deps.rs/crate/bit-set/0.8.0/status.svg 31 | [deps.rs link]: https://deps.rs/crate/bit-set/0.8.0 32 | [shields.io download count]: https://img.shields.io/crates/d/bit-set.svg 33 | 34 | ## Usage 35 | 36 | Add this to your Cargo.toml: 37 | 38 | ```toml 39 | [dependencies] 40 | bit-set = "0.8" 41 | ``` 42 | 43 | Since Rust 2018, `extern crate` is no longer mandatory. If your edition is old (Rust 2015), 44 | add this to your crate root: 45 | 46 | ```rust 47 | extern crate bit_set; 48 | ``` 49 | 50 | If you want to use `serde`, enable it with the `serde` feature: 51 | 52 | ```toml 53 | [dependencies] 54 | bit-set = { version = "0.8", features = ["serde"] } 55 | ``` 56 | 57 | If you want to use bit-set in a program that has `#![no_std]`, just drop default features: 58 | 59 | ```toml 60 | [dependencies] 61 | bit-set = { version = "0.8", default-features = false } 62 | ``` 63 | 64 | If you want to use serde with the alloc crate instead of std, just use the `serde_no_std` feature: 65 | 66 | ```toml 67 | [dependencies] 68 | bit-set = { version = "0.8", default-features = false, features = ["serde", "serde_no_std"] } 69 | ``` 70 | 71 | If you want [borsh-rs](https://github.com/near/borsh-rs) support, include it like this: 72 | 73 | ```toml 74 | [dependencies] 75 | bit-set = { version = "0.8", features = ["borsh"] } 76 | ``` 77 | 78 | Other available serialization libraries can be enabled with the 79 | [`miniserde`](https://github.com/dtolnay/miniserde) and 80 | [`nanoserde`](https://github.com/not-fl3/nanoserde) features. 81 | 82 | 83 | 84 | 85 | ### Description 86 | 87 | An implementation of a set using a bit vector as an underlying 88 | representation for holding unsigned numerical elements. 89 | 90 | It should also be noted that the amount of storage necessary for holding a 91 | set of objects is proportional to the maximum of the objects when viewed 92 | as a `usize`. 93 | 94 | ### Examples 95 | 96 | ```rust 97 | use bit_set::BitSet; 98 | 99 | // It's a regular set 100 | let mut s = BitSet::new(); 101 | s.insert(0); 102 | s.insert(3); 103 | s.insert(7); 104 | 105 | s.remove(7); 106 | 107 | if !s.contains(7) { 108 | println!("There is no 7"); 109 | } 110 | 111 | // Can initialize from a `BitVec` 112 | let other = BitSet::from_bytes(&[0b11010000]); 113 | 114 | s.union_with(&other); 115 | 116 | // Print 0, 1, 3 in some order 117 | for x in s.iter() { 118 | println!("{}", x); 119 | } 120 | 121 | // Can convert back to a `BitVec` 122 | let bv = s.into_bit_vec(); 123 | assert!(bv[3]); 124 | ``` 125 | 126 | 127 | 128 | ## License 129 | 130 | Dual-licensed for compatibility with the Rust project. 131 | 132 | Licensed under the Apache License Version 2.0: http://www.apache.org/licenses/LICENSE-2.0, 133 | or the MIT license: http://opensource.org/licenses/MIT, at your option. 134 | -------------------------------------------------------------------------------- /RELEASES.md: -------------------------------------------------------------------------------- 1 | Version 0.7.0 (not yet released) (ZERO BREAKING CHANGES) 2 | ======================================================== 3 | 4 | 5 | 6 | - `serde::Serialize`, `Deserialize` is derived under the `serde` optional feature 7 | - `impl Display` is implemented 8 | - `impl Debug` has different output (we do not promise stable `Debug` output) 9 | - `fn truncate` is implemented 10 | - `fn get_mut` is implemented 11 | -------------------------------------------------------------------------------- /benches/bench.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2024 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | #![feature(test)] 12 | 13 | extern crate bit_set; 14 | extern crate bit_vec; 15 | extern crate rand; 16 | extern crate test; 17 | 18 | use bit_set::BitSet; 19 | use bit_vec::BitVec; 20 | use rand::{rngs::ThreadRng, thread_rng, RngCore}; 21 | 22 | use test::{black_box, Bencher}; 23 | 24 | const BENCH_BITS: usize = 1 << 14; 25 | const BITS: usize = 32; 26 | 27 | fn rng() -> ThreadRng { 28 | thread_rng() 29 | } 30 | 31 | #[bench] 32 | fn bench_bit_vecset_small(b: &mut Bencher) { 33 | let mut r = rng(); 34 | let mut bit_vec = BitSet::new(); 35 | b.iter(|| { 36 | for _ in 0..100 { 37 | bit_vec.insert((r.next_u32() as usize) % BITS); 38 | } 39 | black_box(&bit_vec); 40 | }); 41 | } 42 | 43 | #[bench] 44 | fn bench_bit_vecset_big(b: &mut Bencher) { 45 | let mut r = rng(); 46 | let mut bit_vec = BitSet::new(); 47 | b.iter(|| { 48 | for _ in 0..100 { 49 | bit_vec.insert((r.next_u32() as usize) % BENCH_BITS); 50 | } 51 | black_box(&bit_vec); 52 | }); 53 | } 54 | 55 | #[bench] 56 | fn bench_bit_vecset_iter(b: &mut Bencher) { 57 | let bit_vec = BitSet::from_bit_vec(BitVec::from_fn(BENCH_BITS, |idx| idx % 3 == 0)); 58 | b.iter(|| { 59 | let mut sum = 0; 60 | for idx in &bit_vec { 61 | sum += idx as usize; 62 | } 63 | sum 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT 2 | // file at the top-level directory of this distribution and at 3 | // http://rust-lang.org/COPYRIGHT. 4 | // 5 | // Licensed under the Apache License, Version 2.0 or the MIT license 7 | // , at your 8 | // option. This file may not be copied, modified, or distributed 9 | // except according to those terms. 10 | 11 | //! # Description 12 | //! 13 | //! An implementation of a set using a bit vector as an underlying 14 | //! representation for holding unsigned numerical elements. 15 | //! 16 | //! It should also be noted that the amount of storage necessary for holding a 17 | //! set of objects is proportional to the maximum of the objects when viewed 18 | //! as a `usize`. 19 | //! 20 | //! # Examples 21 | //! 22 | //! ``` 23 | //! use bit_set::BitSet; 24 | //! 25 | //! // It's a regular set 26 | //! let mut s = BitSet::new(); 27 | //! s.insert(0); 28 | //! s.insert(3); 29 | //! s.insert(7); 30 | //! 31 | //! s.remove(7); 32 | //! 33 | //! if !s.contains(7) { 34 | //! println!("There is no 7"); 35 | //! } 36 | //! 37 | //! // Can initialize from a `BitVec` 38 | //! let other = BitSet::from_bytes(&[0b11010000]); 39 | //! 40 | //! s.union_with(&other); 41 | //! 42 | //! // Print 0, 1, 3 in some order 43 | //! for x in s.iter() { 44 | //! println!("{}", x); 45 | //! } 46 | //! 47 | //! // Can convert back to a `BitVec` 48 | //! let bv = s.into_bit_vec(); 49 | //! assert!(bv[3]); 50 | //! ``` 51 | #![doc(html_root_url = "https://docs.rs/bit-set/0.8.0")] 52 | #![deny(clippy::shadow_reuse)] 53 | #![deny(clippy::shadow_same)] 54 | #![deny(clippy::shadow_unrelated)] 55 | #![no_std] 56 | 57 | #[cfg(any(test, feature = "std"))] 58 | extern crate std; 59 | 60 | use bit_vec::{BitBlock, BitVec, Blocks}; 61 | use core::cmp; 62 | use core::cmp::Ordering; 63 | use core::fmt; 64 | use core::hash; 65 | use core::iter::{self, Chain, Enumerate, FromIterator, Repeat, Skip, Take}; 66 | 67 | #[cfg(feature = "nanoserde")] 68 | extern crate alloc; 69 | #[cfg(feature = "nanoserde")] 70 | use alloc::vec::Vec; 71 | #[cfg(feature = "nanoserde")] 72 | use nanoserde::{DeBin, DeJson, DeRon, SerBin, SerJson, SerRon}; 73 | 74 | type MatchWords<'a, B> = Chain>, Skip>>>>; 75 | 76 | /// Computes how many blocks are needed to store that many bits 77 | fn blocks_for_bits(bits: usize) -> usize { 78 | // If we want 17 bits, dividing by 32 will produce 0. So we add 1 to make sure we 79 | // reserve enough. But if we want exactly a multiple of 32, this will actually allocate 80 | // one too many. So we need to check if that's the case. We can do that by computing if 81 | // bitwise AND by `32 - 1` is 0. But LLVM should be able to optimize the semantically 82 | // superior modulo operator on a power of two to this. 83 | // 84 | // Note that we can technically avoid this branch with the expression 85 | // `(nbits + BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow. 86 | if bits % B::bits() == 0 { 87 | bits / B::bits() 88 | } else { 89 | bits / B::bits() + 1 90 | } 91 | } 92 | 93 | #[allow(clippy::iter_skip_zero)] 94 | // Take two BitVec's, and return iterators of their words, where the shorter one 95 | // has been padded with 0's 96 | fn match_words<'a, 'b, B: BitBlock>( 97 | a: &'a BitVec, 98 | b: &'b BitVec, 99 | ) -> (MatchWords<'a, B>, MatchWords<'b, B>) { 100 | let a_len = a.storage().len(); 101 | let b_len = b.storage().len(); 102 | 103 | // have to uselessly pretend to pad the longer one for type matching 104 | if a_len < b_len { 105 | ( 106 | a.blocks() 107 | .enumerate() 108 | .chain(iter::repeat(B::zero()).enumerate().take(b_len).skip(a_len)), 109 | b.blocks() 110 | .enumerate() 111 | .chain(iter::repeat(B::zero()).enumerate().take(0).skip(0)), 112 | ) 113 | } else { 114 | ( 115 | a.blocks() 116 | .enumerate() 117 | .chain(iter::repeat(B::zero()).enumerate().take(0).skip(0)), 118 | b.blocks() 119 | .enumerate() 120 | .chain(iter::repeat(B::zero()).enumerate().take(a_len).skip(b_len)), 121 | ) 122 | } 123 | } 124 | 125 | #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] 126 | #[cfg_attr( 127 | feature = "borsh", 128 | derive(borsh::BorshDeserialize, borsh::BorshSerialize) 129 | )] 130 | #[cfg_attr( 131 | feature = "miniserde", 132 | derive(miniserde::Deserialize, miniserde::Serialize) 133 | )] 134 | #[cfg_attr( 135 | feature = "nanoserde", 136 | derive(DeBin, DeJson, DeRon, SerBin, SerJson, SerRon) 137 | )] 138 | pub struct BitSet { 139 | bit_vec: BitVec, 140 | } 141 | 142 | impl Clone for BitSet { 143 | fn clone(&self) -> Self { 144 | BitSet { 145 | bit_vec: self.bit_vec.clone(), 146 | } 147 | } 148 | 149 | fn clone_from(&mut self, other: &Self) { 150 | self.bit_vec.clone_from(&other.bit_vec); 151 | } 152 | } 153 | 154 | impl Default for BitSet { 155 | #[inline] 156 | fn default() -> Self { 157 | BitSet { 158 | bit_vec: Default::default(), 159 | } 160 | } 161 | } 162 | 163 | impl FromIterator for BitSet { 164 | fn from_iter>(iter: I) -> Self { 165 | let mut ret = Self::default(); 166 | ret.extend(iter); 167 | ret 168 | } 169 | } 170 | 171 | impl Extend for BitSet { 172 | #[inline] 173 | fn extend>(&mut self, iter: I) { 174 | for i in iter { 175 | self.insert(i); 176 | } 177 | } 178 | } 179 | 180 | impl PartialOrd for BitSet { 181 | #[inline] 182 | fn partial_cmp(&self, other: &Self) -> Option { 183 | Some(self.cmp(other)) 184 | } 185 | } 186 | 187 | impl Ord for BitSet { 188 | #[inline] 189 | fn cmp(&self, other: &Self) -> Ordering { 190 | self.iter().cmp(other) 191 | } 192 | } 193 | 194 | impl PartialEq for BitSet { 195 | #[inline] 196 | fn eq(&self, other: &Self) -> bool { 197 | self.iter().eq(other) 198 | } 199 | } 200 | 201 | impl Eq for BitSet {} 202 | 203 | impl BitSet { 204 | /// Creates a new empty `BitSet`. 205 | /// 206 | /// # Examples 207 | /// 208 | /// ``` 209 | /// use bit_set::BitSet; 210 | /// 211 | /// let mut s = BitSet::new(); 212 | /// ``` 213 | #[inline] 214 | pub fn new() -> Self { 215 | Self::default() 216 | } 217 | 218 | /// Creates a new `BitSet` with initially no contents, able to 219 | /// hold `nbits` elements without resizing. 220 | /// 221 | /// # Examples 222 | /// 223 | /// ``` 224 | /// use bit_set::BitSet; 225 | /// 226 | /// let mut s = BitSet::with_capacity(100); 227 | /// assert!(s.capacity() >= 100); 228 | /// ``` 229 | #[inline] 230 | pub fn with_capacity(nbits: usize) -> Self { 231 | let bit_vec = BitVec::from_elem(nbits, false); 232 | Self::from_bit_vec(bit_vec) 233 | } 234 | 235 | /// Creates a new `BitSet` from the given bit vector. 236 | /// 237 | /// # Examples 238 | /// 239 | /// ``` 240 | /// extern crate bit_vec; 241 | /// extern crate bit_set; 242 | /// 243 | /// fn main() { 244 | /// use bit_vec::BitVec; 245 | /// use bit_set::BitSet; 246 | /// 247 | /// let bv = BitVec::from_bytes(&[0b01100000]); 248 | /// let s = BitSet::from_bit_vec(bv); 249 | /// 250 | /// // Print 1, 2 in arbitrary order 251 | /// for x in s.iter() { 252 | /// println!("{}", x); 253 | /// } 254 | /// } 255 | /// ``` 256 | #[inline] 257 | pub fn from_bit_vec(bit_vec: BitVec) -> Self { 258 | BitSet { bit_vec } 259 | } 260 | 261 | pub fn from_bytes(bytes: &[u8]) -> Self { 262 | BitSet { 263 | bit_vec: BitVec::from_bytes(bytes), 264 | } 265 | } 266 | } 267 | 268 | impl BitSet { 269 | /// Returns the capacity in bits for this bit vector. Inserting any 270 | /// element less than this amount will not trigger a resizing. 271 | /// 272 | /// # Examples 273 | /// 274 | /// ``` 275 | /// use bit_set::BitSet; 276 | /// 277 | /// let mut s = BitSet::with_capacity(100); 278 | /// assert!(s.capacity() >= 100); 279 | /// ``` 280 | #[inline] 281 | pub fn capacity(&self) -> usize { 282 | self.bit_vec.capacity() 283 | } 284 | 285 | /// Reserves capacity for the given `BitSet` to contain `len` distinct elements. In the case 286 | /// of `BitSet` this means reallocations will not occur as long as all inserted elements 287 | /// are less than `len`. 288 | /// 289 | /// The collection may reserve more space to avoid frequent reallocations. 290 | /// 291 | /// 292 | /// # Examples 293 | /// 294 | /// ``` 295 | /// use bit_set::BitSet; 296 | /// 297 | /// let mut s = BitSet::new(); 298 | /// s.reserve_len(10); 299 | /// assert!(s.capacity() >= 10); 300 | /// ``` 301 | pub fn reserve_len(&mut self, len: usize) { 302 | let cur_len = self.bit_vec.len(); 303 | if len >= cur_len { 304 | self.bit_vec.reserve(len - cur_len); 305 | } 306 | } 307 | 308 | /// Reserves the minimum capacity for the given `BitSet` to contain `len` distinct elements. 309 | /// In the case of `BitSet` this means reallocations will not occur as long as all inserted 310 | /// elements are less than `len`. 311 | /// 312 | /// Note that the allocator may give the collection more space than it requests. Therefore 313 | /// capacity can not be relied upon to be precisely minimal. Prefer `reserve_len` if future 314 | /// insertions are expected. 315 | /// 316 | /// 317 | /// # Examples 318 | /// 319 | /// ``` 320 | /// use bit_set::BitSet; 321 | /// 322 | /// let mut s = BitSet::new(); 323 | /// s.reserve_len_exact(10); 324 | /// assert!(s.capacity() >= 10); 325 | /// ``` 326 | pub fn reserve_len_exact(&mut self, len: usize) { 327 | let cur_len = self.bit_vec.len(); 328 | if len >= cur_len { 329 | self.bit_vec.reserve_exact(len - cur_len); 330 | } 331 | } 332 | 333 | /// Consumes this set to return the underlying bit vector. 334 | /// 335 | /// # Examples 336 | /// 337 | /// ``` 338 | /// use bit_set::BitSet; 339 | /// 340 | /// let mut s = BitSet::new(); 341 | /// s.insert(0); 342 | /// s.insert(3); 343 | /// 344 | /// let bv = s.into_bit_vec(); 345 | /// assert!(bv[0]); 346 | /// assert!(bv[3]); 347 | /// ``` 348 | #[inline] 349 | pub fn into_bit_vec(self) -> BitVec { 350 | self.bit_vec 351 | } 352 | 353 | /// Returns a reference to the underlying bit vector. 354 | /// 355 | /// # Examples 356 | /// 357 | /// ``` 358 | /// use bit_set::BitSet; 359 | /// 360 | /// let mut set = BitSet::new(); 361 | /// set.insert(0); 362 | /// 363 | /// let bv = set.get_ref(); 364 | /// assert_eq!(bv[0], true); 365 | /// ``` 366 | #[inline] 367 | pub fn get_ref(&self) -> &BitVec { 368 | &self.bit_vec 369 | } 370 | 371 | /// Returns a mutable reference to the underlying bit vector. 372 | /// 373 | /// # Examples 374 | /// 375 | /// ``` 376 | /// use bit_set::BitSet; 377 | /// 378 | /// let mut set = BitSet::new(); 379 | /// set.insert(0); 380 | /// set.insert(3); 381 | /// 382 | /// { 383 | /// let bv = set.get_mut(); 384 | /// bv.set(1, true); 385 | /// } 386 | /// 387 | /// assert!(set.contains(0)); 388 | /// assert!(set.contains(1)); 389 | /// assert!(set.contains(3)); 390 | /// ``` 391 | #[inline] 392 | pub fn get_mut(&mut self) -> &mut BitVec { 393 | &mut self.bit_vec 394 | } 395 | 396 | #[inline] 397 | fn other_op(&mut self, other: &Self, mut f: F) 398 | where 399 | F: FnMut(B, B) -> B, 400 | { 401 | // Unwrap BitVecs 402 | let self_bit_vec = &mut self.bit_vec; 403 | let other_bit_vec = &other.bit_vec; 404 | 405 | let self_len = self_bit_vec.len(); 406 | let other_len = other_bit_vec.len(); 407 | 408 | // Expand the vector if necessary 409 | if self_len < other_len { 410 | self_bit_vec.grow(other_len - self_len, false); 411 | } 412 | 413 | // virtually pad other with 0's for equal lengths 414 | let other_words = { 415 | let (_, result) = match_words(self_bit_vec, other_bit_vec); 416 | result 417 | }; 418 | 419 | // Apply values found in other 420 | for (i, w) in other_words { 421 | let old = self_bit_vec.storage()[i]; 422 | let new = f(old, w); 423 | unsafe { 424 | self_bit_vec.storage_mut()[i] = new; 425 | } 426 | } 427 | } 428 | 429 | /// Truncates the underlying vector to the least length required. 430 | /// 431 | /// # Examples 432 | /// 433 | /// ``` 434 | /// use bit_set::BitSet; 435 | /// 436 | /// let mut s = BitSet::new(); 437 | /// s.insert(3231); 438 | /// s.remove(3231); 439 | /// 440 | /// // Internal storage will probably be bigger than necessary 441 | /// println!("old capacity: {}", s.capacity()); 442 | /// assert!(s.capacity() >= 3231); 443 | /// 444 | /// // Now should be smaller 445 | /// s.shrink_to_fit(); 446 | /// println!("new capacity: {}", s.capacity()); 447 | /// ``` 448 | #[inline] 449 | pub fn shrink_to_fit(&mut self) { 450 | let bit_vec = &mut self.bit_vec; 451 | // Obtain original length 452 | let old_len = bit_vec.storage().len(); 453 | // Obtain coarse trailing zero length 454 | let n = bit_vec 455 | .storage() 456 | .iter() 457 | .rev() 458 | .take_while(|&&n| n == B::zero()) 459 | .count(); 460 | // Truncate away all empty trailing blocks, then shrink_to_fit 461 | let trunc_len = old_len - n; 462 | unsafe { 463 | bit_vec.storage_mut().truncate(trunc_len); 464 | bit_vec.set_len(trunc_len * B::bits()); 465 | } 466 | bit_vec.shrink_to_fit(); 467 | } 468 | 469 | /// Iterator over each usize stored in the `BitSet`. 470 | /// 471 | /// # Examples 472 | /// 473 | /// ``` 474 | /// use bit_set::BitSet; 475 | /// 476 | /// let s = BitSet::from_bytes(&[0b01001010]); 477 | /// 478 | /// // Print 1, 4, 6 in arbitrary order 479 | /// for x in s.iter() { 480 | /// println!("{}", x); 481 | /// } 482 | /// ``` 483 | #[inline] 484 | pub fn iter(&self) -> Iter { 485 | Iter(BlockIter::from_blocks(self.bit_vec.blocks())) 486 | } 487 | 488 | /// Iterator over each usize stored in `self` union `other`. 489 | /// See [`union_with`] for an efficient in-place version. 490 | /// 491 | /// # Examples 492 | /// 493 | /// ``` 494 | /// use bit_set::BitSet; 495 | /// 496 | /// let a = BitSet::from_bytes(&[0b01101000]); 497 | /// let b = BitSet::from_bytes(&[0b10100000]); 498 | /// 499 | /// // Print 0, 1, 2, 4 in arbitrary order 500 | /// for x in a.union(&b) { 501 | /// println!("{}", x); 502 | /// } 503 | /// ``` 504 | /// 505 | /// [`union_with`]: Self::union_with 506 | #[inline] 507 | pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, B> { 508 | fn or(w1: B, w2: B) -> B { 509 | w1 | w2 510 | } 511 | 512 | Union(BlockIter::from_blocks(TwoBitPositions { 513 | set: self.bit_vec.blocks(), 514 | other: other.bit_vec.blocks(), 515 | merge: or, 516 | })) 517 | } 518 | 519 | /// Iterator over each usize stored in `self` intersect `other`. 520 | /// See [`intersect_with`] for an efficient in-place version. 521 | /// 522 | /// # Examples 523 | /// 524 | /// ``` 525 | /// use bit_set::BitSet; 526 | /// 527 | /// let a = BitSet::from_bytes(&[0b01101000]); 528 | /// let b = BitSet::from_bytes(&[0b10100000]); 529 | /// 530 | /// // Print 2 531 | /// for x in a.intersection(&b) { 532 | /// println!("{}", x); 533 | /// } 534 | /// ``` 535 | /// 536 | /// [`intersect_with`]: Self::intersect_with 537 | #[inline] 538 | pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, B> { 539 | fn bitand(w1: B, w2: B) -> B { 540 | w1 & w2 541 | } 542 | let min = cmp::min(self.bit_vec.len(), other.bit_vec.len()); 543 | 544 | Intersection { 545 | iter: BlockIter::from_blocks(TwoBitPositions { 546 | set: self.bit_vec.blocks(), 547 | other: other.bit_vec.blocks(), 548 | merge: bitand, 549 | }), 550 | n: min, 551 | } 552 | } 553 | 554 | /// Iterator over each usize stored in the `self` setminus `other`. 555 | /// See [`difference_with`] for an efficient in-place version. 556 | /// 557 | /// # Examples 558 | /// 559 | /// ``` 560 | /// use bit_set::BitSet; 561 | /// 562 | /// let a = BitSet::from_bytes(&[0b01101000]); 563 | /// let b = BitSet::from_bytes(&[0b10100000]); 564 | /// 565 | /// // Print 1, 4 in arbitrary order 566 | /// for x in a.difference(&b) { 567 | /// println!("{}", x); 568 | /// } 569 | /// 570 | /// // Note that difference is not symmetric, 571 | /// // and `b - a` means something else. 572 | /// // This prints 0 573 | /// for x in b.difference(&a) { 574 | /// println!("{}", x); 575 | /// } 576 | /// ``` 577 | /// 578 | /// [`difference_with`]: Self::difference_with 579 | #[inline] 580 | pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, B> { 581 | fn diff(w1: B, w2: B) -> B { 582 | w1 & !w2 583 | } 584 | 585 | Difference(BlockIter::from_blocks(TwoBitPositions { 586 | set: self.bit_vec.blocks(), 587 | other: other.bit_vec.blocks(), 588 | merge: diff, 589 | })) 590 | } 591 | 592 | /// Iterator over each usize stored in the symmetric difference of `self` and `other`. 593 | /// See [`symmetric_difference_with`] for an efficient in-place version. 594 | /// 595 | /// # Examples 596 | /// 597 | /// ``` 598 | /// use bit_set::BitSet; 599 | /// 600 | /// let a = BitSet::from_bytes(&[0b01101000]); 601 | /// let b = BitSet::from_bytes(&[0b10100000]); 602 | /// 603 | /// // Print 0, 1, 4 in arbitrary order 604 | /// for x in a.symmetric_difference(&b) { 605 | /// println!("{}", x); 606 | /// } 607 | /// ``` 608 | /// 609 | /// [`symmetric_difference_with`]: Self::symmetric_difference_with 610 | #[inline] 611 | pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, B> { 612 | fn bitxor(w1: B, w2: B) -> B { 613 | w1 ^ w2 614 | } 615 | 616 | SymmetricDifference(BlockIter::from_blocks(TwoBitPositions { 617 | set: self.bit_vec.blocks(), 618 | other: other.bit_vec.blocks(), 619 | merge: bitxor, 620 | })) 621 | } 622 | 623 | /// Unions in-place with the specified other bit vector. 624 | /// 625 | /// # Examples 626 | /// 627 | /// ``` 628 | /// use bit_set::BitSet; 629 | /// 630 | /// let a = 0b01101000; 631 | /// let b = 0b10100000; 632 | /// let res = 0b11101000; 633 | /// 634 | /// let mut a = BitSet::from_bytes(&[a]); 635 | /// let b = BitSet::from_bytes(&[b]); 636 | /// let res = BitSet::from_bytes(&[res]); 637 | /// 638 | /// a.union_with(&b); 639 | /// assert_eq!(a, res); 640 | /// ``` 641 | #[inline] 642 | pub fn union_with(&mut self, other: &Self) { 643 | self.other_op(other, |w1, w2| w1 | w2); 644 | } 645 | 646 | /// Intersects in-place with the specified other bit vector. 647 | /// 648 | /// # Examples 649 | /// 650 | /// ``` 651 | /// use bit_set::BitSet; 652 | /// 653 | /// let a = 0b01101000; 654 | /// let b = 0b10100000; 655 | /// let res = 0b00100000; 656 | /// 657 | /// let mut a = BitSet::from_bytes(&[a]); 658 | /// let b = BitSet::from_bytes(&[b]); 659 | /// let res = BitSet::from_bytes(&[res]); 660 | /// 661 | /// a.intersect_with(&b); 662 | /// assert_eq!(a, res); 663 | /// ``` 664 | #[inline] 665 | pub fn intersect_with(&mut self, other: &Self) { 666 | self.other_op(other, |w1, w2| w1 & w2); 667 | } 668 | 669 | /// Makes this bit vector the difference with the specified other bit vector 670 | /// in-place. 671 | /// 672 | /// # Examples 673 | /// 674 | /// ``` 675 | /// use bit_set::BitSet; 676 | /// 677 | /// let a = 0b01101000; 678 | /// let b = 0b10100000; 679 | /// let a_b = 0b01001000; // a - b 680 | /// let b_a = 0b10000000; // b - a 681 | /// 682 | /// let mut bva = BitSet::from_bytes(&[a]); 683 | /// let bvb = BitSet::from_bytes(&[b]); 684 | /// let bva_b = BitSet::from_bytes(&[a_b]); 685 | /// let bvb_a = BitSet::from_bytes(&[b_a]); 686 | /// 687 | /// bva.difference_with(&bvb); 688 | /// assert_eq!(bva, bva_b); 689 | /// 690 | /// let bva = BitSet::from_bytes(&[a]); 691 | /// let mut bvb = BitSet::from_bytes(&[b]); 692 | /// 693 | /// bvb.difference_with(&bva); 694 | /// assert_eq!(bvb, bvb_a); 695 | /// ``` 696 | #[inline] 697 | pub fn difference_with(&mut self, other: &Self) { 698 | self.other_op(other, |w1, w2| w1 & !w2); 699 | } 700 | 701 | /// Makes this bit vector the symmetric difference with the specified other 702 | /// bit vector in-place. 703 | /// 704 | /// # Examples 705 | /// 706 | /// ``` 707 | /// use bit_set::BitSet; 708 | /// 709 | /// let a = 0b01101000; 710 | /// let b = 0b10100000; 711 | /// let res = 0b11001000; 712 | /// 713 | /// let mut a = BitSet::from_bytes(&[a]); 714 | /// let b = BitSet::from_bytes(&[b]); 715 | /// let res = BitSet::from_bytes(&[res]); 716 | /// 717 | /// a.symmetric_difference_with(&b); 718 | /// assert_eq!(a, res); 719 | /// ``` 720 | #[inline] 721 | pub fn symmetric_difference_with(&mut self, other: &Self) { 722 | self.other_op(other, |w1, w2| w1 ^ w2); 723 | } 724 | 725 | /* 726 | /// Moves all elements from `other` into `Self`, leaving `other` empty. 727 | /// 728 | /// # Examples 729 | /// 730 | /// ``` 731 | /// use bit_set::BitSet; 732 | /// 733 | /// let mut a = BitSet::new(); 734 | /// a.insert(2); 735 | /// a.insert(6); 736 | /// 737 | /// let mut b = BitSet::new(); 738 | /// b.insert(1); 739 | /// b.insert(3); 740 | /// b.insert(6); 741 | /// 742 | /// a.append(&mut b); 743 | /// 744 | /// assert_eq!(a.len(), 4); 745 | /// assert_eq!(b.len(), 0); 746 | /// assert_eq!(a, BitSet::from_bytes(&[0b01110010])); 747 | /// ``` 748 | pub fn append(&mut self, other: &mut Self) { 749 | self.union_with(other); 750 | other.clear(); 751 | } 752 | 753 | /// Splits the `BitSet` into two at the given key including the key. 754 | /// Retains the first part in-place while returning the second part. 755 | /// 756 | /// # Examples 757 | /// 758 | /// ``` 759 | /// use bit_set::BitSet; 760 | /// 761 | /// let mut a = BitSet::new(); 762 | /// a.insert(2); 763 | /// a.insert(6); 764 | /// a.insert(1); 765 | /// a.insert(3); 766 | /// 767 | /// let b = a.split_off(3); 768 | /// 769 | /// assert_eq!(a.len(), 2); 770 | /// assert_eq!(b.len(), 2); 771 | /// assert_eq!(a, BitSet::from_bytes(&[0b01100000])); 772 | /// assert_eq!(b, BitSet::from_bytes(&[0b00010010])); 773 | /// ``` 774 | pub fn split_off(&mut self, at: usize) -> Self { 775 | let mut other = BitSet::new(); 776 | 777 | if at == 0 { 778 | swap(self, &mut other); 779 | return other; 780 | } else if at >= self.bit_vec.len() { 781 | return other; 782 | } 783 | 784 | // Calculate block and bit at which to split 785 | let w = at / BITS; 786 | let b = at % BITS; 787 | 788 | // Pad `other` with `w` zero blocks, 789 | // append `self`'s blocks in the range from `w` to the end to `other` 790 | other.bit_vec.storage_mut().extend(repeat(0u32).take(w) 791 | .chain(self.bit_vec.storage()[w..].iter().cloned())); 792 | other.bit_vec.nbits = self.bit_vec.nbits; 793 | 794 | if b > 0 { 795 | other.bit_vec.storage_mut()[w] &= !0 << b; 796 | } 797 | 798 | // Sets `bit_vec.len()` and fixes the last block as well 799 | self.bit_vec.truncate(at); 800 | 801 | other 802 | } 803 | */ 804 | 805 | /// Counts the number of set bits in this set. 806 | /// 807 | /// Note that this function scans the set to calculate the number. 808 | #[inline] 809 | pub fn count(&self) -> usize { 810 | self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones()) 811 | } 812 | 813 | /// Counts the number of set bits in this set. 814 | /// 815 | /// Note that this function scans the set to calculate the number. 816 | #[inline] 817 | #[deprecated = "use BitVec::count() instead"] 818 | pub fn len(&self) -> usize { 819 | self.count() 820 | } 821 | 822 | /// Returns whether there are no bits set in this set 823 | #[inline] 824 | pub fn is_empty(&self) -> bool { 825 | self.bit_vec.none() 826 | } 827 | 828 | /// Clears all bits in this set 829 | #[inline] 830 | pub fn clear(&mut self) { 831 | self.bit_vec.clear(); 832 | } 833 | 834 | /// Returns `true` if this set contains the specified integer. 835 | #[inline] 836 | pub fn contains(&self, value: usize) -> bool { 837 | let bit_vec = &self.bit_vec; 838 | value < bit_vec.len() && bit_vec[value] 839 | } 840 | 841 | /// Returns `true` if the set has no elements in common with `other`. 842 | /// This is equivalent to checking for an empty intersection. 843 | #[inline] 844 | pub fn is_disjoint(&self, other: &Self) -> bool { 845 | self.intersection(other).next().is_none() 846 | } 847 | 848 | /// Returns `true` if the set is a subset of another. 849 | #[inline] 850 | pub fn is_subset(&self, other: &Self) -> bool { 851 | let self_bit_vec = &self.bit_vec; 852 | let other_bit_vec = &other.bit_vec; 853 | let other_blocks = blocks_for_bits::(other_bit_vec.len()); 854 | 855 | // Check that `self` intersect `other` is self 856 | self_bit_vec.blocks().zip(other_bit_vec.blocks()).all(|(w1, w2)| w1 & w2 == w1) && 857 | // Make sure if `self` has any more blocks than `other`, they're all 0 858 | self_bit_vec.blocks().skip(other_blocks).all(|w| w == B::zero()) 859 | } 860 | 861 | /// Returns `true` if the set is a superset of another. 862 | #[inline] 863 | pub fn is_superset(&self, other: &Self) -> bool { 864 | other.is_subset(self) 865 | } 866 | 867 | /// Adds a value to the set. Returns `true` if the value was not already 868 | /// present in the set. 869 | pub fn insert(&mut self, value: usize) -> bool { 870 | if self.contains(value) { 871 | return false; 872 | } 873 | 874 | // Ensure we have enough space to hold the new element 875 | let len = self.bit_vec.len(); 876 | if value >= len { 877 | self.bit_vec.grow(value - len + 1, false); 878 | } 879 | 880 | self.bit_vec.set(value, true); 881 | true 882 | } 883 | 884 | /// Removes a value from the set. Returns `true` if the value was 885 | /// present in the set. 886 | pub fn remove(&mut self, value: usize) -> bool { 887 | if !self.contains(value) { 888 | return false; 889 | } 890 | 891 | self.bit_vec.set(value, false); 892 | 893 | true 894 | } 895 | 896 | /// Excludes `element` and all greater elements from the `BitSet`. 897 | pub fn truncate(&mut self, element: usize) { 898 | self.bit_vec.truncate(element); 899 | } 900 | } 901 | 902 | impl fmt::Debug for BitSet { 903 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 904 | fmt.debug_struct("BitSet") 905 | .field("bit_vec", &self.bit_vec) 906 | .finish() 907 | } 908 | } 909 | 910 | impl fmt::Display for BitSet { 911 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 912 | fmt.debug_set().entries(self).finish() 913 | } 914 | } 915 | 916 | impl hash::Hash for BitSet { 917 | fn hash(&self, state: &mut H) { 918 | for pos in self { 919 | pos.hash(state); 920 | } 921 | } 922 | } 923 | 924 | #[derive(Clone)] 925 | struct BlockIter { 926 | head: B, 927 | head_offset: usize, 928 | tail: T, 929 | } 930 | 931 | impl BlockIter 932 | where 933 | T: Iterator, 934 | { 935 | fn from_blocks(mut blocks: T) -> BlockIter { 936 | let h = blocks.next().unwrap_or_else(B::zero); 937 | BlockIter { 938 | tail: blocks, 939 | head: h, 940 | head_offset: 0, 941 | } 942 | } 943 | } 944 | 945 | /// An iterator combining two `BitSet` iterators. 946 | #[derive(Clone)] 947 | struct TwoBitPositions<'a, B: 'a> { 948 | set: Blocks<'a, B>, 949 | other: Blocks<'a, B>, 950 | merge: fn(B, B) -> B, 951 | } 952 | 953 | /// An iterator for `BitSet`. 954 | #[derive(Clone)] 955 | pub struct Iter<'a, B: 'a>(BlockIter, B>); 956 | #[derive(Clone)] 957 | pub struct Union<'a, B: 'a>(BlockIter, B>); 958 | #[derive(Clone)] 959 | pub struct Intersection<'a, B: 'a> { 960 | iter: BlockIter, B>, 961 | // as an optimization, we compute the maximum possible 962 | // number of elements in the intersection, and count it 963 | // down as we return elements. If we reach zero, we can 964 | // stop. 965 | n: usize, 966 | } 967 | #[derive(Clone)] 968 | pub struct Difference<'a, B: 'a>(BlockIter, B>); 969 | #[derive(Clone)] 970 | pub struct SymmetricDifference<'a, B: 'a>(BlockIter, B>); 971 | 972 | impl Iterator for BlockIter 973 | where 974 | T: Iterator, 975 | { 976 | type Item = usize; 977 | 978 | fn next(&mut self) -> Option { 979 | while self.head == B::zero() { 980 | match self.tail.next() { 981 | Some(w) => self.head = w, 982 | None => return None, 983 | } 984 | self.head_offset += B::bits(); 985 | } 986 | 987 | // from the current block, isolate the 988 | // LSB and subtract 1, producing k: 989 | // a block with a number of set bits 990 | // equal to the index of the LSB 991 | let k = (self.head & (!self.head + B::one())) - B::one(); 992 | // update block, removing the LSB 993 | self.head = self.head & (self.head - B::one()); 994 | // return offset + (index of LSB) 995 | Some(self.head_offset + (B::count_ones(k))) 996 | } 997 | 998 | fn count(self) -> usize { 999 | self.head.count_ones() + self.tail.map(|block| block.count_ones()).sum::() 1000 | } 1001 | 1002 | #[inline] 1003 | fn size_hint(&self) -> (usize, Option) { 1004 | match self.tail.size_hint() { 1005 | (_, Some(h)) => (0, Some((1 + h) * B::bits())), 1006 | _ => (0, None), 1007 | } 1008 | } 1009 | } 1010 | 1011 | impl Iterator for TwoBitPositions<'_, B> { 1012 | type Item = B; 1013 | 1014 | fn next(&mut self) -> Option { 1015 | match (self.set.next(), self.other.next()) { 1016 | (Some(a), Some(b)) => Some((self.merge)(a, b)), 1017 | (Some(a), None) => Some((self.merge)(a, B::zero())), 1018 | (None, Some(b)) => Some((self.merge)(B::zero(), b)), 1019 | _ => None, 1020 | } 1021 | } 1022 | 1023 | #[inline] 1024 | fn size_hint(&self) -> (usize, Option) { 1025 | let (first_lower_bound, first_upper_bound) = self.set.size_hint(); 1026 | let (second_lower_bound, second_upper_bound) = self.other.size_hint(); 1027 | 1028 | let upper_bound = first_upper_bound.zip(second_upper_bound); 1029 | 1030 | let get_max = |(a, b)| cmp::max(a, b); 1031 | ( 1032 | cmp::max(first_lower_bound, second_lower_bound), 1033 | upper_bound.map(get_max), 1034 | ) 1035 | } 1036 | } 1037 | 1038 | impl Iterator for Iter<'_, B> { 1039 | type Item = usize; 1040 | 1041 | #[inline] 1042 | fn next(&mut self) -> Option { 1043 | self.0.next() 1044 | } 1045 | #[inline] 1046 | fn size_hint(&self) -> (usize, Option) { 1047 | self.0.size_hint() 1048 | } 1049 | #[inline] 1050 | fn count(self) -> usize { 1051 | self.0.count() 1052 | } 1053 | } 1054 | 1055 | impl Iterator for Union<'_, B> { 1056 | type Item = usize; 1057 | 1058 | #[inline] 1059 | fn next(&mut self) -> Option { 1060 | self.0.next() 1061 | } 1062 | #[inline] 1063 | fn size_hint(&self) -> (usize, Option) { 1064 | self.0.size_hint() 1065 | } 1066 | #[inline] 1067 | fn count(self) -> usize { 1068 | self.0.count() 1069 | } 1070 | } 1071 | 1072 | impl Iterator for Intersection<'_, B> { 1073 | type Item = usize; 1074 | 1075 | #[inline] 1076 | fn next(&mut self) -> Option { 1077 | if self.n != 0 { 1078 | self.n -= 1; 1079 | self.iter.next() 1080 | } else { 1081 | None 1082 | } 1083 | } 1084 | #[inline] 1085 | fn size_hint(&self) -> (usize, Option) { 1086 | // We could invoke self.iter.size_hint() and incorporate that into the hint. 1087 | // In practice, that does not seem worthwhile because the lower bound will 1088 | // always be zero and the upper bound could only possibly less then n in a 1089 | // partially iterated iterator. However, it makes little sense ask for size_hint 1090 | // in a partially iterated iterator, so it did not seem worthwhile. 1091 | (0, Some(self.n)) 1092 | } 1093 | #[inline] 1094 | fn count(self) -> usize { 1095 | self.iter.count() 1096 | } 1097 | } 1098 | 1099 | impl Iterator for Difference<'_, B> { 1100 | type Item = usize; 1101 | 1102 | #[inline] 1103 | fn next(&mut self) -> Option { 1104 | self.0.next() 1105 | } 1106 | #[inline] 1107 | fn size_hint(&self) -> (usize, Option) { 1108 | self.0.size_hint() 1109 | } 1110 | #[inline] 1111 | fn count(self) -> usize { 1112 | self.0.count() 1113 | } 1114 | } 1115 | 1116 | impl Iterator for SymmetricDifference<'_, B> { 1117 | type Item = usize; 1118 | 1119 | #[inline] 1120 | fn next(&mut self) -> Option { 1121 | self.0.next() 1122 | } 1123 | #[inline] 1124 | fn size_hint(&self) -> (usize, Option) { 1125 | self.0.size_hint() 1126 | } 1127 | #[inline] 1128 | fn count(self) -> usize { 1129 | self.0.count() 1130 | } 1131 | } 1132 | 1133 | impl<'a, B: BitBlock> IntoIterator for &'a BitSet { 1134 | type Item = usize; 1135 | type IntoIter = Iter<'a, B>; 1136 | 1137 | fn into_iter(self) -> Iter<'a, B> { 1138 | self.iter() 1139 | } 1140 | } 1141 | 1142 | #[cfg(test)] 1143 | mod tests { 1144 | #![allow(clippy::shadow_reuse)] 1145 | #![allow(clippy::shadow_same)] 1146 | #![allow(clippy::shadow_unrelated)] 1147 | 1148 | use super::BitSet; 1149 | use bit_vec::BitVec; 1150 | use std::cmp::Ordering::{Equal, Greater, Less}; 1151 | use std::vec::Vec; 1152 | use std::{format, vec}; 1153 | 1154 | #[test] 1155 | fn test_bit_set_display() { 1156 | let mut s = BitSet::new(); 1157 | s.insert(1); 1158 | s.insert(10); 1159 | s.insert(50); 1160 | s.insert(2); 1161 | assert_eq!("{1, 2, 10, 50}", format!("{}", s)); 1162 | } 1163 | 1164 | #[test] 1165 | fn test_bit_set_debug() { 1166 | let mut s = BitSet::new(); 1167 | s.insert(1); 1168 | s.insert(10); 1169 | s.insert(50); 1170 | s.insert(2); 1171 | let expected = "BitSet { bit_vec: BitVec { storage: \ 1172 | \"01100000001000000000000000000000 \ 1173 | 0000000000000000001\", nbits: 51 } }"; 1174 | let actual = format!("{:?}", s); 1175 | assert_eq!(expected, actual); 1176 | } 1177 | 1178 | #[test] 1179 | fn test_bit_set_from_usizes() { 1180 | let usizes = vec![0, 2, 2, 3]; 1181 | let a: BitSet = usizes.into_iter().collect(); 1182 | let mut b = BitSet::new(); 1183 | b.insert(0); 1184 | b.insert(2); 1185 | b.insert(3); 1186 | assert_eq!(a, b); 1187 | } 1188 | 1189 | #[test] 1190 | fn test_bit_set_iterator() { 1191 | let usizes = vec![0, 2, 2, 3]; 1192 | let bit_vec: BitSet = usizes.into_iter().collect(); 1193 | 1194 | let idxs: Vec<_> = bit_vec.iter().collect(); 1195 | assert_eq!(idxs, [0, 2, 3]); 1196 | assert_eq!(bit_vec.iter().count(), 3); 1197 | 1198 | let long: BitSet = (0..10000).filter(|&n| n % 2 == 0).collect(); 1199 | let real: Vec<_> = (0..10000 / 2).map(|x| x * 2).collect(); 1200 | 1201 | let idxs: Vec<_> = long.iter().collect(); 1202 | assert_eq!(idxs, real); 1203 | assert_eq!(long.iter().count(), real.len()); 1204 | } 1205 | 1206 | #[test] 1207 | fn test_bit_set_frombit_vec_init() { 1208 | let bools = [true, false]; 1209 | let lengths = [10, 64, 100]; 1210 | for &b in &bools { 1211 | for &l in &lengths { 1212 | let bitset = BitSet::from_bit_vec(BitVec::from_elem(l, b)); 1213 | assert_eq!(bitset.contains(1), b); 1214 | assert_eq!(bitset.contains(l - 1), b); 1215 | assert!(!bitset.contains(l)); 1216 | } 1217 | } 1218 | } 1219 | 1220 | #[test] 1221 | fn test_bit_vec_masking() { 1222 | let b = BitVec::from_elem(140, true); 1223 | let mut bs = BitSet::from_bit_vec(b); 1224 | assert!(bs.contains(139)); 1225 | assert!(!bs.contains(140)); 1226 | assert!(bs.insert(150)); 1227 | assert!(!bs.contains(140)); 1228 | assert!(!bs.contains(149)); 1229 | assert!(bs.contains(150)); 1230 | assert!(!bs.contains(151)); 1231 | } 1232 | 1233 | #[test] 1234 | fn test_bit_set_basic() { 1235 | let mut b = BitSet::new(); 1236 | assert!(b.insert(3)); 1237 | assert!(!b.insert(3)); 1238 | assert!(b.contains(3)); 1239 | assert!(b.insert(4)); 1240 | assert!(!b.insert(4)); 1241 | assert!(b.contains(3)); 1242 | assert!(b.insert(400)); 1243 | assert!(!b.insert(400)); 1244 | assert!(b.contains(400)); 1245 | assert_eq!(b.count(), 3); 1246 | } 1247 | 1248 | #[test] 1249 | fn test_bit_set_intersection() { 1250 | let mut a = BitSet::new(); 1251 | let mut b = BitSet::new(); 1252 | 1253 | assert!(a.insert(11)); 1254 | assert!(a.insert(1)); 1255 | assert!(a.insert(3)); 1256 | assert!(a.insert(77)); 1257 | assert!(a.insert(103)); 1258 | assert!(a.insert(5)); 1259 | 1260 | assert!(b.insert(2)); 1261 | assert!(b.insert(11)); 1262 | assert!(b.insert(77)); 1263 | assert!(b.insert(5)); 1264 | assert!(b.insert(3)); 1265 | 1266 | let expected = [3, 5, 11, 77]; 1267 | let actual: Vec<_> = a.intersection(&b).collect(); 1268 | assert_eq!(actual, expected); 1269 | assert_eq!(a.intersection(&b).count(), expected.len()); 1270 | } 1271 | 1272 | #[test] 1273 | fn test_bit_set_difference() { 1274 | let mut a = BitSet::new(); 1275 | let mut b = BitSet::new(); 1276 | 1277 | assert!(a.insert(1)); 1278 | assert!(a.insert(3)); 1279 | assert!(a.insert(5)); 1280 | assert!(a.insert(200)); 1281 | assert!(a.insert(500)); 1282 | 1283 | assert!(b.insert(3)); 1284 | assert!(b.insert(200)); 1285 | 1286 | let expected = [1, 5, 500]; 1287 | let actual: Vec<_> = a.difference(&b).collect(); 1288 | assert_eq!(actual, expected); 1289 | assert_eq!(a.difference(&b).count(), expected.len()); 1290 | } 1291 | 1292 | #[test] 1293 | fn test_bit_set_symmetric_difference() { 1294 | let mut a = BitSet::new(); 1295 | let mut b = BitSet::new(); 1296 | 1297 | assert!(a.insert(1)); 1298 | assert!(a.insert(3)); 1299 | assert!(a.insert(5)); 1300 | assert!(a.insert(9)); 1301 | assert!(a.insert(11)); 1302 | 1303 | assert!(b.insert(3)); 1304 | assert!(b.insert(9)); 1305 | assert!(b.insert(14)); 1306 | assert!(b.insert(220)); 1307 | 1308 | let expected = [1, 5, 11, 14, 220]; 1309 | let actual: Vec<_> = a.symmetric_difference(&b).collect(); 1310 | assert_eq!(actual, expected); 1311 | assert_eq!(a.symmetric_difference(&b).count(), expected.len()); 1312 | } 1313 | 1314 | #[test] 1315 | fn test_bit_set_union() { 1316 | let mut a = BitSet::new(); 1317 | let mut b = BitSet::new(); 1318 | assert!(a.insert(1)); 1319 | assert!(a.insert(3)); 1320 | assert!(a.insert(5)); 1321 | assert!(a.insert(9)); 1322 | assert!(a.insert(11)); 1323 | assert!(a.insert(160)); 1324 | assert!(a.insert(19)); 1325 | assert!(a.insert(24)); 1326 | assert!(a.insert(200)); 1327 | 1328 | assert!(b.insert(1)); 1329 | assert!(b.insert(5)); 1330 | assert!(b.insert(9)); 1331 | assert!(b.insert(13)); 1332 | assert!(b.insert(19)); 1333 | 1334 | let expected = [1, 3, 5, 9, 11, 13, 19, 24, 160, 200]; 1335 | let actual: Vec<_> = a.union(&b).collect(); 1336 | assert_eq!(actual, expected); 1337 | assert_eq!(a.union(&b).count(), expected.len()); 1338 | } 1339 | 1340 | #[test] 1341 | fn test_bit_set_subset() { 1342 | let mut set1 = BitSet::new(); 1343 | let mut set2 = BitSet::new(); 1344 | 1345 | assert!(set1.is_subset(&set2)); // {} {} 1346 | set2.insert(100); 1347 | assert!(set1.is_subset(&set2)); // {} { 1 } 1348 | set2.insert(200); 1349 | assert!(set1.is_subset(&set2)); // {} { 1, 2 } 1350 | set1.insert(200); 1351 | assert!(set1.is_subset(&set2)); // { 2 } { 1, 2 } 1352 | set1.insert(300); 1353 | assert!(!set1.is_subset(&set2)); // { 2, 3 } { 1, 2 } 1354 | set2.insert(300); 1355 | assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3 } 1356 | set2.insert(400); 1357 | assert!(set1.is_subset(&set2)); // { 2, 3 } { 1, 2, 3, 4 } 1358 | set2.remove(100); 1359 | assert!(set1.is_subset(&set2)); // { 2, 3 } { 2, 3, 4 } 1360 | set2.remove(300); 1361 | assert!(!set1.is_subset(&set2)); // { 2, 3 } { 2, 4 } 1362 | set1.remove(300); 1363 | assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 } 1364 | } 1365 | 1366 | #[test] 1367 | fn test_bit_set_is_disjoint() { 1368 | let a = BitSet::from_bytes(&[0b10100010]); 1369 | let b = BitSet::from_bytes(&[0b01000000]); 1370 | let c = BitSet::new(); 1371 | let d = BitSet::from_bytes(&[0b00110000]); 1372 | 1373 | assert!(!a.is_disjoint(&d)); 1374 | assert!(!d.is_disjoint(&a)); 1375 | 1376 | assert!(a.is_disjoint(&b)); 1377 | assert!(a.is_disjoint(&c)); 1378 | assert!(b.is_disjoint(&a)); 1379 | assert!(b.is_disjoint(&c)); 1380 | assert!(c.is_disjoint(&a)); 1381 | assert!(c.is_disjoint(&b)); 1382 | } 1383 | 1384 | #[test] 1385 | fn test_bit_set_union_with() { 1386 | //a should grow to include larger elements 1387 | let mut a = BitSet::new(); 1388 | a.insert(0); 1389 | let mut b = BitSet::new(); 1390 | b.insert(5); 1391 | let expected = BitSet::from_bytes(&[0b10000100]); 1392 | a.union_with(&b); 1393 | assert_eq!(a, expected); 1394 | 1395 | // Standard 1396 | let mut a = BitSet::from_bytes(&[0b10100010]); 1397 | let mut b = BitSet::from_bytes(&[0b01100010]); 1398 | let c = a.clone(); 1399 | a.union_with(&b); 1400 | b.union_with(&c); 1401 | assert_eq!(a.count(), 4); 1402 | assert_eq!(b.count(), 4); 1403 | } 1404 | 1405 | #[test] 1406 | fn test_bit_set_intersect_with() { 1407 | // Explicitly 0'ed bits 1408 | let mut a = BitSet::from_bytes(&[0b10100010]); 1409 | let mut b = BitSet::from_bytes(&[0b00000000]); 1410 | let c = a.clone(); 1411 | a.intersect_with(&b); 1412 | b.intersect_with(&c); 1413 | assert!(a.is_empty()); 1414 | assert!(b.is_empty()); 1415 | 1416 | // Uninitialized bits should behave like 0's 1417 | let mut a = BitSet::from_bytes(&[0b10100010]); 1418 | let mut b = BitSet::new(); 1419 | let c = a.clone(); 1420 | a.intersect_with(&b); 1421 | b.intersect_with(&c); 1422 | assert!(a.is_empty()); 1423 | assert!(b.is_empty()); 1424 | 1425 | // Standard 1426 | let mut a = BitSet::from_bytes(&[0b10100010]); 1427 | let mut b = BitSet::from_bytes(&[0b01100010]); 1428 | let c = a.clone(); 1429 | a.intersect_with(&b); 1430 | b.intersect_with(&c); 1431 | assert_eq!(a.count(), 2); 1432 | assert_eq!(b.count(), 2); 1433 | } 1434 | 1435 | #[test] 1436 | fn test_bit_set_difference_with() { 1437 | // Explicitly 0'ed bits 1438 | let mut a = BitSet::from_bytes(&[0b00000000]); 1439 | let b = BitSet::from_bytes(&[0b10100010]); 1440 | a.difference_with(&b); 1441 | assert!(a.is_empty()); 1442 | 1443 | // Uninitialized bits should behave like 0's 1444 | let mut a = BitSet::new(); 1445 | let b = BitSet::from_bytes(&[0b11111111]); 1446 | a.difference_with(&b); 1447 | assert!(a.is_empty()); 1448 | 1449 | // Standard 1450 | let mut a = BitSet::from_bytes(&[0b10100010]); 1451 | let mut b = BitSet::from_bytes(&[0b01100010]); 1452 | let c = a.clone(); 1453 | a.difference_with(&b); 1454 | b.difference_with(&c); 1455 | assert_eq!(a.count(), 1); 1456 | assert_eq!(b.count(), 1); 1457 | } 1458 | 1459 | #[test] 1460 | fn test_bit_set_symmetric_difference_with() { 1461 | //a should grow to include larger elements 1462 | let mut a = BitSet::new(); 1463 | a.insert(0); 1464 | a.insert(1); 1465 | let mut b = BitSet::new(); 1466 | b.insert(1); 1467 | b.insert(5); 1468 | let expected = BitSet::from_bytes(&[0b10000100]); 1469 | a.symmetric_difference_with(&b); 1470 | assert_eq!(a, expected); 1471 | 1472 | let mut a = BitSet::from_bytes(&[0b10100010]); 1473 | let b = BitSet::new(); 1474 | let c = a.clone(); 1475 | a.symmetric_difference_with(&b); 1476 | assert_eq!(a, c); 1477 | 1478 | // Standard 1479 | let mut a = BitSet::from_bytes(&[0b11100010]); 1480 | let mut b = BitSet::from_bytes(&[0b01101010]); 1481 | let c = a.clone(); 1482 | a.symmetric_difference_with(&b); 1483 | b.symmetric_difference_with(&c); 1484 | assert_eq!(a.count(), 2); 1485 | assert_eq!(b.count(), 2); 1486 | } 1487 | 1488 | #[test] 1489 | fn test_bit_set_eq() { 1490 | let a = BitSet::from_bytes(&[0b10100010]); 1491 | let b = BitSet::from_bytes(&[0b00000000]); 1492 | let c = BitSet::new(); 1493 | 1494 | assert!(a == a); 1495 | assert!(a != b); 1496 | assert!(a != c); 1497 | assert!(b == b); 1498 | assert!(b == c); 1499 | assert!(c == c); 1500 | } 1501 | 1502 | #[test] 1503 | fn test_bit_set_cmp() { 1504 | let a = BitSet::from_bytes(&[0b10100010]); 1505 | let b = BitSet::from_bytes(&[0b00000000]); 1506 | let c = BitSet::new(); 1507 | 1508 | assert_eq!(a.cmp(&b), Greater); 1509 | assert_eq!(a.cmp(&c), Greater); 1510 | assert_eq!(b.cmp(&a), Less); 1511 | assert_eq!(b.cmp(&c), Equal); 1512 | assert_eq!(c.cmp(&a), Less); 1513 | assert_eq!(c.cmp(&b), Equal); 1514 | } 1515 | 1516 | #[test] 1517 | fn test_bit_set_shrink_to_fit_new() { 1518 | // There was a strange bug where we refused to truncate to 0 1519 | // and this would end up actually growing the array in a way 1520 | // that (safely corrupted the state). 1521 | let mut a = BitSet::new(); 1522 | assert_eq!(a.count(), 0); 1523 | assert_eq!(a.capacity(), 0); 1524 | a.shrink_to_fit(); 1525 | assert_eq!(a.count(), 0); 1526 | assert_eq!(a.capacity(), 0); 1527 | assert!(!a.contains(1)); 1528 | a.insert(3); 1529 | assert!(a.contains(3)); 1530 | assert_eq!(a.count(), 1); 1531 | assert!(a.capacity() > 0); 1532 | a.shrink_to_fit(); 1533 | assert!(a.contains(3)); 1534 | assert_eq!(a.count(), 1); 1535 | assert!(a.capacity() > 0); 1536 | } 1537 | 1538 | #[test] 1539 | fn test_bit_set_shrink_to_fit() { 1540 | let mut a = BitSet::new(); 1541 | assert_eq!(a.count(), 0); 1542 | assert_eq!(a.capacity(), 0); 1543 | a.insert(259); 1544 | a.insert(98); 1545 | a.insert(3); 1546 | assert_eq!(a.count(), 3); 1547 | assert!(a.capacity() > 0); 1548 | assert!(!a.contains(1)); 1549 | assert!(a.contains(259)); 1550 | assert!(a.contains(98)); 1551 | assert!(a.contains(3)); 1552 | 1553 | a.shrink_to_fit(); 1554 | assert!(!a.contains(1)); 1555 | assert!(a.contains(259)); 1556 | assert!(a.contains(98)); 1557 | assert!(a.contains(3)); 1558 | assert_eq!(a.count(), 3); 1559 | assert!(a.capacity() > 0); 1560 | 1561 | let old_cap = a.capacity(); 1562 | assert!(a.remove(259)); 1563 | a.shrink_to_fit(); 1564 | assert!(a.capacity() < old_cap, "{} {}", a.capacity(), old_cap); 1565 | assert!(!a.contains(1)); 1566 | assert!(!a.contains(259)); 1567 | assert!(a.contains(98)); 1568 | assert!(a.contains(3)); 1569 | assert_eq!(a.count(), 2); 1570 | 1571 | let old_cap2 = a.capacity(); 1572 | a.clear(); 1573 | assert_eq!(a.capacity(), old_cap2); 1574 | assert_eq!(a.count(), 0); 1575 | assert!(!a.contains(1)); 1576 | assert!(!a.contains(259)); 1577 | assert!(!a.contains(98)); 1578 | assert!(!a.contains(3)); 1579 | 1580 | a.insert(512); 1581 | assert!(a.capacity() > 0); 1582 | assert_eq!(a.count(), 1); 1583 | assert!(a.contains(512)); 1584 | assert!(!a.contains(1)); 1585 | assert!(!a.contains(259)); 1586 | assert!(!a.contains(98)); 1587 | assert!(!a.contains(3)); 1588 | 1589 | a.remove(512); 1590 | a.shrink_to_fit(); 1591 | assert_eq!(a.capacity(), 0); 1592 | assert_eq!(a.count(), 0); 1593 | assert!(!a.contains(512)); 1594 | assert!(!a.contains(1)); 1595 | assert!(!a.contains(259)); 1596 | assert!(!a.contains(98)); 1597 | assert!(!a.contains(3)); 1598 | assert!(!a.contains(0)); 1599 | } 1600 | 1601 | #[test] 1602 | fn test_bit_vec_remove() { 1603 | let mut a = BitSet::new(); 1604 | 1605 | assert!(a.insert(1)); 1606 | assert!(a.remove(1)); 1607 | 1608 | assert!(a.insert(100)); 1609 | assert!(a.remove(100)); 1610 | 1611 | assert!(a.insert(1000)); 1612 | assert!(a.remove(1000)); 1613 | a.shrink_to_fit(); 1614 | } 1615 | 1616 | #[test] 1617 | fn test_bit_vec_clone() { 1618 | let mut a = BitSet::new(); 1619 | 1620 | assert!(a.insert(1)); 1621 | assert!(a.insert(100)); 1622 | assert!(a.insert(1000)); 1623 | 1624 | let mut b = a.clone(); 1625 | 1626 | assert!(a == b); 1627 | 1628 | assert!(b.remove(1)); 1629 | assert!(a.contains(1)); 1630 | 1631 | assert!(a.remove(1000)); 1632 | assert!(b.contains(1000)); 1633 | } 1634 | 1635 | #[test] 1636 | fn test_truncate() { 1637 | let bytes = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]; 1638 | 1639 | let mut s = BitSet::from_bytes(&bytes); 1640 | s.truncate(5 * 8); 1641 | 1642 | assert_eq!(s, BitSet::from_bytes(&bytes[..5])); 1643 | assert_eq!(s.count(), 5 * 8); 1644 | s.truncate(4 * 8); 1645 | assert_eq!(s, BitSet::from_bytes(&bytes[..4])); 1646 | assert_eq!(s.count(), 4 * 8); 1647 | // Truncating to a size > s.len() should be a noop 1648 | s.truncate(5 * 8); 1649 | assert_eq!(s, BitSet::from_bytes(&bytes[..4])); 1650 | assert_eq!(s.count(), 4 * 8); 1651 | s.truncate(8); 1652 | assert_eq!(s, BitSet::from_bytes(&bytes[..1])); 1653 | assert_eq!(s.count(), 8); 1654 | s.truncate(0); 1655 | assert_eq!(s, BitSet::from_bytes(&[])); 1656 | assert_eq!(s.count(), 0); 1657 | } 1658 | 1659 | #[cfg(feature = "serde")] 1660 | #[test] 1661 | fn test_serialization() { 1662 | let bset: BitSet = BitSet::new(); 1663 | let serialized = serde_json::to_string(&bset).unwrap(); 1664 | let unserialized: BitSet = serde_json::from_str(&serialized).unwrap(); 1665 | assert_eq!(bset, unserialized); 1666 | 1667 | let elems: Vec = vec![11, 42, 100, 101]; 1668 | let bset: BitSet = elems.iter().map(|n| *n).collect(); 1669 | let serialized = serde_json::to_string(&bset).unwrap(); 1670 | let unserialized = serde_json::from_str(&serialized).unwrap(); 1671 | assert_eq!(bset, unserialized); 1672 | } 1673 | 1674 | #[cfg(feature = "miniserde")] 1675 | #[test] 1676 | fn test_miniserde_serialization() { 1677 | let bset: BitSet = BitSet::new(); 1678 | let serialized = miniserde::json::to_string(&bset); 1679 | let unserialized: BitSet = miniserde::json::from_str(&serialized[..]).unwrap(); 1680 | assert_eq!(bset, unserialized); 1681 | 1682 | let elems: Vec = vec![11, 42, 100, 101]; 1683 | let bset: BitSet = elems.iter().map(|n| *n).collect(); 1684 | let serialized = miniserde::json::to_string(&bset); 1685 | let unserialized = miniserde::json::from_str(&serialized[..]).unwrap(); 1686 | assert_eq!(bset, unserialized); 1687 | } 1688 | 1689 | #[cfg(feature = "nanoserde")] 1690 | #[test] 1691 | fn test_nanoserde_json_serialization() { 1692 | use nanoserde::{DeJson, SerJson}; 1693 | 1694 | let bset: BitSet = BitSet::new(); 1695 | let serialized = bset.serialize_json(); 1696 | let unserialized: BitSet = BitSet::deserialize_json(&serialized[..]).unwrap(); 1697 | assert_eq!(bset, unserialized); 1698 | 1699 | let elems: Vec = vec![11, 42, 100, 101]; 1700 | let bset: BitSet = elems.iter().map(|n| *n).collect(); 1701 | let serialized = bset.serialize_json(); 1702 | let unserialized = BitSet::deserialize_json(&serialized[..]).unwrap(); 1703 | assert_eq!(bset, unserialized); 1704 | } 1705 | 1706 | #[cfg(feature = "borsh")] 1707 | #[test] 1708 | fn test_borsh_serialization() { 1709 | let bset: BitSet = BitSet::new(); 1710 | let serialized = borsh::to_vec(&bset).unwrap(); 1711 | let unserialized: BitSet = borsh::from_slice(&serialized[..]).unwrap(); 1712 | assert_eq!(bset, unserialized); 1713 | 1714 | let elems: Vec = vec![11, 42, 100, 101]; 1715 | let bset: BitSet = elems.iter().map(|n| *n).collect(); 1716 | let serialized = borsh::to_vec(&bset).unwrap(); 1717 | let unserialized = borsh::from_slice(&serialized[..]).unwrap(); 1718 | assert_eq!(bset, unserialized); 1719 | } 1720 | 1721 | /* 1722 | #[test] 1723 | fn test_bit_set_append() { 1724 | let mut a = BitSet::new(); 1725 | a.insert(2); 1726 | a.insert(6); 1727 | 1728 | let mut b = BitSet::new(); 1729 | b.insert(1); 1730 | b.insert(3); 1731 | b.insert(6); 1732 | 1733 | a.append(&mut b); 1734 | 1735 | assert_eq!(a.len(), 4); 1736 | assert_eq!(b.len(), 0); 1737 | assert!(b.capacity() >= 6); 1738 | 1739 | assert_eq!(a, BitSet::from_bytes(&[0b01110010])); 1740 | } 1741 | 1742 | #[test] 1743 | fn test_bit_set_split_off() { 1744 | // Split at 0 1745 | let mut a = BitSet::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 1746 | 0b00110011, 0b01101011, 0b10101101]); 1747 | 1748 | let b = a.split_off(0); 1749 | 1750 | assert_eq!(a.len(), 0); 1751 | assert_eq!(b.len(), 21); 1752 | 1753 | assert_eq!(b, BitSet::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 1754 | 0b00110011, 0b01101011, 0b10101101]); 1755 | 1756 | // Split behind last element 1757 | let mut a = BitSet::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 1758 | 0b00110011, 0b01101011, 0b10101101]); 1759 | 1760 | let b = a.split_off(50); 1761 | 1762 | assert_eq!(a.len(), 21); 1763 | assert_eq!(b.len(), 0); 1764 | 1765 | assert_eq!(a, BitSet::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 1766 | 0b00110011, 0b01101011, 0b10101101])); 1767 | 1768 | // Split at arbitrary element 1769 | let mut a = BitSet::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 1770 | 0b00110011, 0b01101011, 0b10101101]); 1771 | 1772 | let b = a.split_off(34); 1773 | 1774 | assert_eq!(a.len(), 12); 1775 | assert_eq!(b.len(), 9); 1776 | 1777 | assert_eq!(a, BitSet::from_bytes(&[0b10100000, 0b00010010, 0b10010010, 1778 | 0b00110011, 0b01000000])); 1779 | assert_eq!(b, BitSet::from_bytes(&[0, 0, 0, 0, 1780 | 0b00101011, 0b10101101])); 1781 | } 1782 | */ 1783 | } 1784 | --------------------------------------------------------------------------------