├── .gitignore ├── .travis.yml ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── deploy-docs.sh └── src ├── impls.rs └── lib.rs /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | sudo: false 3 | matrix: 4 | include: 5 | - rust: nightly 6 | env: FEATURES="--features nightly" 7 | - rust: beta 8 | - rust: stable 9 | script: 10 | - cargo build $FEATURES 11 | - cargo test $FEATURES 12 | - cargo doc --no-deps $FEATURES 13 | after_success: | 14 | [ $TRAVIS_TAG ] && 15 | [ $TRAVIS_RUST_VERSION == nightly ] && 16 | bash deploy-docs.sh 17 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "eclectic" 3 | version = "0.11.0" 4 | authors = ["Andrew Paseltiner "] 5 | license = "MIT/Apache-2.0" 6 | homepage = "https://github.com/apasel422/eclectic" 7 | repository = "https://github.com/apasel422/eclectic" 8 | documentation = "https://apasel422.github.io/eclectic/eclectic" 9 | keywords = ["collecton", "map", "set", "data-structure"] 10 | description = "Experimental collection traits." 11 | exclude = [ 12 | ".travis.yml", 13 | "deploy-docs.sh", 14 | ] 15 | 16 | [features] 17 | nightly = [] 18 | -------------------------------------------------------------------------------- /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 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 The Rust Project Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eclectic 2 | 3 | Experimental collection traits for Rust. 4 | 5 | Documentation is available at https://apasel422.github.io/eclectic/eclectic. 6 | 7 | To use `eclectic` with Cargo, add this to `Cargo.toml`: 8 | 9 | ```toml 10 | [dependencies] 11 | eclectic = "0.11" 12 | ``` 13 | 14 | and this to the crate root: 15 | 16 | ```rust 17 | extern crate eclectic; 18 | ``` 19 | -------------------------------------------------------------------------------- /deploy-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit -o nounset 4 | 5 | cd target/doc 6 | 7 | git init 8 | git config user.email 'apaseltiner@gmail.com' 9 | git config user.name 'Andrew Paseltiner' 10 | git remote add upstream "https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git" 11 | 12 | touch . 13 | 14 | git add -A . 15 | git commit -qm "rebuild pages at ${TRAVIS_TAG}" 16 | git push -q upstream HEAD:gh-pages --force 17 | -------------------------------------------------------------------------------- /src/impls.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Borrow; 2 | use std::collections::*; 3 | use std::hash::Hash; 4 | use std::mem; 5 | use std::ops::Range; 6 | use super::*; 7 | 8 | impl Mutate for [T] {} 9 | 10 | impl Collection for [T] { 11 | type Item = T; 12 | 13 | fn len(&self) -> usize { 14 | self.len() 15 | } 16 | 17 | fn capacity(&self) -> usize { 18 | self.len() 19 | } 20 | 21 | fn extend_object(&mut self, _items: &mut Iterator) where Self: AddRemove { 22 | unimplemented!() 23 | } 24 | 25 | fn drain<'a>(&'a mut self) -> Box + 'a> where Self: AddRemove { 26 | unimplemented!() 27 | } 28 | 29 | fn reserve(&mut self, _additional: usize) where Self: AddRemove { 30 | unimplemented!() 31 | } 32 | 33 | fn shrink_to_fit(&mut self) where Self: AddRemove { 34 | unimplemented!() 35 | } 36 | } 37 | 38 | impl Iter for [T] { 39 | fn iter<'a>(&'a self) -> Box + 'a> { 40 | Box::new(self.iter()) 41 | } 42 | 43 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> { 44 | Box::new(self.iter_mut()) 45 | } 46 | } 47 | 48 | impl DrainRange> for [T] { 49 | fn drain_range<'a>(&'a mut self, _range: Range) 50 | -> Box + 'a> where Self: AddRemove 51 | { 52 | unimplemented!() 53 | } 54 | } 55 | 56 | impl List for [T] { 57 | fn get(&self, index: usize) -> Option<&T> { 58 | self.get(index) 59 | } 60 | 61 | fn get_mut(&mut self, index: usize) -> Option<&mut T> { 62 | self.get_mut(index) 63 | } 64 | 65 | fn swap(&mut self, i: usize, j: usize) { 66 | self.swap(i, j); 67 | } 68 | 69 | fn reverse(&mut self) { 70 | self.reverse(); 71 | } 72 | 73 | fn insert(&mut self, _index: usize, _item: T) where Self: AddRemove { 74 | unimplemented!() 75 | } 76 | 77 | fn remove(&mut self, _index: usize) -> Option where Self: AddRemove { 78 | unimplemented!() 79 | } 80 | 81 | fn swap_remove(&mut self, _index: usize) -> Option where Self: AddRemove { 82 | unimplemented!() 83 | } 84 | } 85 | 86 | impl Mutate for BTreeMap {} 87 | 88 | impl AddRemove for BTreeMap {} 89 | 90 | impl Collection for BTreeMap { 91 | type Item = (K, V); 92 | 93 | fn len(&self) -> usize { 94 | self.len() 95 | } 96 | 97 | fn capacity(&self) -> usize { 98 | self.len() 99 | } 100 | 101 | fn append(&mut self, other: &mut Self) { 102 | self.extend(mem::replace(other, Self::new())); 103 | } 104 | 105 | fn extend_object(&mut self, items: &mut Iterator) { 106 | self.extend(items); 107 | } 108 | 109 | fn clear(&mut self) { 110 | self.clear(); 111 | } 112 | 113 | fn drain<'a>(&'a mut self) -> Box + 'a> { 114 | Box::new(mem::replace(self, Self::new()).into_iter()) 115 | } 116 | 117 | fn reserve(&mut self, _additional: usize) {} 118 | 119 | fn shrink_to_fit(&mut self) {} 120 | 121 | fn with_capacity(_capacity: usize) -> Self { 122 | Self::new() 123 | } 124 | 125 | fn into_vec(self) -> Vec<(K, V)> { 126 | self.into_iter().collect() 127 | } 128 | } 129 | 130 | impl map::Base for BTreeMap { 131 | type Key = K; 132 | type Value = V; 133 | 134 | fn iter<'a>(&'a self) -> Box + 'a> { 135 | Box::new(self.iter()) 136 | } 137 | 138 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> { 139 | Box::new(self.iter_mut()) 140 | } 141 | 142 | fn insert(&mut self, key: K, value: V) -> Option { 143 | self.insert(key, value) 144 | } 145 | 146 | fn entry<'a>(&'a mut self, key: K) -> map::Entry<'a, K, V> { 147 | match self.entry(key) { 148 | btree_map::Entry::Occupied(e) => map::Entry::Occupied(Box::new(e)), 149 | btree_map::Entry::Vacant(e) => map::Entry::Vacant(Box::new(e)), 150 | } 151 | } 152 | } 153 | 154 | impl<'a, K: 'a + Ord, V: 'a> map::OccupiedEntry for btree_map::OccupiedEntry<'a, K, V> { 155 | type Key = K; 156 | type Value = V; 157 | type MutValue = &'a mut V; 158 | 159 | fn get(&self) -> &V { 160 | self.get() 161 | } 162 | 163 | fn get_mut(&mut self) -> &mut V { 164 | self.get_mut() 165 | } 166 | 167 | fn into_mut(self: Box) -> &'a mut V { 168 | (*self).into_mut() 169 | } 170 | 171 | fn remove(self: Box) -> V { 172 | (*self).remove() 173 | } 174 | } 175 | 176 | impl<'a, K: 'a + Ord, V: 'a> map::VacantEntry for btree_map::VacantEntry<'a, K, V> { 177 | type Key = K; 178 | type Value = V; 179 | type MutValue = &'a mut V; 180 | 181 | fn insert(self: Box, value: V) -> &'a mut V { 182 | (*self).insert(value) 183 | } 184 | } 185 | 186 | impl AddRemove for BTreeSet {} 187 | 188 | impl Collection for BTreeSet { 189 | type Item = T; 190 | 191 | fn len(&self) -> usize { 192 | self.len() 193 | } 194 | 195 | fn capacity(&self) -> usize { 196 | self.len() 197 | } 198 | 199 | fn append(&mut self, other: &mut Self) { 200 | self.extend(mem::replace(other, Self::new())); 201 | } 202 | 203 | fn extend_object(&mut self, items: &mut Iterator) { 204 | self.extend(items); 205 | } 206 | 207 | fn clear(&mut self) { 208 | self.clear(); 209 | } 210 | 211 | fn drain<'a>(&'a mut self) -> Box + 'a> { 212 | Box::new(mem::replace(self, Self::new()).into_iter()) 213 | } 214 | 215 | fn reserve(&mut self, _additional: usize) {} 216 | 217 | fn shrink_to_fit(&mut self) {} 218 | 219 | fn with_capacity(_capacity: usize) -> Self { 220 | Self::new() 221 | } 222 | 223 | fn into_vec(self) -> Vec { 224 | self.into_iter().collect() 225 | } 226 | } 227 | 228 | impl Iter for BTreeSet { 229 | fn iter<'a>(&'a self) -> Box + 'a> { 230 | Box::new(self.iter()) 231 | } 232 | 233 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> where Self: Mutate { 234 | unimplemented!() 235 | } 236 | } 237 | 238 | impl set::Base for BTreeSet { 239 | fn is_disjoint(&self, other: &Self) -> bool { 240 | self.is_disjoint(other) 241 | } 242 | 243 | fn is_subset(&self, other: &Self) -> bool { 244 | self.is_subset(other) 245 | } 246 | 247 | fn insert(&mut self, item: T) -> bool { 248 | self.insert(item) 249 | } 250 | 251 | fn replace(&mut self, item: T) -> Option { 252 | self.replace(item) 253 | } 254 | } 255 | 256 | impl, Q: ?Sized + Ord> Set for BTreeSet { 257 | fn contains(&self, item: &Q) -> bool { 258 | self.contains(item) 259 | } 260 | 261 | fn get(&self, item: &Q) -> Option<&T> { 262 | self.get(item) 263 | } 264 | 265 | fn remove(&mut self, item: &Q) -> bool { 266 | self.remove(item) 267 | } 268 | 269 | fn take(&mut self, item: &Q) -> Option { 270 | self.take(item) 271 | } 272 | } 273 | 274 | impl AddRemove for BinaryHeap {} 275 | 276 | impl Collection for BinaryHeap { 277 | type Item = T; 278 | 279 | fn len(&self) -> usize { 280 | self.len() 281 | } 282 | 283 | fn capacity(&self) -> usize { 284 | self.capacity() 285 | } 286 | 287 | fn append(&mut self, other: &mut Self) { 288 | self.extend(other.drain()); 289 | } 290 | 291 | fn extend_object(&mut self, items: &mut Iterator) { 292 | self.extend(items); 293 | } 294 | 295 | fn clear(&mut self) { 296 | self.clear(); 297 | } 298 | 299 | fn drain<'a>(&'a mut self) -> Box + 'a> { 300 | Box::new(self.drain()) 301 | } 302 | 303 | fn reserve(&mut self, additional: usize) { 304 | self.reserve(additional); 305 | } 306 | 307 | fn shrink_to_fit(&mut self) { 308 | self.shrink_to_fit(); 309 | } 310 | 311 | fn with_capacity(capacity: usize) -> Self { 312 | Self::with_capacity(capacity) 313 | } 314 | 315 | fn into_vec(self) -> Vec { 316 | self.into_vec() 317 | } 318 | } 319 | 320 | impl Iter for BinaryHeap { 321 | fn iter<'a>(&'a self) -> Box + 'a> { 322 | Box::new(self.iter()) 323 | } 324 | 325 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> where Self: Mutate { 326 | unimplemented!() 327 | } 328 | } 329 | 330 | impl Queue for BinaryHeap { 331 | fn push(&mut self, item: T) { 332 | self.push(item); 333 | } 334 | 335 | fn front(&self) -> Option<&T> { 336 | self.peek() 337 | } 338 | 339 | fn pop_front(&mut self) -> Option { 340 | self.pop() 341 | } 342 | } 343 | 344 | impl PrioQueue for BinaryHeap { 345 | fn push_pop_front(&mut self, item: T) -> T { 346 | match self.peek_mut() { 347 | Some(ref mut old) if item < **old => mem::replace(&mut *old, item), 348 | _ => item, 349 | } 350 | } 351 | 352 | fn replace_front(&mut self, item: T) -> Option { 353 | if let Some(mut old) = self.peek_mut() { 354 | return Some(mem::replace(&mut *old, item)); 355 | }; 356 | 357 | self.push(item); 358 | None 359 | } 360 | } 361 | 362 | impl Mutate for HashMap {} 363 | 364 | impl AddRemove for HashMap {} 365 | 366 | impl Collection for HashMap { 367 | type Item = (K, V); 368 | 369 | fn len(&self) -> usize { 370 | self.len() 371 | } 372 | 373 | fn capacity(&self) -> usize { 374 | self.capacity() 375 | } 376 | 377 | fn append(&mut self, other: &mut Self) { 378 | self.extend(other.drain()); 379 | } 380 | 381 | fn extend_object(&mut self, items: &mut Iterator) { 382 | self.extend(items); 383 | } 384 | 385 | fn clear(&mut self) { 386 | self.clear(); 387 | } 388 | 389 | fn drain<'a>(&'a mut self) -> Box + 'a> { 390 | Box::new(self.drain()) 391 | } 392 | 393 | fn reserve(&mut self, additional: usize) { 394 | self.reserve(additional); 395 | } 396 | 397 | fn shrink_to_fit(&mut self) { 398 | self.shrink_to_fit(); 399 | } 400 | 401 | fn with_capacity(capacity: usize) -> Self { 402 | Self::with_capacity(capacity) 403 | } 404 | 405 | fn into_vec(self) -> Vec<(K, V)> { 406 | self.into_iter().collect() 407 | } 408 | } 409 | 410 | impl map::Base for HashMap { 411 | type Key = K; 412 | type Value = V; 413 | 414 | fn iter<'a>(&'a self) -> Box + 'a> { 415 | Box::new(self.iter()) 416 | } 417 | 418 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> { 419 | Box::new(self.iter_mut()) 420 | } 421 | 422 | fn insert(&mut self, key: K, value: V) -> Option { 423 | self.insert(key, value) 424 | } 425 | 426 | fn entry<'a>(&'a mut self, key: K) -> map::Entry<'a, K, V> { 427 | match self.entry(key) { 428 | hash_map::Entry::Occupied(e) => map::Entry::Occupied(Box::new(e)), 429 | hash_map::Entry::Vacant(e) => map::Entry::Vacant(Box::new(e)), 430 | } 431 | } 432 | } 433 | 434 | impl<'a, K: 'a + Eq + Hash, V: 'a> map::OccupiedEntry for hash_map::OccupiedEntry<'a, K, V> { 435 | type Key = K; 436 | type Value = V; 437 | type MutValue = &'a mut V; 438 | 439 | fn get(&self) -> &V { 440 | self.get() 441 | } 442 | 443 | fn get_mut(&mut self) -> &mut V { 444 | self.get_mut() 445 | } 446 | 447 | fn into_mut(self: Box) -> &'a mut V { 448 | (*self).into_mut() 449 | } 450 | 451 | fn remove(self: Box) -> V { 452 | (*self).remove() 453 | } 454 | } 455 | 456 | impl<'a, K: 'a + Eq + Hash, V: 'a> map::VacantEntry for hash_map::VacantEntry<'a, K, V> { 457 | type Key = K; 458 | type Value = V; 459 | type MutValue = &'a mut V; 460 | 461 | fn insert(self: Box, value: V) -> &'a mut V { 462 | (*self).insert(value) 463 | } 464 | } 465 | 466 | impl AddRemove for HashSet {} 467 | 468 | impl Collection for HashSet { 469 | type Item = T; 470 | 471 | fn len(&self) -> usize { 472 | self.len() 473 | } 474 | 475 | fn capacity(&self) -> usize { 476 | self.capacity() 477 | } 478 | 479 | fn append(&mut self, other: &mut Self) { 480 | self.extend(other.drain()); 481 | } 482 | 483 | fn extend_object(&mut self, items: &mut Iterator) { 484 | self.extend(items); 485 | } 486 | 487 | fn clear(&mut self) { 488 | self.clear(); 489 | } 490 | 491 | fn drain<'a>(&'a mut self) -> Box + 'a> { 492 | Box::new(self.drain()) 493 | } 494 | 495 | fn reserve(&mut self, additional: usize) { 496 | self.reserve(additional); 497 | } 498 | 499 | fn shrink_to_fit(&mut self) { 500 | self.shrink_to_fit(); 501 | } 502 | 503 | fn with_capacity(capacity: usize) -> Self { 504 | Self::with_capacity(capacity) 505 | } 506 | 507 | fn into_vec(self) -> Vec { 508 | self.into_iter().collect() 509 | } 510 | } 511 | 512 | impl Iter for HashSet { 513 | fn iter<'a>(&'a self) -> Box + 'a> { 514 | Box::new(self.iter()) 515 | } 516 | 517 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> where Self: Mutate { 518 | unimplemented!() 519 | } 520 | } 521 | 522 | impl set::Base for HashSet { 523 | fn is_disjoint(&self, other: &Self) -> bool { 524 | self.is_disjoint(other) 525 | } 526 | 527 | fn is_subset(&self, other: &Self) -> bool { 528 | self.is_subset(other) 529 | } 530 | 531 | fn insert(&mut self, item: T) -> bool { 532 | self.insert(item) 533 | } 534 | 535 | fn replace(&mut self, item: T) -> Option { 536 | self.replace(item) 537 | } 538 | } 539 | 540 | impl, Q: ?Sized + Eq + Hash> Set for HashSet { 541 | fn contains(&self, item: &Q) -> bool { 542 | self.contains(item) 543 | } 544 | 545 | fn get(&self, item: &Q) -> Option<&T> { 546 | self.get(item) 547 | } 548 | 549 | fn remove(&mut self, item: &Q) -> bool { 550 | self.remove(item) 551 | } 552 | 553 | fn take(&mut self, item: &Q) -> Option { 554 | self.take(item) 555 | } 556 | } 557 | 558 | impl Mutate for LinkedList {} 559 | 560 | impl AddRemove for LinkedList {} 561 | 562 | impl Collection for LinkedList { 563 | type Item = T; 564 | 565 | fn len(&self) -> usize { 566 | self.len() 567 | } 568 | 569 | fn capacity(&self) -> usize { 570 | self.len() 571 | } 572 | 573 | fn append(&mut self, other: &mut Self) { 574 | self.append(other); 575 | } 576 | 577 | fn extend_object(&mut self, items: &mut Iterator) { 578 | self.extend(items); 579 | } 580 | 581 | fn clear(&mut self) { 582 | self.clear(); 583 | } 584 | 585 | fn drain<'a>(&'a mut self) -> Box + 'a> { 586 | Box::new(mem::replace(self, Self::new()).into_iter()) 587 | } 588 | 589 | fn reserve(&mut self, _additional: usize) {} 590 | 591 | fn shrink_to_fit(&mut self) {} 592 | 593 | fn with_capacity(_capacity: usize) -> Self { 594 | Self::new() 595 | } 596 | 597 | fn into_vec(self) -> Vec { 598 | self.into_iter().collect() 599 | } 600 | } 601 | 602 | impl Iter for LinkedList { 603 | fn iter<'a>(&'a self) -> Box + 'a> { 604 | Box::new(self.iter()) 605 | } 606 | 607 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> { 608 | Box::new(self.iter_mut()) 609 | } 610 | } 611 | 612 | impl Queue for LinkedList { 613 | fn push(&mut self, item: T) { 614 | self.push_back(item); 615 | } 616 | 617 | fn front(&self) -> Option<&T> { 618 | self.front() 619 | } 620 | 621 | fn pop_front(&mut self) -> Option { 622 | self.pop_front() 623 | } 624 | } 625 | 626 | impl Deque for LinkedList { 627 | fn back(&self) -> Option<&T> { 628 | self.back() 629 | } 630 | 631 | fn pop_back(&mut self) -> Option { 632 | self.pop_back() 633 | } 634 | } 635 | 636 | impl FifoQueue for LinkedList { 637 | fn front_mut(&mut self) -> Option<&mut T> { 638 | self.front_mut() 639 | } 640 | } 641 | 642 | impl FifoDeque for LinkedList { 643 | fn push_front(&mut self, item: T) { 644 | self.push_front(item); 645 | } 646 | 647 | fn back_mut(&mut self) -> Option<&mut T> { 648 | self.back_mut() 649 | } 650 | } 651 | 652 | impl Mutate for Vec {} 653 | 654 | impl AddRemove for Vec {} 655 | 656 | impl Collection for Vec { 657 | type Item = T; 658 | 659 | fn len(&self) -> usize { 660 | self.len() 661 | } 662 | 663 | fn capacity(&self) -> usize { 664 | self.capacity() 665 | } 666 | 667 | fn append(&mut self, other: &mut Self) { 668 | self.append(other); 669 | } 670 | 671 | fn extend_object(&mut self, items: &mut Iterator) { 672 | self.extend(items); 673 | } 674 | 675 | fn clear(&mut self) { 676 | self.clear(); 677 | } 678 | 679 | fn drain<'a>(&'a mut self) -> Box + 'a> { 680 | Box::new(self.drain(..)) 681 | } 682 | 683 | fn reserve(&mut self, additional: usize) { 684 | self.reserve(additional); 685 | } 686 | 687 | fn shrink_to_fit(&mut self) { 688 | self.shrink_to_fit(); 689 | } 690 | 691 | fn with_capacity(capacity: usize) -> Self { 692 | Self::with_capacity(capacity) 693 | } 694 | 695 | fn into_vec(self) -> Vec { 696 | self 697 | } 698 | } 699 | 700 | impl Iter for Vec { 701 | fn iter<'a>(&'a self) -> Box + 'a> { 702 | Box::new((**self).iter()) 703 | } 704 | 705 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> { 706 | Box::new((**self).iter_mut()) 707 | } 708 | } 709 | 710 | impl DrainRange> for Vec { 711 | fn drain_range<'a>(&'a mut self, range: Range) -> Box + 'a> { 712 | Box::new(self.drain(range)) 713 | } 714 | } 715 | 716 | impl List for Vec { 717 | fn get(&self, index: usize) -> Option<&T> { 718 | (**self).get(index) 719 | } 720 | 721 | fn get_mut(&mut self, index: usize) -> Option<&mut T> { 722 | (**self).get_mut(index) 723 | } 724 | 725 | fn swap(&mut self, i: usize, j: usize) { 726 | (**self).swap(i, j); 727 | } 728 | 729 | fn reverse(&mut self) { 730 | (**self).reverse(); 731 | } 732 | 733 | fn push(&mut self, item: T) { 734 | self.push(item); 735 | } 736 | 737 | fn insert(&mut self, index: usize, item: T) { 738 | self.insert(index, item); 739 | } 740 | 741 | fn pop(&mut self) -> Option { 742 | self.pop() 743 | } 744 | 745 | fn remove(&mut self, index: usize) -> Option { 746 | if index < self.len() { 747 | Some(self.remove(index)) 748 | } else { 749 | None 750 | } 751 | } 752 | 753 | fn swap_remove(&mut self, index: usize) -> Option { 754 | if index < self.len() { 755 | Some(self.swap_remove(index)) 756 | } else { 757 | None 758 | } 759 | } 760 | 761 | fn truncate(&mut self, len: usize) { 762 | self.truncate(len); 763 | } 764 | 765 | fn split_off(&mut self, index: usize) -> Self { 766 | self.split_off(index) 767 | } 768 | } 769 | 770 | impl Mutate for VecDeque {} 771 | 772 | impl AddRemove for VecDeque {} 773 | 774 | impl Collection for VecDeque { 775 | type Item = T; 776 | 777 | fn len(&self) -> usize { 778 | self.len() 779 | } 780 | 781 | fn capacity(&self) -> usize { 782 | self.capacity() 783 | } 784 | 785 | fn clear(&mut self) { 786 | self.clear(); 787 | } 788 | 789 | fn append(&mut self, other: &mut Self) { 790 | self.append(other); 791 | } 792 | 793 | fn extend_object(&mut self, items: &mut Iterator) { 794 | self.extend(items); 795 | } 796 | 797 | fn drain<'a>(&'a mut self) -> Box + 'a> { 798 | Box::new(self.drain(..)) 799 | } 800 | 801 | fn reserve(&mut self, additional: usize) { 802 | self.reserve(additional); 803 | } 804 | 805 | fn shrink_to_fit(&mut self) { 806 | self.shrink_to_fit(); 807 | } 808 | 809 | fn with_capacity(capacity: usize) -> Self { 810 | Self::with_capacity(capacity) 811 | } 812 | 813 | fn into_vec(self) -> Vec { 814 | self.into_iter().collect() 815 | } 816 | } 817 | 818 | impl Iter for VecDeque { 819 | fn iter<'a>(&'a self) -> Box + 'a> { 820 | Box::new(self.iter()) 821 | } 822 | 823 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> { 824 | Box::new(self.iter_mut()) 825 | } 826 | } 827 | 828 | impl DrainRange> for VecDeque { 829 | fn drain_range<'a>(&'a mut self, range: Range) -> Box + 'a> { 830 | Box::new(self.drain(range)) 831 | } 832 | } 833 | 834 | impl List for VecDeque { 835 | fn get(&self, index: usize) -> Option<&T> { 836 | self.get(index) 837 | } 838 | 839 | fn get_mut(&mut self, index: usize) -> Option<&mut T> { 840 | self.get_mut(index) 841 | } 842 | 843 | fn swap(&mut self, i: usize, j: usize) { 844 | self.swap(i, j); 845 | } 846 | 847 | fn reverse(&mut self) { 848 | let mut it = self.iter_mut(); 849 | while let (Some(a), Some(b)) = (it.next(), it.next_back()) { mem::swap(a, b); } 850 | } 851 | 852 | fn push(&mut self, item: T) { 853 | self.push_back(item); 854 | } 855 | 856 | fn insert(&mut self, index: usize, item: T) { 857 | self.insert(index, item); 858 | } 859 | 860 | fn pop(&mut self) -> Option { 861 | self.pop_back() 862 | } 863 | 864 | fn remove(&mut self, index: usize) -> Option { 865 | self.remove(index) 866 | } 867 | 868 | fn swap_remove(&mut self, index: usize) -> Option { 869 | self.swap_remove_back(index) 870 | } 871 | 872 | fn truncate(&mut self, len: usize) { 873 | self.truncate(len); 874 | } 875 | 876 | fn split_off(&mut self, index: usize) -> Self { 877 | self.split_off(index) 878 | } 879 | } 880 | 881 | impl Queue for VecDeque { 882 | fn push(&mut self, item: T) { 883 | self.push_back(item); 884 | } 885 | 886 | fn front(&self) -> Option<&T> { 887 | self.front() 888 | } 889 | 890 | fn pop_front(&mut self) -> Option { 891 | self.pop_front() 892 | } 893 | } 894 | 895 | impl Deque for VecDeque { 896 | fn back(&self) -> Option<&T> { 897 | self.back() 898 | } 899 | 900 | fn pop_back(&mut self) -> Option { 901 | self.pop_back() 902 | } 903 | } 904 | 905 | impl FifoQueue for VecDeque { 906 | fn front_mut(&mut self) -> Option<&mut T> { 907 | self.front_mut() 908 | } 909 | } 910 | 911 | impl FifoDeque for VecDeque { 912 | fn push_front(&mut self, item: T) { 913 | self.push_front(item); 914 | } 915 | 916 | fn back_mut(&mut self) -> Option<&mut T> { 917 | self.back_mut() 918 | } 919 | } 920 | 921 | #[test] 922 | fn test_binary_heap_push_pop_front() { 923 | let mut h = BinaryHeap::new(); 924 | assert_eq!(h.push_pop_front(5), 5); 925 | assert!(h.is_empty()); 926 | h.push(4); 927 | assert_eq!(h.push_pop_front(5), 5); 928 | assert!(h.iter().eq(&[4])); 929 | assert_eq!(h.push_pop_front(3), 4); 930 | assert!(h.iter().eq(&[3])); 931 | } 932 | 933 | #[test] 934 | fn test_binary_heap_replace_front() { 935 | let mut h = BinaryHeap::new(); 936 | assert_eq!(h.replace_front(5), None); 937 | assert!(h.iter().eq(&[5])); 938 | assert_eq!(h.replace_front(4), Some(5)); 939 | assert!(h.iter().eq(&[4])); 940 | assert_eq!(h.replace_front(6), Some(4)); 941 | assert!(h.iter().eq(&[6])); 942 | } 943 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Collection traits for generic programming. 2 | //! 3 | //! The principal traits in this library are: 4 | //! 5 | //! - [`Collection`] 6 | //! - [`List`] 7 | //! - [`Map`] 8 | //! - [`Set`] 9 | //! - [`Queue`] 10 | //! - [`FifoQueue`] 11 | //! - [`PrioQueue`] 12 | //! - [`Deque`] 13 | //! - [`FifoDeque`] 14 | //! - [`PrioDeque`] 15 | //! 16 | //! When combined with these traits, two marker traits enable the use of additional operations: 17 | //! 18 | //! | Marker | Operations | Analogous Type | 19 | //! |---------------|------------------------------------------------|----------------| 20 | //! | (none) | Read-only access to a collection and its items | `&[T]` | 21 | //! | [`Mutate`] | Write access to a collection's items | `&mut [T]` | 22 | //! | [`AddRemove`] | Insertion and removal of a collection's items | `&mut Vec` | 23 | //! 24 | //! Generic code should specify only those bounds that are needed for its operation, but may 25 | //! specify additional bounds for future compatibility. Generic code should also use the collection 26 | //! traits with a `?Sized` bound in order to support slices and trait objects whenever possible. 27 | //! 28 | //! # Examples 29 | //! 30 | //! Insertion sort: 31 | //! 32 | //! ``` 33 | //! use eclectic::{List, Mutate}; 34 | //! 35 | //! fn insertion_sort(list: &mut L) where L::Item: Ord { 36 | //! for i in 1..list.len() { // `len` is defined on `Collection`, a supertrait of `List` 37 | //! let mut j = i; 38 | //! 39 | //! while j > 0 && list.get(j) < list.get(j - 1) { 40 | //! list.swap(j, j - 1); // the `Mutate` bound on `L` enables the use of `List::swap` 41 | //! j -= 1; 42 | //! } 43 | //! } 44 | //! } 45 | //! 46 | //! use std::collections::VecDeque; 47 | //! 48 | //! let mut vec = vec!['c', 'a', 'e', 'd', 'b']; 49 | //! let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect(); 50 | //! 51 | //! insertion_sort(&mut vec); 52 | //! assert_eq!(vec, ['a', 'b', 'c', 'd', 'e']); 53 | //! 54 | //! insertion_sort(&mut vec_deque); 55 | //! assert!(vec_deque.iter().eq(&['a', 'b', 'c', 'd', 'e'])); 56 | //! ``` 57 | //! 58 | //! [`AddRemove`]: trait.AddRemove.html 59 | //! [`Collection`]: trait.Collection.html 60 | //! [`Deque`]: trait.Deque.html 61 | //! [`FifoDeque`]: trait.FifoDeque.html 62 | //! [`FifoQueue`]: trait.FifoQueue.html 63 | //! [`List`]: trait.List.html 64 | //! [`Map`]: map/trait.Map.html 65 | //! [`Mutate`]: trait.Mutate.html 66 | //! [`PrioDeque`]: trait.PrioDeque.html 67 | //! [`PrioQueue`]: trait.PrioQueue.html 68 | //! [`Queue`]: trait.Queue.html 69 | //! [`Set`]: set/trait.Set.html 70 | //! 71 | //! # A Note on Trait Objects 72 | //! 73 | //! A number of trait methods in this crate return a `Box`, which requires unnecessary 74 | //! heap allocation and opaqueness (e.g. erasure of traits like `Clone` and `DoubleEndedIterator`). 75 | //! This is to make up for the (hopefully temporary) inability to define higher-kinded associated 76 | //! types like: 77 | //! 78 | //! ```ignore 79 | //! trait Collection { 80 | //! type Drain<'a>: 'a + Iterator; 81 | //! 82 | //! fn drain<'a>(&'a mut self) -> Self::Drain<'a> where Self: AddRemove; 83 | //! } 84 | //! ``` 85 | //! 86 | //! If Rust acquires such types, the iterator- and entry-returning methods will be changed to use 87 | //! them. 88 | 89 | #![deny(missing_docs)] 90 | 91 | mod impls; 92 | 93 | pub use map::Map; 94 | pub use set::Set; 95 | 96 | use std::ops::{Range, RangeFrom, RangeFull, RangeTo}; 97 | 98 | /// A marker that indicates that a collection supports the mutation of its items. 99 | pub trait Mutate {} 100 | 101 | /// A marker that indicates that a collection supports the insertion of new items and the removal 102 | /// of existing items. 103 | pub trait AddRemove {} 104 | 105 | /// A collection. 106 | /// 107 | /// A collection maintains a finite number of items. 108 | pub trait Collection { 109 | /// The type of the collection's items. 110 | type Item; 111 | 112 | /// Returns the number of items in the collection. 113 | fn len(&self) -> usize; 114 | 115 | /// Checks if the collection contains no items. 116 | fn is_empty(&self) -> bool { 117 | self.len() == 0 118 | } 119 | 120 | /// Returns the number of items the collection can hold without reallocating. 121 | /// 122 | /// Node-based collections should report a capacity of `self.len()`. 123 | fn capacity(&self) -> usize; 124 | 125 | /// Drains the given collection and inserts its items into the collection. 126 | /// 127 | /// The exact behavior of this method is unspecified, but it must be equivalent to 128 | /// `self.extend_object(&mut other.drain())`. `other`'s capacity should remain the same, when 129 | /// possible. 130 | fn append(&mut self, other: &mut Self) where Self: Sized + AddRemove { 131 | self.extend_object(&mut other.drain()); 132 | } 133 | 134 | /// Inserts the items yielded by the given iterator into the collection. 135 | /// 136 | /// This method is provided for use with trait objects, and generic code should prefer 137 | /// [`Extend::extend`], which this method must be equivalent to. 138 | /// 139 | /// The exact behavior of this method is unspecified, but may be refined by subtraits. 140 | /// 141 | /// Note that this trait cannot extend `Extend` due to object-safety limitations. 142 | /// 143 | /// [`Extend::extend`]: 144 | /// https://doc.rust-lang.org/stable/std/iter/trait.Extend.html#tymethod.extend 145 | fn extend_object(&mut self, items: &mut Iterator) where Self: AddRemove; 146 | 147 | /// Removes all items from the collection. 148 | fn clear(&mut self) where Self: AddRemove { 149 | self.drain(); 150 | } 151 | 152 | /// Removes all items from the collection and returns an iterator that yields them. 153 | /// 154 | /// All items are removed even if the iterator is not exhausted. However, the behavior of 155 | /// this method is unspecified if the iterator is leaked (e.g. via [`mem::forget`]). 156 | /// 157 | /// The iteration order is unspecified, but subtraits may place a requirement on it. 158 | /// 159 | /// `self`'s capacity should remain the same, when possible. 160 | /// 161 | /// [`mem::forget`]: https://doc.rust-lang.org/stable/std/mem/fn.forget.html 162 | fn drain<'a>(&'a mut self) -> Box + 'a> where Self: AddRemove; 163 | 164 | /// Reserves capacity for the given number of additional items to be inserted into the 165 | /// collection. 166 | /// 167 | /// This method may do nothing (e.g. for node-based collections). 168 | fn reserve(&mut self, additional: usize) where Self: AddRemove; 169 | 170 | /// Shrinks the collection's capacity as much as possible. 171 | /// 172 | /// This method may do nothing (e.g. for node-based collections). 173 | fn shrink_to_fit(&mut self) where Self: AddRemove; 174 | 175 | /// Returns a new collection with the given capacity. 176 | /// 177 | /// Collections (e.g. node-based ones) may ignore the capacity hint. 178 | // FIXME(rust-lang/rust#20021): this shouldn't be defaulted 179 | fn with_capacity(capacity: usize) -> Self where Self: Sized + Default { 180 | let _ = capacity; 181 | unimplemented!() 182 | } 183 | 184 | /// Converts the collection into a vector. 185 | // FIXME(rust-lang/rust#20021): this shouldn't be defaulted 186 | fn into_vec(self) -> Vec where Self: Sized { 187 | unimplemented!() 188 | } 189 | } 190 | 191 | /// A collection that supports by-reference iteration. 192 | /// 193 | /// Maps are not expected to implement this interface, because they often provide 194 | /// `Iterator`. 195 | pub trait Iter: Collection { 196 | /// Returns an iterator that yields references to the collection's items. 197 | /// 198 | /// The iteration order is unspecified, but subtraits may place a requirement on it. 199 | fn iter<'a>(&'a self) -> Box + 'a>; 200 | 201 | /// Returns an iterator that yields mutable references to the collection's items. 202 | /// 203 | /// The iteration order is unspecified, but subtraits may place a requirement on it. 204 | fn iter_mut<'a>(&'a mut self) -> Box + 'a> 205 | where Self: Mutate; 206 | } 207 | 208 | /// A collection that supports draining a range of its items. 209 | pub trait DrainRange: Collection { 210 | /// Removes all items from the collection that lie in the given range and returns an iterator 211 | /// that yields them. 212 | /// 213 | /// All items in the given range are removed even if the iterator is not exhausted. However, 214 | /// the behavior of this method is unspecified if the iterator is leaked (e.g. via 215 | /// [`mem::forget`]). 216 | /// 217 | /// The iteration order is unspecified, but subtraits may place a requirement on it. 218 | /// 219 | /// [`mem::forget`]: https://doc.rust-lang.org/stable/std/mem/fn.forget.html 220 | fn drain_range<'a>(&'a mut self, range: R) -> Box + 'a> 221 | where Self: AddRemove; 222 | } 223 | 224 | /// A list. 225 | /// 226 | /// A list is an ordered collection in which each item is located at a corresponding index. The 227 | /// indices are non-negative integers and zero-based. 228 | pub trait List: 229 | Collection + 230 | Iter + 231 | DrainRange> + 232 | DrainRange> + 233 | DrainRange> + 234 | DrainRange 235 | { 236 | /// Returns a reference to the item at the given index in the list. 237 | /// 238 | /// Returns `None` if `index >= self.len()`. 239 | fn get(&self, index: usize) -> Option<&Self::Item>; 240 | 241 | /// Returns a mutable reference to the item at the given index in the list. 242 | /// 243 | /// Returns `None` if `index >= self.len()`. 244 | fn get_mut(&mut self, index: usize) -> Option<&mut Self::Item> where Self: Mutate; 245 | 246 | /// Swaps the items at the given indices in the list. 247 | /// 248 | /// # Panics 249 | /// 250 | /// Panics if `i >= self.len() || j >= self.len()`. 251 | fn swap(&mut self, i: usize, j: usize) where Self: Mutate; 252 | 253 | /// Reverses the order of the items in the list. 254 | fn reverse(&mut self) where Self: Mutate { 255 | let len = self.len(); 256 | 257 | for i in 0..len / 2 { 258 | self.swap(i, len - i - 1); 259 | } 260 | } 261 | 262 | /// Returns a reference to the first item in the list. 263 | /// 264 | /// Returns `None` if the list is empty. 265 | fn first(&self) -> Option<&Self::Item> { 266 | self.get(0) 267 | } 268 | 269 | /// Returns a mutable reference to the first item in the list. 270 | /// 271 | /// Returns `None` if the list is empty. 272 | fn first_mut(&mut self) -> Option<&mut Self::Item> where Self: Mutate { 273 | self.get_mut(0) 274 | } 275 | 276 | /// Returns a reference to the last item in the list. 277 | /// 278 | /// Returns `None` if the list is empty. 279 | fn last(&self) -> Option<&Self::Item> { 280 | self.get(self.len().wrapping_sub(1)) 281 | } 282 | 283 | /// Returns a mutable reference to the last item in the list. 284 | /// 285 | /// Returns `None` if the list is empty. 286 | fn last_mut(&mut self) -> Option<&mut Self::Item> where Self: Mutate { 287 | let len = self.len(); 288 | self.get_mut(len.wrapping_sub(1)) 289 | } 290 | 291 | /// Pushes the given item onto the back of the list. 292 | fn push(&mut self, item: Self::Item) where Self: AddRemove { 293 | let len = self.len(); 294 | self.insert(len, item); 295 | } 296 | 297 | /// Inserts the given item into the list at the given index. 298 | /// 299 | /// All items after the given index are shifted one index to the right. 300 | /// 301 | /// # Panics 302 | /// 303 | /// Panics if `index > self.len()`. 304 | fn insert(&mut self, index: usize, item: Self::Item) where Self: AddRemove; 305 | 306 | /// Removes the last item in the list and returns it. 307 | /// 308 | /// Returns `None` if the list was empty. 309 | fn pop(&mut self) -> Option where Self: AddRemove { 310 | let len = self.len(); 311 | self.remove(len.wrapping_sub(1)) 312 | } 313 | 314 | /// Removes the item at the given index in the list and returns it. 315 | /// 316 | /// Returns `None` if `index >= self.len()`. 317 | /// 318 | /// All items after the given index are shifted one index to the left. 319 | fn remove(&mut self, index: usize) -> Option where Self: AddRemove; 320 | 321 | /// Removes the item at the given index in the list and returns it, replacing it with the last 322 | /// item in the list. 323 | /// 324 | /// Returns `None` if `index >= self.len()`. 325 | fn swap_remove(&mut self, index: usize) -> Option where Self: AddRemove; 326 | 327 | /// Ensures that the list's length is no more than the given length by removing the 328 | /// corresponding number of items from the back. 329 | /// 330 | /// Does nothing if `len >= self.len()`. 331 | fn truncate(&mut self, len: usize) where Self: AddRemove { 332 | if len == 0 { 333 | self.clear(); 334 | } else { 335 | self.drain_range(len..); 336 | } 337 | } 338 | 339 | /// Splits the list in two at the given index. 340 | /// 341 | /// Returns a new list that contains the items in the range `index..self.len()`. 342 | /// 343 | /// After this method returns, `self` contains the items in the range `0..index`. `self`'s 344 | /// capacity should remain the same, when possible. 345 | /// 346 | /// # Panics 347 | /// 348 | /// Panics if `index > self.len()`. 349 | // FIXME(rust-lang/rust#20021): this shouldn't be defaulted 350 | fn split_off(&mut self, index: usize) -> Self where Self: Sized + AddRemove { 351 | let _ = index; 352 | unimplemented!() 353 | } 354 | } 355 | 356 | impl DrainRange> for L { 357 | fn drain_range<'a>(&'a mut self, range: RangeFrom) -> Box + 'a> 358 | where L: AddRemove 359 | { 360 | let len = self.len(); 361 | self.drain_range(range.start..len) 362 | } 363 | } 364 | 365 | impl DrainRange> for L { 366 | fn drain_range<'a>(&'a mut self, range: RangeTo) -> Box + 'a> 367 | where L: AddRemove 368 | { 369 | self.drain_range(0..range.end) 370 | } 371 | } 372 | 373 | impl DrainRange for L { 374 | fn drain_range<'a>(&'a mut self, _range: RangeFull) -> Box + 'a> 375 | where L: AddRemove 376 | { 377 | self.drain() 378 | } 379 | } 380 | 381 | pub mod map { 382 | //! Maps. 383 | 384 | use super::*; 385 | 386 | /// Map functionality that is independent of an additional type parameter. 387 | /// 388 | /// It is unusual to use this trait directly. Consider using [`Map`] instead. 389 | /// 390 | /// This trait exists to prevent the ambiguity that would arise if its methods were instead 391 | /// implemented on [`Map`]. In that scenario, `map.insert(key, value)` would be ambiguous if 392 | /// the type of `map` were `M` and `M: Map + Map`. 393 | /// 394 | /// [`Map`]: trait.Map.html 395 | pub trait Base: Collection::Key, ::Value)> { 396 | /// The type of the map's keys. 397 | type Key; 398 | 399 | /// The type of the map's values. 400 | type Value; 401 | 402 | /// Returns an iterator that yields references to the map's keys and references to their 403 | /// values. 404 | /// 405 | /// The iteration order is unspecified, but subtraits may place a requirement on it. 406 | fn iter<'a>(&'a self) -> Box + 'a>; 407 | 408 | /// Returns an iterator that yields references to the map's keys and mutable references to 409 | /// their values. 410 | /// 411 | /// The iteration order is unspecified, but subtraits may place a requirement on it. 412 | fn iter_mut<'a>(&'a mut self) 413 | -> Box + 'a> where Self: Mutate; 414 | 415 | /// Inserts the given key and value into the map without replacing an equivalent key. 416 | /// 417 | /// If the map contains a key that is equivalent to the given key, that key is not replaced 418 | /// with the given key. The value is always replaced, however. 419 | /// 420 | /// Returns the equivalent key's value if the map contained one, `None` otherwise. 421 | fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option 422 | where Self: AddRemove; 423 | 424 | /// Returns the entry in the map for the given key. 425 | fn entry<'a>(&'a mut self, key: Self::Key) -> Entry<'a, Self::Key, Self::Value> 426 | where Self: AddRemove; 427 | } 428 | 429 | /// A map. 430 | /// 431 | /// A map is a set of keys, each of which is associated with a value. 432 | /// 433 | /// The type parameter `Q` represents an "equivalence" type that can be used to look up values 434 | /// in the map. For example, given a `Map`, it is usually possible to look up 435 | /// items using a `str`. When omitted, `Q` defaults to `Self::Key`. 436 | pub trait Map::Key>: Base { 437 | /// Checks if the map contains a key that is equivalent to the given key. 438 | fn contains_key(&self, key: &Q) -> bool { 439 | self.get(key).is_some() 440 | } 441 | 442 | /// Returns a reference to the value of the key in the map that is equivalent to the given 443 | /// key. 444 | /// 445 | /// Returns `None` if the map contains no such key. 446 | fn get(&self, key: &Q) -> Option<&Self::Value>; 447 | 448 | /// Returns a mutable reference to the value of the key in the map that is equivalent to 449 | /// the given key. 450 | /// 451 | /// Returns `None` if the map contains no such key. 452 | fn get_mut(&mut self, key: &Q) -> Option<&mut Self::Value> where Self: Mutate; 453 | 454 | /// Removes the key in the map that is equivalent to the given key and returns its value. 455 | /// 456 | /// Returns `None` if the map contained no such key. 457 | fn remove(&mut self, key: &Q) -> Option where Self: AddRemove; 458 | } 459 | 460 | /// A map entry. 461 | pub enum Entry<'a, K: 'a, V: 'a> { 462 | /// An occupied map entry. 463 | Occupied(Box + 'a>), 464 | /// A vacant map entry. 465 | Vacant(Box + 'a>), 466 | } 467 | 468 | impl<'a, K: 'a, V: 'a> Entry<'a, K, V> { 469 | /// Ensures that the entry is occupied by inserting it into the map with the given value if 470 | /// it is vacant. 471 | /// 472 | /// Returns a mutable reference to the entry's value with the same lifetime as the map. 473 | pub fn or_insert(self, value: V) -> &'a mut V { 474 | match self { 475 | Entry::Occupied(e) => e.into_mut(), 476 | Entry::Vacant(e) => e.insert(value), 477 | } 478 | } 479 | 480 | /// Ensures that the entry is occupied by inserting it into the map with the result of the 481 | /// given function if it is vacant. 482 | /// 483 | /// Returns a mutable reference to the entry's value with the same lifetime as the map. 484 | pub fn or_insert_with V>(self, f: F) -> &'a mut V { 485 | match self { 486 | Entry::Occupied(e) => e.into_mut(), 487 | Entry::Vacant(e) => e.insert(f()), 488 | } 489 | } 490 | } 491 | 492 | /// An occupied map entry. 493 | pub trait OccupiedEntry { 494 | /// The type of the entry's key. 495 | type Key; 496 | 497 | /// The type of the entry's value. 498 | type Value; 499 | 500 | /// The type of the mutable reference to the entry's value with the same lifetime as the 501 | /// map. 502 | type MutValue; 503 | 504 | /// Returns a reference to the entry's value. 505 | fn get(&self) -> &Self::Value; 506 | 507 | /// Returns a mutable reference to the entry's value. 508 | fn get_mut(&mut self) -> &mut Self::Value; 509 | 510 | /// Returns a mutable reference to the entry's value with the same lifetime as the map. 511 | fn into_mut(self: Box) -> Self::MutValue; 512 | 513 | /// Removes the entry from the map and returns its value. 514 | fn remove(self: Box) -> Self::Value; 515 | } 516 | 517 | /// A vacant entry. 518 | pub trait VacantEntry { 519 | /// The type of the entry's key. 520 | type Key; 521 | 522 | /// The type of the entry's value. 523 | type Value; 524 | 525 | /// The type of the mutable reference to the entry's value with the same lifetime as the 526 | /// map. 527 | type MutValue; 528 | 529 | /// Inserts the entry into the map with the given value. 530 | /// 531 | /// Returns a mutable reference to the entry's value with the same lifetime as the map. 532 | fn insert(self: Box, value: Self::Value) -> Self::MutValue; 533 | } 534 | } 535 | 536 | pub mod set { 537 | //! Sets. 538 | 539 | use super::*; 540 | 541 | /// Set functionality that is independent of an additional type parameter. 542 | /// 543 | /// It is unusual to use this trait directly. Consider using [`Set`] instead. 544 | /// 545 | /// This trait exists to prevent the ambiguity that would arise if its methods were instead 546 | /// implemented on [`Set`]. In that scenario, `set.insert(item)` would be ambiguous if the type 547 | /// of `set` were `S` and `S: Set + Set`. 548 | /// 549 | /// [`Set`]: trait.Set.html 550 | pub trait Base: Collection + Iter { 551 | /// Checks if the set is disjoint from the given set. 552 | /// 553 | /// `self` is disjoint from `other` if `self` contains none of `other`'s items. 554 | fn is_disjoint(&self, other: &Self) -> bool where Self: Sized; 555 | 556 | /// Checks if the set is a subset of the given set. 557 | /// 558 | /// `self` is a subset of `other` if `other` contains all of `self`'s items. 559 | fn is_subset(&self, other: &Self) -> bool where Self: Sized; 560 | 561 | /// Checks if the set is a superset of the given set. 562 | /// 563 | /// `self` is a superset of `other` if `self` contains all of `other`'s items. 564 | fn is_superset(&self, other: &Self) -> bool where Self: Sized { 565 | other.is_subset(self) 566 | } 567 | 568 | /// Inserts the given item into the set without replacement. 569 | /// 570 | /// If the set contains an item that is equivalent to the given item, that item is not 571 | /// replaced with the given item. 572 | /// 573 | /// Returns `true` if the given item was inserted into the set, `false` otherwise. 574 | fn insert(&mut self, item: Self::Item) -> bool where Self: AddRemove; 575 | 576 | /// Inserts the given item into the set with replacement. 577 | /// 578 | /// If the set contains an item that is equivalent to the given item, that item is replaced 579 | /// with the given item. 580 | /// 581 | /// Returns the item that was replaced, or `None` if the set did not contain an equivalent 582 | /// item. 583 | fn replace(&mut self, item: Self::Item) -> Option where Self: AddRemove; 584 | } 585 | 586 | /// A set. 587 | /// 588 | /// A set is a collection that prohibits duplicate items according to some criteria. 589 | /// 590 | /// The type parameter `Q` represents an "equivalence" type that can be used to look up items 591 | /// in the set. For example, given a `Set`, it is usually possible to look up 592 | /// items using a `str`. When omitted, `Q` defaults to `Self::Item`. 593 | pub trait Set::Item>: Base { 594 | /// Checks if the set contains an item that is equivalent to the given item. 595 | fn contains(&self, item: &Q) -> bool { 596 | self.get(item).is_some() 597 | } 598 | 599 | /// Returns a reference to the item in the set that is equivalent to the given item. 600 | /// 601 | /// Returns `None` if the set contains no such item. 602 | fn get(&self, item: &Q) -> Option<&Self::Item>; 603 | 604 | /// Removes the item in the set that is equivalent to the given item. 605 | /// 606 | /// Returns `true` if the set contained such an item, `false` otherwise. 607 | fn remove(&mut self, item: &Q) -> bool where Self: AddRemove { 608 | self.take(item).is_some() 609 | } 610 | 611 | /// Removes the item in the set that is equivalent to the given item and returns it. 612 | /// 613 | /// Returns `None` if the set contained no such item. 614 | fn take(&mut self, item: &Q) -> Option where Self: AddRemove; 615 | } 616 | } 617 | 618 | /// A queue. 619 | pub trait Queue: Collection + Iter { 620 | /// Pushes the given item onto the queue. 621 | /// 622 | /// For FIFO queues, this pushes the item onto the back of the queue. For other queues, the 623 | /// location of the newly inserted item is unspecified. 624 | fn push(&mut self, item: Self::Item) where Self: AddRemove; 625 | 626 | /// Returns a reference to the item at the front of the queue. 627 | /// 628 | /// Returns `None` if the queue is empty. 629 | fn front(&self) -> Option<&Self::Item>; 630 | 631 | /// Removes the item at the front of the queue and returns it. 632 | /// 633 | /// Returns `None` if the queue was empty. 634 | fn pop_front(&mut self) -> Option where Self: AddRemove; 635 | } 636 | 637 | /// A first-in, first-out queue. 638 | pub trait FifoQueue: Queue { 639 | /// Returns a mutable reference to the item at the front of the queue. 640 | /// 641 | /// Returns `None` if the queue is empty. 642 | fn front_mut(&mut self) -> Option<&mut Self::Item> where Self: Mutate; 643 | } 644 | 645 | /// A priority queue. 646 | pub trait PrioQueue: Queue { 647 | /// Pushes the given item onto the queue, then removes the item at the front of the queue and 648 | /// returns it. 649 | /// 650 | /// This method may be deprecated in favor of `front_mut` in the future. 651 | fn push_pop_front(&mut self, item: Self::Item) -> Self::Item where Self: AddRemove { 652 | self.push(item); 653 | self.pop_front().expect("queue was empty after a `push`") 654 | } 655 | 656 | /// Removes the item at the front of the queue, then pushes the given item onto the queue. 657 | /// 658 | /// Returns the item that was removed, or `None` if the queue was empty. 659 | /// 660 | /// This method may be deprecated in favor of `front_mut` in the future. 661 | fn replace_front(&mut self, item: Self::Item) -> Option where Self: AddRemove { 662 | let front = self.pop_front(); 663 | self.push(item); 664 | front 665 | } 666 | } 667 | 668 | /// A double-ended queue. 669 | pub trait Deque: Queue { 670 | /// Returns a reference to the item at the back of the deque. 671 | /// 672 | /// Returns `None` if the deque is empty. 673 | fn back(&self) -> Option<&Self::Item>; 674 | 675 | /// Removes the item at the back of the deque and returns it. 676 | /// 677 | /// Returns `None` if the deque was empty. 678 | fn pop_back(&mut self) -> Option where Self: AddRemove; 679 | } 680 | 681 | /// A double-ended first-in, first-out queue. 682 | pub trait FifoDeque: FifoQueue + Deque { 683 | /// Pushes the given item onto the front of the deque. 684 | fn push_front(&mut self, item: Self::Item) where Self: AddRemove; 685 | 686 | /// Returns a mutable reference to the item at the back of the deque. 687 | /// 688 | /// Returns `None` if the deque is empty. 689 | fn back_mut(&mut self) -> Option<&mut Self::Item> where Self: Mutate; 690 | } 691 | 692 | /// A double-ended priority queue. 693 | pub trait PrioDeque: PrioQueue + Deque { 694 | /// Pushes the given item onto the deque, then removes the item at the back of the deque and 695 | /// returns it. 696 | /// 697 | /// This method may be deprecated in favor of `back_mut` in the future. 698 | fn push_pop_back(&mut self, item: Self::Item) -> Self::Item where Self: AddRemove { 699 | self.push(item); 700 | self.pop_back().expect("deque was empty after a `push`") 701 | } 702 | 703 | /// Removes the item at the back of the deque, then pushes the given item onto the deque. 704 | /// 705 | /// Returns the item that was removed, or `None` if the deque was empty. 706 | /// 707 | /// This method may be deprecated in favor of `back_mut` in the future. 708 | fn replace_back(&mut self, item: Self::Item) -> Option where Self: AddRemove { 709 | let back = self.pop_back(); 710 | self.push(item); 711 | back 712 | } 713 | } 714 | 715 | #[allow(dead_code)] 716 | fn assert_object_safe() { 717 | let _: &Mutate; 718 | let _: &AddRemove; 719 | 720 | let _: &Collection; 721 | 722 | let _: &List; 723 | 724 | let _: &Map; 725 | let _: &map::OccupiedEntry; 726 | let _: &map::VacantEntry; 727 | 728 | let _: &Set; 729 | 730 | let _: &Queue; 731 | let _: &Deque; 732 | 733 | let _: &FifoQueue; 734 | let _: &FifoDeque; 735 | 736 | let _: &PrioQueue; 737 | let _: &PrioDeque; 738 | } 739 | --------------------------------------------------------------------------------