1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
//! This crate provides API for working with arrays, e.g.: //! 1) Abstraction over arrays (you can use [`Array`] trait as bound on //! generics) //! 2) Creation of arrays (see [`Array`] trait) //! 3) Doing operations on arrays that produce arrays (see //! [`ArrayMap`] and [`ArrayAsRef`] traits) //! 4) By-value iterating on array (see [`IterMove`]) //! 5) `Iterator` adapter that yield fixed sized chunks of inner iterator //! (see [`ArrayChunks`]) //! //! [`Array`]: crate::Array //! [`ArrayExt`]: crate::ArrayExt //! [`IterMove`]: crate::iter::IterMove //! [`ArrayChunks`]: crate::iter::ArrayChunks //! //! ## Example //! //! ``` //! use arraylib::{Array, ArrayExt, ArrayMap}; //! //! // Array creation //! let arr = <[_; 11]>::unfold(1, |it| { //! let res = *it; //! *it *= -2; //! res //! }); //! //! // Mapping //! let arr = arr.map(|it| it * 2); //! assert_eq!(arr, [2, -4, 8, -16, 32, -64, 128, -256, 512, -1024, 2048]); //! //! // By-value iterator //! arr.iter_move().for_each(|i: i32| {}) //! ``` //! //! ## Sizes Limitations //! //! Because of lack of [`const generics`] it's impossible to implement traits on //! arrays of _all_ sizes (see [std note about that]), so this crate implements //! traits only for these sizes: //! - `[0; 32]` //! - `8 * [5; 12]` (40, 48, ..., 96) //! - `100 * [1; 10]` (100, 200, ..., 1000) //! - `2 ** [7; 16]` (128, 256, ..., 65536) //! - `[33; 128]` (If **array-impls-33-128** feature enabled) //! - `[129; 256]` (If **array-impls-129-256** feature enabled) //! //! [`const generics`]: https://github.com/rust-lang/rust/issues/44580 //! [std note about that]: https://doc.rust-lang.org/std/primitive.array.html //! //! ## no_std //! //! This lib doesn't depend on `std`, so it can be used in crates with the //! `#![no_std]` attribute. //! //! ## Features //! //! This crate provide next features: //! - **alloc** — enables API that depend on `alloc` crate //! - **nightly** — enable features that require nightly features: //! - `trusted_len` ([tracking issue][trusted_ti]) (Adds impl of `TrustedLen` //! for iterators) //! - `exact_size_is_empty` ([tracking issue][is_empty_ti]) (Implement //! `<{Chunks,IterMove} as ExactSizeIterator>::is_empty` more effective) //! - **array-impls-33-128** — adds impl of the [`Array`] trait for arrays of //! sizes 33-128 (inclusive) //! - **array-impls-129-256** — adds impl of the [`Array`] trait for arrays of //! sizes 129-256 (inclusive) //! //! [trusted_ti]: https://github.com/rust-lang/rust/issues/37572 //! [is_empty_ti]: https://github.com/rust-lang/rust/issues/35428 //! //! ## Alternatives //! //! Crates those provide similar API (or part of it): //! //! - [`generic_array`](https://docs.rs/generic-array) //! - [`array_init`](https://docs.rs/array-init/) (analogs to [`Array::from_fn`] //! and [`Array::from_iter`]) //! - [`array_ext`](https://docs.rs/array_ext) //! - [`slice_as_array`](https://peterreid.github.io/slice_as_array/slice_as_array/index.html) //! (analogs to [`ArrayExt::from_slice`] and [`Array::from_iter`]) //! - [`arraytools`](https://docs.rs/arraytools) //! - [`core::array::FixedSizeArray`](https://doc.rust-lang.org/beta/core/array/trait.FixedSizeArray.html) //! - [`stackvec`](https://docs.rs/stackvec/) //! - [`array_iterator`](https://docs.rs/array_iterator/) //! - [`arraymap`](https://docs.rs/arraymap/) //! //! [`Array::from_fn`]: crate::Array::from_fn //! [`Array::from_iter`]: crate::Array::from_iter //! //! ## Safety //! //! To achieve good performance and support so many array sizes, this //! crate uses a alot of unsafe code (by commit `079871cc` there are 17 `unsafe //! {}` blocks). All `unsafe`s were checked with care and have a "Safety" //! comment. //! //! If you see that some `unsafe`s could be removed without performance loss (we //! need benchmarks, oh) please fill an [issue]. //! //! [issue]: https://github.com/WaffleLapkin/arraylib/issues/new // We use std in tests to catch panic #![cfg_attr(not(test), no_std)] // Some sweaty nightly features #![cfg_attr(feature = "nightly", feature(trusted_len, exact_size_is_empty))] // For running tests from readme #![cfg_attr(all(doctest, feature = "nightly"), feature(external_doc))] // I hate missing docs #![deny(missing_docs)] // And I like inline #![warn(clippy::missing_inline_in_public_items)] #[cfg(feature = "alloc")] extern crate alloc; /// Utils that help implementing public API #[macro_use] pub(crate) mod util { #[macro_use] /// Helper macros these are used in this lib mod local_macros; /// Array initialization pub(crate) mod init; /// `T -> U` transmute (analog to `core::mem::transmute`) pub(crate) mod transmute; } pub use self::{ array::Array, error::SizeError, ext::{ array_ext::ArrayExt, shorthand::ArrayShorthand, slice_ext::{MaybeUninitSlice, Slice}, }, transform::{as_ref::ArrayAsRef, map::ArrayMap}, wrap::ArrayWrapper, }; /// Iterator related things pub mod iter { pub use self::{chunks::ArrayChunks, ext::IteratorExt, iter_move::IterMove}; mod chunks; mod ext; mod iter_move; } // === private but reexported === mod array; mod error; mod wrap; /// Array transformers like map (`[T; N]` -> `[U; N]`) /// /// Commonly just shortcuts for `.iter_move().*method*(...).collect_array()` mod transform { /// `&(mut) [T; N]` -> `[&(mut) T; N]` pub(super) mod as_ref; /// `[T; N]` -> `[U; N]` pub(super) mod map; } /// Different extension traits mod ext { /// Array ext pub(super) mod array_ext; /// Also array ext (but for `.as_slice().method()` -> `.method()` shortcuts) pub(super) mod shorthand; /// Slice ext pub(super) mod slice_ext; } /// Run tests from readme #[cfg_attr(feature = "nightly", doc(include = "../README.md"))] #[cfg(doctest)] pub struct ReadmeDocTests;