cc-traits-2.0.0/.cargo_vcs_info.json0000644000000001360000000000100127240ustar { "git": { "sha1": "c8efa8640e0920371577a5b52ee2d98a0e7656e8" }, "path_in_vcs": "" }cc-traits-2.0.0/.github/workflows/ci.yml000064400000000000000000000027601046102023000162340ustar 00000000000000name: Continuous Integration on: [push, pull_request] env: CARGO_TERM_COLOR: always jobs: test: name: Test Suite runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Install Rust uses: actions-rs/toolchain@v1 with: toolchain: "1.65.0" profile: minimal override: true - name: Build run: cargo build --features all-impls --verbose - name: Test run: cargo test --features all-impls --verbose - name: Test (no default features) run: cargo test --no-default-features --verbose rustfmt: name: Rustfmt runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 - name: Install Rust uses: actions-rs/toolchain@v1 with: toolchain: stable profile: minimal override: true components: rustfmt - name: Check formatting uses: actions-rs/cargo@v1 with: command: fmt args: --all -- --check clippy: name: Clippy runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v2 - name: Install Rust uses: actions-rs/toolchain@v1 with: toolchain: stable profile: minimal override: true components: clippy - name: Clippy Check uses: actions-rs/cargo@v1 with: command: clippy args: --features all-impls -- -D warningscc-traits-2.0.0/.gitignore000064400000000000000000000000221046102023000134760ustar 00000000000000target Cargo.lock cc-traits-2.0.0/.rustfmt.toml000064400000000000000000000000201046102023000141630ustar 00000000000000hard_tabs = truecc-traits-2.0.0/CHANGELOG.md000064400000000000000000000035401046102023000133270ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ## [2.0.0] - 2023-05-22 ### Breaking changes - Changed the "nostd" feature to "std". Enables `std` collection implementations. Enabled by default. ### Added - Add `SimpleKeyedRef` trait. - Add helper macros `simple_collection_*` and `simple_keyed_*`. - Add support for `no_std`. - Add "alloc" feature. Enables `alloc` collection implementations. Enabled by default. ## [1.0.0] - 2022-11-07 ### Changed - GATs are stabilized! No more unstable `generic_associated_types` feature. - Moved some `where` clauses around in the docs (see issue ). ## [0.8.0] - 2022-03-29 ### Added - Traits replacing traits aliases when the `nightly` feature is not enabled. Required since trait aliases seem stalled and won't be stable for a while. ## [0.7.3] - 2021-12-09 ### Added - Explicit bound `Self: 'long` in reference upcast functions (`upcast_item_ref`, `upcast_item_mut`, `upcast_key_ref`). This is required by the latest version of Rust. ## [0.7.2] - 2021-12-01 ### Added - Impl `GetKeyValue` for `serde_json::Map`. ## [0.7.1] - 2021-11-17 ### Added - `GetKeyValue` and `GetKeyValueMut`. Implementations for `HashMap`, `BTreeMap` and `ijson::Object`. ## [0.6.0] - 2021-10-07 ### Added - Required `Clone` traits on immutable reference types. ## [0.5.2] - 2021-09-26 ### Added - `Get` and `GetMut` impls for `SmallVec`. ## [0.5.1] - 2021-09-26 ### Changed - Fix features `slab` and `smallvec`. ## [0.5.0] - 2021-09-22 [YANKED] ### Yanking reason - Errors with features `slab` and `smallvec`. ### Added - `Keyed` and `KeyedRef` traits.cc-traits-2.0.0/Cargo.lock0000644000000055670000000000100107140ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "cc-traits" version = "2.0.0" dependencies = [ "ijson", "serde_json", "slab", "smallvec", ] [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "dashmap" version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" dependencies = [ "cfg-if", "num_cpus", ] [[package]] name = "hermit-abi" version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "ijson" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b96214564d1f12875bd9661b183d8494dd10e373cb693629536fe2f3125e254b" dependencies = [ "dashmap", "lazy_static", "serde", "serde_json", ] [[package]] name = "itoa" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" [[package]] name = "num_cpus" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ "hermit-abi", "libc", ] [[package]] name = "ryu" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "serde" version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" [[package]] name = "serde_json" version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" dependencies = [ "itoa", "ryu", "serde", ] [[package]] name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" [[package]] name = "smallvec" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" cc-traits-2.0.0/Cargo.toml0000644000000024660000000000100107320ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "cc-traits" version = "2.0.0" authors = ["Timothée Haudebourg "] description = "Common collection traits" documentation = "https://docs.rs/cc-traits" readme = "README.md" keywords = [ "trait", "data-structure", "collection", "common", ] categories = [ "data-structures", "no-std", "rust-patterns", ] license = "MIT/Apache-2.0" repository = "https://github.com/timothee-haudebourg/cc-traits" [dependencies.ijson] version = "^0.1" optional = true [dependencies.serde_json] version = "^1.0.71" optional = true [dependencies.slab] version = "^0.4" optional = true [dependencies.smallvec] version = "^1.6" optional = true [features] all-impls = [ "slab", "smallvec", "serde_json", "ijson", ] alloc = [] default = [ "alloc", "std", ] nightly = [] std = [] cc-traits-2.0.0/Cargo.toml.orig0000644000000014160000000000100116630ustar [package] name = "cc-traits" version = "2.0.0" authors = ["Timothée Haudebourg "] edition = "2018" categories = ["data-structures", "no-std", "rust-patterns"] keywords = ["trait", "data-structure", "collection", "common"] description = "Common collection traits" repository = "https://github.com/timothee-haudebourg/cc-traits" documentation = "https://docs.rs/cc-traits" license = "MIT/Apache-2.0" readme = "README.md" [features] default = ["alloc", "std"] alloc = [] std = [] nightly = [] all-impls = ["slab", "smallvec", "serde_json", "ijson"] [dependencies] slab = { version = "^0.4", optional = true } smallvec = { version = "^1.6", optional = true } serde_json = { version = "^1.0.71", optional = true } ijson = { version = "^0.1", optional = true }cc-traits-2.0.0/Cargo.toml.orig000064400000000000000000000014161046102023000144050ustar 00000000000000[package] name = "cc-traits" version = "2.0.0" authors = ["Timothée Haudebourg "] edition = "2018" categories = ["data-structures", "no-std", "rust-patterns"] keywords = ["trait", "data-structure", "collection", "common"] description = "Common collection traits" repository = "https://github.com/timothee-haudebourg/cc-traits" documentation = "https://docs.rs/cc-traits" license = "MIT/Apache-2.0" readme = "README.md" [features] default = ["alloc", "std"] alloc = [] std = [] nightly = [] all-impls = ["slab", "smallvec", "serde_json", "ijson"] [dependencies] slab = { version = "^0.4", optional = true } smallvec = { version = "^1.6", optional = true } serde_json = { version = "^1.0.71", optional = true } ijson = { version = "^0.1", optional = true }cc-traits-2.0.0/LICENSE-APACHE000064400000000000000000000251371046102023000134500ustar 00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. cc-traits-2.0.0/LICENSE-MIT000064400000000000000000000017771046102023000131640ustar 00000000000000Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cc-traits-2.0.0/README.md000064400000000000000000000102171046102023000127740ustar 00000000000000# Common Collection Traits
Documentation Crate informations Repository
This crate provide traits to describe common operations available on data structures. This is particularly useful when building new types on top of generic data structures without relying on the actual implementation of the underlying data structure. Here is an example of the kind of traits provided by this crate: ```rust /// Mutable collection where new elements can be inserted. pub trait Insert: Collection { /// The output of the insertion function. type Output; /// Insert a new element in the collection. fn insert(&mut self, element: Self::Item) -> Self::Output; } ``` ## Usage Such traits can be used to define collections with special properties, independently of the actual internal data structure. For instance the following code defines an `Ordered` stack collection, guarantying the well-sortedness of the elements in the stack. ```rust use cc_traits::{ Collection, Back, PushBack }; /// Ordered stack. pub struct Ordered { inner: S } impl Ordered { pub fn new() -> Self where S: Default { Ordered { inner: S::default() } } } impl Ordered { /// Push the given element on the stack iff it is grater or equal /// to every other element already in the stack. pub fn try_push(&mut self, element: T) -> Result<(), T> where T: PartialOrd, S: Collection + Back + PushBack, // `S` must be a stack providing `back` and `push_back`. for<'a> S::ItemRef<'a>: PartialOrd<&'a T> // The reference type must be comparable with other reference types. { if self.inner.back().map(|back| back <= &element).unwrap_or(true) { self.inner.push_back(element); Ok(()) } else { Err(element) } } } let mut vec: Ordered> = Ordered::new(); // a `Vec` is a stack so it works. assert!(vec.try_push(1).is_ok()); assert!(vec.try_push(2).is_ok()); assert!(vec.try_push(0).is_err()); use std::collections::VecDeque; let mut deque: Ordered> = Ordered::new(); // a `VecDeque` is also a stack. assert!(deque.try_push(1).is_ok()); assert!(deque.try_push(2).is_ok()); assert!(deque.try_push(0).is_err()); ``` ## Trait aliases By enabling the `nightly` you can get access to some trait alias definitions that can be useful to reduce the verbosity of your code. Here is an example of such aliases defining the common interface of stacks: ```rust pub trait Stack = Collection + Len + Back; pub trait StackMut = Stack + BackMut + PushBack + PopBack; ``` As of version 0.8.0, those traits are also available without the `nightly` feature as regular trait definitions. ## Standard library By default, all the traits defined in this crate are implemented (when relevent) for the standard library collections. You can disable it by using the `nostd` feature. ## Foreign implementations In addition to the standard library, traits are implemented for some popular crates if you enable the feature of the same name. Here are the supported crates: - [`slab`](https://crates.io/crates/slab) providing the `Slab` collection. - [`smallvec`](https://crates.io/crates/smallvec) providing the `SmallVec` collection. - [`serde_json`](https://crates.io/crates/serde_json) providing the `Map` collection for JSON objects. - [`ijson`](https://crates.io/crates/ijson) providing the `IObject` and `IArray` collections. ## License Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. ## Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. cc-traits-2.0.0/README.tpl000064400000000000000000000014271046102023000131760ustar 00000000000000# Common Collection Traits
Documentation Crate informations Repository
{{readme}} ## License Licensed under either of * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. ## Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.cc-traits-2.0.0/src/alias.rs000064400000000000000000000065651046102023000137560ustar 00000000000000use crate::*; use std::ops::{Index, IndexMut}; /// Collection with mutable capacity. pub trait CapacityMut = Capacity + Reserve; /// Immutable stack data structure. /// /// A stack provides two main operations: /// - [`PushBack::push_back`], which adds an element to the collection, and /// - [`PopBack::pop_back`], which removes the most recently added element that was not yet removed. /// /// This trait alias describes the immutables operations derived from the two main operation above: /// - [`Len::len`], returning the number of elements in the stack, and /// - [`Back::back`], returning a reference to the most recently added element that was not yet removed. pub trait Stack = Collection + Len + Back; /// Mutable stack data structure. /// /// This trait alias describes the mutables operations on a stack. /// See [`Stack`] for more details. pub trait StackMut = Stack + BackMut + PushBack + PopBack; /// Immutable array data structure (conventionally nammed "Vec"). /// /// A Vec is essentially a [`Stack`] indexable by a `usize`. pub trait Vec = Stack + Index; /// Mutable Vec data structure. /// /// This trait alias describes the mutables operations on a Vec. /// See [`Vec`] for more details. pub trait VecMut = Vec + StackMut + IndexMut; /// Immutable double-ended queue. /// /// A double-ended queue (abbreviated to deque) is a generalization of a stack in which /// elements can be added and removed from both ends. /// Such a data structure provides two additional operations compared to regular stacks: /// - [`PushFront::push_front`], which adds an element to the front of collection, and /// - [`PopFront::pop_front`], which removes the front element of the collection. /// /// This trait alias describes the immutables operations available on deques. pub trait Deque = Stack + Front; /// Mutable double-ended queue. /// /// This trait alias describes the mutables operations on a deque. /// See [`Deque`] for more details. pub trait DequeMut = StackMut + FrontMut + PushFront + PopFront; /// Immutable indexable deque. /// /// See [`Deque`] and [`Vec`] for more details. pub trait VecDeque = Deque + Vec; /// Mutable indexable deque. /// /// See [`VecDeque`], [`DequeMut`] and [`VecMut`] for more details. pub trait VecDequeMut = VecDeque + DequeMut + VecMut; /// Imutable set data structure. /// /// A set is an unordered collection storing at most one single copy of each element. pub trait Set = Collection + Len + for<'a> Get<&'a T>; /// Mutable set data structure. pub trait SetMut = Set + Insert + for<'a> Remove<&'a T>; /// Imutable map data structure. /// /// A map is an unordered collection storing key-value pairs, indexed by the key. pub trait Map = Keyed + Len + for<'a> Get<&'a K> + for<'a> GetKeyValue<&'a K>; /// Mutable map data structure. pub trait MapMut = Map + for<'a> GetMut<&'a K> + MapInsert> + for<'a> Remove<&'a K>; /// Imutable slab data structure. /// /// A slab is a linear collection storing each element at a given index. /// The index of the element is allocated and returned upon insertion. pub trait Slab = Collection + Len + Get; /// Mutable slab data structure. pub trait SlabMut = Slab + GetMut + Insert + Remove; cc-traits-2.0.0/src/impls/alloc/btreemap.rs000064400000000000000000000054641046102023000166770ustar 00000000000000use crate::{ Clear, Collection, CollectionMut, CollectionRef, Get, GetKeyValue, GetMut, Iter, Keyed, KeyedRef, Len, MapInsert, MapIter, MapIterMut, Remove, SimpleCollectionMut, SimpleCollectionRef, SimpleKeyedRef, }; use alloc::collections::BTreeMap; use core::borrow::Borrow; impl Collection for BTreeMap { type Item = V; } impl CollectionRef for BTreeMap { type ItemRef<'a> = &'a V where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for BTreeMap { type ItemMut<'a> = &'a mut V where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for BTreeMap { crate::simple_collection_ref!(); } impl SimpleCollectionMut for BTreeMap { crate::simple_collection_mut!(); } impl Keyed for BTreeMap { type Key = K; } impl KeyedRef for BTreeMap { type KeyRef<'a> = &'a K where Self: 'a; crate::covariant_key_ref!(); } impl SimpleKeyedRef for BTreeMap { crate::simple_keyed_ref!(); } impl Len for BTreeMap { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl<'a, Q, K: Ord, V> Get<&'a Q> for BTreeMap where K: Borrow, Q: Ord + ?Sized, { #[inline(always)] fn get(&self, key: &'a Q) -> Option<&V> { self.get(key) } } impl<'a, Q, K: Ord, V> GetKeyValue<&'a Q> for BTreeMap where K: Borrow, Q: Ord + ?Sized, { #[inline(always)] fn get_key_value(&self, key: &'a Q) -> Option<(&K, &V)> { self.get_key_value(key) } } impl<'a, Q, K: Ord, V> GetMut<&'a Q> for BTreeMap where K: Borrow, Q: Ord + ?Sized, { #[inline(always)] fn get_mut(&mut self, key: &'a Q) -> Option<&mut V> { self.get_mut(key) } } impl MapInsert for BTreeMap { type Output = Option; #[inline(always)] fn insert(&mut self, key: K, value: V) -> Option { self.insert(key, value) } } impl<'a, Q, K: Ord, V> Remove<&'a Q> for BTreeMap where K: Borrow, Q: Ord + ?Sized, { #[inline(always)] fn remove(&mut self, key: &'a Q) -> Option { self.remove(key) } } impl Clear for BTreeMap { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Iter for BTreeMap { type Iter<'a> = alloc::collections::btree_map::Values<'a, K, V> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.values() } } impl MapIter for BTreeMap { type Iter<'a> = alloc::collections::btree_map::Iter<'a, K, V> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.iter() } } impl MapIterMut for BTreeMap { type IterMut<'a> = alloc::collections::btree_map::IterMut<'a, K, V> where Self: 'a; #[inline(always)] fn iter_mut(&mut self) -> Self::IterMut<'_> { self.iter_mut() } } cc-traits-2.0.0/src/impls/alloc/btreeset.rs000064400000000000000000000030731046102023000167070ustar 00000000000000use crate::{ Clear, Collection, CollectionMut, CollectionRef, Get, Insert, Iter, Len, Remove, SimpleCollectionMut, SimpleCollectionRef, }; use alloc::collections::BTreeSet; use core::borrow::Borrow; impl Collection for BTreeSet { type Item = T; } impl CollectionRef for BTreeSet { type ItemRef<'a> = &'a T where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for BTreeSet { type ItemMut<'a> = &'a mut T where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for BTreeSet { crate::simple_collection_ref!(); } impl SimpleCollectionMut for BTreeSet { crate::simple_collection_mut!(); } impl Len for BTreeSet { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl<'a, Q, T: Ord> Get<&'a Q> for BTreeSet where T: Borrow, Q: Ord + ?Sized, { #[inline(always)] fn get(&self, t: &'a Q) -> Option<&T> { self.get(t) } } impl Insert for BTreeSet { type Output = bool; #[inline(always)] fn insert(&mut self, t: T) -> bool { self.insert(t) } } impl<'a, Q, T: Ord> Remove<&'a Q> for BTreeSet where T: Borrow, Q: Ord + ?Sized, { #[inline(always)] fn remove(&mut self, t: &'a Q) -> Option { self.take(t) } } impl Clear for BTreeSet { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Iter for BTreeSet { type Iter<'a> = alloc::collections::btree_set::Iter<'a, T> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.iter() } } cc-traits-2.0.0/src/impls/alloc/deque.rs000064400000000000000000000037651046102023000162050ustar 00000000000000use crate::{ Back, BackMut, Capacity, Clear, Collection, CollectionMut, CollectionRef, Front, FrontMut, Len, PopBack, PushBack, Reserve, SimpleCollectionMut, SimpleCollectionRef, WithCapacity, }; use alloc::collections::VecDeque; impl Collection for VecDeque { type Item = T; } impl CollectionRef for VecDeque { type ItemRef<'a> = &'a T where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for VecDeque { type ItemMut<'a> = &'a mut T where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for VecDeque { crate::simple_collection_ref!(); } impl SimpleCollectionMut for VecDeque { crate::simple_collection_mut!(); } impl WithCapacity for VecDeque { #[inline(always)] fn with_capacity(capacity: usize) -> Self { VecDeque::with_capacity(capacity) } } impl Len for VecDeque { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl Capacity for VecDeque { #[inline(always)] fn capacity(&self) -> usize { self.capacity() } } impl Reserve for VecDeque { #[inline(always)] fn reserve(&mut self, additional: usize) { self.reserve(additional) } } impl Front for VecDeque { #[inline(always)] fn front(&self) -> Option<&T> { self.front() } } impl FrontMut for VecDeque { #[inline(always)] fn front_mut(&mut self) -> Option<&mut T> { self.front_mut() } } impl Back for VecDeque { #[inline(always)] fn back(&self) -> Option<&T> { self.back() } } impl BackMut for VecDeque { #[inline(always)] fn back_mut(&mut self) -> Option<&mut T> { self.back_mut() } } impl PushBack for VecDeque { type Output = (); #[inline(always)] fn push_back(&mut self, t: T) { self.push_back(t) } } impl PopBack for VecDeque { #[inline(always)] fn pop_back(&mut self) -> Option { self.pop_back() } } impl Clear for VecDeque { #[inline(always)] fn clear(&mut self) { self.clear() } } cc-traits-2.0.0/src/impls/alloc/mod.rs000064400000000000000000000000601046102023000156420ustar 00000000000000mod btreemap; mod btreeset; mod deque; mod vec; cc-traits-2.0.0/src/impls/alloc/vec.rs000064400000000000000000000044501046102023000156470ustar 00000000000000use crate::{ Capacity, Clear, Collection, CollectionMut, CollectionRef, Get, GetMut, Iter, IterMut, Len, PopBack, PushBack, Remove, Reserve, SimpleCollectionMut, SimpleCollectionRef, WithCapacity, }; use alloc::vec::Vec; impl Collection for Vec { type Item = T; } impl CollectionRef for Vec { type ItemRef<'a> = &'a T where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for Vec { type ItemMut<'a> = &'a mut T where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for Vec { crate::simple_collection_ref!(); } impl SimpleCollectionMut for Vec { crate::simple_collection_mut!(); } impl WithCapacity for Vec { #[inline(always)] fn with_capacity(capacity: usize) -> Self { Vec::with_capacity(capacity) } } impl Len for Vec { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl Get for Vec { #[inline(always)] fn get(&self, index: usize) -> Option<&T> { self.as_slice().get(index) } } impl GetMut for Vec { #[inline(always)] fn get_mut(&mut self, index: usize) -> Option<&mut T> { self.as_mut_slice().get_mut(index) } } impl Capacity for Vec { #[inline(always)] fn capacity(&self) -> usize { self.capacity() } } impl Reserve for Vec { #[inline(always)] fn reserve(&mut self, additional: usize) { self.reserve(additional) } } impl PushBack for Vec { type Output = (); #[inline(always)] fn push_back(&mut self, t: T) { self.push(t) } } impl PopBack for Vec { #[inline(always)] fn pop_back(&mut self) -> Option { self.pop() } } impl Remove for Vec { #[inline(always)] fn remove(&mut self, index: usize) -> Option { if index < self.len() { Some(self.remove(index)) } else { None } } } impl Clear for Vec { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Iter for Vec { type Iter<'a> = core::slice::Iter<'a, T> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.as_slice().iter() } } impl IterMut for Vec { type IterMut<'a> = core::slice::IterMut<'a, T> where Self: 'a; #[inline(always)] fn iter_mut(&mut self) -> Self::IterMut<'_> { self.as_mut_slice().iter_mut() } } cc-traits-2.0.0/src/impls/ijson.rs000064400000000000000000000106641046102023000151260ustar 00000000000000use crate::{ Capacity, Clear, Collection, CollectionMut, CollectionRef, Get, GetKeyValue, GetKeyValueMut, GetMut, Iter, IterMut, Keyed, KeyedRef, Len, MapInsert, MapIter, MapIterMut, PopBack, PushBack, Remove, Reserve, SimpleCollectionMut, SimpleCollectionRef, SimpleKeyedRef, WithCapacity, }; use ijson::{IArray, IObject, IString, IValue}; impl Collection for IObject { type Item = IValue; } impl CollectionRef for IObject { type ItemRef<'a> = &'a IValue where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for IObject { type ItemMut<'a> = &'a mut IValue where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for IObject { crate::simple_collection_ref!(); } impl SimpleCollectionMut for IObject { crate::simple_collection_mut!(); } impl Keyed for IObject { type Key = IString; } impl KeyedRef for IObject { type KeyRef<'a> = &'a IString where Self: 'a; crate::covariant_key_ref!(); } impl SimpleKeyedRef for IObject { crate::simple_keyed_ref!(); } impl Len for IObject { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl MapIter for IObject { type Iter<'a> = ijson::object::Iter<'a>; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.iter() } } impl MapIterMut for IObject { type IterMut<'a> = ijson::object::IterMut<'a> where Self: 'a; #[inline(always)] fn iter_mut(&mut self) -> Self::IterMut<'_> { self.iter_mut() } } impl Get for IObject { #[inline(always)] fn get(&self, q: Q) -> Option<&IValue> { self.get(q) } } impl GetKeyValue for IObject { #[inline(always)] fn get_key_value(&self, q: Q) -> Option<(&IString, &IValue)> { self.get_key_value(q) } } impl GetMut for IObject { #[inline(always)] fn get_mut(&mut self, q: Q) -> Option<&mut IValue> { self.get_mut(q) } } impl GetKeyValueMut for IObject { #[inline(always)] fn get_key_value_mut(&mut self, q: Q) -> Option<(&IString, &mut IValue)> { self.get_key_value_mut(q) } } impl MapInsert for IObject { type Output = Option; #[inline(always)] fn insert(&mut self, key: IString, value: IValue) -> Option { self.insert(key, value) } } impl Remove for IObject { #[inline(always)] fn remove(&mut self, key: Q) -> Option { self.remove(key) } } impl Clear for IObject { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Collection for IArray { type Item = IValue; } impl CollectionRef for IArray { type ItemRef<'a> = &'a IValue where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for IArray { type ItemMut<'a> = &'a mut IValue where Self: 'a; crate::covariant_item_mut!(); } impl WithCapacity for IArray { #[inline(always)] fn with_capacity(capacity: usize) -> Self { Self::with_capacity(capacity) } } impl Len for IArray { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl Get for IArray { #[inline(always)] fn get(&self, index: usize) -> Option<&IValue> { self.as_slice().get(index) } } impl GetMut for IArray { #[inline(always)] fn get_mut(&mut self, index: usize) -> Option<&mut IValue> { self.as_mut_slice().get_mut(index) } } impl Capacity for IArray { #[inline(always)] fn capacity(&self) -> usize { self.capacity() } } impl Reserve for IArray { #[inline(always)] fn reserve(&mut self, additional: usize) { self.reserve(additional) } } impl PushBack for IArray { type Output = (); #[inline(always)] fn push_back(&mut self, t: IValue) { self.push(t) } } impl PopBack for IArray { #[inline(always)] fn pop_back(&mut self) -> Option { self.pop() } } impl Remove for IArray { #[inline(always)] fn remove(&mut self, index: usize) -> Option { if index < self.len() { self.remove(index) } else { None } } } impl Clear for IArray { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Iter for IArray { type Iter<'a> = std::slice::Iter<'a, IValue>; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.as_slice().iter() } } impl IterMut for IArray { type IterMut<'a> = std::slice::IterMut<'a, IValue>; #[inline(always)] fn iter_mut(&mut self) -> Self::IterMut<'_> { self.as_mut_slice().iter_mut() } } cc-traits-2.0.0/src/impls/mod.rs000064400000000000000000000003551046102023000145570ustar 00000000000000#[cfg(feature = "alloc")] mod alloc; #[cfg(feature = "std")] mod std; #[cfg(feature = "slab")] mod slab; #[cfg(feature = "smallvec")] mod smallvec; #[cfg(feature = "serde_json")] mod serde_json; #[cfg(feature = "ijson")] mod ijson; cc-traits-2.0.0/src/impls/serde_json.rs000064400000000000000000000063211046102023000161320ustar 00000000000000use crate::{ Clear, Collection, CollectionMut, CollectionRef, Get, GetKeyValue, GetMut, Keyed, KeyedRef, Len, MapInsert, MapIter, MapIterMut, Remove, SimpleCollectionMut, SimpleCollectionRef, SimpleKeyedRef, }; use std::{borrow::Borrow, cmp::Ord, hash::Hash}; impl Collection for serde_json::Map { type Item = serde_json::Value; } impl CollectionRef for serde_json::Map { type ItemRef<'a> = &'a serde_json::Value where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for serde_json::Map { type ItemMut<'a> = &'a mut serde_json::Value where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for serde_json::Map { crate::simple_collection_ref!(); } impl SimpleCollectionMut for serde_json::Map { fn into_mut<'a>(r: &'a mut serde_json::Value) -> &'a mut serde_json::Value where Self: 'a, { r } } impl Keyed for serde_json::Map { type Key = String; } impl KeyedRef for serde_json::Map { type KeyRef<'a> = &'a String where Self: 'a; crate::covariant_key_ref!(); } impl SimpleKeyedRef for serde_json::Map { crate::simple_keyed_ref!(); } impl Len for serde_json::Map { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl MapIter for serde_json::Map { type Iter<'a> = serde_json::map::Iter<'a> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.iter() } } impl MapIterMut for serde_json::Map { type IterMut<'a> = serde_json::map::IterMut<'a> where Self: 'a; #[inline(always)] fn iter_mut(&mut self) -> Self::IterMut<'_> { self.iter_mut() } } impl<'a, Q: ?Sized> Get<&'a Q> for serde_json::Map where String: Borrow, Q: Ord + Hash, { #[inline(always)] fn get(&self, q: &'a Q) -> Option<&serde_json::Value> { self.get(q) } } impl<'a, Q: ?Sized> GetMut<&'a Q> for serde_json::Map where String: Borrow, Q: Ord + Hash, { #[inline(always)] fn get_mut(&mut self, q: &'a Q) -> Option<&mut serde_json::Value> { self.get_mut(q) } } impl<'a, Q: ?Sized> GetKeyValue<&'a Q> for serde_json::Map where String: Borrow, Q: Ord + Hash, { #[inline(always)] #[deny(unconditional_recursion)] fn get_key_value(&self, q: &'a Q) -> Option<(&String, &serde_json::Value)> { self.get_key_value(q) } } impl MapInsert for serde_json::Map { type Output = Option; #[inline(always)] fn insert(&mut self, key: String, value: serde_json::Value) -> Option { self.insert(key, value) } } impl<'a, Q: ?Sized> Remove<&'a Q> for serde_json::Map where String: Borrow, Q: Ord + Hash, { #[inline(always)] fn remove(&mut self, key: &'a Q) -> Option { self.remove(key) } } impl Clear for serde_json::Map { #[inline(always)] fn clear(&mut self) { self.clear() } } cc-traits-2.0.0/src/impls/slab.rs000064400000000000000000000031131046102023000147140ustar 00000000000000use crate::{ Capacity, Clear, Collection, CollectionMut, CollectionRef, Get, GetMut, Insert, Len, Remove, Reserve, SimpleCollectionMut, SimpleCollectionRef, WithCapacity, }; use slab::Slab; impl Collection for Slab { type Item = T; } impl CollectionRef for Slab { type ItemRef<'a> = &'a T where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for Slab { type ItemMut<'a> = &'a mut T where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for Slab { crate::simple_collection_ref!(); } impl SimpleCollectionMut for Slab { crate::simple_collection_mut!(); } impl WithCapacity for Slab { fn with_capacity(capacity: usize) -> Self { Slab::with_capacity(capacity) } } impl Len for Slab { fn len(&self) -> usize { self.len() } } impl Capacity for Slab { fn capacity(&self) -> usize { self.capacity() } } impl Reserve for Slab { fn reserve(&mut self, additional: usize) { self.reserve(additional) } } impl Get for Slab { fn get(&self, key: usize) -> Option<&Self::Item> { self.get(key) } } impl GetMut for Slab { fn get_mut(&mut self, key: usize) -> Option<&mut Self::Item> { self.get_mut(key) } } impl Insert for Slab { type Output = usize; fn insert(&mut self, element: T) -> usize { self.insert(element) } } impl Remove for Slab { fn remove(&mut self, key: usize) -> Option { if self.contains(key) { Some(self.remove(key)) } else { None } } } impl Clear for Slab { fn clear(&mut self) { self.clear() } } cc-traits-2.0.0/src/impls/smallvec.rs000064400000000000000000000050771046102023000156140ustar 00000000000000use crate::{ Capacity, Clear, Collection, CollectionMut, CollectionRef, Get, GetMut, Iter, IterMut, Len, PopBack, PushBack, Remove, Reserve, SimpleCollectionMut, SimpleCollectionRef, WithCapacity, }; use smallvec::{Array, SmallVec}; impl Collection for SmallVec { type Item = A::Item; } impl CollectionRef for SmallVec { type ItemRef<'a> = &'a A::Item where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for SmallVec { type ItemMut<'a> = &'a mut A::Item where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for SmallVec { crate::simple_collection_ref!(); } impl SimpleCollectionMut for SmallVec { crate::simple_collection_mut!(); } impl WithCapacity for SmallVec { #[inline(always)] fn with_capacity(capacity: usize) -> Self { SmallVec::with_capacity(capacity) } } impl Len for SmallVec { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl Capacity for SmallVec { #[inline(always)] fn capacity(&self) -> usize { self.capacity() } } impl Reserve for SmallVec { #[inline(always)] fn reserve(&mut self, additional: usize) { self.reserve(additional) } } impl Get for SmallVec { #[inline(always)] fn get(&self, index: usize) -> Option<&A::Item> { self.as_slice().get(index) } } impl GetMut for SmallVec { #[inline(always)] fn get_mut(&mut self, index: usize) -> Option<&mut A::Item> { self.as_mut_slice().get_mut(index) } } impl PushBack for SmallVec { type Output = (); #[inline(always)] fn push_back(&mut self, t: A::Item) { self.push(t) } } impl PopBack for SmallVec { #[inline(always)] fn pop_back(&mut self) -> Option { self.pop() } } impl Remove for SmallVec { #[inline(always)] fn remove(&mut self, index: usize) -> Option { if index < self.len() { Some(self.remove(index)) } else { None } } } impl Clear for SmallVec { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Iter for SmallVec { type Iter<'a> = std::slice::Iter<'a, A::Item> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.as_slice().iter() } } impl IterMut for SmallVec { type IterMut<'a> = std::slice::IterMut<'a, A::Item> where Self: 'a; #[inline(always)] fn iter_mut(&mut self) -> Self::IterMut<'_> { self.as_mut_slice().iter_mut() } } cc-traits-2.0.0/src/impls/std/hashmap.rs000064400000000000000000000055131046102023000162140ustar 00000000000000use crate::{ Clear, Collection, CollectionMut, CollectionRef, Get, GetKeyValue, GetMut, Iter, Keyed, KeyedRef, Len, MapInsert, MapIter, MapIterMut, Remove, SimpleCollectionMut, SimpleCollectionRef, SimpleKeyedRef, }; use std::{borrow::Borrow, collections::HashMap, hash::Hash}; impl Collection for HashMap { type Item = V; } impl CollectionRef for HashMap { type ItemRef<'a> = &'a V where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for HashMap { type ItemMut<'a> = &'a mut V where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for HashMap { crate::simple_collection_ref!(); } impl SimpleCollectionMut for HashMap { crate::simple_collection_mut!(); } impl Keyed for HashMap { type Key = K; } impl KeyedRef for HashMap { type KeyRef<'a> = &'a K where Self: 'a; crate::covariant_key_ref!(); } impl SimpleKeyedRef for HashMap { crate::simple_keyed_ref!(); } impl Len for HashMap { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl<'a, Q, K: Hash + Eq, V> Get<&'a Q> for HashMap where K: Borrow, Q: Hash + Eq + ?Sized, { #[inline(always)] fn get(&self, key: &'a Q) -> Option<&V> { self.get(key) } } impl<'a, Q, K: Hash + Eq, V> GetMut<&'a Q> for HashMap where K: Borrow, Q: Hash + Eq + ?Sized, { #[inline(always)] fn get_mut(&mut self, key: &'a Q) -> Option<&mut V> { self.get_mut(key) } } impl<'a, Q, K: Hash + Eq, V> GetKeyValue<&'a Q> for HashMap where K: Borrow, Q: Hash + Eq + ?Sized, { #[inline(always)] fn get_key_value(&self, key: &'a Q) -> Option<(&K, &V)> { self.get_key_value(key) } } impl MapInsert for HashMap { type Output = Option; #[inline(always)] fn insert(&mut self, key: K, value: V) -> Option { self.insert(key, value) } } impl<'a, Q, K: Hash + Eq, V> Remove<&'a Q> for HashMap where K: Borrow, Q: Hash + Eq + ?Sized, { #[inline(always)] fn remove(&mut self, key: &'a Q) -> Option { self.remove(key) } } impl Clear for HashMap { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Iter for HashMap { type Iter<'a> = std::collections::hash_map::Values<'a, K, V> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.values() } } impl MapIter for HashMap { type Iter<'a> = std::collections::hash_map::Iter<'a, K, V> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.iter() } } impl MapIterMut for HashMap { type IterMut<'a> = std::collections::hash_map::IterMut<'a, K, V> where Self: 'a; #[inline(always)] fn iter_mut(&mut self) -> Self::IterMut<'_> { self.iter_mut() } } cc-traits-2.0.0/src/impls/std/hashset.rs000064400000000000000000000031071046102023000162270ustar 00000000000000use crate::{ Clear, Collection, CollectionMut, CollectionRef, Get, Insert, Iter, Len, Remove, SimpleCollectionMut, SimpleCollectionRef, }; use std::{borrow::Borrow, collections::HashSet, hash::Hash}; impl Collection for HashSet { type Item = T; } impl CollectionRef for HashSet { type ItemRef<'a> = &'a T where Self: 'a; crate::covariant_item_ref!(); } impl CollectionMut for HashSet { type ItemMut<'a> = &'a mut T where Self: 'a; crate::covariant_item_mut!(); } impl SimpleCollectionRef for HashSet { crate::simple_collection_ref!(); } impl SimpleCollectionMut for HashSet { crate::simple_collection_mut!(); } impl Len for HashSet { #[inline(always)] fn len(&self) -> usize { self.len() } #[inline(always)] fn is_empty(&self) -> bool { self.is_empty() } } impl<'a, Q, T: Hash + Eq> Get<&'a Q> for HashSet where T: Borrow, Q: Hash + Eq + ?Sized, { fn get(&self, value: &'a Q) -> Option<&T> { self.get(value) } } impl Insert for HashSet { type Output = bool; #[inline(always)] fn insert(&mut self, t: T) -> bool { self.insert(t) } } impl<'a, Q, T: Hash + Eq> Remove<&'a Q> for HashSet where T: Borrow, Q: Hash + Eq + ?Sized, { #[inline(always)] fn remove(&mut self, t: &'a Q) -> Option { self.take(t) } } impl Clear for HashSet { #[inline(always)] fn clear(&mut self) { self.clear() } } impl Iter for HashSet { type Iter<'a> = std::collections::hash_set::Iter<'a, T> where Self: 'a; #[inline(always)] fn iter(&self) -> Self::Iter<'_> { self.iter() } } cc-traits-2.0.0/src/impls/std/mod.rs000064400000000000000000000000321046102023000153410ustar 00000000000000mod hashmap; mod hashset; cc-traits-2.0.0/src/lib.rs000064400000000000000000000342451046102023000134270ustar 00000000000000//! This crate provide traits to describe common operations available on data structures. //! This is particularly useful when building new types on top of generic data structures without relying on the actual implementation of the underlying data structure. //! //! Here is an example of the kind of traits provided by this crate: //! ```rust //! # use cc_traits::Collection; //! /// Mutable collection where new elements can be inserted. //! pub trait Insert: Collection { //! /// The output of the insertion function. //! type Output; //! //! /// Insert a new element in the collection. //! fn insert(&mut self, element: Self::Item) -> Self::Output; //! } //! ``` //! //! # Usage //! //! Such traits can be used to define collections with special properties, //! independently of the actual internal data structure. //! For instance the following code defines an `Ordered` stack collection, //! guarantying the well-sortedness of the elements in the stack. //! //! ```rust //! use cc_traits::{ //! Collection, //! Back, //! PushBack //! }; //! //! /// Ordered stack. //! pub struct Ordered { //! inner: S //! } //! //! impl Ordered { //! pub fn new() -> Self where S: Default { //! Ordered { //! inner: S::default() //! } //! } //! } //! //! impl Ordered { //! /// Push the given element on the stack iff it is grater or equal //! /// to every other element already in the stack. //! pub fn try_push(&mut self, element: T) -> Result<(), T> //! where //! T: PartialOrd, //! S: Collection + Back + PushBack, // `S` must be a stack providing `back` and `push_back`. //! for<'a> S::ItemRef<'a>: PartialOrd<&'a T> // The reference type must be comparable with other reference types. //! { //! if self.inner.back().map(|back| back <= &element).unwrap_or(true) { //! self.inner.push_back(element); //! Ok(()) //! } else { //! Err(element) //! } //! } //! } //! //! #[cfg(feature = "std")] //! fn ordered_stack_usage() //! where //! S: Default + Collection + Back + PushBack, //! for<'a> S::ItemRef<'a>: PartialOrd<&'a i32>, //! { //! let mut ordered: Ordered = Ordered::new(); //! assert!(ordered.try_push(1).is_ok()); //! assert!(ordered.try_push(2).is_ok()); //! assert!(ordered.try_push(0).is_err()); //! } //! //! #[cfg(feature = "std")] //! ordered_stack_usage::>(); // a `Vec` is a stack so it works. //! //! #[cfg(feature = "std")] //! use std::collections::VecDeque; //! #[cfg(feature = "std")] //! ordered_stack_usage::>(); // a `VecDeque` is also a stack. //! ``` //! //! # Trait aliases //! //! By enabling the `nightly` you can get access to //! some trait alias definitions that can be useful to reduce the //! verbosity of your code. //! Here is an example of such aliases defining the common interface of stacks: //! ```ignore //! pub trait Stack = Collection + Len + Back; //! pub trait StackMut = Stack + BackMut + PushBack + PopBack; //! ``` //! //! As of version 0.8.0, those traits are also available without the `nightly` //! feature as regular trait definitions. //! //! # Standard library //! //! By default, all the traits defined in this crate are implemented (when relevant) //! for the standard library collections. //! You can disable it by using the `nostd` feature. //! //! # Foreign implementations //! //! In addition to the standard library, //! traits are implemented for //! some popular crates if you enable the feature of the same name. //! Here are the supported crates: //! //! - [`slab`](https://crates.io/crates/slab) providing the `Slab` collection. //! - [`smallvec`](https://crates.io/crates/smallvec) providing the `SmallVec` collection. //! - [`serde_json`](https://crates.io/crates/serde_json) providing the `Map` collection for JSON objects. //! - [`ijson`](https://crates.io/crates/ijson) providing the `IObject` and `IArray` collections. #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(feature = "nightly", feature(trait_alias))] #[cfg(feature = "alloc")] extern crate alloc; extern crate core; mod impls; mod macros; #[cfg(feature = "nightly")] mod alias; #[cfg(feature = "nightly")] pub use alias::*; #[cfg(not(feature = "nightly"))] mod non_alias; #[cfg(not(feature = "nightly"))] pub use non_alias::*; use core::ops::{Deref, DerefMut}; /// Abstract collection. pub trait Collection { /// Type of the items of the collection. type Item; } /// Abstract collection that can be immutably referenced. pub trait CollectionRef: Collection { /// Type of references to items of the collection. type ItemRef<'a>: Clone + Deref where Self: 'a; /// Changes an item reference into a shorter lived reference. /// /// Item references are [covariant](https://doc.rust-lang.org/nomicon/subtyping.html#variance) with /// regard to the defined lifetime parameter `'a`. /// Since this cannot be directly expressed by the type system, this associated function /// allows one to explicitly shorten the reference's lifetime. /// /// You can use the [`covariant_item_ref!`] macro to automatically /// implement this function. fn upcast_item_ref<'short, 'long: 'short>(r: Self::ItemRef<'long>) -> Self::ItemRef<'short> where Self: 'long; } /// Collection where each item reference can be converted into a standard /// "simple" rust reference. /// /// This trait is particularly useful to avoid having to include where bounds /// of the form `for<'r> T::ItemRef<'r>: Into<&'r T::Item>`, which can /// currently lead the compiler to try to prove `T: 'static` /// (see https://github.com/rust-lang/rust/pull/96709#issuecomment-1182403490) /// for more details. pub trait SimpleCollectionRef: CollectionRef { fn into_ref<'r>(r: Self::ItemRef<'r>) -> &'r Self::Item where Self: 'r; } /// Abstract collection that can be mutably referenced. pub trait CollectionMut: Collection { /// Type of mutable references to items of the collection. type ItemMut<'a>: DerefMut where Self: 'a; /// Changes an item mutable reference into a shorter lived mutable reference. /// /// See the [`CollectionRef::upcast_item_ref`] function for more information. /// You can use the [`covariant_item_mut!`] macro to automatically /// implement this function. fn upcast_item_mut<'short, 'long: 'short>(r: Self::ItemMut<'long>) -> Self::ItemMut<'short> where Self: 'long; } /// Collection where each item reference can be converted into a standard /// "simple" rust reference. /// /// This trait is particularly useful to avoid having to include where bounds /// of the form `for<'r> T::ItemMut<'r>: Into<&'r mut T::Item>`, which can /// currently lead the compiler to try to prove `T: 'static` /// (see https://github.com/rust-lang/rust/pull/96709#issuecomment-1182403490) /// for more details. pub trait SimpleCollectionMut: CollectionMut { fn into_mut<'r>(r: Self::ItemMut<'r>) -> &'r mut Self::Item where Self: 'r; } /// Abstract keyed collection. pub trait Keyed: Collection { /// Type of the keys indexing each item of the collection. type Key; } /// Abstract keyed collection whose key can be referenced. pub trait KeyedRef: Keyed { /// Type of references to keys of the collection. type KeyRef<'a>: Clone + Deref where Self: 'a; /// Changes a key reference into a shorter lived reference. /// /// See the [`CollectionRef::upcast_item_ref`] function for more information. /// You can use the [`covariant_key_ref!`] macro to automatically /// implement this function. fn upcast_key_ref<'short, 'long: 'short>(r: Self::KeyRef<'long>) -> Self::KeyRef<'short> where Self: 'long; } /// Keyed collection where each key reference can be converted into a standard /// "simple" rust reference. /// /// This trait is particularly useful to avoid having to include where bounds /// of the form `for<'r> T::KeyRef<'r>: Into<&'r T::Key>`, which can /// currently lead the compiler to try to prove `T: 'static` /// (see https://github.com/rust-lang/rust/pull/96709#issuecomment-1182403490) /// for more details. pub trait SimpleKeyedRef: KeyedRef { fn into_ref<'r>(r: Self::KeyRef<'r>) -> &'r Self::Key where Self: 'r; } /// Collection that can be created with a minimum given capacity. pub trait WithCapacity { /// Creates a new instance of `Self` with the given minimum capacity. fn with_capacity(capacity: usize) -> Self; } /// Sized collection. pub trait Len { /// Returns the number of elements in the collection. fn len(&self) -> usize; /// Checks if the collection is empty. fn is_empty(&self) -> bool { self.len() == 0 } } /// Collection with known capacity. pub trait Capacity { /// Returns the current capacity of the collection. /// /// This corresponds to the number of elements the collection can hold without reallocation. fn capacity(&self) -> usize; } /// Collection that can extend their capacity. pub trait Reserve { /// Reserve enough memory for `edditional` more elements. fn reserve(&mut self, additional: usize); } /// Queryable collection. pub trait Get: CollectionRef { /// Returns a reference to the item stored behind the given key (if any). fn get(&self, key: T) -> Option>; /// Checks if the collection contains an item behind the given key. fn contains(&self, key: T) -> bool { self.get(key).is_some() } } /// Mutably queryable collection. pub trait GetMut: Get + CollectionMut { /// Returns a mutable reference to the item stored behind the given key (if any). fn get_mut(&mut self, key: T) -> Option>; } /// Queryable map. pub trait GetKeyValue: CollectionRef + KeyedRef { /// Returns the key-value pair matching the given `key`. fn get_key_value(&self, key: T) -> Option<(Self::KeyRef<'_>, Self::ItemRef<'_>)>; } /// Mutably queryable map. pub trait GetKeyValueMut: CollectionMut + KeyedRef { /// Returns the key-value pair matching the given `key`, with a mutable reference to the value. fn get_key_value_mut(&mut self, key: T) -> Option<(Self::KeyRef<'_>, Self::ItemMut<'_>)>; } /// Collection exposing a reference to its front element. pub trait Front: CollectionRef { /// Get a reference to the front element of the collection. fn front(&self) -> Option>; } impl + Len> Front for T { fn front(&self) -> Option> { match self.len() { 0 => None, _ => self.get(0), } } } /// Collection exposing a reference to its back element. pub trait Back: CollectionRef { /// Get a reference to the back element of the collection. fn back(&self) -> Option>; } impl + Len> Back for T { fn back(&self) -> Option> { match self.len() { 0 => None, l => self.get(l - 1), } } } /// Collection exposing a mutable reference to its front element. pub trait FrontMut: CollectionMut { /// Get a mutable reference to the front element of the collection. fn front_mut(&mut self) -> Option>; } impl + Len> FrontMut for T { fn front_mut(&mut self) -> Option> { match self.len() { 0 => None, _ => self.get_mut(0), } } } /// Collection exposing a mutable reference to its back element. pub trait BackMut: CollectionMut { /// Get a mutable reference to the back element of the collection. fn back_mut(&mut self) -> Option>; } impl + Len> BackMut for T { fn back_mut(&mut self) -> Option> { match self.len() { 0 => None, l => self.get_mut(l - 1), } } } /// Mutable collection where new elements can be inserted. pub trait Insert: Collection { /// The output of the insertion function. type Output; /// Insert a new element in the collection. fn insert(&mut self, element: Self::Item) -> Self::Output; } /// Mutable map where new new key-value pairs can be inserted. pub trait MapInsert: Collection { /// The output of the insertion function. type Output; /// Insert a new key-value pair in the collection. fn insert(&mut self, key: K, value: Self::Item) -> Self::Output; } /// Mutable collection where new elements can be pushed on the front. pub trait PushFront: Collection { /// The output of the push function. type Output; /// Push a new element on the front of the collection. fn push_front(&mut self, element: Self::Item) -> Self::Output; } /// Mutable collection where new elements can be pushed on the back. pub trait PushBack: Collection { /// The output of the push function. type Output; /// Push a new element on the back of the collection. fn push_back(&mut self, element: Self::Item) -> Self::Output; } /// Mutable collection where elements can be removed from. pub trait Remove: Collection { /// Remove the element identified by the given `key`. fn remove(&mut self, key: T) -> Option; } /// Mutable collection where elements can be popped from the front. pub trait PopFront: Collection { /// Remove the front element of the collection and return it (if any). fn pop_front(&mut self) -> Option; } /// Mutable collection where elements can be popped from the back. pub trait PopBack: Collection { /// Remove the back element of the collection and return it (if any). fn pop_back(&mut self) -> Option; } /// Clearable collection. pub trait Clear { /// Remove all the elements of the collection. fn clear(&mut self); } /// Iterable collection. pub trait Iter: CollectionRef { /// Iterator type. type Iter<'a>: Iterator> where Self: 'a; /// Create an iterator over the items of the collection. fn iter(&self) -> Self::Iter<'_>; } /// Mutably iterable collection. pub trait IterMut: CollectionMut { /// Iterator type. type IterMut<'a>: Iterator> where Self: 'a; /// Create an iterator over the mutable items of the collection. fn iter_mut(&mut self) -> Self::IterMut<'_>; } pub trait MapIter: KeyedRef + CollectionRef { type Iter<'a>: Iterator, Self::ItemRef<'a>)> where Self: 'a; fn iter(&self) -> Self::Iter<'_>; } pub trait MapIterMut: KeyedRef + CollectionMut { type IterMut<'a>: Iterator, Self::ItemMut<'a>)> where Self: 'a; fn iter_mut(&mut self) -> Self::IterMut<'_>; } cc-traits-2.0.0/src/macros.rs000064400000000000000000000105761046102023000141460ustar 00000000000000/// Automatically defines the `CollectionRef::upcast_item_ref` function using the /// covariance of the `ItemRef<'a>` type with regards to `'a`. /// /// ## Example /// /// ``` /// use cc_traits::{Collection, CollectionRef, covariant_item_ref}; /// /// pub struct MyVec(Vec); /// /// impl Collection for MyVec { /// type Item = T; /// } /// /// impl CollectionRef for MyVec { /// type ItemRef<'a> /// = &'a T where Self: 'a; /// /// covariant_item_ref!(); /// } /// ``` #[macro_export] macro_rules! covariant_item_ref { () => { fn upcast_item_ref<'short, 'long: 'short>(r: Self::ItemRef<'long>) -> Self::ItemRef<'short> where Self: 'long, { r } }; } /// Automatically defines the `CollectionMut::upcast_item_mut` function using the /// covariance of the `ItemMut<'a>` type with regards to `'a`. /// /// ## Example /// /// ``` /// use cc_traits::{Collection, CollectionMut, covariant_item_mut}; /// /// pub struct MyVec(Vec); /// /// impl Collection for MyVec { /// type Item = T; /// } /// /// impl CollectionMut for MyVec { /// type ItemMut<'a> /// = &'a mut T where Self: 'a; /// /// covariant_item_mut!(); /// } /// ``` #[macro_export] macro_rules! covariant_item_mut { () => { fn upcast_item_mut<'short, 'long: 'short>(r: Self::ItemMut<'long>) -> Self::ItemMut<'short> where Self: 'long, { r } }; } /// Automatically defines the `KeyedRef::upcast_item_ref` function using the /// covariance of the `KeyRef<'a>` type with regards to `'a`. /// /// ## Example /// /// ``` /// use cc_traits::{Collection, Keyed, KeyedRef, covariant_key_ref}; /// /// pub struct MyMap(std::collections::HashMap); /// /// impl Collection for MyMap { /// type Item = V; /// } /// /// impl Keyed for MyMap { /// type Key = K; /// } /// /// impl KeyedRef for MyMap { /// type KeyRef<'a> /// = &'a K where Self: 'a; /// /// covariant_key_ref!(); /// } /// ``` #[macro_export] macro_rules! covariant_key_ref { () => { fn upcast_key_ref<'short, 'long: 'short>(r: Self::KeyRef<'long>) -> Self::KeyRef<'short> where Self: 'long, { r } }; } /// Automatically defines the `CollectionMut::upcast_item_mut` function using the /// covariance of the `ItemMut<'a>` type with regards to `'a`. /// /// ## Example /// /// ``` /// use cc_traits::{Collection, CollectionMut, SimpleCollectionMut, covariant_item_mut, simple_collection_mut}; /// /// pub struct MyVec(Vec); /// /// impl Collection for MyVec { /// type Item = T; /// } /// /// impl CollectionMut for MyVec { /// type ItemMut<'a> /// = &'a mut T where Self: 'a; /// /// covariant_item_mut!(); /// } /// /// impl SimpleCollectionMut for MyVec { /// simple_collection_mut!(); /// } /// ``` #[macro_export] macro_rules! simple_collection_mut { () => { fn into_mut<'r>(r: Self::ItemMut<'r>) -> &'r mut Self::Item where Self: 'r, { r } }; } /// Automatically defines the `SimpleCollectionRef::into_ref` function. /// /// ## Example /// /// ``` /// use cc_traits::{Collection, CollectionRef, SimpleCollectionRef, covariant_item_ref, simple_collection_ref}; /// /// pub struct MyVec(Vec); /// /// impl Collection for MyVec { /// type Item = T; /// } /// /// impl CollectionRef for MyVec { /// type ItemRef<'a> /// = &'a T where Self: 'a; /// /// covariant_item_ref!(); /// } /// /// impl SimpleCollectionRef for MyVec { /// simple_collection_ref!(); /// } /// ``` #[macro_export] macro_rules! simple_collection_ref { () => { fn into_ref<'r>(r: Self::ItemRef<'r>) -> &'r Self::Item where Self: 'r, { r } }; } /// Automatically defines the `SimpleKeyedRef::into_ref` function. /// /// ## Example /// /// ``` /// use cc_traits::{Collection, Keyed, KeyedRef, SimpleKeyedRef, covariant_key_ref, simple_keyed_ref}; /// /// pub struct MyMap(std::collections::HashMap); /// /// impl Collection for MyMap { /// type Item = V; /// } /// /// impl Keyed for MyMap { /// type Key = K; /// } /// /// impl KeyedRef for MyMap { /// type KeyRef<'a> /// = &'a K where Self: 'a; /// /// covariant_key_ref!(); /// } /// /// impl SimpleKeyedRef for MyMap { /// simple_keyed_ref!(); /// } /// ``` #[macro_export] macro_rules! simple_keyed_ref { () => { fn into_ref<'r>(r: Self::KeyRef<'r>) -> &'r Self::Key where Self: 'r, { r } }; } cc-traits-2.0.0/src/non_alias.rs000064400000000000000000000110441046102023000146140ustar 00000000000000use crate::*; use core::ops::{Index, IndexMut}; /// Collection with mutable capacity. pub trait CapacityMut: Capacity + Reserve {} impl CapacityMut for C {} /// Immutable stack data structure. /// /// A stack provides two main operations: /// - [`PushBack::push_back`], which adds an element to the collection, and /// - [`PopBack::pop_back`], which removes the most recently added element that was not yet removed. /// /// This trait alias describes the immutables operations derived from the two main operation above: /// - [`Len::len`], returning the number of elements in the stack, and /// - [`Back::back`], returning a reference to the most recently added element that was not yet removed. pub trait Stack: Collection + Len + Back {} impl + Len + Back> Stack for C {} /// Mutable stack data structure. /// /// This trait alias describes the mutables operations on a stack. /// See [`Stack`] for more details. pub trait StackMut: Stack + BackMut + PushBack + PopBack {} impl + BackMut + PushBack + PopBack> StackMut for C {} /// Immutable array data structure (conventionally nammed "Vec"). /// /// A Vec is essentially a [`Stack`] indexable by a `usize`. pub trait Vec: Stack + Index {} impl + Index> Vec for C {} /// Mutable Vec data structure. /// /// This trait alias describes the mutables operations on a Vec. /// See [`Vec`] for more details. pub trait VecMut: Vec + StackMut + IndexMut {} impl + StackMut + IndexMut> VecMut for C {} /// Immutable double-ended queue. /// /// A double-ended queue (abbreviated to deque) is a generalization of a stack in which /// elements can be added and removed from both ends. /// Such a data structure provides two additional operations compared to regular stacks: /// - [`PushFront::push_front`], which adds an element to the front of collection, and /// - [`PopFront::pop_front`], which removes the front element of the collection. /// /// This trait alias describes the immutables operations available on deques. pub trait Deque: Stack + Front {} impl + Front> Deque for C {} /// Mutable double-ended queue. /// /// This trait alias describes the mutables operations on a deque. /// See [`Deque`] for more details. pub trait DequeMut: StackMut + FrontMut + PushFront + PopFront {} impl + FrontMut + PushFront + PopFront> DequeMut for C {} /// Immutable indexable deque. /// /// See [`Deque`] and [`Vec`] for more details. pub trait VecDeque: Deque + Vec {} impl + Vec> VecDeque for C {} /// Mutable indexable deque. /// /// See [`VecDeque`], [`DequeMut`] and [`VecMut`] for more details. pub trait VecDequeMut: VecDeque + DequeMut + VecMut {} impl + DequeMut + VecMut> VecDequeMut for C {} /// Imutable set data structure. /// /// A set is an unordered collection storing at most one single copy of each element. pub trait Set: Collection + Len + for<'a> Get<&'a T> {} impl + Len + for<'a> Get<&'a T>> Set for C {} /// Mutable set data structure. pub trait SetMut: Set + Insert + for<'a> Remove<&'a T> {} impl + Insert + for<'a> Remove<&'a T>> SetMut for C {} /// Imutable map data structure. /// /// A map is an unordered collection storing key-value pairs, indexed by the key. pub trait Map: Keyed + Len + for<'a> Get<&'a K> + for<'a> GetKeyValue<&'a K> { } impl + Len + for<'a> Get<&'a K> + for<'a> GetKeyValue<&'a K>> Map for C { } /// Mutable map data structure. pub trait MapMut: Map + for<'a> GetMut<&'a K> + MapInsert> + for<'a> Remove<&'a K> { } impl< K, V, C: Map + for<'a> GetMut<&'a K> + MapInsert> + for<'a> Remove<&'a K>, > MapMut for C { } /// Imutable slab data structure. /// /// A slab is a linear collection storing each element at a given index. /// The index of the element is allocated and returned upon insertion. pub trait Slab: Collection + Len + Get {} impl + Len + Get> Slab for C {} /// Mutable slab data structure. pub trait SlabMut: Slab + GetMut + Insert + Remove {} impl + GetMut + Insert + Remove> SlabMut for C {}