├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── Readme.md ├── benches ├── clone.rs ├── drain.rs ├── element_clone.rs ├── insert.rs ├── iter.rs ├── push.rs ├── raw_parts.rs ├── remove.rs ├── swap_remove.rs └── utils.rs ├── doc.bat ├── src ├── any_value │ ├── lazy_clone.rs │ ├── mod.rs │ ├── raw.rs │ └── wrapper.rs ├── any_vec.rs ├── any_vec_ptr.rs ├── any_vec_raw.rs ├── any_vec_typed.rs ├── clone_type.rs ├── element.rs ├── iter.rs ├── lib.rs ├── mem │ ├── empty.rs │ ├── heap.rs │ ├── mod.rs │ ├── stack.rs │ └── stack_n.rs └── ops │ ├── drain.rs │ ├── iter.rs │ ├── mod.rs │ ├── pop.rs │ ├── remove.rs │ ├── splice.rs │ ├── swap_remove.rs │ └── temp.rs └── tests ├── any_value.rs ├── any_vec.rs ├── any_vec_element.rs ├── any_vec_fuzzy.rs ├── any_vec_send_sync.rs ├── any_vec_traits.rs └── any_vec_typed.rs /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: [ main, dev ] 7 | pull_request: 8 | branches: [ main, dev ] 9 | 10 | env: 11 | CARGO_TERM_COLOR: always 12 | 13 | jobs: 14 | build: 15 | name: Build 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | - run: RUSTFLAGS="--deny warnings" cargo build 20 | - run: RUSTFLAGS="--deny warnings" cargo build --all-features 21 | - run: RUSTFLAGS="--deny warnings" cargo build --no-default-features 22 | 23 | tests: 24 | name: Run careful tests 25 | runs-on: ubuntu-latest 26 | steps: 27 | - uses: dtolnay/rust-toolchain@nightly 28 | - uses: taiki-e/install-action@v2 29 | with: 30 | tool: cargo-careful 31 | - uses: actions/checkout@v4 32 | - run: RUSTFLAGS="--deny warnings" cargo +nightly careful test 33 | - run: RUSTFLAGS="--deny warnings" cargo +nightly careful test --all-features 34 | 35 | miri: 36 | name: Miri tests 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: dtolnay/rust-toolchain@nightly 40 | with: 41 | toolchain: nightly 42 | components: miri 43 | - uses: actions/checkout@v4 44 | - run: RUSTFLAGS="--deny warnings" cargo +nightly miri test 45 | - run: RUSTFLAGS="--deny warnings" cargo +nightly miri test --all-features 46 | 47 | benches: 48 | name: Build benchmarks 49 | runs-on: ubuntu-latest 50 | steps: 51 | - uses: actions/checkout@v4 52 | - run: RUSTFLAGS="--deny warnings" cargo build --benches 53 | 54 | doc: 55 | name: Build doc 56 | runs-on: ubuntu-latest 57 | steps: 58 | - uses: actions/checkout@v4 59 | - run: RUSTDOCFLAGS="--deny warnings" cargo doc --lib --all-features 60 | 61 | docrs: 62 | name: Build docrs 63 | runs-on: ubuntu-latest 64 | steps: 65 | - uses: dtolnay/rust-toolchain@nightly 66 | - uses: actions/checkout@v4 67 | - run: 68 | RUSTFLAGS="--deny warnings" 69 | RUSTDOCFLAGS="--cfg docsrs" 70 | cargo +nightly doc --lib --all-features -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /.vscode 3 | /target 4 | /Cargo.lock -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 0.14.0 4 | ### Added 5 | - Now library `no_std` friendly. 6 | 7 | ### Removed 8 | - Helpers `any_value::move_out`, `any_value::move_out_w_size` removed as redundant. 9 | 10 | ## 0.13.0 11 | ### Added 12 | - `AnyVec` now can work with `AnyValueSizeless`. 13 | - `any_value::traits` prelude. 14 | 15 | ### Optimized 16 | - `AnyValue`- family downcast now use provided type for compile-time optimization, 17 | instead of potentially unknown underlying type (which disabled optimization technique). 18 | 19 | ### Breaking Changes 20 | - `AnyValue` + `AnyValueUnknown` traits broken down into: 21 | - `AnyValueUnknown` -> `AnyValueTypeless`. 22 | - Introduced `AnyValueSizeless` - `AnyValue` that does know size and type. 23 | - Added `any_value::move_out`, `any_value::move_out_w_size` helpers. 24 | - Changed AnyValueRaw non-owning wrappers names: 25 | - `AnyValueRawUnknown` -> `AnyValueTypelessRaw`. 26 | - Introduced `AnyValueSizelessRaw`. 27 | 28 | ## 0.12.0 29 | ### Added 30 | - `element::ElementReference` trait, implemented both for `ElementRef`, `ElementMut` and &`Element`. 31 | 32 | ### Changed 33 | - Documentation clarification. 34 | 35 | ### Fixed 36 | - Minor changes, to eliminate warnings with new compiler version. 37 | 38 | ## 0.11.0 39 | ### Added 40 | #### `AnyValueUnknown` 41 | - `AnyValue` split into `AnyValueUnknown` + `AnyValue`. 42 | - `AnyValueMut` split into `AnyValueMutUnknown` + `AnyValueMut`. 43 | - `AnyVec::push_unchecked(AnyValueUnknown)`. 44 | - `AnyVec::insert_unchecked(usize, AnyValueUnknown)`. 45 | - `AnyValueRawUnknown`. 46 | - `mem::Empty`. 47 | 48 | #### Raw parts 49 | - `AnyVec::into_raw_parts` / `AnyVec::from_raw_parts` / `RawParts`. 50 | - `MemRawParts`. 51 | - `AnyVec::element_drop`. 52 | - `AnyVec::element_clone`. 53 | 54 | ### Changed 55 | - `HeapMem` implements `MemRawParts`. 56 | 57 | ### Fixed 58 | - `AnyVec::splice` now check types. 59 | 60 | ## 0.10.0 61 | ### Changed 62 | - `AnyValue::bytes()->*const u8` and `AnyValue::size()->usize` replaced with 63 | `AnyValue::as_bytes()->&[u8]`. Same for `AnyValueMut`. 64 | - `AnyValueWrapper` now `AnyValueMut`. 65 | - `AnyValueRaw` now `AnyValueMut`. 66 | - `AnyValue::as_bytes()` now return `&[u8]`. 67 | 68 | ### Added 69 | - `Debug` implemented for `AnyVec`, `AnyVecTyped`. 70 | - `AnyValueMut::swap()` added. 71 | - `AnyVec`/`AnyVecTyped` `::set_len()` added. 72 | - `AnyVec::as_bytes_mut` added. 73 | - `AnyVec::spare_bytes_mut` added. 74 | - `AnyVecTyped::spare_capacity_mut` added. 75 | - `mem::StackN` added. 76 | 77 | ### Fixed 78 | - Stacked Borrow friendly now. 79 | - `mem::Stack` capacity fixed. 80 | 81 | ## 0.9.1 82 | ### Changed 83 | - `impls` dependency dropped. 84 | - minimum rust version 1.61 requirement dropped. 85 | 86 | ### Fixed 87 | - Empty `HeapMem` used wrong aligned dangling pointer. Fixed. 88 | - `AnyVec` Send/Sync -ability now MemBuilder dependent. 89 | - Fixed UB with `StackMem::as_ptr`. 90 | 91 | ## 0.9.0 92 | ### Added 93 | - `MemBuilder` + `Mem` = Allocator. 94 | - `Stack` Mem/Allocator. 95 | - `AnyVec::clone_empty_in` 96 | - `reserve` 97 | - `reserve_exact` 98 | - `shrink_to_fit` 99 | - `shrink_to` 100 | - `pop` 101 | - `is_empty` 102 | 103 | ## 0.8.0 104 | ### Added 105 | - Added `AnyVec::at` - ergonomic version of `get`. 106 | - `AnyVecRef` now cloneable. 107 | - `ElementRef` now cloneable. 108 | - non-consuming iterators now cloneable. 109 | - `AnyVec::drain`. 110 | - `AnyVecTyped::drain`. 111 | - `AnyVec::slice`. 112 | - `AnyVecTyped::slice`. 113 | - `AnyVec` iterators. 114 | - `AnyVec::clone_empty`, to construct `AnyVec` of the same type. 115 | - `IntoIterator` implemented. 116 | 117 | ### Changed 118 | - `crate::refs` being implementation details, hided. 119 | 120 | ## 0.7.0 121 | ### Added 122 | - `AnyValueClonable` and `LazyClone` added. 123 | - `AnyVec` getters added. 124 | - `AnyValueMut` added. All remove operations now return `AnyValueMut` + `AnyValueClonable`. 125 | 126 | ### Changed 127 | - `any_value::AnyValue::downcast` now return `Option`. 128 | - `traits::EmptyTrait` renamed to `traits::None`. 129 | - `AnyValue` interface changed. 130 | 131 | ### Optimized 132 | - Performance of all remove operations slightly increased. 133 | 134 | ## 0.6.0 135 | ### Added 136 | - `AnyVec` now can be Sync, Send, Clone. 137 | 138 | ### Changed 139 | - `any_value::AnyValueTemp` moved to `ops::AnyValueTemp` 140 | - `any_vec::Unknown` -> `any_vec::any_value::Unknown` 141 | 142 | ### Fixed 143 | - `AnyVec::insert` now check type again. 144 | - `AnyValueWrapper::downcast` UB fx. 145 | 146 | ## 0.5.0 147 | ### Changed 148 | - Major type erased API change. All `AnyVec` operations now safe. 149 | 150 | ### Added 151 | - Introduced `any_value` family, which provide type erased safe operations. 152 | 153 | ## 0.4.0 154 | ### Added 155 | - `AnyVec::remove` 156 | - `AnyVec::remove_into` 157 | - `AnyVecTyped::remove` 158 | - `AnyVec::insert_uninit` 159 | - `AnyVecTyped::insert` 160 | 161 | ## 0.3.0 162 | ### Changed 163 | - Major API change. All typed operations placed into `AnyVecTyped`. 164 | 165 | ## 0.2.2 166 | ### Optimized 167 | - `swap_remove` further optimized. 168 | - `swap_take` on par with `Vec::swap_remove` now. 169 | 170 | ### Fixed 171 | - Fixed UB in `swap_remove` that happens if element destructor panics. 172 | 173 | ## 0.2.1 174 | ### Optimized 175 | - All remove operations become faster. Destructor function is not 176 | called now, if type does not need drop. 177 | 178 | ### Changed 179 | - `AnyVec` is now `Option`-friendly. (by @SabrinaJewson) 180 | - It is now possible for `AnyVec` to have zero capacity. 181 | - `AnyVec::new()` now starts with zero capacity. 182 | 183 | ### Fixed 184 | - Fixed UB with construction with ZST. (by @SabrinaJewson) 185 | - Fixed UB in `clear()` that happens if dropping panics. (by @SabrinaJewson) 186 | - as_mut_slice family now take `&mut self` instead of `&self`. (by @SabrinaJewson) 187 | 188 | ## 0.2.0 189 | ### Added 190 | - `AnyVec::with_capacity` added. 191 | - push benchmark added. 192 | ### Changed 193 | - `AnyVec::element_size` removed, `AnyVec::element_layout` added instead. 194 | ### Optimized 195 | - `push` family performance improved. 196 | ### Fixed 197 | - Fixed Zero-Size-Type memory allocation. 198 | 199 | ## 0.1.0 200 | ### Added 201 | - Initial working implementation with `push`, `swap_remove` and `as_slice`. -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "any_vec" 3 | authors = ["Andrey Diduh "] 4 | license = "MIT OR Apache-2.0" 5 | version = "0.14.0" 6 | edition = "2021" 7 | description = "Type erased vector. Most operations can be done without type knowledge. Mostly zero overhead." 8 | repository = "https://github.com/tower120/any_vec" 9 | keywords = ["vec", "any", "container", "type-erasure", "no_std"] 10 | categories = ["data-structures", "no-std", "no-std::no-alloc"] 11 | exclude = [".github"] 12 | 13 | [features] 14 | default = ["alloc"] 15 | # Include alloc crate. This allows using mem::Heap. 16 | alloc = [] 17 | 18 | [package.metadata.docs.rs] 19 | features = [] 20 | rustdoc-args = ["--cfg", "docsrs"] 21 | 22 | [dependencies] 23 | 24 | [dev-dependencies] 25 | itertools = "0.12.1" 26 | criterion = "0.5.1" 27 | rand = "0.8.5" 28 | impls = "1.0.3" 29 | 30 | [[bench]] 31 | name = "insert" 32 | harness = false 33 | 34 | [[bench]] 35 | name = "push" 36 | harness = false 37 | 38 | [[bench]] 39 | name = "remove" 40 | harness = false 41 | 42 | [[bench]] 43 | name = "swap_remove" 44 | harness = false 45 | 46 | [[bench]] 47 | name = "drain" 48 | harness = false 49 | 50 | [[bench]] 51 | name = "iter" 52 | harness = false 53 | 54 | [[bench]] 55 | name = "element_clone" 56 | harness = false 57 | 58 | [[bench]] 59 | name = "clone" 60 | harness = false 61 | 62 | [[bench]] 63 | name = "raw_parts" 64 | harness = false -------------------------------------------------------------------------------- /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 2022 Andrey Diduh 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. -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Andrey Diduh 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. -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | [![crates.io](https://img.shields.io/crates/v/any_vec.svg)](https://crates.io/crates/any_vec) 2 | [![license](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue?style=flat-square)](#license) 3 | [![Docs](https://docs.rs/any_vec/badge.svg)](https://docs.rs/any_vec) 4 | [![CI](https://github.com/tower120/any_vec/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/tower120/any_vec/actions/workflows/ci.yml) 5 | 6 | Type erased vector. All elements have the same type. 7 | 8 | Designed to be type-erased as far as possible - most operations do not know a concrete type. 9 | For example, you can move or copy/clone items from one type-erased vector to another, without ever knowing 10 | their type. Or you can erase, swap, move, copy elements inside type-erased vector, etc... 11 | 12 | Only type-erased destruct and clone operations have additional overhead of indirect call. 13 | 14 | # Usage 15 | 16 | ```rust 17 | let mut vec: AnyVec = AnyVec::new::(); 18 | { 19 | // Typed operations. 20 | let mut vec = vec.downcast_mut::().unwrap(); 21 | vec.push(String::from("0")); 22 | vec.push(String::from("1")); 23 | vec.push(String::from("2")); 24 | } 25 | 26 | let mut other_vec: AnyVec = AnyVec::new::(); 27 | // Fully type erased element move from one vec to another 28 | // without intermediate mem-copies. 29 | let element = vec.swap_remove(0); 30 | other_vec.push(element); 31 | 32 | // Output 2 1 33 | for s in vec.downcast_ref::().unwrap(){ 34 | println!("{}", s); 35 | } 36 | ``` 37 | 38 | See [documentation](https://docs.rs/any_vec) for more. 39 | 40 | ## Send, Sync, Clone 41 | 42 | You can make `AnyVec` `Send`able, `Sync`able, `Clone`able: 43 | 44 | ```rust 45 | use any_vec::AnyVec; 46 | use any_vec::traits::*; 47 | let v1: AnyVec = AnyVec::new::(); 48 | let v2 = v1.clone(); 49 | ``` 50 | This constraints will be applied compiletime to element type: 51 | ```rust 52 | // This will fail to compile. 53 | let v1: AnyVec = AnyVec::new::>(); 54 | ``` 55 | 56 | Non-Clonable `AnyVec` has a size 1 pointer smaller. 57 | 58 | ## LazyClone 59 | 60 | Whenever possible, `any_vec` type erased elements can be lazily cloned: 61 | 62 | ```rust 63 | let mut v1: AnyVec = AnyVec::new::(); 64 | v1.push(AnyValueWrapper::new(String::from("0"))); 65 | 66 | let mut v2: AnyVec = AnyVec::new::(); 67 | let e = v1.swap_remove(0); 68 | v2.push(e.lazy_clone()); 69 | v2.push(e.lazy_clone()); 70 | ``` 71 | 72 | ## MemBuilder 73 | 74 | `MemBuilder` + `Mem` works like `Allocator` for `AnyVec`. But unlike allocator, 75 | `Mem` container-specialized design allows to perform more optimizations. For example, 76 | it is possible to make stack-allocated `FixedAnyVec` and small-buffer-optimized(SBO) `SmallAnyVec` 77 | from `AnyVec` by just changing `MemBuilder`: 78 | 79 | ```rust 80 | type FixedAnyVec = AnyVec>; 81 | let mut any_vec: FixedAnyVec = AnyVec::new::(); 82 | 83 | // This will be on stack, without any allocations. 84 | any_vec.push(AnyValueWrapper::new(String::from("0"))) 85 | ``` 86 | 87 | With help of `clone_empty_in` you can use stack allocated, or SBO `AnyVec` 88 | as fast intermediate storage for values of unknown type: 89 | 90 | ```rust 91 | fn self_push_first_element(any_vec: &mut AnyVec){ 92 | let mut tmp = any_vec.clone_empty_in(StackN::<1, 256>); 93 | tmp.push(any_vec.at(0).lazy_clone()); 94 | any_vec.push(tmp.pop().unwrap()); 95 | } 96 | ``` 97 | 98 | `MemBuilder` interface, being stateful, allow to make `Mem`, which can work with complex custom allocators. 99 | 100 | ## no_std + no_alloc 101 | 102 | This is `no_std` library, which can work without `alloc` too. 103 | 104 | ### Changelog 105 | 106 | See [CHANGELOG.md](CHANGELOG.md) for version differences. 107 | 108 | # Known alternatives 109 | 110 | * [type_erased_vec](https://crates.io/crates/type_erased_vec). Allow to store `Vec` in type erased way, 111 | but you need to perform operations, you need to "cast" to concrete type first. 112 | * [untyped_vec](https://crates.io/crates/untyped_vec). Some operations like `len`, `capacity` performed without type 113 | knowledge; but the rest - require concrete type. 114 | -------------------------------------------------------------------------------- /benches/clone.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use std::time::{Duration, Instant}; 4 | use criterion::{criterion_group, criterion_main, Criterion, black_box}; 5 | use any_vec::AnyVec; 6 | use any_vec::traits::Cloneable; 7 | use crate::utils::bench_custom; 8 | 9 | const SIZE: usize = 10000; 10 | 11 | // usize is worst case scenario, since it is copyable. 12 | type Element = usize; 13 | static VALUE: Element = 100; 14 | 15 | fn vec_clone() -> Duration { 16 | let mut vec = Vec::new(); 17 | for _ in 0..SIZE{ 18 | vec.push(VALUE.clone()); 19 | } 20 | 21 | let start = Instant::now(); 22 | let other = vec.clone(); 23 | black_box(other); 24 | start.elapsed() 25 | } 26 | 27 | 28 | fn any_vec_clone() -> Duration { 29 | let mut any_vec: AnyVec = AnyVec::new::(); 30 | for _ in 0..SIZE{ 31 | any_vec.downcast_mut::().unwrap() 32 | .push(VALUE.clone()); 33 | } 34 | 35 | let start = Instant::now(); 36 | let other = any_vec.clone(); 37 | black_box(other); 38 | start.elapsed() 39 | } 40 | 41 | 42 | pub fn bench_clone(c: &mut Criterion) { 43 | bench_custom(c, "Vec clone", vec_clone); 44 | bench_custom(c, "AnyVec clone", any_vec_clone); 45 | } 46 | 47 | criterion_group!(benches, bench_clone); 48 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/drain.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use std::time::{Duration, Instant}; 4 | use criterion::{criterion_group, criterion_main, Criterion}; 5 | use any_vec::AnyVec; 6 | use crate::utils::bench_custom; 7 | 8 | // TODO: drain in both reverse and front. 9 | 10 | const SIZE: usize = 10000; 11 | const DRAIN_SIZE: usize = 40; 12 | 13 | type Element = String; 14 | static VALUE: Element = String::new(); 15 | 16 | fn vec_drain() -> Duration { 17 | let mut vec = Vec::new(); 18 | for _ in 0..SIZE{ 19 | vec.push(VALUE.clone()); 20 | } 21 | 22 | let start = Instant::now(); 23 | while vec.len() >= DRAIN_SIZE { 24 | vec.drain(0..DRAIN_SIZE); 25 | } 26 | start.elapsed() 27 | } 28 | 29 | fn any_vec_drain() -> Duration { 30 | let mut any_vec: AnyVec = AnyVec::new::(); 31 | for _ in 0..SIZE{ 32 | any_vec.downcast_mut::().unwrap() 33 | .push(VALUE.clone()); 34 | } 35 | 36 | let start = Instant::now(); 37 | while any_vec.len() >= DRAIN_SIZE { 38 | any_vec.drain(0..DRAIN_SIZE); 39 | } 40 | start.elapsed() 41 | } 42 | 43 | fn any_vec_typed_drain() -> Duration { 44 | let mut any_vec: AnyVec = AnyVec::new::(); 45 | for _ in 0..SIZE{ 46 | any_vec.downcast_mut::().unwrap() 47 | .push(VALUE.clone()); 48 | } 49 | 50 | let start = Instant::now(); 51 | while any_vec.len() >= DRAIN_SIZE { 52 | let _ = any_vec.downcast_mut::().unwrap() 53 | .drain(0..DRAIN_SIZE); 54 | } 55 | start.elapsed() 56 | } 57 | 58 | pub fn bench_drain(c: &mut Criterion) { 59 | bench_custom(c, "Vec drain", vec_drain); 60 | bench_custom(c, "AnyVec drain", any_vec_drain); 61 | bench_custom(c, "AnyVecTyped drain", any_vec_typed_drain); 62 | } 63 | 64 | criterion_group!(benches, bench_drain); 65 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/element_clone.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use std::time::{Duration, Instant}; 4 | use criterion::{criterion_group, criterion_main, Criterion, black_box}; 5 | use any_vec::any_value::{AnyValueCloneable, AnyValueSizeless}; 6 | use any_vec::AnyVec; 7 | use any_vec::traits::Cloneable; 8 | use crate::utils::bench_custom; 9 | 10 | const SIZE: usize = 10000; 11 | 12 | // usize is worst case scenario, since it is copyable. 13 | type Element = usize; 14 | static VALUE: Element = 100; 15 | 16 | fn vec_iter_clone() -> Duration { 17 | let mut vec = Vec::new(); 18 | for _ in 0..SIZE{ 19 | vec.push(VALUE.clone()); 20 | } 21 | 22 | let start = Instant::now(); 23 | let mut sum = 0; 24 | for i in &vec{ 25 | sum += i.clone(); 26 | } 27 | black_box(sum); 28 | start.elapsed() 29 | } 30 | 31 | fn any_vec_iter() -> Duration { 32 | let mut any_vec: AnyVec = AnyVec::new::(); 33 | for _ in 0..SIZE{ 34 | any_vec.downcast_mut::().unwrap() 35 | .push(VALUE.clone()); 36 | } 37 | 38 | let start = Instant::now(); 39 | let mut sum = 0; 40 | for i in &any_vec{ 41 | sum += unsafe{i.downcast_ref_unchecked::()}; 42 | } 43 | black_box(sum); 44 | start.elapsed() 45 | } 46 | 47 | fn any_vec_iter_clone() -> Duration { 48 | let mut any_vec: AnyVec = AnyVec::new::(); 49 | for _ in 0..SIZE{ 50 | any_vec.downcast_mut::().unwrap() 51 | .push(VALUE.clone()); 52 | } 53 | 54 | let start = Instant::now(); 55 | let mut sum = 0; 56 | for i in &any_vec{ 57 | sum += unsafe{i.lazy_clone().downcast_ref_unchecked::()}; 58 | } 59 | black_box(sum); 60 | start.elapsed() 61 | } 62 | 63 | fn any_vec_typed_iter_clone() -> Duration { 64 | let mut any_vec: AnyVec = AnyVec::new::(); 65 | let mut vec = any_vec.downcast_mut::().unwrap(); 66 | for _ in 0..SIZE{ 67 | vec.push(VALUE.clone()); 68 | } 69 | 70 | let start = Instant::now(); 71 | let mut sum = 0; 72 | for i in vec{ 73 | sum += i.clone(); 74 | } 75 | black_box(sum); 76 | start.elapsed() 77 | } 78 | 79 | 80 | pub fn bench_element_clone(c: &mut Criterion) { 81 | bench_custom(c, "Vec iter clone", vec_iter_clone); 82 | bench_custom(c, "AnyVec iter", any_vec_iter); 83 | bench_custom(c, "AnyVec iter clone", any_vec_iter_clone); 84 | bench_custom(c, "AnyVecTyped iter clone", any_vec_typed_iter_clone); 85 | } 86 | 87 | criterion_group!(benches, bench_element_clone); 88 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/insert.rs: -------------------------------------------------------------------------------- 1 | use std::any::TypeId; 2 | use std::mem::size_of; 3 | use std::ptr::NonNull; 4 | use criterion::{criterion_group, criterion_main, Criterion}; 5 | use any_vec::any_value::{AnyValueRaw}; 6 | use any_vec::AnyVec; 7 | 8 | const SIZE: usize = 10000; 9 | 10 | fn vec_insert_front(){ 11 | let mut vec = Vec::new(); 12 | for i in 0..SIZE{ 13 | vec.insert(0, i); 14 | } 15 | } 16 | 17 | fn any_vec_insert_front(){ 18 | let mut any_vec: AnyVec = AnyVec::new::(); 19 | for i in 0..SIZE{ 20 | let raw_value = unsafe{ 21 | AnyValueRaw::new( 22 | NonNull::from(&i).cast::(), 23 | size_of::(), 24 | TypeId::of::() 25 | )}; 26 | any_vec.insert(0, raw_value); 27 | } 28 | } 29 | 30 | fn any_vec_typed_insert_front(){ 31 | let mut any_vec: AnyVec = AnyVec::new::(); 32 | for i in 0..SIZE{ 33 | let mut vec = any_vec.downcast_mut::().unwrap(); 34 | vec.insert(0, i); 35 | } 36 | } 37 | 38 | fn vec_insert_back(){ 39 | let mut vec = Vec::new(); 40 | for i in 0..SIZE{ 41 | vec.insert(i, i); 42 | } 43 | } 44 | 45 | fn any_vec_insert_back(){ 46 | let mut any_vec: AnyVec = AnyVec::new::(); 47 | for i in 0..SIZE{ 48 | let raw_value = unsafe{ 49 | AnyValueRaw::new( 50 | NonNull::from(&i).cast::(), 51 | size_of::(), 52 | TypeId::of::() 53 | )}; 54 | any_vec.insert(i, raw_value); 55 | } 56 | } 57 | 58 | fn any_vec_typed_insert_back(){ 59 | let mut any_vec: AnyVec = AnyVec::new::(); 60 | for i in 0..SIZE{ 61 | let mut vec = any_vec.downcast_mut::().unwrap(); 62 | vec.insert(i, i); 63 | } 64 | } 65 | 66 | pub fn bench_push(c: &mut Criterion) { 67 | c.bench_function("Vec insert front", |b|b.iter(||vec_insert_front())); 68 | c.bench_function("AnyVec insert front", |b|b.iter(||any_vec_insert_front())); 69 | c.bench_function("AnyVecTyped insert front", |b|b.iter(||any_vec_typed_insert_front())); 70 | c.bench_function("Vec insert back", |b|b.iter(||vec_insert_back())); 71 | c.bench_function("AnyVec insert back", |b|b.iter(||any_vec_insert_back())); 72 | c.bench_function("AnyVecTyped insert back", |b|b.iter(||any_vec_typed_insert_back())); 73 | 74 | } 75 | 76 | criterion_group!(benches, bench_push); 77 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/iter.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use std::time::{Duration, Instant}; 4 | use criterion::{black_box, criterion_group, criterion_main, Criterion}; 5 | use any_vec::AnyVec; 6 | use crate::utils::bench_custom; 7 | 8 | const SIZE: usize = 10000; 9 | 10 | fn vec_iter() -> Duration { 11 | let mut vec = Vec::new(); 12 | for i in 0..SIZE{ 13 | vec.push(i); 14 | } 15 | 16 | let start = Instant::now(); 17 | let sum: usize = vec.iter().sum(); 18 | black_box(sum); 19 | start.elapsed() 20 | } 21 | 22 | fn any_vec_typed_iter() -> Duration { 23 | let mut any_vec: AnyVec = AnyVec::new::(); 24 | let mut any_vec_typed = any_vec.downcast_mut::().unwrap(); 25 | for i in 0..SIZE{ 26 | any_vec_typed.push(i); 27 | } 28 | 29 | let start = Instant::now(); 30 | let sum: usize = any_vec_typed.iter().sum(); 31 | black_box(sum); 32 | start.elapsed() 33 | } 34 | 35 | fn any_vec_iter() -> Duration { 36 | let mut any_vec: AnyVec = AnyVec::new::(); 37 | for i in 0..SIZE{ 38 | any_vec.downcast_mut::().unwrap() 39 | .push(i); 40 | } 41 | 42 | let start = Instant::now(); 43 | let sum: usize = any_vec.iter() 44 | //.map(|e|e.downcast_ref().unwrap()) 45 | .map(|e|unsafe{e.downcast_ref_unchecked()}) 46 | .sum(); 47 | black_box(sum); 48 | start.elapsed() 49 | } 50 | 51 | pub fn bench_iter(c: &mut Criterion) { 52 | bench_custom(c, "Vec iter", vec_iter); 53 | bench_custom(c, "AnyVecTyped iter", any_vec_typed_iter); 54 | bench_custom(c, "AnyVec iter", any_vec_iter); 55 | } 56 | 57 | criterion_group!(benches, bench_iter); 58 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/push.rs: -------------------------------------------------------------------------------- 1 | use std::any::TypeId; 2 | use std::mem::size_of; 3 | use std::ptr::NonNull; 4 | use criterion::{criterion_group, criterion_main, Criterion}; 5 | use any_vec::any_value::{AnyValueSizelessRaw, AnyValueRaw}; 6 | use any_vec::AnyVec; 7 | 8 | const SIZE: usize = 10000; 9 | 10 | type Element = (usize, usize); 11 | #[inline] 12 | fn make_element(i: usize) -> Element{ 13 | (i,i) 14 | } 15 | 16 | fn vec_push(size: usize){ 17 | let mut vec = Vec::new(); 18 | for i in 0..size{ 19 | vec.push(make_element(i)); 20 | } 21 | } 22 | 23 | fn any_vec_push(size: usize){ 24 | let mut any_vec: AnyVec = AnyVec::new::(); 25 | let mut vec = any_vec.downcast_mut::().unwrap(); 26 | for i in 0..size{ 27 | vec.push(make_element(i)); 28 | } 29 | } 30 | 31 | fn any_vec_push_untyped(size: usize){ 32 | let mut any_vec: AnyVec = AnyVec::new::(); 33 | for i in 0..size{ 34 | let value = make_element(i); 35 | let raw_value = unsafe{ 36 | AnyValueRaw::new( 37 | NonNull::from(&value).cast::(), 38 | size_of::(), 39 | TypeId::of::() 40 | )}; 41 | any_vec.push(raw_value); 42 | } 43 | } 44 | 45 | fn any_vec_push_untyped_unchecked(size: usize){ 46 | let mut any_vec: AnyVec = AnyVec::new::(); 47 | for i in 0..size{ 48 | let value = make_element(i); 49 | let raw_value = unsafe{ 50 | AnyValueSizelessRaw::new( 51 | NonNull::from(&value).cast::(), 52 | )}; 53 | unsafe{ 54 | any_vec.push_unchecked(raw_value); 55 | } 56 | } 57 | } 58 | 59 | pub fn bench_push(c: &mut Criterion) { 60 | use criterion::black_box; 61 | 62 | c.bench_function("Vec push", |b|b.iter(||vec_push(black_box(SIZE)))); 63 | c.bench_function("AnyVec push", |b|b.iter(||any_vec_push(black_box(SIZE)))); 64 | c.bench_function("AnyVec push untyped unchecked", |b|b.iter(||any_vec_push_untyped_unchecked(black_box(SIZE)))); 65 | c.bench_function("AnyVec push untyped", |b|b.iter(||any_vec_push_untyped(black_box(SIZE)))); 66 | } 67 | 68 | criterion_group!(benches, bench_push); 69 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/raw_parts.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | use criterion::{criterion_group, criterion_main, Criterion}; 3 | use any_vec::AnyVec; 4 | 5 | const SIZE: usize = 10000; 6 | 7 | type Element = (usize, usize, usize, usize); 8 | static VALUE: Element = (0,0,0,0); 9 | 10 | fn vec_push(){ 11 | let mut vec = Vec::new(); 12 | for _ in 0..SIZE{ 13 | vec.push(VALUE.clone()); 14 | } 15 | } 16 | 17 | fn vec_from_raw_parts_push(){ 18 | let mut vec = Vec::new(); 19 | for _ in 0..SIZE{ 20 | let mut vec = unsafe{Vec::from_raw_parts( 21 | vec.as_mut_ptr(), 22 | vec.len(), 23 | vec.capacity() 24 | )}; 25 | vec.push(VALUE.clone()); 26 | mem::forget(vec); 27 | } 28 | } 29 | 30 | fn any_vec_push(){ 31 | let mut any_vec: AnyVec = AnyVec::new::(); 32 | for _ in 0..SIZE{ 33 | let mut vec = any_vec.downcast_mut::().unwrap(); 34 | vec.push(VALUE.clone()); 35 | } 36 | } 37 | 38 | fn any_vec_from_parts_push(){ 39 | let any_vec: AnyVec = AnyVec::new::(); 40 | let raw_parts = any_vec.into_raw_parts(); 41 | 42 | for _ in 0..SIZE{ 43 | let mut any_vec: AnyVec = unsafe{AnyVec::from_raw_parts(raw_parts.clone())}; 44 | let mut vec = any_vec.downcast_mut::().unwrap(); 45 | vec.push(VALUE.clone()); 46 | mem::forget(any_vec); 47 | } 48 | 49 | let any_vec: AnyVec = unsafe{AnyVec::from_raw_parts(raw_parts)}; 50 | drop(any_vec) 51 | } 52 | 53 | pub fn bench_push(c: &mut Criterion) { 54 | c.bench_function("Vec push", |b|b.iter(||vec_push())); 55 | c.bench_function("Vec from_raw_parts push", |b|b.iter(||vec_from_raw_parts_push())); 56 | c.bench_function("AnyVec push", |b|b.iter(||any_vec_push())); 57 | c.bench_function("AnyVec from_raw_parts push", |b|b.iter(||any_vec_from_parts_push())); 58 | } 59 | 60 | criterion_group!(benches, bench_push); 61 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/remove.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use std::time::{Duration, Instant}; 4 | use criterion::{criterion_group, criterion_main, Criterion}; 5 | use any_vec::AnyVec; 6 | use crate::utils::bench_custom; 7 | 8 | const SIZE: usize = 10000; 9 | 10 | type Element = String; 11 | static VALUE: Element = String::new(); 12 | 13 | trait Impl{ 14 | fn index(i:usize) -> usize; 15 | 16 | fn vec_remove() -> Duration { 17 | let mut vec = Vec::new(); 18 | for _ in 0..SIZE{ 19 | vec.push(VALUE.clone()); 20 | } 21 | 22 | let start = Instant::now(); 23 | for i in (0..SIZE).rev(){ 24 | vec.remove(Self::index(i)); 25 | } 26 | start.elapsed() 27 | } 28 | 29 | fn any_vec_remove() -> Duration { 30 | let mut any_vec: AnyVec = AnyVec::new::(); 31 | for _ in 0..SIZE{ 32 | any_vec.downcast_mut::().unwrap() 33 | .push(VALUE.clone()); 34 | } 35 | 36 | let start = Instant::now(); 37 | for i in (0..SIZE).rev(){ 38 | any_vec.remove(Self::index(i)); 39 | } 40 | start.elapsed() 41 | } 42 | 43 | fn any_vec_typed_remove() -> Duration { 44 | let mut any_vec: AnyVec = AnyVec::new::(); 45 | for _ in 0..SIZE{ 46 | any_vec.downcast_mut::().unwrap() 47 | .push(VALUE.clone()); 48 | } 49 | 50 | let start = Instant::now(); 51 | for i in (0..SIZE).rev(){ 52 | any_vec.downcast_mut::().unwrap() 53 | .remove(Self::index(i)); 54 | } 55 | start.elapsed() 56 | } 57 | } 58 | 59 | struct Front; 60 | impl Impl for Front { 61 | #[inline] 62 | fn index(_: usize) -> usize { 0 } 63 | } 64 | 65 | struct Back; 66 | impl Impl for Back { 67 | #[inline] 68 | fn index(i: usize) -> usize { i } 69 | } 70 | 71 | pub fn bench_remove(c: &mut Criterion) { 72 | bench_custom(c, "Vec remove front", Front::vec_remove); 73 | bench_custom(c, "AnyVec remove front", Front::any_vec_remove); 74 | bench_custom(c, "AnyVecTyped remove front", Front::any_vec_typed_remove); 75 | 76 | bench_custom(c, "Vec remove back", Back::vec_remove); 77 | bench_custom(c, "AnyVec remove back", Back::any_vec_remove); 78 | bench_custom(c, "AnyVecTyped remove back", Back::any_vec_typed_remove); 79 | } 80 | 81 | criterion_group!(benches, bench_remove); 82 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/swap_remove.rs: -------------------------------------------------------------------------------- 1 | mod utils; 2 | 3 | use std::time::{Duration, Instant}; 4 | use criterion::{criterion_group, criterion_main, Criterion}; 5 | use any_vec::AnyVec; 6 | use crate::utils::bench_custom; 7 | 8 | const SIZE: usize = 10000; 9 | 10 | type Element = String; 11 | static VALUE: Element = String::new(); 12 | 13 | fn vec_swap_remove() -> Duration { 14 | let mut vec = Vec::new(); 15 | for _ in 0..SIZE{ 16 | vec.push(VALUE.clone()); 17 | } 18 | 19 | let start = Instant::now(); 20 | for _ in 0..SIZE{ 21 | vec.swap_remove(0); 22 | } 23 | start.elapsed() 24 | } 25 | 26 | fn any_vec_swap_remove() -> Duration { 27 | let mut any_vec: AnyVec = AnyVec::new::(); 28 | for _ in 0..SIZE{ 29 | any_vec.downcast_mut::().unwrap() 30 | .push(VALUE.clone()); 31 | } 32 | 33 | let start = Instant::now(); 34 | for _ in 0..SIZE{ 35 | any_vec.swap_remove(0); 36 | } 37 | start.elapsed() 38 | } 39 | 40 | fn any_vec_typed_swap_remove() -> Duration { 41 | let mut any_vec: AnyVec = AnyVec::new::(); 42 | for _ in 0..SIZE{ 43 | any_vec.downcast_mut::().unwrap() 44 | .push(VALUE.clone()); 45 | } 46 | 47 | let start = Instant::now(); 48 | for _ in 0..SIZE{ 49 | any_vec.downcast_mut::().unwrap() 50 | .swap_remove(0); 51 | } 52 | start.elapsed() 53 | } 54 | 55 | pub fn bench_swap_remove(c: &mut Criterion) { 56 | bench_custom(c, "Vec swap_remove", vec_swap_remove); 57 | bench_custom(c, "AnyVec swap_remove", any_vec_swap_remove); 58 | bench_custom(c, "AnyVecTyped swap_remove", any_vec_typed_swap_remove); 59 | } 60 | 61 | criterion_group!(benches, bench_swap_remove); 62 | criterion_main!(benches); -------------------------------------------------------------------------------- /benches/utils.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | use criterion::Criterion; 3 | 4 | pub fn bench_custom Duration>(c: &mut Criterion, id: &str, mut routine: F) { 5 | c.bench_function(id, move |b|b.iter_custom(|iters| 6 | (0..iters).map(|_|routine()).sum() 7 | )); 8 | } -------------------------------------------------------------------------------- /doc.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | set RUSTDOCFLAGS=--cfg docsrs 4 | cargo +nightly doc --lib --no-deps %1 5 | endlocal -------------------------------------------------------------------------------- /src/any_value/lazy_clone.rs: -------------------------------------------------------------------------------- 1 | use core::any::TypeId; 2 | use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueTypeless, AnyValueSizeless}; 3 | 4 | /// Makes [`AnyValueCloneable`] actually [`Clone`]able. 5 | /// Clone underlying value on consumption. 6 | /// 7 | /// Source must outlive `LazyClone`. `LazyClone` let you 8 | /// take element from one [`AnyVec`] and put it multiple times 9 | /// into another, without intermediate copies and cast to concrete type. 10 | /// 11 | /// Can be constructed by calling [AnyValueCloneable::lazy_clone]. 12 | /// 13 | /// [`AnyVec`]: crate::AnyVec 14 | pub struct LazyClone<'a, T: AnyValueCloneable>{ 15 | value: &'a T 16 | } 17 | 18 | impl<'a, T: AnyValueCloneable> LazyClone<'a, T>{ 19 | #[inline] 20 | pub fn new(value: &'a T) -> Self{ 21 | Self{value} 22 | } 23 | } 24 | 25 | impl<'a, T: AnyValueCloneable> AnyValueSizeless for LazyClone<'a, T> { 26 | type Type = T::Type; 27 | 28 | #[inline] 29 | fn as_bytes_ptr(&self) -> *const u8 { 30 | self.value.as_bytes_ptr() 31 | } 32 | 33 | #[inline] 34 | unsafe fn move_into(self, out: *mut u8, _bytes_size: usize) { 35 | self.value.clone_into(out); 36 | } 37 | } 38 | 39 | impl<'a, T: AnyValueCloneable + AnyValueTypeless> AnyValueTypeless for LazyClone<'a, T>{ 40 | #[inline] 41 | fn size(&self) -> usize { 42 | self.value.size() 43 | } 44 | } 45 | 46 | impl<'a, T: AnyValueCloneable + AnyValue> AnyValue for LazyClone<'a, T>{ 47 | #[inline] 48 | fn value_typeid(&self) -> TypeId { 49 | self.value.value_typeid() 50 | } 51 | } 52 | 53 | impl<'a, T: AnyValueCloneable> AnyValueCloneable for LazyClone<'a, T>{ 54 | #[inline] 55 | unsafe fn clone_into(&self, out: *mut u8) { 56 | self.value.clone_into(out); 57 | } 58 | } 59 | 60 | impl<'a, T: AnyValueCloneable> Clone for LazyClone<'a, T>{ 61 | #[inline] 62 | fn clone(&self) -> Self { 63 | Self{value: self.value} 64 | } 65 | } -------------------------------------------------------------------------------- /src/any_value/mod.rs: -------------------------------------------------------------------------------- 1 | //! AnyValue is concept of type-erased object, that 2 | //! can be moved around without type knowledge. 3 | //! 4 | //! With default trait implementation, all "consume" operations 5 | //! boils down to [move_into]. By redefining [move_into] and [Drop][^1] behavior - 6 | //! you can have some additional logic on AnyValue consumption. 7 | //! (Consumption - is any operation that "move out" data from AnyValue) 8 | //! 9 | //! [AnyValueSizeless] -> [AnyValueTypeless] -> [AnyValue] 10 | //! 11 | //! # Usage 12 | //! 13 | //! Some [AnyVec] operations will accept and return [AnyValue]. 14 | //! This allows to move data between [AnyVec]s in 15 | //! fast, safe, type erased way. 16 | //! 17 | //! [^1]: AnyValue could have blanket implementation for Drop as well, 18 | //! but that is unstable Rust now. 19 | //! 20 | //! [AnyVec]: crate::AnyVec 21 | //! [move_into]: AnyValueSizeless::move_into 22 | 23 | mod wrapper; 24 | mod raw; 25 | mod lazy_clone; 26 | 27 | pub use lazy_clone::LazyClone; 28 | pub use wrapper::AnyValueWrapper; 29 | pub use raw::{AnyValueRaw, AnyValueSizelessRaw, AnyValueTypelessRaw}; 30 | 31 | use core::any::TypeId; 32 | use core::{mem, ptr, slice}; 33 | use core::mem::{MaybeUninit, size_of}; 34 | 35 | /// Marker for unknown type. 36 | pub struct Unknown; 37 | impl Unknown { 38 | #[inline] 39 | pub fn is() -> bool { 40 | TypeId::of::() == TypeId::of::() 41 | } 42 | } 43 | 44 | /// Prelude for traits. 45 | pub mod traits{ 46 | pub use super::{AnyValueSizeless, AnyValueSizelessMut}; 47 | pub use super::{AnyValueTypeless, AnyValueTypelessMut}; 48 | pub use super::{AnyValue, AnyValueMut}; 49 | pub use super::AnyValueCloneable; 50 | } 51 | 52 | /// [AnyValue] that doesn't know its size or type, and can provide only object ptr. 53 | pub trait AnyValueSizeless { 54 | /// Concrete type, or [`Unknown`] 55 | /// 56 | /// N.B. This should be in `AnyValueTyped`. It is here due to ergonomic reasons, 57 | /// since Rust does not have impl specialization. 58 | type Type: 'static /*= Unknown*/; 59 | 60 | /// Aligned address. 61 | fn as_bytes_ptr(&self) -> *const u8; 62 | 63 | #[inline] 64 | unsafe fn downcast_ref_unchecked(&self) -> &T{ 65 | &*(self.as_bytes_ptr() as *const T) 66 | } 67 | 68 | #[inline] 69 | unsafe fn downcast_unchecked(self) -> T 70 | where Self: Sized 71 | { 72 | let mut tmp = MaybeUninit::::uninit(); 73 | self.move_into::(tmp.as_mut_ptr() as *mut u8, size_of::()); 74 | tmp.assume_init() 75 | } 76 | 77 | /// Move self into `out`. 78 | /// 79 | /// Will do compile-time optimization if type/size known. 80 | /// 81 | /// # Safety 82 | /// 83 | /// - `bytes_size` must be correct object size. 84 | /// - `out` must not overlap with `self`. 85 | /// - `out` must have at least `bytes_size` bytes. 86 | /// - `KnownType` must be correct object type or [Unknown]. 87 | #[inline] 88 | unsafe fn move_into(self, out: *mut u8, bytes_size: usize) 89 | where Self: Sized 90 | { 91 | crate::copy_nonoverlapping_value::(self.as_bytes_ptr(), out, bytes_size); 92 | mem::forget(self); 93 | } 94 | } 95 | 96 | /// [AnyValue] that doesn't know it's type, but know it's size. 97 | pub trait AnyValueTypeless: AnyValueSizeless { 98 | /// Aligned. 99 | #[inline] 100 | fn as_bytes(&self) -> &[u8]{ 101 | unsafe{slice::from_raw_parts( 102 | self.as_bytes_ptr(), 103 | self.size() 104 | )} 105 | } 106 | 107 | /// Aligned. 108 | fn size(&self) -> usize; 109 | } 110 | 111 | /// Type erased value interface. 112 | /// 113 | /// Know it's type and size, possibly compile-time. 114 | pub trait AnyValue: AnyValueTypeless { 115 | fn value_typeid(&self) -> TypeId; 116 | 117 | #[inline] 118 | fn downcast_ref(&self) -> Option<&T>{ 119 | if self.value_typeid() != TypeId::of::(){ 120 | None 121 | } else { 122 | Some(unsafe{ self.downcast_ref_unchecked::() }) 123 | } 124 | } 125 | 126 | #[inline] 127 | fn downcast(self) -> Option 128 | where Self: Sized 129 | { 130 | if self.value_typeid() != TypeId::of::(){ 131 | None 132 | } else { 133 | Some(unsafe{ self.downcast_unchecked::() }) 134 | } 135 | } 136 | } 137 | 138 | /// Mutable [AnyValueSizeless]. 139 | pub trait AnyValueSizelessMut: AnyValueSizeless { 140 | // Rust MIRI requires mut pointer to actually come from mut self. 141 | /// Aligned address. 142 | fn as_bytes_mut_ptr(&mut self) -> *mut u8; 143 | 144 | #[inline] 145 | unsafe fn downcast_mut_unchecked(&mut self) -> &mut T{ 146 | &mut *(self.as_bytes_mut_ptr() as *mut T) 147 | } 148 | } 149 | 150 | /// Mutable [AnyValueTypeless]. 151 | pub trait AnyValueTypelessMut: AnyValueTypeless + AnyValueSizelessMut { 152 | #[inline(always)] 153 | fn as_bytes_mut(&mut self) -> &mut [u8]{ 154 | unsafe{slice::from_raw_parts_mut( 155 | self.as_bytes_mut_ptr(), 156 | self.size() 157 | )} 158 | } 159 | 160 | #[inline(always)] 161 | unsafe fn swap_unchecked(&mut self, other: &mut Other){ 162 | // compile-time check 163 | if !Unknown::is::() { 164 | mem::swap( 165 | self.downcast_mut_unchecked::(), 166 | other.downcast_mut_unchecked::() 167 | ); 168 | } else if !Unknown::is::() { 169 | mem::swap( 170 | self.downcast_mut_unchecked::(), 171 | other.downcast_mut_unchecked::() 172 | ); 173 | } else { 174 | let bytes = self.as_bytes_mut(); 175 | ptr::swap_nonoverlapping( 176 | bytes.as_mut_ptr(), 177 | other.as_bytes_mut().as_mut_ptr(), 178 | bytes.len() 179 | ); 180 | } 181 | } 182 | } 183 | 184 | /// Mutable [AnyValue]. 185 | pub trait AnyValueMut: AnyValueTypelessMut + AnyValue { 186 | #[inline(always)] 187 | fn downcast_mut(&mut self) -> Option<&mut T>{ 188 | if self.value_typeid() != TypeId::of::(){ 189 | None 190 | } else { 191 | Some(unsafe{ self.downcast_mut_unchecked::() }) 192 | } 193 | } 194 | 195 | /// Swaps underlying values. 196 | /// 197 | /// # Panic 198 | /// 199 | /// Panics, if type mismatch. 200 | #[inline(always)] 201 | fn swap(&mut self, other: &mut Other){ 202 | assert_eq!(self.value_typeid(), other.value_typeid()); 203 | unsafe{ 204 | self.swap_unchecked(other); 205 | } 206 | } 207 | } 208 | 209 | /// [`LazyClone`] friendly [`AnyValueSizeless`]. 210 | pub trait AnyValueCloneable: AnyValueSizeless { 211 | unsafe fn clone_into(&self, out: *mut u8); 212 | 213 | #[inline] 214 | fn lazy_clone(&self) -> LazyClone 215 | where Self: Sized 216 | { 217 | LazyClone::new(self) 218 | } 219 | } 220 | -------------------------------------------------------------------------------- /src/any_value/raw.rs: -------------------------------------------------------------------------------- 1 | use core::any::TypeId; 2 | use core::ptr::NonNull; 3 | use crate::any_value::{AnyValue, AnyValueMut, AnyValueTypelessMut, AnyValueTypeless, AnyValueSizeless, AnyValueSizelessMut}; 4 | use crate::any_value::Unknown; 5 | 6 | /// [AnyValueSizeless] non-owning byte ptr wrapper, that knows nothing about it's type. 7 | /// 8 | /// Source should be forgotten, before pushing to [AnyVec]. 9 | /// Contained value **WILL NOT** be dropped on wrapper drop. 10 | /// 11 | /// # Example 12 | /// ```rust 13 | /// # use std::any::TypeId; 14 | /// # use std::mem; 15 | /// # use std::mem::size_of; 16 | /// # use std::ptr::NonNull; 17 | /// # use any_vec::AnyVec; 18 | /// # use any_vec::any_value::AnyValueSizelessRaw; 19 | /// let s = String::from("Hello!"); 20 | /// let raw_value = unsafe{AnyValueSizelessRaw::new( 21 | /// NonNull::from(&s).cast::() 22 | /// )}; 23 | /// mem::forget(s); 24 | /// 25 | /// let mut any_vec: AnyVec = AnyVec::new::(); 26 | /// unsafe{ 27 | /// any_vec.push_unchecked(raw_value); 28 | /// } 29 | /// ``` 30 | /// 31 | /// [AnyVec]: crate::AnyVec 32 | pub struct AnyValueSizelessRaw { 33 | ptr: NonNull 34 | } 35 | 36 | impl AnyValueSizelessRaw { 37 | #[inline] 38 | pub unsafe fn new(ptr: NonNull) -> Self{ 39 | Self{ptr} 40 | } 41 | } 42 | impl AnyValueSizeless for AnyValueSizelessRaw { 43 | type Type = Unknown; 44 | 45 | #[inline] 46 | fn as_bytes_ptr(&self) -> *const u8 { 47 | self.ptr.as_ptr() 48 | } 49 | } 50 | impl AnyValueSizelessMut for AnyValueSizelessRaw { 51 | #[inline] 52 | fn as_bytes_mut_ptr(&mut self) -> *mut u8 { 53 | self.ptr.as_ptr() 54 | } 55 | } 56 | 57 | /// [AnyValueTypeless] byte ptr wrapper, that know it's type size. 58 | /// 59 | /// Source should be forgotten, before pushing to [AnyVec]. 60 | /// Contained value **WILL NOT** be dropped on wrapper drop. 61 | /// 62 | /// # Example 63 | /// ```rust 64 | /// # use std::any::TypeId; 65 | /// # use std::mem; 66 | /// # use std::mem::size_of; 67 | /// # use std::ptr::NonNull; 68 | /// # use any_vec::AnyVec; 69 | /// # use any_vec::any_value::AnyValueTypelessRaw; 70 | /// let s = String::from("Hello!"); 71 | /// let raw_value = unsafe{AnyValueTypelessRaw::new( 72 | /// NonNull::from(&s).cast::(), 73 | /// size_of::() 74 | /// )}; 75 | /// mem::forget(s); 76 | /// 77 | /// let mut any_vec: AnyVec = AnyVec::new::(); 78 | /// unsafe{ 79 | /// any_vec.push_unchecked(raw_value); 80 | /// } 81 | /// ``` 82 | /// 83 | /// [AnyVec]: crate::AnyVec 84 | pub struct AnyValueTypelessRaw { 85 | ptr: NonNull, 86 | size: usize, 87 | } 88 | 89 | impl AnyValueTypelessRaw { 90 | #[inline] 91 | pub unsafe fn new(ptr: NonNull, size: usize) -> Self{ 92 | Self{ptr, size} 93 | } 94 | } 95 | 96 | impl AnyValueSizeless for AnyValueTypelessRaw { 97 | type Type = Unknown; 98 | 99 | #[inline] 100 | fn as_bytes_ptr(&self) -> *const u8 { 101 | self.ptr.as_ptr() 102 | } 103 | } 104 | impl AnyValueSizelessMut for AnyValueTypelessRaw { 105 | #[inline] 106 | fn as_bytes_mut_ptr(&mut self) -> *mut u8 { 107 | self.ptr.as_ptr() 108 | } 109 | } 110 | impl AnyValueTypeless for AnyValueTypelessRaw { 111 | #[inline] 112 | fn size(&self) -> usize { 113 | self.size 114 | } 115 | } 116 | impl AnyValueTypelessMut for AnyValueTypelessRaw {} 117 | 118 | 119 | /// [AnyValue] byte ptr wrapper, that know it's type. 120 | /// 121 | /// Source should be forgotten, before pushing to [AnyVec]. 122 | /// Contained value **WILL NOT** be dropped on wrapper drop. 123 | /// 124 | /// # Example 125 | /// ```rust 126 | /// # use std::any::TypeId; 127 | /// # use std::mem; 128 | /// # use std::mem::size_of; 129 | /// # use std::ptr::NonNull; 130 | /// # use any_vec::AnyVec; 131 | /// # use any_vec::any_value::AnyValueRaw; 132 | /// let s = String::from("Hello!"); 133 | /// let raw_value = unsafe{AnyValueRaw::new( 134 | /// NonNull::from(&s).cast::(), 135 | /// size_of::(), 136 | /// TypeId::of::() 137 | /// )}; 138 | /// mem::forget(s); 139 | /// 140 | /// let mut any_vec: AnyVec = AnyVec::new::(); 141 | /// unsafe{ 142 | /// any_vec.push_unchecked(raw_value); 143 | /// } 144 | /// ``` 145 | /// 146 | /// [AnyVec]: crate::AnyVec 147 | pub struct AnyValueRaw { 148 | raw_unsafe: AnyValueTypelessRaw, 149 | typeid: TypeId 150 | } 151 | 152 | impl AnyValueRaw { 153 | #[inline] 154 | pub unsafe fn new(ptr: NonNull, size: usize, typeid: TypeId) -> Self{ 155 | Self{ 156 | raw_unsafe: AnyValueTypelessRaw::new(ptr, size), 157 | typeid 158 | } 159 | } 160 | } 161 | 162 | impl AnyValueSizeless for AnyValueRaw { 163 | type Type = Unknown; 164 | 165 | #[inline] 166 | fn as_bytes_ptr(&self) -> *const u8 { 167 | self.raw_unsafe.ptr.as_ptr() 168 | } 169 | } 170 | impl AnyValueSizelessMut for AnyValueRaw { 171 | #[inline] 172 | fn as_bytes_mut_ptr(&mut self) -> *mut u8 { 173 | self.raw_unsafe.ptr.as_ptr() 174 | } 175 | } 176 | impl AnyValueTypeless for AnyValueRaw { 177 | #[inline] 178 | fn size(&self) -> usize { 179 | self.raw_unsafe.size 180 | } 181 | } 182 | impl AnyValue for AnyValueRaw { 183 | #[inline] 184 | fn value_typeid(&self) -> TypeId { 185 | self.typeid 186 | } 187 | } 188 | 189 | impl AnyValueTypelessMut for AnyValueRaw {} 190 | impl AnyValueMut for AnyValueRaw {} -------------------------------------------------------------------------------- /src/any_value/wrapper.rs: -------------------------------------------------------------------------------- 1 | use core::any::TypeId; 2 | use core::mem::size_of; 3 | use crate::any_value::{AnyValue, AnyValueMut, AnyValueTypelessMut, AnyValueTypeless, AnyValueSizeless, AnyValueSizelessMut}; 4 | 5 | /// Helper struct to convert concrete type to [`AnyValueMut`]. 6 | /// 7 | /// Unlike [AnyValueRaw] this one owns underlying value. So, its not 8 | /// special in any way. 9 | /// 10 | /// [AnyValueRaw]: super::AnyValueRaw 11 | pub struct AnyValueWrapper{ 12 | value: T 13 | } 14 | impl AnyValueWrapper { 15 | #[inline] 16 | pub fn new(value: T) -> Self{ 17 | Self{ value } 18 | } 19 | } 20 | 21 | impl AnyValueSizeless for AnyValueWrapper { 22 | type Type = T; 23 | 24 | #[inline] 25 | fn as_bytes_ptr(&self) -> *const u8 { 26 | &self.value as *const _ as *const u8 27 | } 28 | } 29 | impl AnyValueSizelessMut for AnyValueWrapper { 30 | #[inline] 31 | fn as_bytes_mut_ptr(&mut self) -> *mut u8 { 32 | &mut self.value as *mut _ as *mut u8 33 | } 34 | } 35 | impl AnyValueTypeless for AnyValueWrapper { 36 | #[inline] 37 | fn size(&self) -> usize { 38 | size_of::() 39 | } 40 | } 41 | impl AnyValue for AnyValueWrapper { 42 | #[inline] 43 | fn value_typeid(&self) -> TypeId { 44 | TypeId::of::() 45 | } 46 | } 47 | impl AnyValueTypelessMut for AnyValueWrapper {} 48 | impl AnyValueMut for AnyValueWrapper {} -------------------------------------------------------------------------------- /src/any_vec.rs: -------------------------------------------------------------------------------- 1 | use core::alloc::Layout; 2 | use core::any::TypeId; 3 | use core::fmt::{Debug, Formatter}; 4 | use core::marker::PhantomData; 5 | use core::mem::{ManuallyDrop, MaybeUninit}; 6 | use core::ops::{Deref, DerefMut, Range, RangeBounds}; 7 | use core::ptr::NonNull; 8 | use core::{fmt, ptr, slice}; 9 | use core::slice::{from_raw_parts, from_raw_parts_mut}; 10 | use crate::{AnyVecTyped, into_range, mem, ops}; 11 | use crate::any_value::{AnyValue, AnyValueSizeless}; 12 | use crate::any_vec_raw::{AnyVecRaw, DropFn}; 13 | use crate::ops::{TempValue, Remove, SwapRemove, remove, swap_remove, Pop, pop}; 14 | use crate::ops::{Drain, Splice, drain, splice}; 15 | use crate::any_vec::traits::{None}; 16 | use crate::clone_type::{CloneFn, CloneFnTrait, CloneType}; 17 | use crate::element::{ElementPointer, ElementMut, ElementRef}; 18 | use crate::any_vec_ptr::AnyVecPtr; 19 | use crate::iter::{Iter, IterMut, IterRef}; 20 | use crate::mem::{Mem, MemBuilder, MemBuilderSizeable, MemRawParts, MemResizable}; 21 | use crate::traits::{Cloneable, Trait}; 22 | 23 | /// Trait constraints. 24 | /// Possible variants [`Cloneable`], [`Send`] and [`Sync`], in any combination. 25 | /// 26 | /// # Example 27 | /// ```rust 28 | /// use any_vec::AnyVec; 29 | /// use any_vec::traits::*; 30 | /// let v1: AnyVec = AnyVec::new::(); 31 | /// let v2 = v1.clone(); 32 | /// 33 | /// ``` 34 | pub mod traits{ 35 | // TODO: rename to TraitConstraints or Constraints? 36 | /// [`AnyVec`]s trait constraints. 37 | /// 38 | /// [`AnyVec`]: crate::AnyVec 39 | pub trait Trait: 'static + crate::clone_type::CloneType{} 40 | impl Trait for dyn None {} 41 | impl Trait for dyn Sync{} 42 | impl Trait for dyn Send{} 43 | impl Trait for dyn Sync + Send{} 44 | impl Trait for dyn Cloneable{} 45 | impl Trait for dyn Cloneable + Send{} 46 | impl Trait for dyn Cloneable + Sync{} 47 | impl Trait for dyn Cloneable + Send+ Sync{} 48 | 49 | /// Does not enforce anything. Default. 50 | pub trait None {} 51 | 52 | pub use core::marker::Sync; 53 | 54 | pub use core::marker::Send; 55 | 56 | /// Enforce type [`Clone`]-ability. 57 | pub trait Cloneable{} 58 | } 59 | 60 | /// Trait for compile time check - does `T` satisfy `Traits` constraints. 61 | /// 62 | /// Almost for sure you don't need to use it. It is public - just in case. 63 | /// In our tests we found niche case where it was needed: 64 | /// ```rust 65 | /// # use any_vec::AnyVec; 66 | /// # use any_vec::SatisfyTraits; 67 | /// # use any_vec::traits::*; 68 | /// fn do_test(vec: &mut AnyVec) 69 | /// where String: SatisfyTraits, 70 | /// usize: SatisfyTraits 71 | /// { 72 | /// # let something = true; 73 | /// # let other_something = true; 74 | /// if something { 75 | /// *vec = AnyVec::new::(); 76 | /// /*...*/ 77 | /// } else if other_something { 78 | /// *vec = AnyVec::new::(); 79 | /// /*...*/ 80 | /// } 81 | /// # } 82 | /// ``` 83 | pub trait SatisfyTraits: CloneFnTrait {} 84 | impl SatisfyTraits for T{} 85 | impl SatisfyTraits for T{} 86 | impl SatisfyTraits for T{} 87 | impl SatisfyTraits for T{} 88 | impl SatisfyTraits for T{} 89 | impl SatisfyTraits for T{} 90 | impl SatisfyTraits for T{} 91 | impl SatisfyTraits for T{} 92 | 93 | /// [`AnyVec`] raw parts. 94 | /// 95 | /// You can get it with [`AnyVec::into_raw_parts`], or build/edit 96 | /// it manually. And with [`AnyVec::from_raw_parts`], you can construct 97 | /// [`AnyVec`]. 98 | pub struct RawParts 99 | where 100 | M::Mem: MemRawParts 101 | { 102 | pub mem_builder: M, 103 | pub mem_handle: ::Handle, 104 | pub capacity: usize, 105 | pub len: usize, 106 | pub element_layout: Layout, 107 | pub element_typeid: TypeId, 108 | pub element_drop: Option, 109 | 110 | /// Ignored if non Cloneable. 111 | pub element_clone: CloneFn, 112 | } 113 | 114 | impl Clone for RawParts 115 | where 116 | M::Mem: MemRawParts, 117 | ::Handle: Clone 118 | { 119 | #[inline] 120 | fn clone(&self) -> Self { 121 | Self{ 122 | mem_builder: self.mem_builder.clone(), 123 | mem_handle: self.mem_handle.clone(), 124 | capacity: self.capacity, 125 | len: self.capacity, 126 | element_layout: self.element_layout, 127 | element_typeid: self.element_typeid, 128 | element_drop: self.element_drop, 129 | element_clone: self.element_clone, 130 | } 131 | } 132 | } 133 | 134 | /// Type erased vec-like container. 135 | /// All elements have the same type. 136 | /// 137 | /// Only destruct and clone operations have indirect call overhead. 138 | /// 139 | /// You can make AnyVec [`Send`]-able, [`Sync`]-able, [`Cloneable`], by 140 | /// specifying trait constraints: `AnyVec`. See [`traits`]. 141 | /// 142 | /// Some operations return [`TempValue`], which internally holds &mut to [`AnyVec`]. 143 | /// You can drop it, cast to concrete type, or put into another vector. (See [any_value]) 144 | /// 145 | /// *`T: 'static` due to TypeId requirements* 146 | /// 147 | /// [any_value]: crate::any_value 148 | pub struct AnyVec 149 | { 150 | pub(crate) raw: AnyVecRaw, 151 | clone_fn: ::Type, // ZST if Traits: !Cloneable 152 | phantom: PhantomData 153 | } 154 | 155 | impl AnyVec 156 | { 157 | #[inline] 158 | fn build>(raw: AnyVecRaw) -> Self { 159 | let clone_fn = >::CLONE_FN; 160 | Self{ 161 | raw, 162 | clone_fn: ::new(clone_fn), 163 | phantom: PhantomData 164 | } 165 | } 166 | 167 | /// Constructs empty [`AnyVec`] with elements of type `T`, 168 | /// using [`Default`] [`MemBuilder`]. 169 | /// 170 | /// `T` should satisfy requested Traits. 171 | /// 172 | /// Not available, if provided [`MemBuilder`] is not [`Default`]. 173 | #[inline] 174 | #[must_use] 175 | pub fn new() -> Self 176 | where 177 | T: SatisfyTraits, 178 | M: Default 179 | { 180 | Self::new_in::(Default::default()) 181 | } 182 | 183 | /// Constructs empty [`AnyVec`] with elements of type `T`, 184 | /// using provided `mem_builder`. 185 | /// 186 | /// `T` should satisfy requested Traits. 187 | #[inline] 188 | #[must_use] 189 | pub fn new_in(mut mem_builder: M) -> Self 190 | where T: SatisfyTraits 191 | { 192 | let mem = mem_builder.build(Layout::new::()); 193 | let raw = AnyVecRaw::new::(mem_builder, mem); 194 | Self::build::(raw) 195 | } 196 | 197 | /// Constructs empty [`AnyVec`] with specified capacity and 198 | /// elements of type `T`, using [`Default`] [`MemBuilder`]. 199 | /// 200 | /// `T` should satisfy requested Traits. 201 | /// 202 | /// Not available, if provided [`MemBuilder`] is not 203 | /// [`MemBuilderSizeable`] and [`Default`]. 204 | #[inline] 205 | #[must_use] 206 | pub fn with_capacity(capacity: usize) -> Self 207 | where 208 | T: SatisfyTraits, 209 | M: MemBuilderSizeable, 210 | M: Default 211 | { 212 | Self::with_capacity_in::(capacity, Default::default()) 213 | } 214 | 215 | /// Constructs empty [`AnyVec`] with specified capacity and 216 | /// elements of type `T`, using `mem_builder`. 217 | /// 218 | /// `T` should satisfy requested Traits. 219 | /// 220 | /// Not available, if provided [`MemBuilder`] is not 221 | /// [`MemBuilderSizeable`]. 222 | #[inline] 223 | #[must_use] 224 | pub fn with_capacity_in(capacity: usize, mut mem_builder: M) -> Self 225 | where 226 | T: SatisfyTraits, 227 | M: MemBuilderSizeable 228 | { 229 | let mem = mem_builder.build_with_size(Layout::new::(), capacity); 230 | let raw = AnyVecRaw::new::(mem_builder, mem); 231 | Self::build::(raw) 232 | } 233 | 234 | /// Destructure `AnyVec` into [`RawParts`]. 235 | #[inline] 236 | #[must_use] 237 | pub fn into_raw_parts(self) -> RawParts 238 | where 239 | M::Mem: MemRawParts 240 | { 241 | let this = ManuallyDrop::new(self); 242 | 243 | let mem_builder = unsafe{ ptr::read(&this.raw.mem_builder) }; 244 | let mem = unsafe{ ptr::read(&this.raw.mem) }; 245 | let (mem_handle, element_layout, capacity) = mem.into_raw_parts(); 246 | RawParts{ 247 | mem_builder, 248 | mem_handle, 249 | capacity, 250 | len: this.raw.len, 251 | element_layout, 252 | element_typeid: this.raw.type_id, 253 | element_drop: this.raw.drop_fn, 254 | element_clone: this.clone_fn() 255 | } 256 | } 257 | 258 | /// Construct `AnyVec` from previously deconstructed raw parts. 259 | /// 260 | /// # Safety 261 | /// 262 | /// ## Traits 263 | /// 264 | /// Traits validity not checked. `RawParts` of underlying type must implement Traits. 265 | /// It is not safe to opt-in [`Cloneable`], if initial `AnyVec` was not constructed with 266 | /// that trait. 267 | /// 268 | /// ## RawParts 269 | /// 270 | /// `RawParts` validity not checked. 271 | /// 272 | #[inline] 273 | #[must_use] 274 | pub unsafe fn from_raw_parts(raw_parts: RawParts) -> Self 275 | where 276 | M::Mem: MemRawParts 277 | { 278 | Self{ 279 | raw: AnyVecRaw{ 280 | mem_builder: raw_parts.mem_builder, 281 | mem: MemRawParts::from_raw_parts( 282 | raw_parts.mem_handle, 283 | raw_parts.element_layout, 284 | raw_parts.capacity 285 | ), 286 | len: raw_parts.len, 287 | type_id: raw_parts.element_typeid, 288 | drop_fn: raw_parts.element_drop 289 | }, 290 | clone_fn: ::new(raw_parts.element_clone), 291 | phantom: PhantomData 292 | } 293 | } 294 | 295 | /// Constructs **empty** [`AnyVec`] with the same elements type, `Traits` and `MemBuilder`. 296 | /// IOW, same as [`clone`], but without elements copy. 297 | /// 298 | /// [`clone`]: Clone::clone 299 | #[inline] 300 | #[must_use] 301 | pub fn clone_empty(&self) -> Self { 302 | Self { 303 | raw: self.raw.clone_empty(), 304 | clone_fn: self.clone_fn, 305 | phantom: PhantomData 306 | } 307 | } 308 | 309 | /// Constructs **empty** [`AnyVec`] with the same elements type and `Traits`, 310 | /// but with other `MemBuilder`. 311 | /// 312 | /// Use it to construct intermediate storage, with fast [`MemBuilder`]. 313 | /// 314 | /// # Example 315 | /// 316 | /// ``` 317 | /// # use any_vec::any_value::AnyValueCloneable; 318 | /// # use any_vec::AnyVec; 319 | /// # use any_vec::mem::Stack; 320 | /// # use any_vec::traits::Cloneable; 321 | /// # let mut any_vec: AnyVec = AnyVec::new::(); 322 | /// # any_vec.downcast_mut::().unwrap().push(String::from("0")); 323 | /// let mut tmp = any_vec.clone_empty_in(Stack::<256>); 324 | /// tmp.push(any_vec.at(0).lazy_clone()); 325 | /// any_vec.push(tmp.pop().unwrap()); 326 | /// ``` 327 | #[inline] 328 | #[must_use] 329 | pub fn clone_empty_in(&self, mem_builder: NewM) -> AnyVec { 330 | AnyVec { 331 | raw: self.raw.clone_empty_in(mem_builder), 332 | clone_fn: self.clone_fn, 333 | phantom: PhantomData 334 | } 335 | } 336 | 337 | #[inline] 338 | pub(crate) fn clone_fn(&self) -> CloneFn{ 339 | ::get(self.clone_fn) 340 | } 341 | 342 | /// Reserves capacity for at least `additional` more elements to be inserted 343 | /// in the given container. More space may be reserved to avoid 344 | /// frequent reallocations. After calling `reserve`, capacity will be 345 | /// greater than or equal to `self.len() + additional`. Exact behavior defined by 346 | /// implementation of [`MemResizable`]. Does nothing if capacity is already sufficient. 347 | /// 348 | /// Not available, if provided [`MemBuilder::Mem`] is not [`MemResizable`]. 349 | /// 350 | /// # Panics 351 | /// 352 | /// [`MemResizable`] implementation may panic - see implementation description. 353 | #[inline] 354 | pub fn reserve(&mut self, additional: usize) 355 | where M::Mem: MemResizable 356 | { 357 | self.raw.reserve(additional) 358 | } 359 | 360 | /// Reserves the minimum capacity for exactly `additional` more elements to 361 | /// be inserted in the given container. After calling `reserve_exact`, 362 | /// capacity will be greater than or equal to `self.len() + additional`. 363 | /// Exact behavior defined by implementation of [`MemResizable`]. 364 | /// Does nothing if the capacity is already sufficient. 365 | /// 366 | /// Note that the [`Mem`] implementation may grow bigger then requested. 367 | /// Therefore, capacity can not be relied upon to be precisely 368 | /// minimal. Prefer [`reserve`] if future insertions are expected. 369 | /// 370 | /// Not available, if provided [`MemBuilder::Mem`] is not [`MemResizable`]. 371 | /// 372 | /// # Panics 373 | /// 374 | /// [`MemResizable`] implementation may panic - see implementation description. 375 | /// 376 | /// [`reserve`]: Self::reserve 377 | #[inline] 378 | pub fn reserve_exact(&mut self, additional: usize) 379 | where M::Mem: MemResizable 380 | { 381 | self.raw.reserve_exact(additional) 382 | } 383 | 384 | /// Shrinks the capacity as much as possible. 385 | /// Exact behavior defined by implementation of [`MemResizable`]. 386 | /// 387 | /// Not available, if provided [`MemBuilder::Mem`] is not [`MemResizable`]. 388 | /// 389 | /// # Panics 390 | /// 391 | /// [`MemResizable`] implementation may panic - see implementation description. 392 | #[inline] 393 | pub fn shrink_to_fit(&mut self) 394 | where M::Mem: MemResizable 395 | { 396 | self.raw.shrink_to_fit() 397 | } 398 | 399 | /// Shrinks the capacity of the vector with a lower bound. 400 | /// 401 | /// The capacity will remain at least as large as both the length 402 | /// and the supplied value. Exact behavior defined by implementation of [`MemResizable`]. 403 | /// 404 | /// If the current capacity is less than the lower limit, this is a no-op. 405 | /// 406 | /// Not available, if provided [`MemBuilder::Mem`] is not [`MemResizable`]. 407 | /// 408 | /// # Panics 409 | /// 410 | /// [`MemResizable`] implementation may panic - see implementation description. 411 | #[inline] 412 | pub fn shrink_to(&mut self, min_capacity: usize) 413 | where M::Mem: MemResizable 414 | { 415 | self.raw.shrink_to(min_capacity) 416 | } 417 | 418 | #[inline] 419 | pub unsafe fn set_len(&mut self, new_len: usize) { 420 | self.raw.set_len(new_len); 421 | } 422 | 423 | /// Returns [`AnyVecRef`] - typed view to const AnyVec, 424 | /// if container holds elements of type T, or None if it isn’t. 425 | #[inline] 426 | pub fn downcast_ref(&self) -> Option> { 427 | if self.element_typeid() == TypeId::of::() { 428 | unsafe{ Some(self.downcast_ref_unchecked()) } 429 | } else { 430 | None 431 | } 432 | } 433 | 434 | /// Returns [`AnyVecRef`] - typed view to const AnyVec. 435 | /// 436 | /// # Safety 437 | /// 438 | /// The container elements must be of type `T`. 439 | /// Calling this method with the incorrect type is undefined behavior. 440 | #[inline] 441 | pub unsafe fn downcast_ref_unchecked(&self) -> AnyVecRef { 442 | AnyVecRef(AnyVecTyped::new(NonNull::from(&self.raw))) 443 | } 444 | 445 | /// Returns [`AnyVecMut`] - typed view to mut AnyVec, 446 | /// if container holds elements of type T, or None if it isn’t. 447 | #[inline] 448 | pub fn downcast_mut(&mut self) -> Option> { 449 | if self.element_typeid() == TypeId::of::() { 450 | unsafe{ Some(self.downcast_mut_unchecked()) } 451 | } else { 452 | None 453 | } 454 | } 455 | 456 | /// Returns [`AnyVecMut`] - typed view to mut AnyVec. 457 | /// 458 | /// # Safety 459 | /// 460 | /// The container elements must be of type `T`. 461 | /// Calling this method with the incorrect type is undefined behavior. 462 | #[inline] 463 | pub unsafe fn downcast_mut_unchecked(&mut self) -> AnyVecMut { 464 | AnyVecMut(AnyVecTyped::new(NonNull::from(&mut self.raw))) 465 | } 466 | 467 | #[inline] 468 | pub fn as_bytes(&self) -> &[u8] { 469 | unsafe{from_raw_parts( 470 | self.raw.mem.as_ptr(), 471 | self.len() * self.element_layout().size() 472 | )} 473 | } 474 | 475 | #[inline] 476 | pub fn as_bytes_mut(&mut self) -> &mut [u8]{ 477 | unsafe{from_raw_parts_mut( 478 | self.raw.mem.as_mut_ptr(), 479 | self.len() * self.element_layout().size() 480 | )} 481 | } 482 | 483 | #[inline] 484 | pub fn spare_bytes_mut(&mut self) -> &mut [MaybeUninit]{ 485 | unsafe{from_raw_parts_mut( 486 | self.raw.mem.as_mut_ptr().add(self.len()) as *mut MaybeUninit, 487 | (self.capacity() - self.len()) * self.element_layout().size() 488 | )} 489 | } 490 | 491 | #[inline] 492 | pub fn iter(&self) -> IterRef{ 493 | Iter::new(AnyVecPtr::from(self), 0, self.len()) 494 | } 495 | 496 | #[inline] 497 | pub fn iter_mut(&mut self) -> IterMut{ 498 | let len = self.len(); 499 | Iter::new(AnyVecPtr::from(self), 0, len) 500 | } 501 | 502 | /// Return reference to element at `index` with bounds check. 503 | /// 504 | /// # Panics 505 | /// 506 | /// * Panics if index is out of bounds. 507 | #[inline] 508 | pub fn at(&self, index: usize) -> ElementRef{ 509 | self.get(index).unwrap() 510 | } 511 | 512 | #[inline] 513 | pub fn get(&self, index: usize) -> Option>{ 514 | if index < self.len(){ 515 | Some(unsafe{ self.get_unchecked(index) }) 516 | } else { 517 | None 518 | } 519 | } 520 | 521 | #[inline] 522 | pub unsafe fn get_unchecked(&self, index: usize) -> ElementRef{ 523 | let element_ptr = self.raw.get_unchecked(index) as *mut u8; 524 | ElementRef( 525 | ManuallyDrop::new(ElementPointer::new( 526 | AnyVecPtr::from(self), 527 | NonNull::new_unchecked(element_ptr) 528 | )) 529 | ) 530 | } 531 | 532 | /// Return mutable reference to element at `index` with bounds check. 533 | /// 534 | /// # Panics 535 | /// 536 | /// * Panics if index is out of bounds. 537 | #[inline] 538 | pub fn at_mut(&mut self, index: usize) -> ElementMut{ 539 | self.get_mut(index).unwrap() 540 | } 541 | 542 | #[inline] 543 | pub fn get_mut(&mut self, index: usize) -> Option>{ 544 | if index < self.len(){ 545 | Some(unsafe{ self.get_unchecked_mut(index) }) 546 | } else { 547 | None 548 | } 549 | } 550 | 551 | #[inline] 552 | pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> ElementMut { 553 | let element_ptr = self.raw.get_unchecked_mut(index); 554 | ElementMut( 555 | ManuallyDrop::new(ElementPointer::new( 556 | AnyVecPtr::from(self), 557 | NonNull::new_unchecked(element_ptr) 558 | )) 559 | ) 560 | } 561 | 562 | /// # Panics 563 | /// 564 | /// * Panics if type mismatch. 565 | /// * Panics if index is out of bounds. 566 | /// * Panics if out of memory. 567 | #[inline] 568 | pub fn insert(&mut self, index: usize, value: V) { 569 | self.raw.type_check(&value); 570 | unsafe{ 571 | self.raw.insert_unchecked(index, value); 572 | } 573 | } 574 | 575 | /// Same as [`insert`], but without type checks. 576 | /// 577 | /// # Panics 578 | /// 579 | /// * Panics if index is out of bounds. 580 | /// * Panics if out of memory. 581 | /// 582 | /// # Safety 583 | /// 584 | /// Type not checked. 585 | /// 586 | /// [`insert`]: Self::insert 587 | #[inline] 588 | pub unsafe fn insert_unchecked(&mut self, index: usize, value: V) { 589 | self.raw.insert_unchecked(index, value); 590 | } 591 | 592 | /// # Panics 593 | /// 594 | /// * Panics if type mismatch. 595 | /// * Panics if out of memory. 596 | #[inline] 597 | pub fn push(&mut self, value: V) { 598 | self.raw.type_check(&value); 599 | unsafe{ 600 | self.raw.push_unchecked(value); 601 | } 602 | } 603 | 604 | /// Same as [`push`], but without type checks. 605 | /// 606 | /// # Panics 607 | /// 608 | /// Panics if out of memory. 609 | /// 610 | /// # Safety 611 | /// 612 | /// Type not checked. 613 | /// 614 | /// [`push`]: Self::push 615 | #[inline] 616 | pub unsafe fn push_unchecked(&mut self, value: V) { 617 | self.raw.push_unchecked(value); 618 | } 619 | 620 | /// # Leaking 621 | /// 622 | /// If the returned [`TempValue`] goes out of scope without being dropped (due to 623 | /// [`mem::forget`], for example), the vector will lost and leak last element. 624 | /// 625 | /// [`mem::forget`]: core::mem::forget 626 | /// 627 | #[inline] 628 | pub fn pop(&mut self) -> Option> { 629 | if self.is_empty(){ 630 | None 631 | } else { 632 | Some(TempValue::new( 633 | pop::Pop::new(AnyVecPtr::from(self)) 634 | )) 635 | } 636 | } 637 | 638 | /// # Panics 639 | /// 640 | /// Panics if index out of bounds. 641 | /// 642 | /// # Leaking 643 | /// 644 | /// If the returned [`TempValue`] goes out of scope without being dropped (due to 645 | /// [`mem::forget`], for example), the vector may have lost and leaked 646 | /// elements with indices >= index. 647 | /// 648 | /// [`mem::forget`]: core::mem::forget 649 | /// 650 | #[inline] 651 | pub fn remove(&mut self, index: usize) -> Remove { 652 | self.raw.index_check(index); 653 | TempValue::new(remove::Remove::new( 654 | AnyVecPtr::from(self), 655 | index 656 | )) 657 | } 658 | 659 | /// # Panics 660 | /// 661 | /// Panics if index out of bounds. 662 | /// 663 | /// # Leaking 664 | /// 665 | /// If the returned [`TempValue`] goes out of scope without being dropped (due to 666 | /// [`mem::forget`], for example), the vector may have lost and leaked 667 | /// elements with indices >= index. 668 | /// 669 | /// [`mem::forget`]: core::mem::forget 670 | /// 671 | #[inline] 672 | pub fn swap_remove(&mut self, index: usize) -> SwapRemove { 673 | self.raw.index_check(index); 674 | TempValue::new(swap_remove::SwapRemove::new( 675 | AnyVecPtr::from(self), 676 | index 677 | )) 678 | } 679 | 680 | /// Removes the specified range from the vector in bulk, returning all removed 681 | /// elements as an iterator. If the iterator is dropped before being fully consumed, 682 | /// it drops the remaining removed elements. 683 | /// 684 | /// The returned iterator keeps a mutable borrow on the vector. 685 | /// 686 | /// # Panics 687 | /// 688 | /// Panics if the starting point is greater than the end point or if the end point 689 | /// is greater than the length of the vector. 690 | /// 691 | /// # Leaking 692 | /// 693 | /// If the returned iterator goes out of scope without being dropped (due to 694 | /// [`mem::forget`], for example), the vector may have lost and leaked 695 | /// elements with indices in and past the range. 696 | /// 697 | /// [`mem::forget`]: core::mem::forget 698 | /// 699 | #[inline] 700 | pub fn drain(&mut self, range: impl RangeBounds) -> Drain { 701 | let Range{start, end} = into_range(self.len(), range); 702 | ops::Iter(drain::Drain::new( 703 | AnyVecPtr::from(self), 704 | start, 705 | end 706 | )) 707 | } 708 | 709 | /// Creates a splicing iterator that replaces the specified range in the vector 710 | /// with the given `replace_with` iterator and yields the removed items. 711 | /// `replace_with` does not need to be the same length as `range`. 712 | /// 713 | /// `range` is removed even if the iterator is not consumed until the end. 714 | /// 715 | /// The returned iterator keeps a mutable borrow on the vector. 716 | /// 717 | /// # Panics 718 | /// 719 | /// Panics if the starting point is greater than the end point or if 720 | /// the end point is greater than the length of the vector. 721 | /// 722 | /// # Leaking 723 | /// 724 | /// If the returned iterator goes out of scope without being dropped (due to 725 | /// [`mem::forget`], for example), the vector may have lost and leaked 726 | /// elements with indices in and past the range. 727 | /// 728 | /// [`mem::forget`]: core::mem::forget 729 | /// 730 | #[inline] 731 | pub fn splice(&mut self, range: impl RangeBounds, replace_with: I) 732 | -> Splice 733 | where 734 | I::IntoIter: ExactSizeIterator, 735 | I::Item: AnyValue 736 | { 737 | let Range{start, end} = into_range(self.len(), range); 738 | ops::Iter(splice::Splice::new( 739 | AnyVecPtr::from(self), 740 | start, 741 | end, 742 | replace_with.into_iter() 743 | )) 744 | } 745 | 746 | #[inline] 747 | pub fn clear(&mut self){ 748 | self.raw.clear() 749 | } 750 | 751 | /// Element TypeId 752 | #[inline] 753 | pub fn element_typeid(&self) -> TypeId{ 754 | self.raw.type_id 755 | } 756 | 757 | /// Element Layout 758 | #[inline] 759 | pub fn element_layout(&self) -> Layout { 760 | self.raw.element_layout() 761 | } 762 | 763 | /// Element drop function. 764 | /// 765 | /// `len` - elements count. 766 | /// None - drop is not needed. 767 | #[inline] 768 | pub fn element_drop(&self) -> Option { 769 | self.raw.drop_fn 770 | } 771 | 772 | /// Element clone function. 773 | /// 774 | /// `len` - elements count. 775 | #[inline] 776 | pub fn element_clone(&self) -> CloneFn 777 | where 778 | Traits: Cloneable 779 | { 780 | self.clone_fn() 781 | } 782 | 783 | #[inline] 784 | pub fn len(&self) -> usize { 785 | self.raw.len 786 | } 787 | 788 | #[inline] 789 | pub fn is_empty(&self) -> bool { 790 | self.len() == 0 791 | } 792 | 793 | #[inline] 794 | pub fn capacity(&self) -> usize { 795 | self.raw.capacity() 796 | } 797 | } 798 | 799 | unsafe impl Send for AnyVec 800 | where M::Mem: Send 801 | {} 802 | unsafe impl Sync for AnyVec 803 | where M::Mem: Sync 804 | {} 805 | impl Clone for AnyVec 806 | { 807 | fn clone(&self) -> Self { 808 | Self{ 809 | raw: unsafe{ self.raw.clone(self.clone_fn()) }, 810 | clone_fn: self.clone_fn, 811 | phantom: PhantomData 812 | } 813 | } 814 | } 815 | 816 | impl Debug for AnyVec{ 817 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 818 | f.debug_struct("AnyVec") 819 | .field("typeid", &self.element_typeid()) 820 | .field("len", &self.len()) 821 | .finish() 822 | } 823 | } 824 | 825 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> IntoIterator for &'a AnyVec{ 826 | type Item = ElementRef<'a, Traits, M>; 827 | type IntoIter = IterRef<'a, Traits, M>; 828 | 829 | #[inline] 830 | fn into_iter(self) -> Self::IntoIter { 831 | self.iter() 832 | } 833 | } 834 | 835 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> IntoIterator for &'a mut AnyVec{ 836 | type Item = ElementMut<'a, Traits, M>; 837 | type IntoIter = IterMut<'a, Traits, M>; 838 | 839 | #[inline] 840 | fn into_iter(self) -> Self::IntoIter { 841 | self.iter_mut() 842 | } 843 | } 844 | 845 | /// Typed view to &[`AnyVec`]. 846 | /// 847 | /// You can get it from [`AnyVec::downcast_ref`]. 848 | /// 849 | /// [`AnyVec`]: crate::AnyVec 850 | /// [`AnyVec::downcast_ref`]: crate::AnyVec::downcast_ref 851 | pub struct AnyVecRef<'a, T: 'static, M: MemBuilder + 'a>(pub(crate) AnyVecTyped<'a, T, M>); 852 | impl<'a, T: 'static, M: MemBuilder + 'a> Clone for AnyVecRef<'a, T, M>{ 853 | #[inline] 854 | fn clone(&self) -> Self { 855 | Self(self.0.clone()) 856 | } 857 | } 858 | impl<'a, T: 'static, M: MemBuilder + 'a> Deref for AnyVecRef<'a, T, M>{ 859 | type Target = AnyVecTyped<'a, T, M>; 860 | 861 | #[inline] 862 | fn deref(&self) -> &Self::Target { 863 | &self.0 864 | } 865 | } 866 | impl<'a, T: 'static, M: MemBuilder + 'a> IntoIterator for AnyVecRef<'a, T, M>{ 867 | type Item = &'a T; 868 | type IntoIter = slice::Iter<'a, T>; 869 | 870 | #[inline] 871 | fn into_iter(self) -> Self::IntoIter { 872 | self.iter() 873 | } 874 | } 875 | impl<'a, T: 'static + Debug, M: MemBuilder + 'a> Debug for AnyVecRef<'a, T, M>{ 876 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 877 | self.0.fmt(f) 878 | } 879 | } 880 | 881 | /// Typed view to &mut [`AnyVec`]. 882 | /// 883 | /// You can get it from [`AnyVec::downcast_mut`]. 884 | /// 885 | /// [`AnyVec`]: crate::AnyVec 886 | /// [`AnyVec::downcast_mut`]: crate::AnyVec::downcast_mut 887 | pub struct AnyVecMut<'a, T: 'static, M: MemBuilder + 'a>(pub(crate) AnyVecTyped<'a, T, M>); 888 | impl<'a, T: 'static, M: MemBuilder + 'a> Deref for AnyVecMut<'a, T, M>{ 889 | type Target = AnyVecTyped<'a, T, M>; 890 | 891 | #[inline] 892 | fn deref(&self) -> &Self::Target { 893 | &self.0 894 | } 895 | } 896 | impl<'a, T: 'static, M: MemBuilder + 'a> DerefMut for AnyVecMut<'a, T, M>{ 897 | #[inline] 898 | fn deref_mut(&mut self) -> &mut Self::Target { 899 | &mut self.0 900 | } 901 | } 902 | impl<'a, T: 'static, M: MemBuilder + 'a> IntoIterator for AnyVecMut<'a, T, M>{ 903 | type Item = &'a mut T; 904 | type IntoIter = slice::IterMut<'a, T>; 905 | 906 | #[inline] 907 | fn into_iter(mut self) -> Self::IntoIter { 908 | self.iter_mut() 909 | } 910 | } 911 | impl<'a, T: 'static + Debug, M: MemBuilder + 'a> Debug for AnyVecMut<'a, T, M>{ 912 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 913 | self.0.fmt(f) 914 | } 915 | } -------------------------------------------------------------------------------- /src/any_vec_ptr.rs: -------------------------------------------------------------------------------- 1 | //! Type dispatched analog of `enum{*AnyVecRaw, *AnyVec}`. 2 | 3 | use core::marker::PhantomData; 4 | use core::ptr::NonNull; 5 | use crate::any_value::Unknown; 6 | use crate::any_vec_raw::AnyVecRaw; 7 | use crate::AnyVec; 8 | use crate::mem::{MemBuilder}; 9 | use crate::traits::Trait; 10 | 11 | pub trait IAnyVecRawPtr: Copy{ 12 | /// Known element type of AnyVec 13 | type Element: 'static/* = Unknown*/; 14 | type M: MemBuilder; 15 | unsafe fn any_vec_raw<'a>(&self) -> &'a AnyVecRaw; 16 | unsafe fn any_vec_raw_mut<'a>(&mut self) -> &'a mut AnyVecRaw; 17 | } 18 | pub trait IAnyVecPtr: IAnyVecRawPtr{ 19 | type Traits: ?Sized + Trait; 20 | unsafe fn any_vec<'a>(&self) -> &'a AnyVec; 21 | unsafe fn any_vec_mut<'a>(&mut self) -> &'a mut AnyVec; 22 | } 23 | 24 | 25 | pub struct AnyVecRawPtr{ 26 | ptr: NonNull>, 27 | phantom: PhantomData<*mut Type> 28 | } 29 | impl From>> for AnyVecRawPtr{ 30 | #[inline] 31 | fn from(ptr: NonNull>) -> Self { 32 | Self{ptr, phantom: PhantomData} 33 | } 34 | } 35 | impl Copy for AnyVecRawPtr {} 36 | impl Clone for AnyVecRawPtr { 37 | #[inline] 38 | fn clone(&self) -> Self { 39 | Self{ 40 | ptr: self.ptr, 41 | phantom: PhantomData 42 | } 43 | } 44 | } 45 | 46 | impl IAnyVecRawPtr for AnyVecRawPtr{ 47 | type Element = Type; 48 | type M = M; 49 | 50 | #[inline] 51 | unsafe fn any_vec_raw<'a>(&self) -> &'a AnyVecRaw { 52 | self.ptr.as_ref() 53 | } 54 | 55 | #[inline] 56 | unsafe fn any_vec_raw_mut<'a>(&mut self) -> &'a mut AnyVecRaw { 57 | self.ptr.as_mut() 58 | } 59 | } 60 | 61 | 62 | pub struct AnyVecPtr{ 63 | ptr: NonNull> 64 | } 65 | impl From>> for AnyVecPtr { 66 | #[inline] 67 | fn from(ptr: NonNull>) -> Self { 68 | Self{ptr} 69 | } 70 | } 71 | impl From<&mut AnyVec> for AnyVecPtr { 72 | #[inline] 73 | fn from(reference: &mut AnyVec) -> Self { 74 | Self{ptr: NonNull::from(reference)} 75 | } 76 | } 77 | impl From<&AnyVec> for AnyVecPtr { 78 | #[inline] 79 | fn from(reference: &AnyVec) -> Self { 80 | Self{ptr: NonNull::from(reference)} 81 | } 82 | } 83 | impl Clone for AnyVecPtr{ 84 | #[inline] 85 | fn clone(&self) -> Self { 86 | Self{ptr: self.ptr} 87 | } 88 | } 89 | impl Copy for AnyVecPtr{} 90 | 91 | impl IAnyVecRawPtr for AnyVecPtr { 92 | type Element = Unknown; 93 | type M = M; 94 | 95 | #[inline] 96 | unsafe fn any_vec_raw<'a>(&self) -> &'a AnyVecRaw { 97 | &self.ptr.as_ref().raw 98 | } 99 | 100 | #[inline] 101 | unsafe fn any_vec_raw_mut<'a>(&mut self) -> &'a mut AnyVecRaw { 102 | &mut self.ptr.as_mut().raw 103 | } 104 | } 105 | impl IAnyVecPtr for AnyVecPtr { 106 | type Traits = Traits; 107 | 108 | #[inline] 109 | unsafe fn any_vec<'a>(&self) -> &'a AnyVec { 110 | self.ptr.as_ref() 111 | } 112 | 113 | #[inline] 114 | unsafe fn any_vec_mut<'a>(&mut self) -> &'a mut AnyVec { 115 | self.ptr.as_mut() 116 | } 117 | } 118 | 119 | 120 | /// Type knowledge optimized operations. 121 | /// 122 | /// All unsafe, because dereferencing pointer is unsafe. 123 | pub(crate) mod utils{ 124 | use core::{mem, ptr}; 125 | use core::any::TypeId; 126 | use core::mem::size_of; 127 | use core::ptr::NonNull; 128 | use crate::any_value::Unknown; 129 | use crate::any_vec_ptr::IAnyVecRawPtr; 130 | use crate::AnyVecTyped; 131 | 132 | #[inline] 133 | pub unsafe fn element_typeid(any_vec_ptr: AnyVecPtr) -> TypeId 134 | { 135 | if Unknown::is::(){ 136 | let any_vec_raw = any_vec_ptr.any_vec_raw(); 137 | any_vec_raw.type_id 138 | } else { 139 | TypeId::of::() 140 | } 141 | } 142 | 143 | /// In bytes. 144 | #[inline] 145 | pub unsafe fn element_size(any_vec_ptr: AnyVecPtr) -> usize 146 | { 147 | if Unknown::is::(){ 148 | let any_vec_raw = any_vec_ptr.any_vec_raw(); 149 | any_vec_raw.element_layout().size() 150 | } else { 151 | size_of::() 152 | } 153 | } 154 | 155 | #[inline] 156 | pub unsafe fn element_ptr_at(any_vec_ptr: AnyVecPtr, index: usize) 157 | -> *const u8 158 | { 159 | let any_vec_raw = any_vec_ptr.any_vec_raw(); 160 | if Unknown::is::(){ 161 | any_vec_raw.get_unchecked(index) 162 | } else { 163 | // AnyVecTyped::get_unchecked cause MIRI error 164 | AnyVecTyped::::new(NonNull::from(any_vec_raw)) 165 | .as_ptr().add(index) 166 | as *const _ as *const u8 167 | } 168 | } 169 | 170 | #[inline] 171 | pub unsafe fn element_mut_ptr_at(mut any_vec_ptr: AnyVecPtr, index: usize) 172 | -> *mut u8 173 | { 174 | let any_vec_raw = any_vec_ptr.any_vec_raw_mut(); 175 | if Unknown::is::(){ 176 | any_vec_raw.get_unchecked_mut(index) 177 | } else { 178 | // AnyVecTyped::get_unchecked_mut cause MIRI error 179 | AnyVecTyped::::new(NonNull::from(any_vec_raw)) 180 | .as_mut_ptr().add(index) 181 | as *mut _ as *mut u8 182 | } 183 | } 184 | 185 | #[inline] 186 | pub unsafe fn move_elements_at 187 | (any_vec_ptr: AnyVecPtr, src_index: usize, dst_index: usize, len: usize) 188 | { 189 | let src = element_ptr_at(any_vec_ptr, src_index); 190 | let dst = element_mut_ptr_at(any_vec_ptr, dst_index); 191 | if Unknown::is::(){ 192 | let any_vec_raw = any_vec_ptr.any_vec_raw(); 193 | ptr::copy( 194 | src, 195 | dst, 196 | any_vec_raw.element_layout().size() * len 197 | ); 198 | } else { 199 | ptr::copy( 200 | src as * const AnyVecPtr::Element, 201 | dst as *mut AnyVecPtr::Element, 202 | len 203 | ); 204 | } 205 | } 206 | 207 | #[inline] 208 | pub unsafe fn drop_elements_range 209 | (any_vec_ptr: AnyVecPtr, start_index: usize, end_index: usize) 210 | { 211 | debug_assert!(start_index <= end_index); 212 | 213 | if Unknown::is::(){ 214 | let any_vec_raw = any_vec_ptr.any_vec_raw(); 215 | if let Some(drop_fn) = any_vec_raw.drop_fn{ 216 | (drop_fn)( 217 | element_mut_ptr_at(any_vec_ptr, start_index), 218 | end_index - start_index 219 | ); 220 | } 221 | } else if mem::needs_drop::(){ 222 | // drop as slice. This is marginally faster then one by one. 223 | let start_ptr = element_mut_ptr_at(any_vec_ptr, start_index) as *mut AnyVecPtr::Element; 224 | let to_drop = ptr::slice_from_raw_parts_mut(start_ptr, end_index - start_index); 225 | ptr::drop_in_place(to_drop); 226 | } 227 | } 228 | } -------------------------------------------------------------------------------- /src/any_vec_raw.rs: -------------------------------------------------------------------------------- 1 | use core::{cmp, mem, ptr}; 2 | use core::alloc::Layout; 3 | use core::any::TypeId; 4 | use core::mem::size_of; 5 | use crate::any_value::{AnyValue, Unknown, AnyValueSizeless}; 6 | use crate::assert_types_equal; 7 | use crate::clone_type::CloneFn; 8 | use crate::mem::{Mem, MemBuilder, MemResizable}; 9 | 10 | pub type DropFn = unsafe fn(ptr: *mut u8, len: usize); 11 | 12 | pub struct AnyVecRaw { 13 | pub(crate) mem_builder: M, // usually ZST 14 | pub(crate) mem: M::Mem, 15 | pub(crate) len: usize, // in elements 16 | pub(crate) type_id: TypeId, // purely for safety checks 17 | pub(crate) drop_fn: Option 18 | } 19 | 20 | impl AnyVecRaw { 21 | #[inline] 22 | pub fn new(mem_builder: M, mem: M::Mem) -> Self { 23 | Self{ 24 | mem_builder, 25 | mem, 26 | len: 0, 27 | type_id: TypeId::of::(), 28 | drop_fn: 29 | if !mem::needs_drop::(){ 30 | None 31 | } else{ 32 | Some(|mut ptr: *mut u8, len: usize|{ 33 | for _ in 0..len{ 34 | unsafe{ 35 | ptr::drop_in_place(ptr as *mut T); 36 | ptr = ptr.add(mem::size_of::()); 37 | } 38 | } 39 | }) 40 | } 41 | } 42 | } 43 | 44 | #[inline] 45 | pub(crate) fn clone_empty(&self) -> Self { 46 | self.clone_empty_in(self.mem_builder.clone()) 47 | } 48 | 49 | #[inline] 50 | pub(crate) fn clone_empty_in(&self, mut mem_builder: NewM) -> AnyVecRaw{ 51 | let mem = mem_builder.build(self.element_layout()); 52 | AnyVecRaw{ 53 | mem_builder, 54 | mem, 55 | len: 0, 56 | type_id: self.type_id, 57 | drop_fn: self.drop_fn, 58 | } 59 | } 60 | 61 | /// Unsafe, because type cloneability is not checked 62 | pub(crate) unsafe fn clone(&self, clone_fn: CloneFn) -> Self { 63 | // 1. construct empty "prototype" 64 | let mut cloned = self.clone_empty(); 65 | 66 | // 2. allocate 67 | cloned.mem.expand(self.len); 68 | 69 | // 3. copy/clone 70 | { 71 | let src = self.mem.as_ptr(); 72 | let dst = cloned.mem.as_mut_ptr(); 73 | (clone_fn)(src, dst, self.len); 74 | } 75 | 76 | // 4. set len 77 | cloned.len = self.len; 78 | cloned 79 | } 80 | 81 | #[inline] 82 | pub(crate) fn index_check(&self, index: usize){ 83 | assert!(index < self.len, "Index out of range!"); 84 | } 85 | 86 | #[inline] 87 | pub(crate) fn type_check(&self, value: &V){ 88 | assert_types_equal(value.value_typeid(), self.type_id); 89 | } 90 | 91 | #[inline] 92 | pub unsafe fn get_unchecked(&self, index: usize) -> *const u8{ 93 | self.mem.as_ptr().add(self.element_layout().size() * index) 94 | } 95 | 96 | #[inline] 97 | pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> *mut u8{ 98 | self.mem.as_mut_ptr().add(self.element_layout().size() * index) 99 | } 100 | 101 | #[cold] 102 | #[inline(never)] 103 | fn expand_one(&mut self){ 104 | self.mem.expand(1); 105 | } 106 | 107 | #[inline] 108 | /*pub(crate)*/ fn reserve_one(&mut self){ 109 | if self.len == self.capacity(){ 110 | self.expand_one(); 111 | } 112 | } 113 | 114 | /// Leave this, for Mem, because implementation need it. 115 | /// If M::Mem does not implement MemResizable, then `expand` 116 | /// will panic, if out of capacity. 117 | #[inline] 118 | pub fn reserve(&mut self, additional: usize) { 119 | let new_len = self.len + additional; 120 | if self.capacity() < new_len{ 121 | self.mem.expand(new_len - self.capacity()); 122 | } 123 | } 124 | 125 | #[inline] 126 | pub fn reserve_exact(&mut self, additional: usize) 127 | where M::Mem: MemResizable 128 | { 129 | let new_len = self.len + additional; 130 | if self.capacity() < new_len{ 131 | self.mem.expand_exact(new_len - self.capacity()); 132 | } 133 | } 134 | 135 | pub fn shrink_to_fit(&mut self) 136 | where M::Mem: MemResizable 137 | { 138 | self.mem.resize(self.len); 139 | } 140 | 141 | pub fn shrink_to(&mut self, min_capacity: usize) 142 | where M::Mem: MemResizable 143 | { 144 | let new_len = cmp::max(self.len, min_capacity); 145 | self.mem.resize(new_len); 146 | } 147 | 148 | #[inline] 149 | pub unsafe fn set_len(&mut self, new_len: usize) { 150 | debug_assert!(new_len <= self.capacity()); 151 | self.len = new_len; 152 | } 153 | 154 | /// # Safety 155 | /// 156 | /// Type is not checked. 157 | pub unsafe fn insert_unchecked(&mut self, index: usize, value: V) { 158 | assert!(index <= self.len, "Index out of range!"); 159 | 160 | self.reserve_one(); 161 | 162 | // Compile time type optimization 163 | if !Unknown::is::(){ 164 | let element = self.mem.as_mut_ptr().cast::().add(index); 165 | 166 | // 1. shift right 167 | ptr::copy( 168 | element, 169 | element.add(1), 170 | self.len - index 171 | ); 172 | 173 | // 2. write value 174 | value.move_into::(element as *mut u8, size_of::()); 175 | } else { 176 | let element_size = self.element_layout().size(); 177 | let element = self.mem.as_mut_ptr().add(element_size * index); 178 | 179 | // 1. shift right 180 | crate::copy_bytes( 181 | element, 182 | element.add(element_size), 183 | element_size * (self.len - index) 184 | ); 185 | 186 | // 2. write value 187 | value.move_into::(element, element_size); 188 | } 189 | 190 | self.len += 1; 191 | } 192 | 193 | /// # Safety 194 | /// 195 | /// Type is not checked. 196 | #[inline] 197 | pub unsafe fn push_unchecked(&mut self, value: V) { 198 | self.reserve_one(); 199 | 200 | // Compile time type optimization 201 | if !Unknown::is::(){ 202 | let element = self.mem.as_mut_ptr().cast::().add(self.len) as *mut u8; 203 | value.move_into::(element, size_of::()); 204 | } else { 205 | let element_size = self.element_layout().size(); 206 | let element = self.mem.as_mut_ptr().add(element_size * self.len); 207 | value.move_into::(element, element_size); 208 | }; 209 | 210 | self.len += 1; 211 | } 212 | 213 | #[inline] 214 | pub fn clear(&mut self){ 215 | let len = self.len; 216 | 217 | // Prematurely set the length to zero so that even if dropping the values panics users 218 | // won't be able to access the dropped values. 219 | self.len = 0; 220 | 221 | if let Some(drop_fn) = self.drop_fn{ 222 | unsafe{ 223 | (drop_fn)(self.mem.as_mut_ptr(), len); 224 | } 225 | } 226 | } 227 | 228 | /// Element Layout 229 | #[inline] 230 | pub fn element_layout(&self) -> Layout { 231 | self.mem.element_layout() 232 | } 233 | 234 | #[inline] 235 | pub fn capacity(&self) -> usize { 236 | self.mem.size() 237 | } 238 | } 239 | 240 | impl Drop for AnyVecRaw { 241 | #[inline] 242 | fn drop(&mut self) { 243 | self.clear(); 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /src/any_vec_typed.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{Debug, Formatter}; 2 | use core::marker::PhantomData; 3 | use core::mem::MaybeUninit; 4 | use core::ops::{Range, RangeBounds}; 5 | use core::ptr::NonNull; 6 | use core::{fmt, slice}; 7 | use crate::any_value::{AnyValueSizeless, AnyValueWrapper}; 8 | use crate::any_vec_raw::AnyVecRaw; 9 | use crate::ops::{Iter, pop, remove, swap_remove, TempValue}; 10 | use crate::any_vec_ptr::AnyVecRawPtr; 11 | use crate::into_range; 12 | use crate::iter::ElementIterator; 13 | use crate::mem::{MemBuilder, Mem, MemResizable}; 14 | use crate::ops::drain::Drain; 15 | use crate::ops::splice::Splice; 16 | 17 | /// Concrete type [`AnyVec`] representation. 18 | /// 19 | /// Obtained by dereferencing [`AnyVecRef`] or [`AnyVecMut`]. 20 | /// 21 | /// Operations with concrete type are somewhat faster, due to 22 | /// the fact, that compiler are able to optimize harder with full 23 | /// type knowledge. 24 | /// 25 | /// [`AnyVec`]: crate::AnyVec 26 | /// [`AnyVec::downcast_`]: crate::AnyVec::downcast_ref 27 | /// [`AnyVecRef`]: crate::AnyVecRef 28 | /// [`AnyVecMut`]: crate::AnyVecMut 29 | pub struct AnyVecTyped<'a, T: 'static, M: MemBuilder + 'a>{ 30 | // NonNull - to have one struct for both & and &mut 31 | any_vec: NonNull>, 32 | phantom: PhantomData<&'a mut T> 33 | } 34 | 35 | unsafe impl<'a, T: 'static + Send, M: MemBuilder + Send> Send for AnyVecTyped<'a, T, M> 36 | where M::Mem: Send 37 | {} 38 | unsafe impl<'a, T: 'static + Sync, M: MemBuilder + Sync> Sync for AnyVecTyped<'a, T, M> 39 | where M::Mem: Sync 40 | {} 41 | 42 | impl<'a, T: 'static, M: MemBuilder + 'a> AnyVecTyped<'a, T, M>{ 43 | /// # Safety 44 | /// 45 | /// Unsafe, because type not checked 46 | #[inline] 47 | pub(crate) unsafe fn new(any_vec: NonNull>) -> Self { 48 | Self{any_vec, phantom: PhantomData} 49 | } 50 | 51 | /// AnyVecTyped should not be Clone, because it can be both & and &mut. 52 | #[inline] 53 | pub(crate) fn clone(&self) -> Self { 54 | Self{any_vec: self.any_vec, phantom: PhantomData} 55 | } 56 | 57 | #[inline] 58 | fn this(&self) -> &'a AnyVecRaw { 59 | unsafe{ self.any_vec.as_ref() } 60 | } 61 | 62 | #[inline] 63 | fn this_mut(&mut self) -> &'a mut AnyVecRaw { 64 | unsafe{ self.any_vec.as_mut() } 65 | } 66 | 67 | #[inline] 68 | pub fn reserve(&mut self, additional: usize) 69 | where M::Mem: MemResizable 70 | { 71 | self.this_mut().reserve(additional) 72 | } 73 | 74 | #[inline] 75 | pub fn reserve_exact(&mut self, additional: usize) 76 | where M::Mem: MemResizable 77 | { 78 | self.this_mut().reserve_exact(additional) 79 | } 80 | 81 | #[inline] 82 | pub fn shrink_to_fit(&mut self) 83 | where M::Mem: MemResizable 84 | { 85 | self.this_mut().shrink_to_fit() 86 | } 87 | 88 | #[inline] 89 | pub fn shrink_to(&mut self, min_capacity: usize) 90 | where M::Mem: MemResizable 91 | { 92 | self.this_mut().shrink_to(min_capacity) 93 | } 94 | 95 | #[inline] 96 | pub unsafe fn set_len(&mut self, new_len: usize) { 97 | self.this_mut().set_len(new_len); 98 | } 99 | 100 | #[inline] 101 | pub fn insert(&mut self, index: usize, value: T){ 102 | unsafe{ 103 | self.this_mut().insert_unchecked(index, AnyValueWrapper::new(value)); 104 | } 105 | } 106 | 107 | #[inline] 108 | pub fn push(&mut self, value: T){ 109 | unsafe{ 110 | self.this_mut().push_unchecked(AnyValueWrapper::new(value)); 111 | } 112 | } 113 | 114 | #[inline] 115 | pub fn pop(&mut self) -> Option { 116 | if self.is_empty(){ 117 | None 118 | } else { 119 | let value = unsafe{ 120 | TempValue::new(pop::Pop::new( 121 | AnyVecRawPtr::::from(self.any_vec) 122 | )).downcast_unchecked::() 123 | }; 124 | Some(value) 125 | } 126 | } 127 | 128 | #[inline] 129 | pub fn remove(&mut self, index: usize) -> T { 130 | self.this().index_check(index); 131 | unsafe{ 132 | TempValue::new(remove::Remove::new( 133 | AnyVecRawPtr::::from(self.any_vec), 134 | index 135 | )).downcast_unchecked::() 136 | } 137 | } 138 | 139 | #[inline] 140 | pub fn swap_remove(&mut self, index: usize) -> T { 141 | self.this().index_check(index); 142 | unsafe{ 143 | TempValue::new(swap_remove::SwapRemove::new( 144 | AnyVecRawPtr::::from(self.any_vec), 145 | index 146 | )).downcast_unchecked::() 147 | } 148 | } 149 | 150 | #[inline] 151 | pub fn drain(&mut self, range: impl RangeBounds) 152 | -> impl ElementIterator + 'a 153 | { 154 | let Range{start, end} = into_range(self.len(), range); 155 | Iter(Drain::new( 156 | AnyVecRawPtr::::from(self.any_vec), 157 | start, 158 | end 159 | )).map(|e| unsafe{ 160 | e.downcast_unchecked::() 161 | }) 162 | } 163 | 164 | #[inline] 165 | pub fn splice(&mut self, range: impl RangeBounds, replace_with: I) 166 | -> impl ElementIterator + 'a 167 | where 168 | I: IntoIterator, 169 | I::IntoIter: ExactSizeIterator + 'a, 170 | { 171 | let Range{start, end} = into_range(self.len(), range); 172 | let replace_with = replace_with.into_iter() 173 | .map(|e| AnyValueWrapper::new(e)); 174 | 175 | Iter(Splice::new( 176 | AnyVecRawPtr::::from(self.any_vec), 177 | start, 178 | end, 179 | replace_with 180 | )).map(|e| unsafe{ 181 | e.downcast_unchecked::() 182 | }) 183 | } 184 | 185 | #[inline] 186 | pub fn clear(&mut self){ 187 | self.this_mut().clear(); 188 | } 189 | 190 | #[inline] 191 | pub fn iter(&self) -> slice::Iter<'a, T> { 192 | self.as_slice().iter() 193 | } 194 | 195 | #[inline] 196 | pub fn iter_mut(&mut self) -> slice::IterMut<'a, T> { 197 | self.as_mut_slice().iter_mut() 198 | } 199 | 200 | #[inline] 201 | pub fn at(&self, index: usize) -> &'a T{ 202 | self.get(index).unwrap() 203 | } 204 | 205 | #[inline] 206 | pub fn get(&self, index: usize) -> Option<&'a T> { 207 | self.as_slice().get(index) 208 | } 209 | 210 | #[inline] 211 | pub unsafe fn get_unchecked(&self, index: usize) -> &'a T { 212 | self.as_slice().get_unchecked(index) 213 | } 214 | 215 | #[inline] 216 | pub fn at_mut(&mut self, index: usize) -> &'a mut T{ 217 | self.get_mut(index).unwrap() 218 | } 219 | 220 | #[inline] 221 | pub fn get_mut(&mut self, index: usize) -> Option<&'a mut T>{ 222 | self.as_mut_slice().get_mut(index) 223 | } 224 | 225 | #[inline] 226 | pub unsafe fn get_unchecked_mut(&mut self, index: usize) -> &'a mut T { 227 | self.as_mut_slice().get_unchecked_mut(index) 228 | } 229 | 230 | #[inline] 231 | pub fn as_ptr(&self) -> *const T { 232 | self.this().mem.as_ptr().cast::() 233 | } 234 | 235 | #[inline] 236 | pub fn as_mut_ptr(&mut self) -> *mut T { 237 | self.this_mut().mem.as_mut_ptr().cast::() 238 | } 239 | 240 | #[inline] 241 | pub fn as_slice(&self) -> &'a [T] { 242 | unsafe{ 243 | slice::from_raw_parts( 244 | self.as_ptr(), 245 | self.len(), 246 | ) 247 | } 248 | } 249 | 250 | #[inline] 251 | pub fn as_mut_slice(&mut self) -> &'a mut[T] { 252 | unsafe{ 253 | slice::from_raw_parts_mut( 254 | self.as_mut_ptr(), 255 | self.len(), 256 | ) 257 | } 258 | } 259 | 260 | #[inline] 261 | pub fn spare_capacity_mut(&mut self) -> &'a mut[MaybeUninit] { 262 | unsafe { 263 | slice::from_raw_parts_mut( 264 | self.as_mut_ptr().add(self.len()) as *mut MaybeUninit, 265 | self.capacity() - self.len(), 266 | ) 267 | } 268 | } 269 | 270 | #[inline] 271 | pub fn len(&self) -> usize { 272 | self.this().len 273 | } 274 | 275 | #[inline] 276 | pub fn is_empty(&self) -> bool { 277 | self.len() == 0 278 | } 279 | 280 | #[inline] 281 | pub fn capacity(&self) -> usize { 282 | self.this().capacity() 283 | } 284 | } 285 | 286 | impl<'a, T: 'static + Debug, M: MemBuilder> Debug for AnyVecTyped<'a, T, M>{ 287 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 288 | (*self.as_slice()).fmt(f) 289 | } 290 | } 291 | 292 | // Do not implement Index, since we can't do the same for AnyVec 293 | /* 294 | impl<'a, T: 'static, I: SliceIndex<[T]>> Index for AnyVecTyped<'a, T> { 295 | type Output = I::Output; 296 | 297 | #[inline] 298 | fn index(&self, index: I) -> &'a Self::Output { 299 | self.as_slice().index(index) 300 | } 301 | } 302 | 303 | impl<'a, T: 'static, I: SliceIndex<[T]>> IndexMut for AnyVecTyped<'a, T> { 304 | #[inline] 305 | fn index_mut(&mut self, index: I) -> &'a mut Self::Output { 306 | self.as_mut_slice().index_mut(index) 307 | } 308 | } 309 | */ -------------------------------------------------------------------------------- /src/clone_type.rs: -------------------------------------------------------------------------------- 1 | //! 2 | //! Trait object based compile-time dispatch. 3 | //! 4 | 5 | use crate::traits::*; 6 | 7 | #[derive(Copy, Clone, Default)] 8 | pub struct Empty; 9 | 10 | pub type CloneFn = unsafe fn(src: *const u8, dst: *mut u8, len: usize); 11 | unsafe fn clone_fn(src: *const u8, dst: *mut u8, len: usize){ 12 | let src = src as *const T; 13 | let dst = dst as *mut T; 14 | for i in 0..len { 15 | let dst = dst.add(i); 16 | let src = src.add(i); 17 | dst.write((*src).clone()); 18 | } 19 | } 20 | fn nop_fn(_: *const u8, _: *mut u8, _: usize){} 21 | 22 | 23 | pub trait CloneFnTrait{ 24 | const CLONE_FN: CloneFn = nop_fn; 25 | } 26 | impl CloneFnTrait for T{ 27 | const CLONE_FN: CloneFn = clone_fn::; 28 | } 29 | impl CloneFnTrait for T{ 30 | const CLONE_FN: CloneFn = clone_fn::; 31 | } 32 | impl CloneFnTrait for T{ 33 | const CLONE_FN: CloneFn = clone_fn::; 34 | } 35 | impl CloneFnTrait for T{ 36 | const CLONE_FN: CloneFn = clone_fn::; 37 | } 38 | impl CloneFnTrait for T{} 39 | impl CloneFnTrait for T{} 40 | impl CloneFnTrait for T{} 41 | impl CloneFnTrait for T{} 42 | 43 | 44 | /// This all just to replace AnyVec's clone function pointer with ZST, 45 | /// when non-Cloneable. 46 | pub trait CloneType{ 47 | type Type: Copy; 48 | fn new(f: CloneFn) -> Self::Type; 49 | fn get(f: Self::Type) -> CloneFn; 50 | } 51 | macro_rules! impl_clone_type_empty { 52 | ($t:ty) => { 53 | impl CloneType for $t { 54 | type Type = Empty; 55 | fn new(_: CloneFn) -> Self::Type{ Empty } 56 | fn get(_: Self::Type) -> CloneFn{ nop_fn } 57 | } 58 | } 59 | } 60 | macro_rules! impl_clone_type_fn { 61 | ($t:ty) => { 62 | impl CloneType for $t { 63 | type Type = CloneFn; 64 | fn new(f: CloneFn) -> Self::Type{ f } 65 | fn get(f: Self::Type) -> CloneFn{ f as CloneFn } 66 | } 67 | } 68 | } 69 | impl_clone_type_empty!(dyn None); 70 | impl_clone_type_empty!(dyn Sync); 71 | impl_clone_type_empty!(dyn Send); 72 | impl_clone_type_empty!(dyn Send + Sync); 73 | impl_clone_type_fn!(dyn Cloneable); 74 | impl_clone_type_fn!(dyn Cloneable + Send); 75 | impl_clone_type_fn!(dyn Cloneable + Sync); 76 | impl_clone_type_fn!(dyn Cloneable + Send + Sync); 77 | -------------------------------------------------------------------------------- /src/element.rs: -------------------------------------------------------------------------------- 1 | use core::any::TypeId; 2 | use core::marker::PhantomData; 3 | use core::mem::ManuallyDrop; 4 | use core::ops::{Deref, DerefMut}; 5 | use core::ptr::NonNull; 6 | use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueMut, AnyValueTypelessMut, AnyValueTypeless, AnyValueSizeless, AnyValueSizelessMut}; 7 | use crate::any_vec_raw::AnyVecRaw; 8 | use crate::any_vec_ptr::{AnyVecPtr, IAnyVecPtr, IAnyVecRawPtr}; 9 | use crate::{AnyVec, mem}; 10 | use crate::mem::MemBuilder; 11 | use crate::traits::{Cloneable, None, Trait}; 12 | 13 | // Typed operations will never use type-erased ElementPointer, so there is no 14 | // need in type-known-based optimizations. 15 | 16 | /// Owning pointer to type-erased [`AnyVec`] element. 17 | /// 18 | /// Obtained by dereferencing [`ElementRef`], [`ElementMut`] or from some 19 | /// destructive [`AnyVec`] operations, like [`drain`] or [`splice`]. 20 | /// 21 | /// # Consuming 22 | /// 23 | /// Whenever you have `ElementPointer` as a value (from destructive [`AnyVec`] operations), 24 | /// you can safely take pointed value with [`AnyValue::downcast`], or unsafely 25 | /// take its content with [`AnyValueSizeless::move_into`]. 26 | /// Otherwise, it will be destructed with destruction of [`Element`]. 27 | /// 28 | /// # Notes 29 | /// 30 | /// `ElementPointer` have it's own implementation of `downcast_` family (which return `&'a T`, instead of `&T`). 31 | /// This is done, so you don't have to keep [`ElementRef`]/[`ElementMut`] alive, while casting to concrete type. 32 | /// 33 | /// [`AnyVec`]: crate::AnyVec 34 | /// [`AnyVec::get`]: crate::AnyVec::get 35 | /// [`drain`]: crate::AnyVec::drain 36 | /// [`splice`]: crate::AnyVec::splice 37 | /// [`any_value`]: crate::any_value 38 | pub struct ElementPointer<'a, AnyVecPtr: IAnyVecRawPtr>{ 39 | any_vec_ptr: AnyVecPtr, 40 | element: NonNull, 41 | phantom: PhantomData<&'a mut AnyVecRaw> 42 | } 43 | 44 | impl<'a, AnyVecPtr: IAnyVecRawPtr> ElementPointer<'a, AnyVecPtr>{ 45 | #[inline] 46 | pub(crate) fn new(any_vec_ptr: AnyVecPtr, element: NonNull) -> Self { 47 | Self{any_vec_ptr, element, phantom: PhantomData} 48 | } 49 | 50 | /// ElementPointer should not be `Clone`, because it can be both & and &mut. 51 | #[inline] 52 | pub(crate) fn clone(&self) -> Self { 53 | Self::new(self.any_vec_ptr, self.element) 54 | } 55 | 56 | #[inline] 57 | fn any_vec_raw(&self) -> &'a AnyVecRaw{ 58 | unsafe { self.any_vec_ptr.any_vec_raw() } 59 | } 60 | 61 | /// Same as [`AnyValue::downcast_ref`], but return `&'a T`, instead of `&T`. 62 | #[inline] 63 | pub fn downcast_ref(&self) -> Option<&'a T>{ 64 | if self.value_typeid() != TypeId::of::(){ 65 | None 66 | } else { 67 | Some(unsafe{ self.downcast_ref_unchecked::() }) 68 | } 69 | } 70 | 71 | /// Same as [`AnyValueSizeless::downcast_ref_unchecked`], but return `&'a T`, instead of `&T`. 72 | #[inline] 73 | pub unsafe fn downcast_ref_unchecked(&self) -> &'a T{ 74 | &*(self.as_bytes().as_ptr() as *const T) 75 | } 76 | 77 | /// Same as [`AnyValueMut::downcast_mut`], but return `&'a mut T`, instead of `&mut T`. 78 | #[inline] 79 | pub fn downcast_mut(&mut self) -> Option<&'a mut T>{ 80 | if self.value_typeid() != TypeId::of::(){ 81 | None 82 | } else { 83 | Some(unsafe{ self.downcast_mut_unchecked::() }) 84 | } 85 | } 86 | 87 | /// Same as [`AnyValueSizelessMut::downcast_mut_unchecked`], but return `&'a mut T`, instead of `&mut T`. 88 | #[inline] 89 | pub unsafe fn downcast_mut_unchecked(&mut self) -> &'a mut T{ 90 | &mut *(self.as_bytes_mut().as_mut_ptr() as *mut T) 91 | } 92 | } 93 | 94 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Drop for ElementPointer<'a, AnyVecPtr>{ 95 | #[inline] 96 | fn drop(&mut self) { 97 | if let Some(drop_fn) = self.any_vec_raw().drop_fn{ 98 | unsafe{ 99 | (drop_fn)(self.element.as_ptr(), 1); 100 | } 101 | } 102 | } 103 | } 104 | 105 | impl<'a, AnyVecPtr: IAnyVecRawPtr> AnyValueSizeless for ElementPointer<'a, AnyVecPtr> { 106 | type Type = AnyVecPtr::Element; 107 | 108 | #[inline] 109 | fn as_bytes_ptr(&self) -> *const u8 { 110 | self.element.as_ptr() 111 | } 112 | } 113 | impl<'a, AnyVecPtr: IAnyVecRawPtr> AnyValueTypeless for ElementPointer<'a, AnyVecPtr>{ 114 | #[inline] 115 | fn size(&self) -> usize { 116 | self.any_vec_raw().element_layout().size() 117 | } 118 | } 119 | impl<'a, AnyVecPtr: IAnyVecRawPtr> AnyValue for ElementPointer<'a, AnyVecPtr>{ 120 | #[inline] 121 | fn value_typeid(&self) -> TypeId { 122 | self.any_vec_raw().type_id 123 | } 124 | } 125 | 126 | impl<'a, AnyVecPtr: IAnyVecRawPtr> AnyValueSizelessMut for ElementPointer<'a, AnyVecPtr>{ 127 | #[inline] 128 | fn as_bytes_mut_ptr(&mut self) -> *mut u8 { 129 | self.element.as_ptr() 130 | } 131 | } 132 | impl<'a, AnyVecPtr: IAnyVecRawPtr> AnyValueTypelessMut for ElementPointer<'a, AnyVecPtr>{} 133 | impl<'a, AnyVecPtr: IAnyVecRawPtr> AnyValueMut for ElementPointer<'a, AnyVecPtr>{} 134 | 135 | impl<'a, Traits: ?Sized + Cloneable + Trait, M: MemBuilder> 136 | AnyValueCloneable for ElementPointer<'a, AnyVecPtr> 137 | { 138 | #[inline] 139 | unsafe fn clone_into(&self, out: *mut u8) { 140 | let clone_fn = self.any_vec_ptr.any_vec().clone_fn(); 141 | (clone_fn)(self.as_bytes().as_ptr(), out, 1); 142 | } 143 | } 144 | 145 | unsafe impl<'a, Traits: ?Sized + Trait, M: MemBuilder> Send 146 | for 147 | ElementPointer<'a, AnyVecPtr> 148 | where 149 | AnyVec: Send 150 | {} 151 | 152 | unsafe impl<'a, Traits: ?Sized + Trait, M: MemBuilder> Sync 153 | for 154 | ElementPointer<'a, AnyVecPtr> 155 | where 156 | AnyVec: Sync 157 | {} 158 | 159 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> ElementReference<'a, Traits, M> 160 | for &'a ElementPointer<'a, AnyVecPtr> 161 | {} 162 | 163 | 164 | // Do not implement Send/Sync for AnyVecPtrRaw, since it will be casted to concrete type anyway. 165 | 166 | 167 | /// [`AnyVec`] element. 168 | /// 169 | /// See [`ElementPointer`]. 170 | /// 171 | /// [`AnyVec`]: crate::AnyVec 172 | pub type Element<'a, Traits = dyn None, M = mem::Default> = ElementPointer<'a, AnyVecPtr>; 173 | 174 | /// Reference to [`AnyVec`] element. 175 | /// 176 | /// Implemented by [`ElementRef`], [`ElementMut`] and &[`Element`]. 177 | pub trait ElementReference<'a, Traits: ?Sized + Trait = dyn None, M: MemBuilder + 'a = mem::Default> 178 | : Deref > 179 | {} 180 | 181 | /// Reference to [`AnyVec`] element. 182 | /// 183 | /// Created by [`AnyVec::get`]. 184 | /// 185 | /// [`AnyVec::get`]: crate::AnyVec::get 186 | pub struct ElementRef<'a, Traits: ?Sized + Trait = dyn None, M: MemBuilder = mem::Default>( 187 | pub(crate) ManuallyDrop> 188 | ); 189 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> ElementReference<'a, Traits, M> for ElementRef<'a, Traits, M>{} 190 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> Deref for ElementRef<'a, Traits, M>{ 191 | type Target = Element<'a, Traits, M>; 192 | 193 | #[inline] 194 | fn deref(&self) -> &Self::Target { 195 | &self.0 196 | } 197 | } 198 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> Clone for ElementRef<'a, Traits, M>{ 199 | #[inline] 200 | fn clone(&self) -> Self { 201 | Self(ManuallyDrop::new(self.0.clone())) 202 | } 203 | } 204 | 205 | /// Mutable reference to [`AnyVec`] element. 206 | /// 207 | /// Created by [`AnyVec::get_mut`]. 208 | /// 209 | /// [`AnyVec::get_mut`]: crate::AnyVec::get_mut 210 | pub struct ElementMut<'a, Traits: ?Sized + Trait = dyn None, M: MemBuilder = mem::Default>( 211 | pub(crate) ManuallyDrop> 212 | ); 213 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> ElementReference<'a, Traits, M> for ElementMut<'a, Traits, M>{} 214 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> Deref for ElementMut<'a, Traits, M>{ 215 | type Target = Element<'a, Traits, M>; 216 | 217 | #[inline] 218 | fn deref(&self) -> &Self::Target { 219 | &self.0 220 | } 221 | } 222 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> DerefMut for ElementMut<'a, Traits, M>{ 223 | #[inline] 224 | fn deref_mut(&mut self) -> &mut Self::Target { 225 | &mut self.0 226 | } 227 | } -------------------------------------------------------------------------------- /src/iter.rs: -------------------------------------------------------------------------------- 1 | use core::iter::{FusedIterator}; 2 | use core::marker::PhantomData; 3 | use core::mem::ManuallyDrop; 4 | use core::ptr::NonNull; 5 | use crate::any_vec_ptr::{AnyVecPtr, AnyVecRawPtr, IAnyVecRawPtr}; 6 | use crate::any_vec_ptr::utils::element_ptr_at; 7 | use crate::any_vec_raw::AnyVecRaw; 8 | use crate::{AnyVec, AnyVecTyped}; 9 | use crate::element::{ElementPointer, ElementMut, ElementRef}; 10 | use crate::mem::MemBuilder; 11 | use crate::traits::Trait; 12 | 13 | // TODO :Additional [`AnyVec`] Iterator operations. 14 | /*pub trait AnyVecIterator: Iterator{ 15 | fn lazy_cloned(self) -> impl 16 | }*/ 17 | 18 | pub trait ElementIterator: 19 | DoubleEndedIterator + ExactSizeIterator + FusedIterator 20 | {} 21 | 22 | impl ElementIterator for T 23 | where 24 | T: DoubleEndedIterator + ExactSizeIterator + FusedIterator 25 | {} 26 | 27 | /// [`AnyVec`] iterator. 28 | /// 29 | /// Return [`Element`], [`ElementRef`] or [`ElementMut`] items, depending on `IterItem`. 30 | /// Cloneable for `Ref` and `Mut` versions. 31 | /// 32 | /// [`AnyVec`]: crate::AnyVec 33 | /// [`Element`]: crate::element::Element 34 | /// [`ElementRef`]: crate::element::ElementRef 35 | /// [`ElementMut`]: crate::element::ElementMut 36 | pub struct Iter<'a, 37 | AnyVecPtr: IAnyVecRawPtr, 38 | IterItem: IteratorItem<'a, AnyVecPtr> = ElementIterItem<'a, AnyVecPtr>> 39 | { 40 | pub(crate) any_vec_ptr: AnyVecPtr, 41 | 42 | pub(crate) index: usize, 43 | pub(crate) end: usize, 44 | 45 | phantom: PhantomData<(&'a AnyVecRaw, IterItem)> 46 | } 47 | 48 | impl<'a, AnyVecPtr: IAnyVecRawPtr, IterItem: IteratorItem<'a, AnyVecPtr>> 49 | Iter<'a, AnyVecPtr, IterItem> 50 | { 51 | #[inline] 52 | pub(crate) fn new(any_vec_ptr: AnyVecPtr, start: usize, end: usize) -> Self { 53 | Self{any_vec_ptr, index: start, end, phantom: PhantomData} 54 | } 55 | } 56 | 57 | impl<'a, AnyVecPtr: IAnyVecRawPtr, IterItem: IteratorItem<'a, AnyVecPtr> + Clone> 58 | Clone 59 | for 60 | Iter<'a, AnyVecPtr, IterItem> 61 | { 62 | #[inline] 63 | fn clone(&self) -> Self { 64 | Self{ 65 | any_vec_ptr: self.any_vec_ptr, 66 | index: self.index, 67 | end: self.end, 68 | phantom: PhantomData 69 | } 70 | } 71 | } 72 | 73 | impl<'a, AnyVecPtr: IAnyVecRawPtr, IterItem: IteratorItem<'a, AnyVecPtr>> Iterator 74 | for Iter<'a, AnyVecPtr, IterItem> 75 | { 76 | type Item = IterItem::Item; 77 | 78 | #[inline] 79 | fn next(&mut self) -> Option { 80 | if self.index == self.end{ 81 | None 82 | } else { 83 | let element = ElementPointer::new( 84 | self.any_vec_ptr, 85 | unsafe{NonNull::new_unchecked( 86 | element_ptr_at(self.any_vec_ptr, self.index) as *mut u8 87 | )} 88 | ); 89 | 90 | self.index += 1; 91 | Some(IterItem::element_to_item(element)) 92 | } 93 | } 94 | 95 | #[inline] 96 | fn size_hint(&self) -> (usize, Option) { 97 | let size = self.end - self.index; 98 | (size, Some(size)) 99 | } 100 | } 101 | 102 | impl<'a, AnyVecPtr: IAnyVecRawPtr, IterItem: IteratorItem<'a, AnyVecPtr>> DoubleEndedIterator 103 | for Iter<'a, AnyVecPtr, IterItem> 104 | { 105 | #[inline] 106 | fn next_back(&mut self) -> Option { 107 | if self.end == self.index{ 108 | None 109 | } else { 110 | self.end -= 1; 111 | let element = ElementPointer::new( 112 | self.any_vec_ptr, 113 | unsafe{NonNull::new_unchecked( 114 | element_ptr_at(self.any_vec_ptr, self.end) as *mut u8 115 | )} 116 | ); 117 | 118 | Some(IterItem::element_to_item(element)) 119 | } 120 | } 121 | } 122 | 123 | impl<'a, AnyVecPtr: IAnyVecRawPtr, IterItem: IteratorItem<'a, AnyVecPtr>> ExactSizeIterator 124 | for Iter<'a, AnyVecPtr, IterItem> 125 | { 126 | #[inline] 127 | fn len(&self) -> usize { 128 | self.end - self.index 129 | } 130 | } 131 | 132 | impl<'a, AnyVecPtr: IAnyVecRawPtr, IterItem: IteratorItem<'a, AnyVecPtr>> FusedIterator 133 | for Iter<'a, AnyVecPtr, IterItem> 134 | {} 135 | 136 | 137 | #[allow(renamed_and_removed_lints, suspicious_auto_trait_impls)] 138 | unsafe impl<'a, Traits, M, IterItem> Send 139 | for 140 | Iter<'a, AnyVecPtr, IterItem> 141 | where 142 | Traits: ?Sized + Trait, 143 | M: MemBuilder, 144 | IterItem: IteratorItem<'a, AnyVecPtr>, 145 | AnyVec: Send 146 | {} 147 | #[allow(renamed_and_removed_lints, suspicious_auto_trait_impls)] 148 | unsafe impl<'a, T, M, IterItem> Send 149 | for 150 | Iter<'a, AnyVecRawPtr, IterItem> 151 | where 152 | M: MemBuilder, 153 | IterItem: IteratorItem<'a, AnyVecRawPtr>, 154 | AnyVecTyped<'a, T, M>: Send 155 | {} 156 | 157 | unsafe impl<'a, Traits, M, IterItem> Sync 158 | for 159 | Iter<'a, AnyVecPtr, IterItem> 160 | where 161 | Traits: ?Sized + Trait, 162 | M: MemBuilder, 163 | IterItem: IteratorItem<'a, AnyVecPtr>, 164 | AnyVec: Sync 165 | {} 166 | unsafe impl<'a, T, M, IterItem> Sync 167 | for 168 | Iter<'a, AnyVecRawPtr, IterItem> 169 | where 170 | T: Sync, 171 | M: MemBuilder, 172 | IterItem: IteratorItem<'a, AnyVecRawPtr>, 173 | AnyVecTyped<'a, T, M>: Sync 174 | {} 175 | 176 | 177 | pub trait IteratorItem<'a, AnyVecPtr: IAnyVecRawPtr>{ 178 | type Item; 179 | fn element_to_item(element: ElementPointer<'a, AnyVecPtr>) -> Self::Item; 180 | } 181 | 182 | /// Default 183 | pub struct ElementIterItem<'a, AnyVecPtr: IAnyVecRawPtr>( 184 | pub(crate) PhantomData> 185 | ); 186 | impl<'a, AnyVecPtr: IAnyVecRawPtr> IteratorItem<'a, AnyVecPtr> for ElementIterItem<'a, AnyVecPtr>{ 187 | type Item = ElementPointer<'a, AnyVecPtr>; 188 | 189 | #[inline] 190 | fn element_to_item(element: ElementPointer<'a, AnyVecPtr>) -> Self::Item { 191 | element 192 | } 193 | } 194 | 195 | /// Ref 196 | pub struct ElementRefIterItem<'a, Traits: ?Sized + Trait, M: MemBuilder>( 197 | pub(crate) PhantomData>> 198 | ); 199 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> IteratorItem<'a, AnyVecPtr> for ElementRefIterItem<'a, Traits, M>{ 200 | type Item = ElementRef<'a, Traits, M>; 201 | 202 | #[inline] 203 | fn element_to_item(element: ElementPointer<'a, AnyVecPtr>) -> Self::Item { 204 | ElementRef(ManuallyDrop::new(element)) 205 | } 206 | } 207 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> Clone for ElementRefIterItem<'a, Traits, M>{ 208 | fn clone(&self) -> Self { 209 | Self(PhantomData) 210 | } 211 | } 212 | 213 | 214 | /// Mut 215 | pub struct ElementMutIterItem<'a, Traits: ?Sized + Trait, M: MemBuilder>( 216 | pub(crate) PhantomData>> 217 | ); 218 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> IteratorItem<'a, AnyVecPtr> for ElementMutIterItem<'a, Traits, M>{ 219 | type Item = ElementMut<'a, Traits, M>; 220 | 221 | #[inline] 222 | fn element_to_item(element: ElementPointer<'a, AnyVecPtr>) -> Self::Item { 223 | ElementMut(ManuallyDrop::new(element)) 224 | } 225 | } 226 | impl<'a, Traits: ?Sized + Trait, M: MemBuilder> Clone for ElementMutIterItem<'a, Traits, M>{ 227 | fn clone(&self) -> Self { 228 | Self(PhantomData) 229 | } 230 | } 231 | 232 | 233 | /// Reference [`AnyVec`] iterator. Return [`ElementRef`] items. 234 | /// 235 | /// [`AnyVec`]: crate::AnyVec 236 | /// [`ElementRef`]: crate::element::ElementRef 237 | pub type IterRef<'a, Traits, M> = Iter<'a, AnyVecPtr, ElementRefIterItem<'a, Traits, M>>; 238 | 239 | /// Mutable reference [`AnyVec`] iterator. Return [`ElementMut`] items. 240 | /// 241 | /// [`AnyVec`]: crate::AnyVec 242 | /// [`ElementMut`]: crate::element::ElementMut 243 | pub type IterMut<'a, Traits, M> = Iter<'a, AnyVecPtr, ElementMutIterItem<'a, Traits, M>>; -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![no_std] 2 | #![cfg_attr(miri, feature(alloc_layout_extra) )] 3 | #![cfg_attr(docsrs, feature(doc_cfg))] 4 | 5 | //! Type erased vector [`AnyVec`]. Allow to store elements of the same type. 6 | //! Have same performance and *operations* as `std::vec::Vec`. 7 | //! 8 | //! You can downcast type erased [`AnyVec`] to concrete [`AnyVecTyped`] with `downcast`-family. 9 | //! Or use [`AnyVec`] type erased operations, which works with [`any_value`]. 10 | //! 11 | //! ```rust 12 | //! use any_vec::AnyVec; 13 | //! let mut vec: AnyVec = AnyVec::new::(); 14 | //! { 15 | //! // Typed operations. 16 | //! let mut vec = vec.downcast_mut::().unwrap(); 17 | //! vec.push(String::from("0")); 18 | //! vec.push(String::from("1")); 19 | //! vec.push(String::from("2")); 20 | //! } 21 | //! 22 | //! let mut other_vec: AnyVec = AnyVec::new::(); 23 | //! // Fully type erased element move from one vec to another 24 | //! // without intermediate mem-copies. 25 | //! let element = vec.swap_remove(0); 26 | //! other_vec.push(element); 27 | //! 28 | //! // Output 2 1 29 | //! for s in vec.downcast_ref::().unwrap(){ 30 | //! println!("{}", s); 31 | //! } 32 | //! 33 | //!``` 34 | //! 35 | //! N.B. [`AnyVecTyped`] operations may be somewhat faster, due to the fact that 36 | //! compiler able to do better optimisation with full type knowledge. 37 | //! 38 | //! # Send, Sync, Clone 39 | //! 40 | //! You can make [`AnyVec`] [`Send`]able, [`Sync`]able, [`Cloneable`]: 41 | //! 42 | //! [`Cloneable`]: traits::Cloneable 43 | //! 44 | //!```rust 45 | //! use any_vec::AnyVec; 46 | //! use any_vec::traits::*; 47 | //! let v1: AnyVec = AnyVec::new::(); 48 | //! let v2 = v1.clone(); 49 | //! ``` 50 | //! This constraints will be applied compiletime to element type: 51 | //!```compile_fail 52 | //! # use any_vec::AnyVec; 53 | //! # use std::rc::Rc; 54 | //! let v1: AnyVec = AnyVec::new::>(); 55 | //!``` 56 | //! 57 | //! # LazyClone 58 | //! 59 | //! Whenever possible, [`any_vec`] types implement [`AnyValueCloneable`], which 60 | //! can work with [`LazyClone`]: 61 | //! 62 | //! [`any_vec`]: crate 63 | //! [`AnyValueCloneable`]: any_value::AnyValueCloneable 64 | //! [`LazyClone`]: any_value::LazyClone 65 | //! 66 | //!```rust 67 | //! # use any_vec::any_value::{AnyValueCloneable, AnyValueWrapper}; 68 | //! # use any_vec::AnyVec; 69 | //! # use any_vec::traits::*; 70 | //! let mut v1: AnyVec = AnyVec::new::(); 71 | //! v1.push(AnyValueWrapper::new(String::from("0"))); 72 | //! 73 | //! let mut v2: AnyVec = AnyVec::new::(); 74 | //! let e = v1.swap_remove(0); 75 | //! v2.push(e.lazy_clone()); 76 | //! v2.push(e.lazy_clone()); 77 | //! ``` 78 | //! 79 | //! # MemBuilder 80 | //! 81 | //! [`MemBuilder`] + [`Mem`] works like [`Allocator`] for [`AnyVec`]. But unlike allocator, 82 | //! [`Mem`] container-specialized design allows to perform more optimizations. For example, 83 | //! it is possible to make stack-allocated `FixedAnyVec` and small-buffer-optimized(SBO) `SmallAnyVec` 84 | //! from `AnyVec` by just changing [`MemBuilder`]: 85 | //! 86 | //!```rust 87 | //! # use any_vec::any_value::AnyValueWrapper; 88 | //! # use any_vec::AnyVec; 89 | //! # use any_vec::mem::Stack; 90 | //! # use any_vec::traits::None; 91 | //! 92 | //! type FixedAnyVec = AnyVec>; 93 | //! let mut any_vec: FixedAnyVec = AnyVec::new::(); 94 | //! 95 | //! // This will be on stack, without any allocations. 96 | //! any_vec.push(AnyValueWrapper::new(String::from("0"))) 97 | //!``` 98 | //! 99 | //! With help of [`clone_empty_in`] you can use stack allocated, or SBO [`AnyVec`] 100 | //! as fast intermediate storage for values of unknown type: 101 | //! 102 | //!```rust 103 | //! # use any_vec::any_value::{AnyValueCloneable, AnyValueWrapper}; 104 | //! # use any_vec::AnyVec; 105 | //! # use any_vec::mem::StackN; 106 | //! # use any_vec::traits::*; 107 | //! 108 | //! fn self_push_first_element(any_vec: &mut AnyVec){ 109 | //! let mut tmp = any_vec.clone_empty_in(StackN::<1, 256>); 110 | //! tmp.push(any_vec.at(0).lazy_clone()); 111 | //! any_vec.push(tmp.pop().unwrap()); 112 | //! } 113 | //!``` 114 | //! 115 | //! [`MemBuilder`] interface, being stateful, allow to make [`Mem`], 116 | //! which can work with complex custom allocators. 117 | //! 118 | //! [`MemBuilder`]: mem::MemBuilder 119 | //! [`Mem`]: mem::Mem 120 | //! [`Allocator`]: core::alloc::Allocator 121 | //! [`clone_empty_in`]: AnyVec::clone_empty_in 122 | //! 123 | //! # AnyValue 124 | //! 125 | //! Being type erased, [AnyVec] needs a way to operate on untyped values safely. 126 | //! Instead of working with plain `*mut u8`, [AnyVec] operates with [any_value]. 127 | //! 128 | //! [AnyValue] is a trait, that provide operations to work with type erased values. 129 | //! Any type that implements [AnyValue] can be used with [AnyVec]. 130 | //! [AnyValue] interface allows to perform postponed operations on consumption. 131 | //! This trick used heavily by [AnyVec] destructive operations, which instead of concrete 132 | //! type return [AnyValue], which perform actual operation on value drop. 133 | //! 134 | //! Implementing [AnyValueMut] and [AnyValueCloneable] makes type mutable and 135 | //! cloneable respectively. 136 | //! 137 | //! [AnyValue]: any_value::AnyValue 138 | //! [AnyValueMut]: any_value::AnyValueMut 139 | //! [AnyValueCloneable]: any_value::AnyValueCloneable 140 | //! 141 | //! # No `alloc` 142 | //! 143 | //! This library is `no_std` and can work without `alloc`. 144 | //! For this - disable default `alloc` feature. [mem::Heap] will become unavailable 145 | //! after that, and you'll have to specify [MemBuilder] for [AnyVec]. You can use 146 | //! [mem::Stack], or specify your own [Mem]. 147 | //! 148 | //! [MemBuilder]: mem::MemBuilder 149 | //! [Mem]: mem::Mem 150 | 151 | mod any_vec; 152 | mod clone_type; 153 | mod any_vec_ptr; 154 | mod any_vec_raw; 155 | mod any_vec_typed; 156 | mod iter; 157 | 158 | use core::any::TypeId; 159 | pub use crate::any_vec::{AnyVec, AnyVecMut, AnyVecRef, RawParts, SatisfyTraits, traits}; 160 | pub use any_vec_typed::AnyVecTyped; 161 | pub use iter::{ElementIterator, Iter, IterMut, IterRef}; 162 | 163 | pub mod mem; 164 | pub mod any_value; 165 | pub mod ops; 166 | pub mod element; 167 | 168 | use core::ptr; 169 | use core::ops::{Bound, Range, RangeBounds}; 170 | use crate::any_value::Unknown; 171 | 172 | /// This is faster then ptr::copy, 173 | /// when count is runtime value, and count is small. 174 | /// 175 | /// Last time benchmarked on nightly 1.80 176 | #[inline(always)] 177 | unsafe fn copy_bytes(src: *const u8, dst: *mut u8, count: usize){ 178 | // MIRI hack 179 | if cfg!(miri) 180 | || count >= 128 181 | { 182 | ptr::copy(src, dst, count); 183 | return; 184 | } 185 | 186 | for i in 0..count{ 187 | *dst.add(i) = *src.add(i); 188 | } 189 | } 190 | 191 | /// One element copy_nonoverlapping, that utilize type knowledge. 192 | #[inline(always)] 193 | pub(crate) unsafe fn copy_nonoverlapping_value( 194 | input: *const u8, out: *mut u8, value_size: usize 195 | ) { 196 | if !Unknown::is::() { 197 | ptr::copy_nonoverlapping( 198 | input as *const KnownType, 199 | out as *mut KnownType, 200 | 1 201 | ); 202 | } else { 203 | ptr::copy_nonoverlapping( 204 | input, 205 | out, 206 | value_size 207 | ); 208 | } 209 | } 210 | 211 | #[inline] 212 | fn into_range( 213 | len: usize, 214 | range: impl RangeBounds 215 | ) -> Range { 216 | let start = match range.start_bound() { 217 | Bound::Included(i) => *i, 218 | Bound::Excluded(i) => *i + 1, 219 | Bound::Unbounded => 0, 220 | }; 221 | let end = match range.end_bound() { 222 | Bound::Included(i) => *i + 1, 223 | Bound::Excluded(i) => *i, 224 | Bound::Unbounded => len, 225 | }; 226 | assert!(start <= end); 227 | assert!(end <= len); 228 | start..end 229 | } 230 | 231 | #[inline] 232 | fn assert_types_equal(t1: TypeId, t2: TypeId){ 233 | assert_eq!(t1, t2, "Type mismatch!"); 234 | } -------------------------------------------------------------------------------- /src/mem/empty.rs: -------------------------------------------------------------------------------- 1 | use core::alloc::Layout; 2 | use crate::mem::{dangling, Mem, MemBuilder, MemRawParts}; 3 | 4 | /// Zero-size memory. 5 | /// 6 | /// Contain only element Layout. This can be useful for constructing [`RawParts`] with zero overhead. 7 | /// 8 | /// [`RawParts`]: crate::RawParts 9 | #[derive(Default, Clone, Copy)] 10 | pub struct Empty; 11 | impl MemBuilder for Empty{ 12 | /// Implements [`MemRawParts`]. 13 | type Mem = EmptyMem; 14 | 15 | #[inline] 16 | fn build(&mut self, element_layout: Layout) -> Self::Mem { 17 | EmptyMem { element_layout } 18 | } 19 | } 20 | 21 | pub struct EmptyMem{ 22 | element_layout: Layout 23 | } 24 | 25 | impl Mem for EmptyMem{ 26 | #[inline] 27 | fn as_ptr(&self) -> *const u8 { 28 | dangling(&self.element_layout).as_ptr() 29 | } 30 | 31 | #[inline] 32 | fn as_mut_ptr(&mut self) -> *mut u8 { 33 | dangling(&self.element_layout).as_ptr() 34 | } 35 | 36 | #[inline] 37 | fn element_layout(&self) -> Layout { 38 | self.element_layout 39 | } 40 | 41 | #[inline] 42 | fn size(&self) -> usize { 43 | 0 44 | } 45 | } 46 | 47 | impl MemRawParts for EmptyMem{ 48 | type Handle = (); 49 | 50 | #[inline] 51 | fn into_raw_parts(self) -> (Self::Handle, Layout, usize) { 52 | ((), self.element_layout, 0) 53 | } 54 | 55 | /// `size` must be 0. 56 | #[inline] 57 | unsafe fn from_raw_parts(_: Self::Handle, element_layout: Layout, size: usize) -> Self { 58 | debug_assert!(size == 0); 59 | Self{ 60 | element_layout 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/mem/heap.rs: -------------------------------------------------------------------------------- 1 | extern crate alloc; 2 | 3 | use alloc::alloc::{alloc, dealloc, handle_alloc_error, Layout, realloc}; 4 | use core::cmp; 5 | use core::mem::ManuallyDrop; 6 | use core::ptr::NonNull; 7 | use crate::mem::{dangling, Mem, MemBuilder, MemBuilderSizeable, MemRawParts, MemResizable}; 8 | 9 | /// Heap allocated memory. 10 | #[derive(Default, Clone, Copy)] 11 | pub struct Heap; 12 | impl MemBuilder for Heap { 13 | /// Implements [`MemResizable`], [`MemRawParts`]. 14 | type Mem = HeapMem; 15 | 16 | #[inline] 17 | fn build(&mut self, element_layout: Layout) -> HeapMem { 18 | HeapMem { 19 | mem: dangling(&element_layout), 20 | size: 0, 21 | element_layout 22 | } 23 | } 24 | } 25 | impl MemBuilderSizeable for Heap{ 26 | #[inline] 27 | fn build_with_size(&mut self, element_layout: Layout, capacity: usize) -> Self::Mem 28 | { 29 | let mut mem = self.build(element_layout); 30 | mem.resize(capacity); 31 | mem 32 | } 33 | } 34 | 35 | pub struct HeapMem { 36 | mem: NonNull, 37 | size: usize, // in elements 38 | element_layout: Layout, // size is aligned 39 | } 40 | 41 | impl Mem for HeapMem { 42 | #[inline] 43 | fn as_ptr(&self) -> *const u8 { 44 | self.mem.as_ptr() 45 | } 46 | 47 | #[inline] 48 | fn as_mut_ptr(&mut self) -> *mut u8 { 49 | self.mem.as_ptr() 50 | } 51 | 52 | #[inline] 53 | fn element_layout(&self) -> Layout { 54 | self.element_layout 55 | } 56 | 57 | #[inline] 58 | fn size(&self) -> usize { 59 | self.size 60 | } 61 | 62 | fn expand(&mut self, additional: usize){ 63 | let requested_size = self.size() + additional; 64 | let new_size = cmp::max(self.size() * 2, requested_size); 65 | self.resize(new_size); 66 | } 67 | } 68 | 69 | impl MemResizable for HeapMem { 70 | fn resize(&mut self, new_size: usize) { 71 | if self.size == new_size{ 72 | return; 73 | } 74 | 75 | if self.element_layout.size() != 0 { 76 | unsafe{ 77 | // Non checked mul, because this memory size already allocated. 78 | let mem_layout = Layout::from_size_align_unchecked( 79 | self.element_layout.size() * self.size, 80 | self.element_layout.align() 81 | ); 82 | 83 | self.mem = 84 | if new_size == 0 { 85 | dealloc(self.mem.as_ptr(), mem_layout); 86 | dangling(&self.element_layout) 87 | } else { 88 | // mul carefully, to prevent overflow. 89 | let new_mem_size = self.element_layout.size() 90 | .checked_mul(new_size).unwrap(); 91 | let new_mem_layout = Layout::from_size_align_unchecked( 92 | new_mem_size, self.element_layout.align() 93 | ); 94 | 95 | if self.size == 0 { 96 | // allocate 97 | NonNull::new(alloc(new_mem_layout)) 98 | } else { 99 | // reallocate 100 | NonNull::new(realloc( 101 | self.mem.as_ptr(), mem_layout,new_mem_size 102 | )) 103 | } 104 | .unwrap_or_else(|| handle_alloc_error(new_mem_layout)) 105 | } 106 | } 107 | } 108 | self.size = new_size; 109 | } 110 | } 111 | 112 | impl MemRawParts for HeapMem{ 113 | type Handle = NonNull; 114 | 115 | #[inline] 116 | fn into_raw_parts(self) -> (Self::Handle, Layout, usize) { 117 | let this = ManuallyDrop::new(self); 118 | (this.mem, this.element_layout, this.size) 119 | } 120 | 121 | #[inline] 122 | unsafe fn from_raw_parts(handle: Self::Handle, element_layout: Layout, size: usize) -> Self { 123 | Self{ 124 | mem: handle, 125 | size, 126 | element_layout 127 | } 128 | } 129 | } 130 | 131 | impl Drop for HeapMem { 132 | fn drop(&mut self) { 133 | self.resize(0); 134 | } 135 | } 136 | 137 | unsafe impl Send for HeapMem{} 138 | unsafe impl Sync for HeapMem{} -------------------------------------------------------------------------------- /src/mem/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature="alloc")] 2 | mod heap; 3 | mod stack; 4 | mod stack_n; 5 | mod empty; 6 | 7 | #[cfg(feature="alloc")] 8 | #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] 9 | pub use heap::Heap; 10 | pub use stack::Stack; 11 | pub use stack_n::StackN; 12 | pub use empty::Empty; 13 | 14 | #[cfg(feature="alloc")] 15 | pub(crate) type Default = Heap; 16 | #[cfg(not(feature="alloc"))] 17 | pub(crate) type Default = Empty; 18 | 19 | use core::alloc::Layout; 20 | use core::ptr::NonNull; 21 | 22 | /// This is [`Mem`] builder. 23 | /// 24 | /// It can be stateful. You can use it like Allocator. 25 | /// Making `MemBuilder` default constructible, allow to use [`AnyVec::new`], without that you 26 | /// limited to [`AnyVec::new_in`]. 27 | /// 28 | /// [`AnyVec::new`]: crate::AnyVec::new 29 | /// [`AnyVec::new_in`]: crate::AnyVec::new_in 30 | pub trait MemBuilder: Clone { 31 | type Mem: Mem; 32 | fn build(&mut self, element_layout: Layout) -> Self::Mem; 33 | } 34 | 35 | /// This allows to use [`AnyVec::with_capacity`] with it. 36 | /// 37 | /// [`AnyVec::with_capacity`]: crate::AnyVec::with_capacity 38 | pub trait MemBuilderSizeable: MemBuilder{ 39 | fn build_with_size(&mut self, element_layout: Layout, capacity: usize) -> Self::Mem; 40 | } 41 | 42 | /// Interface for [`AnyVec`] memory chunk. 43 | /// 44 | /// Responsible for allocation, dealocation, reallocation of the memory chunk. 45 | /// Constructed through [`MemBuilder`]. 46 | /// 47 | /// _`Mem` is fixed capacity memory. Implement [`MemResizable`] if you want it 48 | /// to be resizable._ 49 | /// 50 | /// [`AnyVec`]: crate::AnyVec 51 | pub trait Mem{ 52 | fn as_ptr(&self) -> *const u8; 53 | 54 | fn as_mut_ptr(&mut self) -> *mut u8; 55 | 56 | /// Aligned. 57 | fn element_layout(&self) -> Layout; 58 | 59 | /// In elements. 60 | fn size(&self) -> usize; 61 | 62 | /// Expand `Mem` size for **at least** `additional` more elements. 63 | /// Implementation encouraged to avoid frequent reallocations. 64 | /// 65 | /// # Notes 66 | /// 67 | /// Consider, that `expand` is in [`MemResizable`]. 68 | /// Implement this only if your type [`MemResizable`]. 69 | /// 70 | /// It's here, only due to technical reasons (see `AnyVecRaw::reserve`). 71 | /// _Rust does not support specialization_ 72 | /// 73 | /// # Panics 74 | /// 75 | /// Implementation may panic, if fail to allocate/reallocate memory. 76 | fn expand(&mut self, additional: usize){ 77 | let _ = additional; 78 | panic!("Can't change capacity!"); 79 | 80 | /*let requested_size = self.size() + additional; 81 | let new_size = cmp::max(self.size() * 2, requested_size); 82 | self.resize(new_size);*/ 83 | } 84 | } 85 | 86 | /// Resizable [`Mem`]. 87 | /// 88 | /// Implemented by [`Heap::Mem`]. 89 | pub trait MemResizable: Mem{ 90 | /// Expand `Mem` size for **exactly** `additional` more elements. 91 | /// Implementation encouraged to be as precise as possible with new memory size. 92 | /// 93 | /// # Panics 94 | /// 95 | /// Implementation may panic, if fail to allocate/reallocate memory. 96 | fn expand_exact(&mut self, additional: usize){ 97 | self.resize(self.size() + additional); 98 | } 99 | 100 | /// Resize memory chunk to specified size. 101 | /// 102 | /// # Panics 103 | /// 104 | /// Implementation may panic, if fail to allocate/reallocate/deallocate memory. 105 | fn resize(&mut self, new_size: usize); 106 | } 107 | 108 | /// [`Mem`] destructurable into raw parts. 109 | /// 110 | /// Implemented by [`Heap::Mem`], [`Empty::Mem`]. 111 | pub trait MemRawParts: Mem{ 112 | type Handle; 113 | 114 | fn into_raw_parts(self) -> (Self::Handle, Layout, usize); 115 | unsafe fn from_raw_parts(handle: Self::Handle, element_layout: Layout, size: usize) -> Self; 116 | } 117 | 118 | #[inline] 119 | const fn dangling(layout: &Layout) -> NonNull{ 120 | #[cfg(miri)] 121 | { 122 | layout.dangling() 123 | } 124 | #[cfg(not(miri))] 125 | { 126 | unsafe { NonNull::new_unchecked(layout.align() as *mut u8) } 127 | } 128 | } -------------------------------------------------------------------------------- /src/mem/stack.rs: -------------------------------------------------------------------------------- 1 | use core::alloc::Layout; 2 | use core::mem::MaybeUninit; 3 | use crate::mem::{Mem, MemBuilder}; 4 | 5 | /// Fixed `SIZE` capacity on-stack memory. 6 | /// 7 | /// Can contain at most `SIZE` bytes. 8 | /// Upon `build()` real capacity calculated based on `element_layout`. 9 | /// This involves `idiv` operation. You may want to consider [`StackN`] 10 | /// for intermediate storage instead. 11 | /// 12 | /// [`StackN`]: super::StackN 13 | #[derive(Default, Clone, Copy)] 14 | pub struct Stack; 15 | impl MemBuilder for Stack{ 16 | type Mem = StackMem; 17 | 18 | #[inline] 19 | fn build(&mut self, element_layout: Layout) -> StackMem { 20 | let size = 21 | if element_layout.size() == 0{ 22 | usize::MAX 23 | } else{ 24 | SIZE / element_layout.size() 25 | }; 26 | 27 | StackMem{ 28 | mem: MaybeUninit::uninit(), 29 | element_layout, 30 | size 31 | } 32 | } 33 | } 34 | 35 | pub struct StackMem{ 36 | mem: MaybeUninit<[u8; SIZE]>, 37 | element_layout: Layout, 38 | size: usize 39 | } 40 | 41 | impl Mem for StackMem{ 42 | #[inline] 43 | fn as_ptr(&self) -> *const u8 { 44 | self.mem.as_ptr() as *const u8 45 | } 46 | 47 | #[inline] 48 | fn as_mut_ptr(&mut self) -> *mut u8 { 49 | self.mem.as_mut_ptr() as *mut u8 50 | } 51 | 52 | #[inline] 53 | fn element_layout(&self) -> Layout { 54 | self.element_layout 55 | } 56 | 57 | #[inline] 58 | fn size(&self) -> usize { 59 | self.size 60 | } 61 | } -------------------------------------------------------------------------------- /src/mem/stack_n.rs: -------------------------------------------------------------------------------- 1 | use core::alloc::Layout; 2 | use core::mem::MaybeUninit; 3 | use crate::mem::{Mem, MemBuilder}; 4 | 5 | /// Fixed `SIZE` capacity on-stack memory for `N` elements. 6 | /// 7 | /// Can contain `N` elements, with total size at most `SIZE` bytes. 8 | /// Unlike [`Stack`] does not involve heavy operations for building. 9 | /// 10 | /// N.B. It should be `ELEMENT_SIZE` instead of total `SIZE`, but Rust 11 | /// still can't do `N * ELEMENT_SIZE` in generic context. 12 | /// 13 | /// [`Stack`]: super::Stack 14 | #[derive(Default, Clone, Copy)] 15 | pub struct StackN; 16 | impl MemBuilder for StackN{ 17 | type Mem = StackNMem; 18 | 19 | #[inline] 20 | fn build(&mut self, element_layout: Layout) -> Self::Mem { 21 | assert!(N*element_layout.size() <= SIZE, "Insufficient storage!"); 22 | StackNMem{ 23 | mem: MaybeUninit::uninit(), 24 | element_layout 25 | } 26 | } 27 | } 28 | 29 | pub struct StackNMem{ 30 | mem: MaybeUninit<[u8; SIZE]>, 31 | element_layout: Layout 32 | } 33 | 34 | impl Mem for StackNMem{ 35 | #[inline] 36 | fn as_ptr(&self) -> *const u8 { 37 | self.mem.as_ptr() as *const u8 38 | } 39 | 40 | #[inline] 41 | fn as_mut_ptr(&mut self) -> *mut u8 { 42 | self.mem.as_mut_ptr() as *mut u8 43 | } 44 | 45 | #[inline] 46 | fn element_layout(&self) -> Layout { 47 | self.element_layout 48 | } 49 | 50 | #[inline] 51 | fn size(&self) -> usize { 52 | N 53 | } 54 | } -------------------------------------------------------------------------------- /src/ops/drain.rs: -------------------------------------------------------------------------------- 1 | use crate::any_vec_ptr::IAnyVecRawPtr; 2 | use crate::iter::Iter; 3 | use crate::any_vec_ptr; 4 | use crate::ops::iter::Iterable; 5 | 6 | pub struct Drain<'a, AnyVecPtr: IAnyVecRawPtr> 7 | { 8 | iter: Iter<'a, AnyVecPtr>, 9 | start: usize, 10 | original_len: usize 11 | } 12 | 13 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Drain<'a, AnyVecPtr> 14 | { 15 | #[inline] 16 | pub(crate) fn new(mut any_vec_ptr: AnyVecPtr, start: usize, end: usize) -> Self { 17 | debug_assert!(start <= end); 18 | let any_vec_raw = unsafe{ any_vec_ptr.any_vec_raw_mut() }; 19 | let original_len = any_vec_raw.len; 20 | debug_assert!(end <= original_len); 21 | 22 | // mem::forget and element drop panic "safety". 23 | any_vec_raw.len = start; 24 | 25 | Self{ 26 | iter: Iter::new(any_vec_ptr, start, end), 27 | start, 28 | original_len 29 | } 30 | } 31 | } 32 | 33 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Iterable 34 | for 35 | Drain<'a, AnyVecPtr> 36 | { 37 | type Iter = Iter<'a, AnyVecPtr>; 38 | 39 | #[inline] 40 | fn iter(&self) -> &Self::Iter { 41 | &self.iter 42 | } 43 | 44 | #[inline] 45 | fn iter_mut(&mut self) -> &mut Self::Iter { 46 | &mut self.iter 47 | } 48 | } 49 | 50 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Drop for Drain<'a, AnyVecPtr> 51 | { 52 | fn drop(&mut self) { 53 | use any_vec_ptr::utils::*; 54 | 55 | // 1. drop the rest of the elements 56 | unsafe{ 57 | drop_elements_range( 58 | self.iter.any_vec_ptr, 59 | self.iter.index, 60 | self.iter.end 61 | ); 62 | } 63 | 64 | // 2. mem move 65 | unsafe{ 66 | let elements_left = self.original_len - self.iter.end; 67 | move_elements_at( 68 | self.iter.any_vec_ptr, 69 | self.iter.end, 70 | self.start, 71 | elements_left 72 | ); 73 | } 74 | 75 | // 3. len 76 | let distance = self.iter.end - self.start; 77 | let any_vec_raw = unsafe{ self.iter.any_vec_ptr.any_vec_raw_mut() }; 78 | any_vec_raw.len = self.original_len - distance; 79 | } 80 | } -------------------------------------------------------------------------------- /src/ops/iter.rs: -------------------------------------------------------------------------------- 1 | use core::iter::FusedIterator; 2 | 3 | pub trait Iterable { 4 | type Iter: Iterator; 5 | fn iter(&self) -> &Self::Iter; 6 | fn iter_mut(&mut self) -> &mut Self::Iter; 7 | } 8 | 9 | /// Iterator over [`AnyVec`] slice. Will do some action on destruction. 10 | /// 11 | /// [`AnyVec`]: crate::AnyVec 12 | pub struct Iter(pub(crate) I); 13 | 14 | impl Iterator 15 | for Iter 16 | { 17 | type Item = ::Item; 18 | 19 | #[inline] 20 | fn next(&mut self) -> Option { 21 | self.0.iter_mut().next() 22 | } 23 | 24 | #[inline] 25 | fn size_hint(&self) -> (usize, Option) { 26 | self.0.iter().size_hint() 27 | } 28 | } 29 | 30 | impl DoubleEndedIterator 31 | for Iter 32 | where 33 | I::Iter: DoubleEndedIterator 34 | { 35 | #[inline] 36 | fn next_back(&mut self) -> Option { 37 | self.0.iter_mut().next_back() 38 | } 39 | } 40 | 41 | impl ExactSizeIterator 42 | for 43 | Iter 44 | where 45 | I::Iter: ExactSizeIterator 46 | { 47 | #[inline] 48 | fn len(&self) -> usize { 49 | self.0.iter().len() 50 | } 51 | } 52 | 53 | impl FusedIterator 54 | for 55 | Iter 56 | where 57 | I::Iter: FusedIterator 58 | {} -------------------------------------------------------------------------------- /src/ops/mod.rs: -------------------------------------------------------------------------------- 1 | //! [AnyVec] operations. 2 | //! 3 | //! You don't need, nor can't construct anything from this module manually. 4 | //! 5 | //! [AnyVec]: crate::AnyVec 6 | 7 | mod temp; 8 | mod iter; 9 | pub(crate) mod swap_remove; 10 | pub(crate) mod remove; 11 | pub(crate) mod drain; 12 | pub(crate) mod splice; 13 | pub(crate) mod pop; 14 | 15 | pub use temp::TempValue; 16 | pub use iter::Iter; 17 | 18 | use crate::any_vec_ptr::AnyVecPtr; 19 | 20 | /// Lazily `pop` on consumption/drop. 21 | /// 22 | /// This is created by [`AnyVec::pop`]. 23 | /// 24 | /// [`AnyVec::pop`]: crate::AnyVec::pop 25 | pub type Pop<'a, Traits, M> = TempValue>>; 26 | 27 | /// Lazily `remove` element on consumption/drop. 28 | /// 29 | /// This is created by [`AnyVec::remove`]. 30 | /// 31 | /// [`AnyVec::remove`]: crate::AnyVec::remove 32 | pub type Remove<'a, Traits, M> = TempValue>>; 33 | 34 | /// Lazily `swap_remove` element on consumption/drop. 35 | /// 36 | /// This is created by [`AnyVec::swap_remove`]. 37 | /// 38 | /// [`AnyVec::swap_remove`]: crate::AnyVec::swap_remove 39 | pub type SwapRemove<'a, Traits, M> = TempValue>>; 40 | 41 | /// A draining [`ElementIterator`] for [`AnyVec`]. Return items as [`Element`]s. 42 | /// 43 | /// This is created by [`AnyVec::drain`]. 44 | /// 45 | /// [`AnyVec`]: crate::AnyVec 46 | /// [`AnyVec::drain`]: crate::AnyVec::drain 47 | /// [`Element`]: crate::element::Element 48 | /// [`ElementIterator`]: crate::iter::ElementIterator 49 | pub type Drain<'a, Traits, M> = Iter>>; 50 | 51 | /// A splicing [`ElementIterator`] for [`AnyVec`]. Return items as [`Element`]s. 52 | /// 53 | /// This is created by [`AnyVec::splice`]. 54 | /// 55 | /// [`AnyVec`]: crate::AnyVec 56 | /// [`AnyVec::splice`]: crate::AnyVec::splice 57 | /// [`Element`]: crate::element::Element 58 | /// [`ElementIterator`]: crate::iter::ElementIterator 59 | pub type Splice<'a, Traits, M, I> = Iter, I>>; -------------------------------------------------------------------------------- /src/ops/pop.rs: -------------------------------------------------------------------------------- 1 | use core::marker::PhantomData; 2 | use crate::any_vec_ptr::IAnyVecRawPtr; 3 | use crate::any_vec_ptr::utils::element_ptr_at; 4 | use crate::any_vec_raw::AnyVecRaw; 5 | use crate::ops::temp::Operation; 6 | 7 | pub struct Pop<'a, AnyVecPtr: IAnyVecRawPtr>{ 8 | any_vec_ptr: AnyVecPtr, 9 | phantom: PhantomData<&'a mut AnyVecRaw>, 10 | } 11 | 12 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Pop<'a, AnyVecPtr>{ 13 | #[inline] 14 | pub(crate) fn new(mut any_vec_ptr: AnyVecPtr) -> Self{ 15 | let any_vec_raw = unsafe{ any_vec_ptr.any_vec_raw_mut() }; 16 | 17 | // mem::forget and element drop panic "safety". 18 | debug_assert!(any_vec_raw.len > 0); 19 | any_vec_raw.len -= 1; 20 | 21 | Self{ 22 | any_vec_ptr, 23 | phantom: PhantomData 24 | } 25 | } 26 | } 27 | 28 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Operation for Pop<'a, AnyVecPtr>{ 29 | type AnyVecPtr = AnyVecPtr; 30 | 31 | #[inline] 32 | fn any_vec_ptr(&self) -> Self::AnyVecPtr { 33 | self.any_vec_ptr 34 | } 35 | 36 | #[inline] 37 | fn bytes(&self) -> *const u8 { 38 | unsafe{ 39 | let any_vec_raw = self.any_vec_ptr.any_vec_raw(); 40 | let index = any_vec_raw.len; 41 | element_ptr_at(self.any_vec_ptr, index) 42 | } 43 | } 44 | 45 | #[inline] 46 | fn consume(&mut self) { 47 | // do nothing. 48 | } 49 | } -------------------------------------------------------------------------------- /src/ops/remove.rs: -------------------------------------------------------------------------------- 1 | use core::marker::PhantomData; 2 | use core::ptr; 3 | use crate::any_value::Unknown; 4 | use crate::any_vec_ptr::IAnyVecRawPtr; 5 | use crate::any_vec_ptr::utils::element_ptr_at; 6 | use crate::any_vec_raw::AnyVecRaw; 7 | use crate::ops::temp::Operation; 8 | 9 | pub struct Remove<'a, AnyVecPtr: IAnyVecRawPtr>{ 10 | any_vec_ptr: AnyVecPtr, 11 | index: usize, 12 | last_index: usize, 13 | phantom: PhantomData<&'a mut AnyVecRaw> 14 | } 15 | 16 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Remove<'a, AnyVecPtr>{ 17 | #[inline] 18 | pub(crate) fn new(mut any_vec_ptr: AnyVecPtr, index: usize) -> Self{ 19 | // 1. mem::forget and element drop panic "safety". 20 | let any_vec_raw = unsafe{ any_vec_ptr.any_vec_raw_mut() }; 21 | let last_index = any_vec_raw.len - 1; 22 | any_vec_raw.len = index; 23 | 24 | Self{any_vec_ptr, index, last_index, phantom: PhantomData} 25 | } 26 | } 27 | 28 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Operation for Remove<'a, AnyVecPtr>{ 29 | type AnyVecPtr = AnyVecPtr; 30 | 31 | #[inline] 32 | fn any_vec_ptr(&self) -> Self::AnyVecPtr { 33 | self.any_vec_ptr 34 | } 35 | 36 | #[inline] 37 | fn bytes(&self) -> *const u8 { 38 | unsafe{ element_ptr_at(self.any_vec_ptr, self.index) } 39 | } 40 | 41 | #[inline] 42 | fn consume(&mut self) { 43 | unsafe{ 44 | // 2. shift everything left 45 | if !Unknown::is::() { 46 | let dst = self.bytes() as *mut AnyVecPtr::Element; 47 | let src = dst.add(1); 48 | ptr::copy(src, dst, self.last_index - self.index); 49 | } else { 50 | let size = self.any_vec_ptr.any_vec_raw().element_layout().size(); 51 | let dst = self.bytes() as *mut u8; 52 | let src = dst.add(size); 53 | crate::copy_bytes(src, dst, size * (self.last_index - self.index)); 54 | } 55 | 56 | // 3. shrink len `self.any_vec.len -= 1` 57 | { 58 | let any_vec_raw = self.any_vec_ptr.any_vec_raw_mut(); 59 | any_vec_raw.len = self.last_index; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/ops/splice.rs: -------------------------------------------------------------------------------- 1 | use crate::any_vec_ptr::IAnyVecRawPtr; 2 | use crate::{any_vec_ptr, assert_types_equal, Iter}; 3 | use crate::any_value::{AnyValue, AnyValueSizeless}; 4 | use crate::ops::iter::Iterable; 5 | 6 | pub struct Splice<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> 7 | where 8 | ReplaceIter::Item: AnyValue 9 | { 10 | iter: Iter<'a, AnyVecPtr>, 11 | start: usize, 12 | original_len: usize, 13 | replace_with: ReplaceIter 14 | } 15 | 16 | impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> 17 | Splice<'a, AnyVecPtr, ReplaceIter> 18 | where 19 | ReplaceIter::Item: AnyValue 20 | { 21 | #[inline] 22 | pub fn new( 23 | mut any_vec_ptr: AnyVecPtr, start: usize, end: usize, 24 | replace_with: ReplaceIter 25 | ) -> Self { 26 | debug_assert!(start <= end); 27 | let any_vec_raw = unsafe{ any_vec_ptr.any_vec_raw_mut() }; 28 | let original_len = any_vec_raw.len; 29 | debug_assert!(end <= original_len); 30 | 31 | // mem::forget and element drop panic "safety". 32 | any_vec_raw.len = start; 33 | 34 | Self{ 35 | iter: Iter::new(any_vec_ptr, start, end), 36 | start, 37 | original_len, 38 | replace_with 39 | } 40 | } 41 | } 42 | 43 | impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> Iterable 44 | for 45 | Splice<'a, AnyVecPtr, ReplaceIter> 46 | where 47 | ReplaceIter::Item: AnyValue 48 | { 49 | type Iter = Iter<'a, AnyVecPtr>; 50 | 51 | #[inline] 52 | fn iter(&self) -> &Self::Iter { 53 | &self.iter 54 | } 55 | 56 | #[inline] 57 | fn iter_mut(&mut self) -> &mut Self::Iter { 58 | &mut self.iter 59 | } 60 | } 61 | 62 | impl<'a, AnyVecPtr: IAnyVecRawPtr, ReplaceIter: ExactSizeIterator> Drop 63 | for 64 | Splice<'a, AnyVecPtr, ReplaceIter> 65 | where 66 | ReplaceIter::Item: AnyValue 67 | { 68 | fn drop(&mut self) { 69 | use any_vec_ptr::utils::*; 70 | let mut any_vec_ptr = self.iter.any_vec_ptr; 71 | 72 | let elements_left = self.original_len - self.iter.end; 73 | let replace_end = self.start + self.replace_with.len(); 74 | let new_len = replace_end + elements_left; 75 | 76 | // 0. capacity. 77 | { 78 | let any_vec_raw = unsafe{any_vec_ptr.any_vec_raw_mut()}; 79 | any_vec_raw.reserve(new_len); 80 | } 81 | 82 | // 1. drop elements. 83 | unsafe{ 84 | drop_elements_range( 85 | any_vec_ptr, 86 | self.iter.index, 87 | self.iter.end 88 | ); 89 | } 90 | 91 | // 2. move elements 92 | unsafe{ 93 | move_elements_at( 94 | any_vec_ptr, 95 | self.iter.end, 96 | replace_end, 97 | elements_left 98 | ); 99 | } 100 | 101 | // 3. move replace_with in 102 | unsafe{ 103 | let type_id = element_typeid(any_vec_ptr); 104 | let element_size = element_size(any_vec_ptr); 105 | let mut ptr = element_mut_ptr_at(any_vec_ptr, self.start); 106 | while let Some(replace_element) = self.replace_with.next() { 107 | assert_types_equal(type_id, replace_element.value_typeid()); 108 | replace_element.move_into::< 109 | ::Type 110 | >(ptr, element_size); 111 | ptr = ptr.add(element_size); 112 | } 113 | } 114 | 115 | // 4. restore len 116 | { 117 | let any_vec_raw = unsafe{any_vec_ptr.any_vec_raw_mut()}; 118 | any_vec_raw.len = new_len; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /src/ops/swap_remove.rs: -------------------------------------------------------------------------------- 1 | use core::marker::PhantomData; 2 | use crate::copy_nonoverlapping_value; 3 | use crate::any_vec_ptr::IAnyVecRawPtr; 4 | use crate::any_vec_ptr::utils::{element_mut_ptr_at, element_ptr_at}; 5 | use crate::any_vec_raw::AnyVecRaw; 6 | use crate::ops::temp::Operation; 7 | 8 | pub struct SwapRemove<'a, AnyVecPtr: IAnyVecRawPtr>{ 9 | any_vec_ptr: AnyVecPtr, 10 | element: *mut u8, 11 | last_index: usize, 12 | phantom: PhantomData<&'a mut AnyVecRaw>, 13 | } 14 | 15 | impl<'a, AnyVecPtr: IAnyVecRawPtr> SwapRemove<'a, AnyVecPtr>{ 16 | #[inline] 17 | pub(crate) fn new(mut any_vec_ptr: AnyVecPtr, index: usize) -> Self{ 18 | let element = unsafe{ element_mut_ptr_at(any_vec_ptr, index) }; 19 | 20 | // 1. mem::forget and element drop panic "safety". 21 | let any_vec_raw = unsafe{ any_vec_ptr.any_vec_raw_mut() }; 22 | let last_index = any_vec_raw.len - 1; 23 | any_vec_raw.len = index; 24 | 25 | Self{ any_vec_ptr, element, last_index, phantom: PhantomData } 26 | } 27 | } 28 | 29 | impl<'a, AnyVecPtr: IAnyVecRawPtr> Operation for SwapRemove<'a, AnyVecPtr>{ 30 | type AnyVecPtr = AnyVecPtr; 31 | 32 | #[inline] 33 | fn any_vec_ptr(&self) -> Self::AnyVecPtr { 34 | self.any_vec_ptr 35 | } 36 | 37 | #[inline] 38 | fn bytes(&self) -> *const u8 { 39 | self.element 40 | } 41 | 42 | #[inline] 43 | fn consume(&mut self) { 44 | unsafe{ 45 | // 2. overwrite with last element 46 | let last_element = element_ptr_at(self.any_vec_ptr, self.last_index); 47 | let any_vec_raw = self.any_vec_ptr.any_vec_raw_mut(); 48 | 49 | if self.element as *const u8 != last_element { 50 | copy_nonoverlapping_value::( 51 | last_element, 52 | self.element, 53 | any_vec_raw.element_layout().size() 54 | ); 55 | } 56 | 57 | // 3. shrink len `self.any_vec.len -= 1` 58 | any_vec_raw.len = self.last_index; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/ops/temp.rs: -------------------------------------------------------------------------------- 1 | use core::any::TypeId; 2 | use core::{mem, ptr}; 3 | use crate::any_value::{AnyValue, AnyValueCloneable, AnyValueMut, AnyValueSizeless, AnyValueSizelessMut, AnyValueTypeless, AnyValueTypelessMut, Unknown}; 4 | use crate::any_vec_raw::AnyVecRaw; 5 | use crate::any_vec_ptr::{IAnyVecPtr, IAnyVecRawPtr}; 6 | use crate::{AnyVec, copy_nonoverlapping_value}; 7 | use crate::traits::Cloneable; 8 | 9 | pub trait Operation { 10 | type AnyVecPtr: IAnyVecRawPtr; 11 | 12 | fn any_vec_ptr(&self) -> Self::AnyVecPtr; 13 | 14 | fn bytes(&self) -> *const u8; 15 | 16 | /// Called after bytes move. 17 | fn consume(&mut self); 18 | } 19 | 20 | /// Temporary existing value in memory. 21 | /// Data will be erased with TempValue destruction. 22 | /// 23 | /// Have internal `&mut AnyVec`. 24 | /// 25 | /// May do some postponed actions on consumption/destruction. 26 | /// 27 | pub struct TempValue{ 28 | op: Op, 29 | } 30 | impl TempValue{ 31 | #[inline] 32 | pub(crate) fn new(op: Op) -> Self { 33 | Self{op} 34 | } 35 | 36 | #[inline] 37 | fn any_vec_raw(&self) -> &AnyVecRaw<::M>{ 38 | unsafe{ self.op.any_vec_ptr().any_vec_raw() } 39 | } 40 | 41 | #[inline] 42 | fn bytes_len(&self) -> usize{ 43 | if Unknown::is::<::Element>() { 44 | self.any_vec_raw().element_layout().size() 45 | } else{ 46 | mem::size_of::<::Element>() 47 | } 48 | } 49 | } 50 | 51 | impl AnyValueSizeless for TempValue { 52 | type Type = ::Element; 53 | 54 | #[inline] 55 | fn as_bytes_ptr(&self) -> *const u8 { 56 | self.op.bytes() 57 | } 58 | 59 | #[inline] 60 | unsafe fn move_into(mut self, out: *mut u8, bytes_size: usize) { 61 | copy_nonoverlapping_value::(self.as_bytes_ptr(), out, bytes_size); 62 | self.op.consume(); 63 | mem::forget(self); 64 | } 65 | } 66 | impl AnyValueSizelessMut for TempValue { 67 | #[inline] 68 | fn as_bytes_mut_ptr(&mut self) -> *mut u8 { 69 | // Somehow this is OK with MIRI. 70 | self.op.bytes() as *mut u8 71 | } 72 | } 73 | impl AnyValueTypeless for TempValue{ 74 | #[inline] 75 | fn size(&self) -> usize { 76 | self.bytes_len() 77 | } 78 | } 79 | impl AnyValue for TempValue{ 80 | #[inline] 81 | fn value_typeid(&self) -> TypeId { 82 | let typeid = TypeId::of::(); 83 | if typeid == TypeId::of::(){ 84 | self.any_vec_raw().type_id 85 | } else { 86 | typeid 87 | } 88 | } 89 | } 90 | 91 | impl AnyValueTypelessMut for TempValue {} 92 | impl AnyValueMut for TempValue {} 93 | 94 | impl AnyValueCloneable for TempValue 95 | where 96 | Op::AnyVecPtr: IAnyVecPtr, 97 | ::Traits: Cloneable 98 | { 99 | #[inline] 100 | unsafe fn clone_into(&self, out: *mut u8) { 101 | let clone_fn = self.op.any_vec_ptr().any_vec().clone_fn(); 102 | (clone_fn)(self.as_bytes().as_ptr(), out, 1); 103 | } 104 | } 105 | 106 | impl Drop for TempValue{ 107 | #[inline] 108 | fn drop(&mut self) { 109 | unsafe{ 110 | let drop_fn = self.any_vec_raw().drop_fn; 111 | let element = self.op.bytes() as *mut u8; 112 | 113 | // compile-time check 114 | if Unknown::is::<::Type>() { 115 | if let Some(drop_fn) = drop_fn{ 116 | (drop_fn)(element, 1); 117 | } 118 | } else { 119 | ptr::drop_in_place(element as *mut ::Type); 120 | } 121 | } 122 | self.op.consume(); 123 | } 124 | } 125 | 126 | unsafe impl Send for TempValue 127 | where 128 | Op::AnyVecPtr: IAnyVecPtr, 129 | AnyVec< 130 | ::Traits, 131 | ::M 132 | >: Send 133 | {} 134 | 135 | unsafe impl Sync for TempValue 136 | where 137 | Op::AnyVecPtr: IAnyVecPtr, 138 | AnyVec< 139 | ::Traits, 140 | ::M 141 | >: Sync 142 | {} 143 | -------------------------------------------------------------------------------- /tests/any_value.rs: -------------------------------------------------------------------------------- 1 | use std::any::TypeId; 2 | use std::mem::size_of; 3 | use std::ptr::NonNull; 4 | use any_vec::any_value::{AnyValue, AnyValueMut, AnyValueRaw, AnyValueWrapper}; 5 | 6 | #[test] 7 | fn swap_test(){ 8 | // typed <-> typed 9 | { 10 | let mut a1 = AnyValueWrapper::new(String::from("1")); 11 | let mut a2 = AnyValueWrapper::new(String::from("2")); 12 | 13 | a1.swap(&mut a2); 14 | assert_eq!(a1.downcast_ref::().unwrap(), &String::from("2")); 15 | assert_eq!(a2.downcast_ref::().unwrap(), &String::from("1")); 16 | } 17 | 18 | // untyped <-> untyped 19 | { 20 | let mut s1 = String::from("1"); 21 | let mut s2 = String::from("2"); 22 | 23 | let mut a1 = unsafe{ 24 | AnyValueRaw::new( 25 | NonNull::from(&mut s1).cast::(), 26 | size_of::(), 27 | TypeId::of::() 28 | )}; 29 | let mut a2 = unsafe{ 30 | AnyValueRaw::new( 31 | NonNull::from(&mut s2).cast::(), 32 | size_of::(), 33 | TypeId::of::() 34 | )}; 35 | 36 | a1.swap(&mut a2); 37 | assert_eq!(a1.downcast_ref::().unwrap(), &String::from("2")); 38 | assert_eq!(a2.downcast_ref::().unwrap(), &String::from("1")); 39 | } 40 | 41 | // untyped <-> typed 42 | { 43 | let mut s1 = String::from("1"); 44 | let mut a1 = unsafe{ 45 | AnyValueRaw::new( 46 | NonNull::from(&mut s1).cast::(), 47 | size_of::(), 48 | TypeId::of::() 49 | )}; 50 | let mut a2 = AnyValueWrapper::new(String::from("2")); 51 | 52 | a1.swap(&mut a2); 53 | assert_eq!(a1.downcast_ref::().unwrap(), &String::from("2")); 54 | assert_eq!(a2.downcast_ref::().unwrap(), &String::from("1")); 55 | 56 | a2.swap(&mut a1); 57 | assert_eq!(a1.downcast_ref::().unwrap(), &String::from("1")); 58 | assert_eq!(a2.downcast_ref::().unwrap(), &String::from("2")); 59 | } 60 | } -------------------------------------------------------------------------------- /tests/any_vec.rs: -------------------------------------------------------------------------------- 1 | use std::any::{TypeId}; 2 | use std::mem::{size_of}; 3 | use std::mem::forget; 4 | use std::ptr::NonNull; 5 | use itertools::assert_equal; 6 | use any_vec::AnyVec; 7 | use any_vec::any_value::{AnyValueMut, AnyValueRaw, AnyValueWrapper}; 8 | use any_vec::mem::Stack; 9 | 10 | #[allow(dead_code)] 11 | unsafe fn any_as_u8_slice(p: &T) -> &[u8] { 12 | std::slice::from_raw_parts( 13 | (p as *const T) as *const u8, 14 | std::mem::size_of::(), 15 | ) 16 | } 17 | 18 | struct S{i:usize} 19 | impl Drop for S{ 20 | fn drop(&mut self) { 21 | println!("Drop {}",self.i); 22 | } 23 | } 24 | 25 | #[test] 26 | fn drop_test() { 27 | let mut any_vec: AnyVec = AnyVec::new::(); 28 | let mut vec = any_vec.downcast_mut::().unwrap(); 29 | vec.push(S{i:1}); 30 | vec.push(S{i:2}); 31 | vec.push(S{i:3}); 32 | 33 | assert_equal(vec.as_slice().iter().map(|s|s.i), [1, 2, 3]); 34 | } 35 | 36 | #[test] 37 | fn any_value_raw_test() { 38 | let mut any_vec: AnyVec = AnyVec::new::(); 39 | 40 | unsafe{ 41 | let str1 = "Hello".to_string(); 42 | any_vec.push(AnyValueRaw::new( 43 | NonNull::from(&str1).cast::(), size_of::(), 44 | TypeId::of::() 45 | )); 46 | forget(str1); 47 | 48 | let str2 = " to ".to_string(); 49 | any_vec.push(AnyValueRaw::new( 50 | NonNull::from(&str2).cast::(), size_of::(), 51 | TypeId::of::() 52 | )); 53 | forget(str2); 54 | 55 | let str3 = "world".to_string(); 56 | any_vec.push(AnyValueRaw::new( 57 | NonNull::from(&str3).cast::(), size_of::(), 58 | TypeId::of::() 59 | )); 60 | forget(str3); 61 | } 62 | 63 | assert_equal( 64 | any_vec.downcast_ref::().unwrap().as_slice(), 65 | ["Hello", " to ", "world"] 66 | ); 67 | } 68 | 69 | #[test] 70 | pub fn push_with_capacity_test(){ 71 | const SIZE: usize = 10000; 72 | let mut any_vec: AnyVec = AnyVec::with_capacity::(SIZE); 73 | let mut vec = any_vec.downcast_mut::().unwrap(); 74 | for i in 0..SIZE{ 75 | vec.push(i); 76 | } 77 | 78 | assert_equal(vec.as_slice().iter().copied(), 0..SIZE); 79 | } 80 | 81 | #[test] 82 | fn zero_size_type_test() { 83 | struct Empty{} 84 | let mut any_vec: AnyVec = AnyVec::new::(); 85 | let mut vec = any_vec.downcast_mut::().unwrap(); 86 | vec.push(Empty{}); 87 | vec.push(Empty{}); 88 | vec.push(Empty{}); 89 | 90 | let mut i = 0; 91 | for _ in vec.as_mut_slice(){ 92 | i += 1; 93 | } 94 | assert_eq!(i, 3); 95 | } 96 | 97 | #[test] 98 | fn remove_test() { 99 | let mut any_vec: AnyVec = AnyVec::new::(); 100 | { 101 | let mut vec = any_vec.downcast_mut::().unwrap(); 102 | vec.push(String::from("0")); 103 | vec.push(String::from("1")); 104 | vec.push(String::from("2")); 105 | vec.push(String::from("3")); 106 | vec.push(String::from("4")); 107 | } 108 | 109 | // type erased remove 110 | { 111 | let mut removed = any_vec.remove(2); 112 | // test temp_mut_access 113 | let str = removed.downcast_mut::().unwrap(); 114 | str.push_str("xxx"); 115 | assert_eq!(str, "2xxx"); 116 | } 117 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 118 | String::from("0"), 119 | String::from("1"), 120 | String::from("3"), 121 | String::from("4"), 122 | ]); 123 | 124 | // remove last 125 | any_vec.remove(3); 126 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 127 | String::from("0"), 128 | String::from("1"), 129 | String::from("3"), 130 | ]); 131 | 132 | // remove first 133 | any_vec.remove(0); 134 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 135 | String::from("1"), 136 | String::from("3"), 137 | ]); 138 | } 139 | 140 | #[test] 141 | fn swap_remove_test() { 142 | let mut any_vec: AnyVec = AnyVec::new::(); 143 | { 144 | let mut vec = any_vec.downcast_mut::().unwrap(); 145 | vec.push(String::from("0")); 146 | vec.push(String::from("1")); 147 | vec.push(String::from("2")); 148 | vec.push(String::from("3")); 149 | vec.push(String::from("4")); 150 | 151 | let e: String = vec.swap_remove(1); 152 | assert_eq!(e, String::from("1")); 153 | assert_equal(vec.as_slice(), &[ 154 | String::from("0"), 155 | String::from("4"), 156 | String::from("2"), 157 | String::from("3"), 158 | ]); 159 | } 160 | 161 | any_vec.swap_remove(2); 162 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 163 | String::from("0"), 164 | String::from("4"), 165 | String::from("3"), 166 | ]); 167 | 168 | any_vec.swap_remove(2); 169 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 170 | String::from("0"), 171 | String::from("4"), 172 | ]); 173 | } 174 | 175 | #[test] 176 | fn any_vec_swap_remove_push_test() { 177 | let mut any_vec: AnyVec = AnyVec::new::(); 178 | any_vec.push(AnyValueWrapper::new(String::from("0"))); 179 | any_vec.push(AnyValueWrapper::new(String::from("1"))); 180 | any_vec.push(AnyValueWrapper::new(String::from("3"))); 181 | any_vec.push(AnyValueWrapper::new(String::from("4"))); 182 | 183 | let mut any_vec_other: AnyVec = AnyVec::new::(); 184 | let mut element = any_vec.swap_remove(1); 185 | *element.downcast_mut::().unwrap() += "+"; 186 | any_vec_other.push(element); 187 | 188 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 189 | String::from("0"), 190 | String::from("4"), 191 | String::from("3"), 192 | ]); 193 | assert_equal(any_vec_other.downcast_ref::().unwrap().as_slice(), &[ 194 | String::from("1+"), 195 | ]); 196 | } 197 | 198 | #[test] 199 | fn any_vec_drain_all_test() { 200 | let mut any_vec: AnyVec = AnyVec::new::(); 201 | any_vec.push(AnyValueWrapper::new(String::from("0"))); 202 | any_vec.push(AnyValueWrapper::new(String::from("1"))); 203 | any_vec.push(AnyValueWrapper::new(String::from("2"))); 204 | any_vec.push(AnyValueWrapper::new(String::from("3"))); 205 | 206 | let mut any_vec2: AnyVec = AnyVec::new::(); 207 | for e in any_vec.drain(..){ 208 | any_vec2.push(e); 209 | } 210 | assert_eq!(any_vec.len(), 0); 211 | assert_equal(any_vec2.downcast_ref::().unwrap().as_slice(), &[ 212 | String::from("0"), 213 | String::from("1"), 214 | String::from("2"), 215 | String::from("3"), 216 | ]); 217 | } 218 | 219 | #[test] 220 | fn any_vec_drain_in_the_middle_test() { 221 | let mut any_vec: AnyVec = AnyVec::new::(); 222 | any_vec.push(AnyValueWrapper::new(String::from("0"))); 223 | any_vec.push(AnyValueWrapper::new(String::from("1"))); 224 | any_vec.push(AnyValueWrapper::new(String::from("2"))); 225 | any_vec.push(AnyValueWrapper::new(String::from("3"))); 226 | any_vec.push(AnyValueWrapper::new(String::from("4"))); 227 | 228 | let mut any_vec2: AnyVec = AnyVec::new::(); 229 | for e in any_vec.drain(1..3){ 230 | any_vec2.push(e); 231 | } 232 | assert_equal(any_vec2.downcast_ref::().unwrap().as_slice(), &[ 233 | String::from("1"), 234 | String::from("2"), 235 | ]); 236 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 237 | String::from("0"), 238 | String::from("3"), 239 | String::from("4"), 240 | ]); 241 | } 242 | 243 | #[test] 244 | fn any_vec_splice_test() { 245 | let mut any_vec: AnyVec = AnyVec::new::(); 246 | any_vec.push(AnyValueWrapper::new(String::from("0"))); 247 | any_vec.push(AnyValueWrapper::new(String::from("1"))); 248 | any_vec.push(AnyValueWrapper::new(String::from("2"))); 249 | any_vec.push(AnyValueWrapper::new(String::from("3"))); 250 | any_vec.push(AnyValueWrapper::new(String::from("4"))); 251 | 252 | let mut any_vec2: AnyVec = AnyVec::new::(); 253 | let drained = any_vec.splice(1..4, [ 254 | AnyValueWrapper::new(String::from("100")), 255 | AnyValueWrapper::new(String::from("200")) 256 | ]); 257 | assert_eq!(drained.len(), 3); // Test ExactSizeIterator 258 | for e in drained{ 259 | any_vec2.push(e); 260 | } 261 | assert_equal(any_vec2.downcast_ref::().unwrap().as_slice(), &[ 262 | String::from("1"), 263 | String::from("2"), 264 | String::from("3"), 265 | ]); 266 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 267 | String::from("0"), 268 | String::from("100"), 269 | String::from("200"), 270 | String::from("4"), 271 | ]); 272 | } 273 | 274 | #[test] 275 | fn any_vec_insert_front(){ 276 | let mut any_vec: AnyVec = AnyVec::new::(); 277 | let mut vec = any_vec.downcast_mut::().unwrap(); 278 | for i in 0..100{ 279 | vec.insert(0, i); 280 | } 281 | assert_equal(vec.as_slice().iter().copied(), (0..100).rev()); 282 | } 283 | 284 | #[test] 285 | fn any_vec_insert_back(){ 286 | let mut any_vec: AnyVec = AnyVec::new::(); 287 | let mut vec = any_vec.downcast_mut::().unwrap(); 288 | for i in 0..100{ 289 | vec.insert(i, i); 290 | } 291 | assert_equal(vec.as_slice().iter().copied(), 0..100); 292 | } 293 | 294 | #[test] 295 | fn reserve_test(){ 296 | let mut any_vec: AnyVec = AnyVec::new::(); 297 | assert_eq!(any_vec.capacity(), 0); 298 | 299 | any_vec.reserve(4); 300 | assert_eq!(any_vec.capacity(), 4); 301 | 302 | any_vec.reserve(6); 303 | assert_eq!(any_vec.capacity(), 8); 304 | } 305 | 306 | #[test] 307 | fn reserve_exact_test(){ 308 | let mut any_vec: AnyVec = AnyVec::new::(); 309 | assert_eq!(any_vec.capacity(), 0); 310 | 311 | any_vec.reserve_exact(4); 312 | assert_eq!(any_vec.capacity(), 4); 313 | 314 | any_vec.reserve_exact(6); 315 | assert_eq!(any_vec.capacity(), 6); 316 | } 317 | 318 | #[test] 319 | fn shrink_to_fit_test(){ 320 | let mut any_vec: AnyVec = AnyVec::new::(); 321 | assert_eq!(any_vec.capacity(), 0); 322 | 323 | any_vec.reserve_exact(10); 324 | assert_eq!(any_vec.capacity(), 10); 325 | 326 | any_vec.shrink_to_fit(); 327 | assert_eq!(any_vec.capacity(), 0); 328 | } 329 | 330 | #[test] 331 | fn shrink_to_test(){ 332 | let mut any_vec: AnyVec = AnyVec::new::(); 333 | assert_eq!(any_vec.capacity(), 0); 334 | 335 | any_vec.reserve_exact(10); 336 | assert_eq!(any_vec.capacity(), 10); 337 | 338 | any_vec.shrink_to(5); 339 | assert_eq!(any_vec.capacity(), 5); 340 | } 341 | 342 | #[test] 343 | fn mem_stack_test(){ 344 | use any_vec::traits::None; 345 | type FixedAnyVec = AnyVec>; 346 | 347 | let mut any_vec: FixedAnyVec = AnyVec::new::(); 348 | { 349 | let mut vec = any_vec.downcast_mut::().unwrap(); 350 | vec.push(String::from("0")); 351 | vec.push(String::from("1")); 352 | vec.push(String::from("2")); 353 | vec.push(String::from("3")); 354 | } 355 | 356 | // Should fail to compile. 357 | //any_vec.reserve(1); 358 | 359 | assert_eq!(any_vec.capacity(), 513/size_of::()); 360 | assert_eq!(any_vec.len(), 4); 361 | assert_equal(any_vec.downcast_ref::().unwrap(), &[ 362 | String::from("0"), 363 | String::from("1"), 364 | String::from("2"), 365 | String::from("3") 366 | ]); 367 | } 368 | 369 | #[test] 370 | fn any_vec_into_iter_test() { 371 | let mut any_vec: AnyVec = AnyVec::new::(); 372 | { 373 | let mut vec = any_vec.downcast_mut::().unwrap(); 374 | vec.push(1); 375 | vec.push(10); 376 | vec.push(100); 377 | } 378 | 379 | let mut sum = 0; 380 | for e in &any_vec{ 381 | sum += e.downcast_ref::().unwrap(); 382 | } 383 | assert_eq!(sum, 111); 384 | 385 | let mut sum = 0; 386 | for mut e in &mut any_vec{ 387 | let value = e.downcast_mut::().unwrap(); 388 | *value *= 10; 389 | sum += *value; 390 | } 391 | assert_eq!(sum, 1110); 392 | } 393 | 394 | #[test] 395 | fn any_vec_debug() { 396 | let any_vec: AnyVec = AnyVec::new::(); 397 | let typeid = TypeId::of::(); 398 | assert_eq!(format!("{any_vec:?}"), format!("AnyVec {{ typeid: {typeid:?}, len: 0 }}")); 399 | } -------------------------------------------------------------------------------- /tests/any_vec_element.rs: -------------------------------------------------------------------------------- 1 | use std::any::TypeId; 2 | use itertools::{assert_equal}; 3 | use any_vec::any_value::{AnyValue, AnyValueCloneable, LazyClone}; 4 | use any_vec::AnyVec; 5 | use any_vec::element::ElementReference; 6 | use any_vec::mem::{MemBuilder, Stack}; 7 | use any_vec::traits::{Cloneable, Trait}; 8 | 9 | #[test] 10 | fn lazy_clone_test(){ 11 | let mut any_vec: AnyVec = AnyVec::new::(); 12 | { 13 | let mut vec = any_vec.downcast_mut::().unwrap(); 14 | vec.push(String::from("0")); 15 | vec.push(String::from("1")); 16 | vec.push(String::from("2")); 17 | } 18 | 19 | let mut any_vec_other: AnyVec = AnyVec::new::(); 20 | { 21 | let e1 = any_vec.swap_remove(1); 22 | let lz1 = LazyClone::new(&e1); 23 | let lz2 = LazyClone::new(&lz1).clone(); 24 | 25 | any_vec_other.push(LazyClone::new(&e1)); 26 | any_vec_other.push(LazyClone::new(&lz2)); 27 | } 28 | 29 | assert_equal( 30 | any_vec.downcast_ref::().unwrap().as_slice(), 31 | &[String::from("0"), String::from("2")] 32 | ); 33 | assert_equal( 34 | any_vec_other.downcast_ref::().unwrap().as_slice(), 35 | &[String::from("1"), String::from("1")] 36 | ); 37 | } 38 | 39 | #[test] 40 | fn any_vec_get_test(){ 41 | let mut any_vec: AnyVec = AnyVec::new::(); 42 | assert_eq!(any_vec.element_typeid(), TypeId::of::()); 43 | { 44 | let mut vec = any_vec.downcast_mut::().unwrap(); 45 | vec.push(String::from("0")); 46 | vec.push(String::from("1")); 47 | vec.push(String::from("2")); 48 | } 49 | 50 | let e1_ref = any_vec.get(1).unwrap(); 51 | assert_eq!(e1_ref.downcast_ref::().unwrap(), &String::from("1")); 52 | assert_eq!(e1_ref.value_typeid(), TypeId::of::()); 53 | 54 | { 55 | let e1 = e1_ref.lazy_clone(); 56 | let e2 = e1.lazy_clone(); 57 | let e3 = e2.lazy_clone(); 58 | 59 | // Consume in reverse order, since lazy clone source must outlive it. 60 | assert_eq!(e3.downcast::().unwrap(), String::from("1")); 61 | assert_eq!(e2.downcast::().unwrap(), String::from("1")); 62 | assert_eq!(e1.downcast::().unwrap(), String::from("1")); 63 | } 64 | 65 | // Mutability test 66 | { 67 | let e = any_vec.downcast_mut::().unwrap().as_mut_slice().get_mut(1).unwrap(); 68 | *e += "A"; 69 | 70 | let str = any_vec.get_mut(1).unwrap().downcast_mut::().unwrap(); 71 | *str += "B"; 72 | 73 | assert_eq!(any_vec.get(1).unwrap().downcast_ref::().unwrap(), &String::from("1AB")); 74 | } 75 | } 76 | 77 | #[test] 78 | fn any_vec_iter_test(){ 79 | let mut any_vec: AnyVec = AnyVec::new::(); 80 | { 81 | let mut vec = any_vec.downcast_mut::().unwrap(); 82 | vec.push(String::from("0")); 83 | vec.push(String::from("1")); 84 | vec.push(String::from("2")); 85 | } 86 | 87 | assert_equal( 88 | any_vec.iter().map(|e|e.downcast_ref::().unwrap()), 89 | any_vec.downcast_ref::().unwrap().as_slice() 90 | ); 91 | 92 | let mut any_vec2 = any_vec.clone_empty(); 93 | for e in any_vec.iter(){ 94 | any_vec2.push(e.lazy_clone()); 95 | } 96 | 97 | assert_equal( 98 | any_vec.downcast_ref::().unwrap().as_slice(), 99 | any_vec2.downcast_ref::().unwrap().as_slice() 100 | ); 101 | 102 | for mut e in any_vec2.iter_mut(){ 103 | *e.downcast_mut::().unwrap() = String::from("100"); 104 | } 105 | assert_equal( 106 | any_vec2.downcast_ref::().unwrap().as_slice(), 107 | &[String::from("100"), String::from("100"), String::from("100")] 108 | ); 109 | 110 | // test ElementRef cloneability 111 | { 112 | let r1 = any_vec.get(1).unwrap(); 113 | let r2 = r1.clone(); 114 | assert_eq!(r1.downcast_ref::().unwrap(), &String::from("1")); 115 | assert_eq!(r2.downcast_ref::().unwrap(), &String::from("1")); 116 | } 117 | 118 | // This should not compile 119 | /*{ 120 | let iter = any_vec.iter(); 121 | let mut iter_mut = any_vec.iter_mut(); 122 | iter_mut.next().unwrap().downcast_mut::(); 123 | iter.next().unwrap().downcast::(); 124 | }*/ 125 | } 126 | 127 | #[test] 128 | fn any_vec_iter_clone_test(){ 129 | let mut any_vec: AnyVec = AnyVec::new::(); 130 | { 131 | let mut vec = any_vec.downcast_mut::().unwrap(); 132 | vec.push(1); 133 | vec.push(10); 134 | vec.push(100); 135 | } 136 | 137 | fn into_usize<'a, T: ?Sized + Trait, M: MemBuilder + 'a>(e: impl ElementReference<'a, T, M>) -> &'a usize 138 | { 139 | e.downcast_ref::().unwrap() 140 | } 141 | assert_eq!(any_vec.iter().clone().map(into_usize).sum::(), 111); 142 | assert_eq!(any_vec.iter_mut().clone().map(into_usize).sum::(), 111); 143 | } 144 | 145 | #[test] 146 | fn any_vec_push_to_self_test(){ 147 | let mut any_vec: AnyVec = AnyVec::new::(); 148 | { 149 | let mut vec = any_vec.downcast_mut::().unwrap(); 150 | vec.push(String::from("0")); 151 | vec.push(String::from("1")); 152 | vec.push(String::from("2")); 153 | } 154 | 155 | let mut intermediate = any_vec.clone_empty_in(Stack::<512>); 156 | intermediate.push(any_vec.get(1).unwrap().lazy_clone()); 157 | let e = intermediate.pop().unwrap(); 158 | 159 | any_vec.push(e.lazy_clone()); 160 | any_vec.push(e); 161 | 162 | assert!(intermediate.is_empty()); 163 | assert_equal( 164 | any_vec.downcast_ref::().unwrap().as_slice(), 165 | &[ 166 | String::from("0"), 167 | String::from("1"), 168 | String::from("2"), 169 | String::from("1"), 170 | String::from("1") 171 | ] 172 | ); 173 | } 174 | 175 | #[test] 176 | fn any_vec_double_ended_iterator_test(){ 177 | let mut any_vec: AnyVec = AnyVec::new::(); 178 | { 179 | let mut vec = any_vec.downcast_mut::().unwrap(); 180 | vec.push(String::from("0")); 181 | vec.push(String::from("1")); 182 | vec.push(String::from("2")); 183 | } 184 | 185 | assert_equal( 186 | any_vec.iter().rev().map(|e|e.downcast_ref::().unwrap()), 187 | [ 188 | String::from("2"), 189 | String::from("1"), 190 | String::from("0"), 191 | ].iter() 192 | ); 193 | } -------------------------------------------------------------------------------- /tests/any_vec_fuzzy.rs: -------------------------------------------------------------------------------- 1 | use std::cmp; 2 | use std::ops::Range; 3 | use itertools::assert_equal; 4 | use rand::Rng; 5 | use any_vec::any_value::{AnyValue, AnyValueWrapper}; 6 | use any_vec::AnyVec; 7 | 8 | const REPEATS: usize = if cfg!(miri){ 4 }else{ 100 }; 9 | const SIZE: usize = if cfg!(miri){ 100 }else{ 10000 }; 10 | 11 | fn rnd_range(max: usize) -> Range { 12 | let start = rand::thread_rng().gen_range(0..max); 13 | let len = rand::thread_rng().gen_range(0..max); 14 | let end = cmp::min(max, start+len); 15 | Range{start, end} 16 | } 17 | 18 | #[test] 19 | fn any_vec_drain_fuzzy_test() { 20 | for _ in 0..REPEATS{ 21 | let mut any_vec: AnyVec = AnyVec::new::(); 22 | let mut vec = Vec::new(); 23 | 24 | // 1. fill 25 | for i in 0..SIZE { 26 | any_vec.push(AnyValueWrapper::new(i.to_string())); 27 | vec.push(i.to_string()); 28 | } 29 | 30 | // 2. do drain 31 | let drain_range = rnd_range(vec.len()); 32 | let drain = vec.drain(drain_range.clone()); 33 | let any_drain = any_vec.drain(drain_range.clone()); 34 | assert_equal(drain, any_drain.map(|e|e.downcast::().unwrap())); 35 | assert_equal(vec.iter(), any_vec.downcast_ref::().unwrap()); 36 | } 37 | } 38 | 39 | #[test] 40 | fn any_vec_splice_fuzzy_test() { 41 | for _ in 0..REPEATS{ 42 | let mut any_vec: AnyVec = AnyVec::new::(); 43 | let mut vec = Vec::new(); 44 | 45 | // 1. fill 46 | for i in 0..SIZE { 47 | any_vec.push(AnyValueWrapper::new(i.to_string())); 48 | vec.push(i.to_string()); 49 | } 50 | 51 | // 2. prepare insertion 52 | let mut vec_insertion = Vec::new(); 53 | let insertion_size = rand::thread_rng().gen_range(0..SIZE); 54 | for i in 0..insertion_size{ 55 | vec_insertion.push(i.to_string()); 56 | } 57 | 58 | // 3. do splice 59 | let drain_range = rnd_range(vec.len()); 60 | let drain = vec.splice( 61 | drain_range.clone(), 62 | vec_insertion.iter().cloned() 63 | ); 64 | let any_drain = any_vec.splice( 65 | drain_range.clone(), 66 | vec_insertion.iter().cloned().map(|e|AnyValueWrapper::new(e)) 67 | ); 68 | assert_equal(drain, any_drain.map(|e|e.downcast::().unwrap())); 69 | assert_equal(vec.iter(), any_vec.downcast_ref::().unwrap()); 70 | } 71 | } 72 | 73 | #[test] 74 | fn any_vec_typed_splice_fuzzy_test() { 75 | for _ in 0..REPEATS{ 76 | let mut any_vec: AnyVec = AnyVec::new::(); 77 | let mut any_vec = any_vec.downcast_mut::().unwrap(); 78 | let mut vec = Vec::new(); 79 | 80 | // 1. fill 81 | for i in 0..SIZE { 82 | any_vec.push(i.to_string()); 83 | vec.push(i.to_string()); 84 | } 85 | 86 | // 2. prepare insertion 87 | let mut vec_insertion = Vec::new(); 88 | let insertion_size = rand::thread_rng().gen_range(0..SIZE); 89 | for i in 0..insertion_size{ 90 | vec_insertion.push(i.to_string()); 91 | } 92 | 93 | // 3. do splice 94 | let drain_range = rnd_range(vec.len()); 95 | let drain = vec.splice( 96 | drain_range.clone(), 97 | vec_insertion.iter().cloned() 98 | ); 99 | let any_drain = any_vec.splice( 100 | drain_range.clone(), 101 | vec_insertion.iter().cloned() 102 | ); 103 | assert_equal(drain, any_drain); 104 | assert_equal(vec.iter(), any_vec.iter()); 105 | } 106 | } -------------------------------------------------------------------------------- /tests/any_vec_send_sync.rs: -------------------------------------------------------------------------------- 1 | use std::iter; 2 | use impls::impls; 3 | use any_vec::{AnyVec, AnyVecMut, IterMut, IterRef, mem}; 4 | use any_vec::any_value::AnyValueWrapper; 5 | use any_vec::mem::MemBuilder; 6 | use any_vec::ops::Drain; 7 | use any_vec::ops::Splice; 8 | use any_vec::traits::None; 9 | 10 | const fn is_send(_: &impl Send){} 11 | const fn is_sync(_: &impl Sync){} 12 | 13 | #[test] 14 | fn any_vec_heap_send_sync_test() { 15 | fn test_negative() 16 | { 17 | let mut any_vec: AnyVec = AnyVec::new::(); 18 | assert!(!impls!(AnyVec: Send)); 19 | assert!(!impls!(AnyVec: Sync)); 20 | { 21 | let iter: IterRef = any_vec.iter(); 22 | assert!(!impls!(IterRef: Send)); 23 | assert!(!impls!(IterRef: Sync)); 24 | drop(iter); 25 | } 26 | { 27 | let iter: IterMut = any_vec.iter_mut(); 28 | assert!(!impls!(IterMut: Send)); 29 | assert!(!impls!(IterMut: Sync)); 30 | drop(iter); 31 | } 32 | 33 | { 34 | let vec: AnyVecMut = any_vec.downcast_mut::().unwrap(); 35 | assert!(!impls!(AnyVecMut: Send)); 36 | assert!(!impls!(AnyVecMut: Sync)); 37 | drop(vec); 38 | } 39 | 40 | { 41 | let drained: Drain = any_vec.drain(..); 42 | assert!(!impls!(AnyVec: Send)); 43 | assert!(!impls!(AnyVec: Sync)); 44 | drop(drained); 45 | } 46 | { 47 | let drained: Splice>> = 48 | any_vec.splice(.., iter::empty::>()); 49 | assert!(!impls!(Splice>>: Send)); 50 | assert!(!impls!(Splice>>: Sync)); 51 | drop(drained); 52 | } 53 | } 54 | 55 | fn test_positive() 56 | where M::Mem: Sync + Send 57 | { 58 | let mut any_vec: AnyVec = AnyVec::new::(); 59 | is_sync(&any_vec); 60 | is_send(&any_vec); 61 | is_sync(&any_vec.iter()); 62 | is_send(&any_vec.iter()); 63 | is_sync(&any_vec.iter_mut()); 64 | is_send(&any_vec.iter_mut()); 65 | { 66 | let mut vec = any_vec.downcast_mut::().unwrap(); 67 | is_sync(&vec); 68 | is_send(&vec); 69 | is_sync(&vec.iter()); 70 | is_send(&vec.iter()); 71 | is_sync(&vec.iter_mut()); 72 | is_send(&vec.iter_mut()); 73 | } 74 | 75 | { 76 | let drained = any_vec.drain(..); 77 | is_sync(&drained); 78 | is_send(&drained); 79 | } 80 | { 81 | let drained = any_vec.splice(.., [AnyValueWrapper::new(String::new())]); 82 | is_sync(&drained); 83 | is_send(&drained); 84 | } 85 | } 86 | test_positive::(); 87 | test_positive::>(); 88 | 89 | test_negative::(); 90 | test_negative::>(); 91 | } 92 | -------------------------------------------------------------------------------- /tests/any_vec_traits.rs: -------------------------------------------------------------------------------- 1 | use std::mem::size_of_val; 2 | use itertools::assert_equal; 3 | use any_vec::{AnyVec, SatisfyTraits}; 4 | use any_vec::traits::*; 5 | 6 | #[test] 7 | pub fn test_default(){ 8 | let _any_vec: AnyVec = AnyVec::new::(); 9 | // should not compile 10 | //fn t(_: impl Sync){} 11 | //t(any_vec); 12 | } 13 | 14 | #[test] 15 | pub fn test_sync(){ 16 | let any_vec: AnyVec = AnyVec::new::(); 17 | fn t(_: impl Sync){} 18 | t(any_vec); 19 | } 20 | 21 | #[test] 22 | pub fn test_clone(){ 23 | fn do_test() 24 | where String: SatisfyTraits 25 | { 26 | let mut any_vec: AnyVec = AnyVec::new::(); 27 | { 28 | let mut vec = any_vec.downcast_mut::().unwrap(); 29 | vec.push(String::from("0")); 30 | vec.push(String::from("1")); 31 | vec.push(String::from("2")); 32 | } 33 | 34 | let any_vec2 = any_vec.clone(); 35 | assert_equal( 36 | any_vec.downcast_ref::().unwrap().as_slice(), 37 | any_vec2.downcast_ref::().unwrap().as_slice() 38 | ); 39 | } 40 | 41 | do_test::(); 42 | do_test::(); 43 | do_test::(); 44 | do_test::(); 45 | } 46 | 47 | #[test] 48 | pub fn type_check_test(){ 49 | fn fn_send(_: &impl Send){} 50 | fn fn_sync(_: &impl Sync){} 51 | 52 | { 53 | let any_vec: AnyVec = AnyVec::new::(); 54 | let _ = any_vec.clone(); 55 | } 56 | { 57 | let any_vec: AnyVec = AnyVec::new::(); 58 | fn_send(&any_vec); 59 | } 60 | { 61 | let any_vec: AnyVec = AnyVec::new::(); 62 | fn_sync(&any_vec); 63 | } 64 | { 65 | let any_vec: AnyVec = AnyVec::new::(); 66 | fn_send(&any_vec); 67 | fn_sync(&any_vec); 68 | } 69 | { 70 | let any_vec: AnyVec = AnyVec::new::(); 71 | fn_send(&any_vec); 72 | fn_sync(&any_vec); 73 | let _ = any_vec.clone(); 74 | } 75 | } 76 | 77 | /*// Should not compile 78 | #[test] 79 | pub fn type_check_fail_test(){ 80 | let any_vec: AnyVec = AnyVec::new::(); 81 | any_vec.clone(); 82 | }*/ 83 | 84 | #[test] 85 | fn any_vec_cloneable_zst_test(){ 86 | let v1: AnyVec = AnyVec::new::(); 87 | let v2: AnyVec = AnyVec::new::(); 88 | 89 | let s1 = size_of_val(&v1); 90 | let s2 = size_of_val(&v2); 91 | 92 | assert!(s1 > s2); 93 | } -------------------------------------------------------------------------------- /tests/any_vec_typed.rs: -------------------------------------------------------------------------------- 1 | use itertools::assert_equal; 2 | use any_vec::any_value::AnyValueWrapper; 3 | use any_vec::AnyVec; 4 | 5 | #[test] 6 | fn remove_test() { 7 | let mut any_vec: AnyVec = AnyVec::new::(); 8 | let mut vec = any_vec.downcast_mut::().unwrap(); 9 | vec.push(String::from("0")); 10 | vec.push(String::from("1")); 11 | vec.push(String::from("2")); 12 | vec.push(String::from("3")); 13 | vec.push(String::from("4")); 14 | 15 | // type erased remove 16 | vec.remove(2); 17 | assert_equal(vec.as_slice(), &[ 18 | String::from("0"), 19 | String::from("1"), 20 | String::from("3"), 21 | String::from("4"), 22 | ]); 23 | 24 | // remove last 25 | vec.remove(3); 26 | assert_equal(vec.as_slice(), &[ 27 | String::from("0"), 28 | String::from("1"), 29 | String::from("3"), 30 | ]); 31 | 32 | // remove first 33 | vec.remove(0); 34 | assert_equal(vec.as_slice(), &[ 35 | String::from("1"), 36 | String::from("3"), 37 | ]); 38 | } 39 | 40 | #[test] 41 | fn swap_remove_test() { 42 | let mut any_vec: AnyVec = AnyVec::new::(); 43 | let mut vec = any_vec.downcast_mut::().unwrap(); 44 | 45 | vec.push(String::from("0")); 46 | vec.push(String::from("1")); 47 | vec.push(String::from("2")); 48 | vec.push(String::from("3")); 49 | vec.push(String::from("4")); 50 | 51 | let e: String = vec.swap_remove(1); 52 | assert_eq!(e, String::from("1")); 53 | assert_equal(vec.as_slice(), &[ 54 | String::from("0"), 55 | String::from("4"), 56 | String::from("2"), 57 | String::from("3"), 58 | ]); 59 | 60 | vec.swap_remove(2); 61 | assert_equal(vec.as_slice(), &[ 62 | String::from("0"), 63 | String::from("4"), 64 | String::from("3"), 65 | ]); 66 | 67 | vec.swap_remove(2); 68 | assert_equal(vec.as_slice(), &[ 69 | String::from("0"), 70 | String::from("4"), 71 | ]); 72 | } 73 | 74 | #[test] 75 | fn drain_all_test() { 76 | let mut any_vec: AnyVec = AnyVec::new::(); 77 | let mut vec = any_vec.downcast_mut::().unwrap(); 78 | vec.push(String::from("0")); 79 | vec.push(String::from("1")); 80 | vec.push(String::from("2")); 81 | vec.push(String::from("3")); 82 | 83 | let mut vec2 = Vec::new(); 84 | for e in vec.drain(..){ 85 | vec2.push(e); 86 | } 87 | assert_eq!(any_vec.len(), 0); 88 | assert_equal(vec2, [ 89 | String::from("0"), 90 | String::from("1"), 91 | String::from("2"), 92 | String::from("3"), 93 | ]); 94 | } 95 | 96 | #[test] 97 | fn any_vec_drain_in_the_middle_test() { 98 | let mut any_vec: AnyVec = AnyVec::new::(); 99 | let mut vec = any_vec.downcast_mut::().unwrap(); 100 | vec.push(String::from("0")); 101 | vec.push(String::from("1")); 102 | vec.push(String::from("2")); 103 | vec.push(String::from("3")); 104 | vec.push(String::from("4")); 105 | 106 | let mut vec2 = Vec::new(); 107 | for e in vec.drain(1..3){ 108 | vec2.push(e); 109 | } 110 | assert_equal(vec2, [ 111 | String::from("1"), 112 | String::from("2"), 113 | ]); 114 | assert_equal(any_vec.downcast_ref::().unwrap().as_slice(), &[ 115 | String::from("0"), 116 | String::from("3"), 117 | String::from("4"), 118 | ]); 119 | } 120 | 121 | #[test] 122 | fn any_vec_splice_lifetime_test() { 123 | let mut any_vec: AnyVec = AnyVec::new::(); 124 | any_vec.push(AnyValueWrapper::new(String::from("0"))); 125 | any_vec.push(AnyValueWrapper::new(String::from("1"))); 126 | any_vec.push(AnyValueWrapper::new(String::from("2"))); 127 | any_vec.push(AnyValueWrapper::new(String::from("3"))); 128 | any_vec.push(AnyValueWrapper::new(String::from("4"))); 129 | 130 | // lifetime check ? 131 | { 132 | let mut vec = any_vec.downcast_mut::().unwrap(); 133 | let replace = [ 134 | String::from("100"), 135 | String::from("200") 136 | ]; 137 | let drained = vec.splice(1..4, replace.iter().cloned()); 138 | drained.count(); 139 | drop(replace); 140 | //drained.count(); 141 | } 142 | } 143 | 144 | #[test] 145 | pub fn downcast_mut_test(){ 146 | let mut any_vec: AnyVec = AnyVec::new::(); 147 | let mut vec = any_vec.downcast_mut::().unwrap(); 148 | vec.push("Hello".into()); 149 | assert_eq!(vec.len(), 1); 150 | } 151 | 152 | #[test] 153 | pub fn downcast_ref_test(){ 154 | let mut any_vec: AnyVec = AnyVec::new::(); 155 | any_vec.clear(); 156 | let vec1 = any_vec.downcast_ref::().unwrap(); 157 | let vec2 = any_vec.downcast_ref::().unwrap(); 158 | let vec3 = vec2.clone(); 159 | assert_eq!(vec1.len(), 0); 160 | assert_eq!(vec2.len(), 0); 161 | assert_eq!(vec3.len(), 0); 162 | } 163 | 164 | #[test] 165 | fn any_vec_into_iter_test() { 166 | let mut any_vec: AnyVec = AnyVec::new::(); 167 | let mut vec = any_vec.downcast_mut::().unwrap(); 168 | vec.push(1); 169 | vec.push(10); 170 | vec.push(100); 171 | 172 | let mut sum = 0; 173 | for e in vec{ 174 | sum += *e; 175 | } 176 | assert_eq!(sum, 111); 177 | } 178 | 179 | #[test] 180 | fn any_vec_debug() { 181 | let mut any_vec: AnyVec = AnyVec::new::(); 182 | let mut vec = any_vec.downcast_mut::().unwrap(); 183 | vec.push(1); 184 | vec.push(2); 185 | vec.push(3); 186 | 187 | let mut control_vec = Vec::new(); 188 | control_vec.push(1); 189 | control_vec.push(2); 190 | control_vec.push(3); 191 | 192 | assert_eq!(format!("{vec:?}"), format!("{control_vec:?}")); 193 | drop(vec); 194 | 195 | let vec = any_vec.downcast_ref::().unwrap(); 196 | assert_eq!(format!("{vec:?}"), format!("{control_vec:?}")); 197 | } 198 | 199 | /* 200 | #[test] 201 | fn any_vec_index_test() { 202 | let mut any_vec: AnyVec = AnyVec::new::(); 203 | let mut vec = any_vec.downcast_mut::().unwrap(); 204 | vec.push(1); 205 | vec.push(10); 206 | vec.push(100); 207 | 208 | assert_eq!(vec[1], 10); 209 | assert_eq!(vec[..], [1, 10, 100]); 210 | assert_eq!(vec[1..3], [10, 100]); 211 | } 212 | */ --------------------------------------------------------------------------------