├── cl-aux ├── LICENSE ├── src │ ├── lib.rs │ ├── structures.rs │ ├── structures │ │ ├── error.rs │ │ ├── single_item_storage.rs │ │ ├── iter_wrapper.rs │ │ ├── auto_clear.rs │ │ ├── full_auto_clear.rs │ │ ├── array_wrapper_ref.rs │ │ └── doc_tests.rs │ ├── traits.rs │ ├── macros.rs │ ├── traits │ │ ├── dyn_contig_coll.rs │ │ ├── dyn_string.rs │ │ ├── single_type_storage.rs │ │ ├── retain.rs │ │ ├── clear.rs │ │ ├── remove.rs │ │ ├── truncate.rs │ │ ├── with_capacity.rs │ │ ├── swap.rs │ │ ├── capacity.rs │ │ ├── capacity_upper_bound.rs │ │ ├── get_mut.rs │ │ ├── get.rs │ │ ├── iter.rs │ │ ├── extend.rs │ │ ├── length.rs │ │ ├── push.rs │ │ ├── insert.rs │ │ └── size_hint.rs │ └── tuple_impls.rs ├── Cargo.toml └── README.md ├── ndstruct ├── LICENSE ├── src │ ├── lib.rs │ ├── dense │ │ └── dense_error.rs │ ├── coo │ │ ├── coo_utils.rs │ │ └── coo_error.rs │ ├── error.rs │ ├── utils.rs │ ├── csl │ │ ├── csl_rayon.rs │ │ ├── csl_line_iter.rs │ │ ├── csl_error.rs │ │ ├── csl_rnd.rs │ │ ├── csl_utils.rs │ │ └── csl_line_constructor.rs │ ├── dense.rs │ ├── doc_tests.rs │ └── coo.rs ├── Cargo.toml └── README.md ├── rust-tools ├── LICENSE ├── src │ ├── cfg.rs │ ├── actions.rs │ ├── actions │ │ ├── target_dir.rs │ │ ├── rust_flags.rs │ │ ├── set_up.rs │ │ ├── tools.rs │ │ └── cargo.rs │ ├── cfg_option.rs │ ├── transforming_params.rs │ ├── action_option.rs │ ├── params.rs │ ├── macros.rs │ ├── error.rs │ ├── parse_cfg.rs │ ├── cfg │ │ └── you_rust.rs │ └── main.rs ├── Cargo.toml └── README.md ├── .gitignore ├── .scripts ├── rust-tools.sh ├── all.sh ├── common.sh ├── fuzz.sh ├── ndstruct.sh └── cl-aux.sh ├── README.md ├── rust-toolchain ├── Cargo.toml ├── .editorconfig ├── rustfmt.toml ├── .github ├── dependabot.yml └── workflows │ └── ci.yaml ├── ndstruct-fuzz ├── random_coo.rs ├── random_csl.rs ├── coo.rs ├── csl.rs └── Cargo.toml └── Cargo.lock /cl-aux/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /ndstruct/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /rust-tools/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /rust-tools/src/cfg.rs: -------------------------------------------------------------------------------- 1 | mod you_rust; 2 | 3 | pub(crate) use you_rust::YouRust; 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | **/*.rs.bk 3 | **/artifacts 4 | **/Cargo.lock 5 | **/corpus 6 | **/target 7 | **/target -------------------------------------------------------------------------------- /.scripts/rust-tools.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | . ".scripts/common.sh" 4 | 5 | $rt test-with-features rust-tools 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Regular crates 2 | 3 | Aggregation of single-crate projects. See the desired project's README for more information. -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2025-07-17" 3 | components = ["clippy", "miri", "rustfmt"] 4 | profile = "minimal" 5 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [profile.profiling] 2 | inherits = "release" 3 | debug = true 4 | 5 | [workspace] 6 | members = ["cl-aux", "ndstruct", "ndstruct-fuzz", "rust-tools"] 7 | resolver = "2" 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | edition="2021" 2 | imports_granularity = "Crate" 3 | newline_style = "Unix" 4 | reorder_imports = true 5 | tab_spaces=2 6 | use_field_init_shorthand=true 7 | use_small_heuristics="Max" 8 | -------------------------------------------------------------------------------- /.scripts/all.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | . ".scripts/common.sh" 4 | 5 | $rt rustfmt 6 | $rt clippy 7 | 8 | .scripts/cl-aux.sh 9 | .scripts/ndstruct.sh 10 | .scripts/rust-tools.sh 11 | 12 | cargo test --all-features --doc -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | updates: 4 | - package-ecosystem: "cargo" 5 | directory: "/" 6 | schedule: 7 | interval: daily 8 | 9 | - package-ecosystem: "github-actions" 10 | directory: "/" 11 | schedule: 12 | interval: "weekly" 13 | -------------------------------------------------------------------------------- /.scripts/common.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | export rt='cargo run --bin rust-tools -- --template you-rust' 6 | 7 | export CARGO_TARGET_DIR="$($rt target-dir)" 8 | export RUST_BACKTRACE=1 9 | export RUSTFLAGS="$($rt rust-flags)" 10 | -------------------------------------------------------------------------------- /.scripts/fuzz.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euxo pipefail 4 | 5 | cargo fuzz run --features libfuzzer-sys/link_libfuzzer --fuzz-dir ndstruct-fuzz coo -- -runs=100000 6 | cargo fuzz run --features libfuzzer-sys/link_libfuzzer --fuzz-dir ndstruct-fuzz csl -- -runs=100000 7 | -------------------------------------------------------------------------------- /.scripts/ndstruct.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | . ".scripts/common.sh" 4 | 5 | $rt test-generic ndstruct 6 | $rt test-with-features ndstruct alloc 7 | $rt test-with-features ndstruct std 8 | $rt test-with-features ndstruct rand 9 | $rt test-with-features ndstruct rayon 10 | $rt test-with-features ndstruct serde 11 | -------------------------------------------------------------------------------- /rust-tools/src/actions.rs: -------------------------------------------------------------------------------- 1 | mod cargo; 2 | mod rust_flags; 3 | mod set_up; 4 | mod target_dir; 5 | mod tools; 6 | 7 | use crate::Params; 8 | 9 | pub(crate) struct Actions { 10 | pub(crate) params: Params, 11 | } 12 | 13 | impl Actions { 14 | #[inline] 15 | pub(crate) fn new(params: Params) -> Self { 16 | Self { params } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.scripts/cl-aux.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | . ".scripts/common.sh" 4 | 5 | $rt test-with-features cl-aux 6 | $rt test-with-features cl-aux alloc 7 | $rt test-with-features cl-aux arrayvec 8 | $rt test-with-features cl-aux serde 9 | $rt test-with-features cl-aux smallvec 10 | $rt test-with-features cl-aux std 11 | $rt test-with-features cl-aux tinyvec 12 | -------------------------------------------------------------------------------- /rust-tools/src/actions/target_dir.rs: -------------------------------------------------------------------------------- 1 | use crate::Actions; 2 | use std::io::{stdout, Write as _}; 3 | 4 | const TARGET_DIR: &str = "target/rust-tools-target"; 5 | 6 | impl Actions { 7 | pub(crate) fn target_dir() -> crate::Result<()> { 8 | let mut stdout = stdout(); 9 | stdout.write_all(TARGET_DIR.as_bytes())?; 10 | stdout.flush()?; 11 | Ok(()) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ndstruct-fuzz/random_coo.rs: -------------------------------------------------------------------------------- 1 | //! Random COO 2 | 3 | #![no_main] 4 | 5 | use arbitrary as _; 6 | use rayon as _; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use ndstruct::csl::CslVec; 10 | use rand::rngs::mock::StepRng; 11 | 12 | fuzz_target!(|values: ([usize; 2], usize)| { 13 | let (dims, nnz) = values; 14 | let _rslt = CslVec::new_controlled_random_rand(dims, nnz, &mut StepRng::new(0, 0), |_, _| 0); 15 | }); 16 | -------------------------------------------------------------------------------- /ndstruct-fuzz/random_csl.rs: -------------------------------------------------------------------------------- 1 | //! Random CSL 2 | 3 | #![no_main] 4 | 5 | use arbitrary as _; 6 | use rayon as _; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use ndstruct::coo::CooVec; 10 | use rand::rngs::mock::StepRng; 11 | 12 | fuzz_target!(|values: ([usize; 2], usize)| { 13 | let (dims, nnz) = values; 14 | let _rslt = CooVec::new_controlled_random_rand(dims, nnz, &mut StepRng::new(0, 0), |_, _| 0); 15 | }); 16 | -------------------------------------------------------------------------------- /rust-tools/src/cfg_option.rs: -------------------------------------------------------------------------------- 1 | use crate::{cfg::YouRust, Params}; 2 | 3 | create_enum_with_list! { 4 | crate::Error::UnknownCfg; 5 | 6 | #[derive(Debug)] 7 | pub(crate) enum CfgOption { 8 | YouRust, "you-rust"; 9 | } 10 | } 11 | 12 | impl CfgOption { 13 | pub(crate) fn into_params(self) -> Params { 14 | match self { 15 | Self::YouRust => YouRust::default().0, 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /rust-tools/src/transforming_params.rs: -------------------------------------------------------------------------------- 1 | #[derive(Default)] 2 | pub(crate) struct TransformingParams { 3 | pub(crate) add_clippy_flags: Vec, 4 | pub(crate) add_rust_flags: Vec, 5 | pub(crate) add_rustfmt_flags: Vec, 6 | pub(crate) rm_clippy_flags: Vec, 7 | pub(crate) rm_rust_flags: Vec, 8 | pub(crate) rm_rustfmt_flags: Vec, 9 | pub(crate) toolchain: String, 10 | } 11 | -------------------------------------------------------------------------------- /cl-aux/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![doc = include_str!("../README.md")] 2 | #![cfg_attr(not(feature = "std"), no_std)] 3 | 4 | #[cfg(feature = "alloc")] 5 | extern crate alloc; 6 | 7 | #[macro_use] 8 | mod macros; 9 | 10 | mod structures; 11 | mod traits; 12 | mod tuple_impls; 13 | 14 | pub use structures::*; 15 | pub use traits::*; 16 | 17 | /// Alias of [`core::result::Result`]. 18 | pub type Result = core::result::Result; 19 | -------------------------------------------------------------------------------- /cl-aux/src/structures.rs: -------------------------------------------------------------------------------- 1 | mod array_wrapper; 2 | mod array_wrapper_ref; 3 | mod auto_clear; 4 | #[doc(hidden)] 5 | pub mod doc_tests; 6 | mod error; 7 | mod full_auto_clear; 8 | mod iter_wrapper; 9 | mod single_item_storage; 10 | 11 | pub use array_wrapper::*; 12 | pub use array_wrapper_ref::*; 13 | pub use auto_clear::*; 14 | pub use error::*; 15 | pub use full_auto_clear::*; 16 | pub use iter_wrapper::*; 17 | pub use single_item_storage::*; 18 | -------------------------------------------------------------------------------- /rust-tools/Cargo.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | default = [] 3 | 4 | [package] 5 | authors = ["Caio Fernandes "] 6 | categories = ["command-line-interface", "config"] 7 | description = "Rust tools" 8 | edition = "2021" 9 | keywords = ["ci", "tools"] 10 | license = "Apache-2.0" 11 | name = "rust-tools" 12 | readme = "README.md" 13 | repository = "https://github.com/c410-f3r/regular-crates" 14 | rust-version = "1.65" 15 | version = "1.0.3" 16 | -------------------------------------------------------------------------------- /rust-tools/src/actions/rust_flags.rs: -------------------------------------------------------------------------------- 1 | use crate::Actions; 2 | use std::io::{stdout, Write as _}; 3 | 4 | impl Actions { 5 | pub(crate) fn rust_flags(&self) -> crate::Result<()> { 6 | let mut iter = self.params.rust_flags.iter(); 7 | let mut stdout = stdout(); 8 | if let Some(first) = iter.next() { 9 | stdout.write_all(first.as_bytes())?; 10 | } 11 | for element in iter { 12 | stdout.write_all(b" ")?; 13 | stdout.write_all(element.as_bytes())?; 14 | } 15 | stdout.flush()?; 16 | Ok(()) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ndstruct/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # ndstruct 2 | //! 3 | //! This crate provides structures to store and retrieve N-dimensional data. 4 | 5 | #![cfg_attr(not(feature = "std"), no_std)] 6 | 7 | #[cfg(feature = "alloc")] 8 | extern crate alloc; 9 | 10 | pub mod coo; 11 | pub mod csl; 12 | pub mod dense; 13 | pub mod doc_tests; 14 | mod error; 15 | mod utils; 16 | 17 | /// Shorcut of [`core::result::Result`]. 18 | pub type Result = core::result::Result; 19 | 20 | pub use error::*; 21 | #[cfg(feature = "rayon")] 22 | pub use utils::{ParallelIteratorWrapper, ParallelProducerWrapper}; 23 | -------------------------------------------------------------------------------- /cl-aux/src/structures/error.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{Debug, Display, Formatter}; 2 | 3 | /// Groups all possible crate errors 4 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 5 | pub enum Error { 6 | /// It is not possible to insert an already existing element 7 | AlreadyExistingElement, 8 | /// Structure can't store more elements 9 | InsufficientCapacity(u32), 10 | /// Index is out of structure bounds 11 | OutOfBounds(u32), 12 | } 13 | 14 | impl Display for Error { 15 | #[inline] 16 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 17 | Debug::fmt(self, f) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /rust-tools/src/action_option.rs: -------------------------------------------------------------------------------- 1 | create_enum_with_list! { 2 | crate::Error::UnknownAction; 3 | 4 | #[derive(Debug)] 5 | pub(crate) enum ActionOption { 6 | BuildGeneric, "build-generic"; 7 | BuildWithFeatures, "build-with-features"; 8 | CheckGeneric, "check-generic"; 9 | CheckWithFeatures, "check-with-features"; 10 | Clippy, "clippy"; 11 | RustFlags, "rust-flags"; 12 | Rustfmt, "rustfmt"; 13 | SetUp, "set-up"; 14 | TargetDir, "target-dir"; 15 | TestGeneric, "test-generic"; 16 | TestWithFeatures, "test-with-features"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ndstruct-fuzz/coo.rs: -------------------------------------------------------------------------------- 1 | //! COO 2 | 3 | #![no_main] 4 | 5 | use rand as _; 6 | use rayon as _; 7 | 8 | use libfuzzer_sys::fuzz_target; 9 | use ndstruct::coo::CooVec; 10 | 11 | type Array = [usize; 3]; 12 | 13 | #[derive(Debug, arbitrary::Arbitrary)] 14 | struct Values { 15 | data: Vec<(Array, i32)>, 16 | dims: Array, 17 | value: Array, 18 | } 19 | 20 | fuzz_target!(|values: Values| { 21 | let real_data = values.data.into_iter().collect::>(); 22 | 23 | let coo: CooVec = if let Ok(r) = CooVec::new(values.dims, real_data) { 24 | r 25 | } else { 26 | return; 27 | }; 28 | 29 | let _ = coo.value(values.value); 30 | }); 31 | -------------------------------------------------------------------------------- /rust-tools/src/actions/set_up.rs: -------------------------------------------------------------------------------- 1 | use crate::Actions; 2 | use std::{fs::File, io::Write as _}; 3 | 4 | impl Actions { 5 | pub(crate) fn set_up(&self) -> crate::Result<()> { 6 | if !self.params.toolchain.is_empty() { 7 | let mut file = File::create("rust-toolchain")?; 8 | file.write_all(self.params.toolchain.as_bytes())?; 9 | } 10 | 11 | if !self.params.rustfmt_flags.is_empty() { 12 | let mut file = File::create("rustfmt.toml")?; 13 | for rustfmt_flag in &self.params.rustfmt_flags { 14 | file.write_all(rustfmt_flag.as_bytes())?; 15 | file.write_all(b"\n")?; 16 | } 17 | } 18 | Ok(()) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /ndstruct/src/dense/dense_error.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{Debug, Display, Formatter}; 2 | 3 | /// Any error related to `Coo` operations 4 | #[derive(Debug, Eq, PartialEq)] 5 | #[non_exhaustive] 6 | pub enum DenseError { 7 | /// Some index overflows the maximum number of dimensions. 8 | /// 9 | /// ```rust 10 | /// use ndstruct::dense::{DenseArray, DenseError}; 11 | /// let dense = DenseArray::new([2, 3], [1, 2, 3, 4]); 12 | /// assert_eq!(dense, Err(ndstruct::Error::Dense(DenseError::InvalidIndcs))); 13 | /// ``` 14 | InvalidIndcs, 15 | } 16 | 17 | impl Display for DenseError { 18 | #[inline] 19 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 20 | Debug::fmt(self, f) 21 | } 22 | } 23 | 24 | impl core::error::Error for DenseError {} 25 | -------------------------------------------------------------------------------- /cl-aux/src/structures/single_item_storage.rs: -------------------------------------------------------------------------------- 1 | use core::slice; 2 | 3 | /// A structure that holds one, and only one `T`. 4 | /// 5 | /// Behaves like [T; 1] but has additional `Default` and `From` implementations. 6 | #[derive(Debug, Default, Eq, PartialEq, PartialOrd)] 7 | pub struct SingleItemStorage( 8 | // Single item 9 | pub T, 10 | ); 11 | 12 | impl AsMut<[T]> for SingleItemStorage { 13 | #[inline] 14 | fn as_mut(&mut self) -> &mut [T] { 15 | slice::from_mut(&mut self.0) 16 | } 17 | } 18 | 19 | impl AsRef<[T]> for SingleItemStorage { 20 | #[inline] 21 | fn as_ref(&self) -> &[T] { 22 | slice::from_ref(&self.0) 23 | } 24 | } 25 | 26 | impl From for SingleItemStorage { 27 | #[inline] 28 | fn from(from: T) -> Self { 29 | Self(from) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ndstruct/src/coo/coo_utils.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::windows2; 2 | 3 | macro_rules! create_value { 4 | ($get:ident $fn_name:ident $([$mut:tt])?) => { 5 | #[inline] 6 | pub(crate) fn $fn_name( 7 | indcs: [usize; D], 8 | data: &$($mut)? [([usize; D], DATA)], 9 | ) -> Option<&$($mut)? DATA> { 10 | if let Ok(idx) = data.binary_search_by(|value| value.0.cmp(&indcs)) { 11 | Some(&$($mut)? data.$get(idx)?.1) 12 | } else { 13 | None 14 | } 15 | } 16 | } 17 | } 18 | 19 | create_value!(get value); 20 | create_value!(get_mut value_mut [mut]); 21 | 22 | #[inline] 23 | pub(crate) fn does_not_have_duplicates_sorted( 24 | slice: &[T], 25 | mut cb: impl FnMut(&T, &T) -> bool, 26 | ) -> bool { 27 | windows2(slice).all(|[a, b]| cb(a, b)) 28 | } 29 | -------------------------------------------------------------------------------- /cl-aux/Cargo.toml: -------------------------------------------------------------------------------- 1 | [dependencies] 2 | arrayvec = { default-features = false, optional = true, version = "0.7" } 3 | serde = { default-features = false, optional = true, version = "1.0" } 4 | smallvec = { default-features = false, optional = true, version = "1.0" } 5 | tinyvec = { default-features = false, optional = true, version = "1.0" } 6 | 7 | [features] 8 | alloc = ["tinyvec?/alloc"] 9 | default = [] 10 | std = ["alloc"] 11 | 12 | [package] 13 | authors = ["Caio Fernandes "] 14 | categories = ["development-tools"] 15 | description = "Provides elements that describe collections" 16 | edition = "2021" 17 | keywords = ["collections", "traits"] 18 | license = "Apache-2.0" 19 | name = "cl-aux" 20 | readme = "README.md" 21 | repository = "https://github.com/c410-f3r/regular-crates" 22 | rust-version = "1.65" 23 | version = "5.1.0" 24 | -------------------------------------------------------------------------------- /cl-aux/src/structures/iter_wrapper.rs: -------------------------------------------------------------------------------- 1 | /// A wrapper around `I: Iterator` to workaround trait implementation conflicts 2 | #[derive(Debug)] 3 | pub struct IterWrapper( 4 | /// Iterator 5 | pub I, 6 | ) 7 | where 8 | I: Iterator; 9 | 10 | #[cfg(feature = "serde")] 11 | mod serde { 12 | use crate::IterWrapper; 13 | use serde::{ser::SerializeSeq as _, Serialize, Serializer}; 14 | 15 | impl Serialize for IterWrapper 16 | where 17 | I: Clone + Iterator, 18 | I::Item: Serialize, 19 | { 20 | #[inline] 21 | fn serialize(&self, serializer: S) -> Result 22 | where 23 | S: Serializer, 24 | { 25 | let mut seq = serializer.serialize_seq(None)?; 26 | for elem in self.0.clone() { 27 | seq.serialize_element(&elem)?; 28 | } 29 | seq.end() 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ndstruct-fuzz/csl.rs: -------------------------------------------------------------------------------- 1 | //! CSL 2 | 3 | #![no_main] 4 | 5 | use rand as _; 6 | 7 | use libfuzzer_sys::fuzz_target; 8 | use ndstruct::csl::CslVec; 9 | use rayon::prelude::*; 10 | 11 | type Array = [usize; 3]; 12 | 13 | #[derive(Debug, arbitrary::Arbitrary)] 14 | struct Values { 15 | data: Vec, 16 | dims: Array, 17 | indcs: Vec, 18 | line: Array, 19 | offs: Vec, 20 | value: Array, 21 | } 22 | 23 | fuzz_target!(|values: Values| { 24 | let Ok(csl) = CslVec::new(values.dims, values.data, values.indcs, values.offs) else { 25 | return; 26 | }; 27 | 28 | let _ = csl.line(values.line); 29 | 30 | let _ = csl.value(values.value); 31 | 32 | if let Ok(r) = csl.outermost_line_iter() { 33 | r.for_each(|_| {}); 34 | } else { 35 | return; 36 | }; 37 | 38 | if let Ok(r) = csl.outermost_line_rayon_iter() { 39 | r.enumerate().for_each(|(_, _)| {}); 40 | } 41 | }); 42 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | fuzz: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - uses: actions-rs/toolchain@v1 14 | with: 15 | override: true 16 | profile: minimal 17 | toolchain: nightly-2025-07-17 18 | - uses: actions-rs/install@v0.1 19 | with: 20 | crate: cargo-fuzz 21 | use-tool-cache: true 22 | 23 | - run: .scripts/fuzz.sh 24 | 25 | internal-tests: 26 | runs-on: ubuntu-latest 27 | steps: 28 | - uses: actions/checkout@v4 29 | - uses: actions-rs/toolchain@v1 30 | with: 31 | components: clippy, rustfmt 32 | override: true 33 | profile: minimal 34 | toolchain: nightly-2025-07-17 35 | - uses: Swatinem/rust-cache@v2 36 | 37 | - run: .scripts/all.sh -------------------------------------------------------------------------------- /ndstruct/Cargo.toml: -------------------------------------------------------------------------------- 1 | [dependencies] 2 | cl-aux = { default-features = false, features = ["serde"], path = "../cl-aux", version = "5.0" } 3 | rand = { default-features = false, optional = true, version = "0.9" } 4 | rayon = { default-features = false, optional = true, version = "1.0" } 5 | serde = { default-features = false, features = ["derive"], optional = true, version = "1.0" } 6 | 7 | [features] 8 | alloc = ["cl-aux/alloc"] 9 | default = [] 10 | std = ["alloc"] 11 | 12 | [package] 13 | authors = ["Caio Fernandes "] 14 | categories = ["data-structures", "concurrency", "science", "no-std"] 15 | description = "Structures for N-dimensions" 16 | edition = "2021" 17 | keywords = ["collection", "dense", "dimension", "sparse", "structure"] 18 | license = "Apache-2.0" 19 | name = "ndstruct" 20 | readme = "README.md" 21 | repository = "https://github.com/c410-f3r/regular-crates" 22 | version = "2.3.0" 23 | 24 | [package.metadata.docs.rs] 25 | all-features = true 26 | -------------------------------------------------------------------------------- /cl-aux/src/traits.rs: -------------------------------------------------------------------------------- 1 | mod capacity; 2 | mod capacity_upper_bound; 3 | mod clear; 4 | mod dyn_contig_coll; 5 | mod dyn_string; 6 | mod extend; 7 | mod get; 8 | mod get_mut; 9 | mod insert; 10 | mod iter; 11 | mod length; 12 | mod push; 13 | mod remove; 14 | mod retain; 15 | mod single_type_storage; 16 | mod size_hint; 17 | mod swap; 18 | mod truncate; 19 | mod with_capacity; 20 | 21 | pub use capacity::Capacity; 22 | pub use capacity_upper_bound::CapacityUpperBound; 23 | pub use clear::Clear; 24 | pub use dyn_contig_coll::DynContigColl; 25 | pub use dyn_string::DynString; 26 | pub use extend::Extend; 27 | pub use get::Get; 28 | pub use get_mut::GetMut; 29 | pub use insert::Insert; 30 | pub use iter::Iter; 31 | pub use length::Length; 32 | pub use push::Push; 33 | pub use remove::Remove; 34 | pub use retain::Retain; 35 | pub use single_type_storage::SingleTypeStorage; 36 | pub use size_hint::SizeHint; 37 | pub use swap::Swap; 38 | pub use truncate::Truncate; 39 | pub use with_capacity::WithCapacity; 40 | -------------------------------------------------------------------------------- /rust-tools/src/actions/tools.rs: -------------------------------------------------------------------------------- 1 | use crate::{handle_cmd_output, Actions}; 2 | use std::{env::Args, process::Command}; 3 | 4 | impl Actions { 5 | pub(crate) fn clippy(&self, args: &mut Args) -> crate::Result<()> { 6 | handle_cmd_output( 7 | Command::new("echo").args(["-e", r"\e[0;33m***** Running clippy *****\e[0m\n"]), 8 | )?; 9 | let mut cmd = Command::new("cargo"); 10 | handle_cmd_output( 11 | cmd 12 | .args( 13 | [String::from("clippy"), String::from("--workspace")] 14 | .into_iter() 15 | .chain(args.by_ref()) 16 | .chain([String::from("--")]), 17 | ) 18 | .args(&self.params.clippy_flags), 19 | )?; 20 | Ok(()) 21 | } 22 | 23 | pub(crate) fn rustfmt() -> crate::Result<()> { 24 | handle_cmd_output( 25 | Command::new("echo").args(["-e", r"\e[0;33m***** Running rustfmt *****\e[0m\n"]), 26 | )?; 27 | handle_cmd_output(Command::new("cargo").args(["fmt", "--all", "--", "--check"]))?; 28 | Ok(()) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rust-tools/src/params.rs: -------------------------------------------------------------------------------- 1 | use crate::TransformingParams; 2 | 3 | #[derive(Debug, Default, PartialEq)] 4 | pub(crate) struct Params { 5 | pub(crate) clippy_flags: Vec, 6 | pub(crate) rust_flags: Vec, 7 | pub(crate) rustfmt_flags: Vec, 8 | pub(crate) toolchain: String, 9 | } 10 | 11 | impl Params { 12 | pub(crate) fn modify(&mut self, tp: &TransformingParams) { 13 | manage_flags(&mut self.clippy_flags, &tp.add_clippy_flags, &tp.rm_clippy_flags); 14 | manage_flags(&mut self.rust_flags, &tp.add_rust_flags, &tp.rm_rust_flags); 15 | manage_flags(&mut self.rustfmt_flags, &tp.add_rustfmt_flags, &tp.rm_rustfmt_flags); 16 | if !tp.toolchain.is_empty() { 17 | self.toolchain.clone_from(&tp.toolchain); 18 | } 19 | } 20 | } 21 | 22 | fn manage_flags(flags: &mut Vec, to_add: &[String], to_subtract: &[String]) { 23 | let iter = flags 24 | .iter() 25 | .chain(to_add) 26 | .filter(move |flag| !flag.is_empty() && to_subtract.iter().all(|s| s != *flag)); 27 | *flags = iter.cloned().collect(); 28 | } 29 | -------------------------------------------------------------------------------- /cl-aux/src/macros.rs: -------------------------------------------------------------------------------- 1 | macro_rules! _check_capacity { 2 | ($elem:expr) => {{ 3 | let capacity_upper_bound = crate::CapacityUpperBound::capacity_upper_bound($elem); 4 | let length = crate::Length::length($elem); 5 | if length >= capacity_upper_bound { 6 | return Err(crate::Error::InsufficientCapacity( 7 | capacity_upper_bound.try_into().unwrap_or(u32::MAX), 8 | )); 9 | } 10 | }}; 11 | } 12 | 13 | macro_rules! _check_indcs { 14 | ($elem:expr, $( $idx:expr ),*) => {{ 15 | let length = crate::Length::length($elem); 16 | if $( $idx >= length || )* false { 17 | return Err(crate::Error::OutOfBounds(length.try_into().unwrap_or(u32::MAX))); 18 | } 19 | }}; 20 | } 21 | 22 | macro_rules! _get { 23 | ($elem:expr, $idx:expr) => {{ 24 | $elem.get($idx).ok_or(crate::Error::OutOfBounds($idx.try_into().unwrap_or(u32::MAX))) 25 | }}; 26 | } 27 | 28 | macro_rules! _get_mut { 29 | ($elem:expr, $idx:expr) => {{ 30 | $elem.get_mut($idx).ok_or(crate::Error::OutOfBounds($idx.try_into().unwrap_or(u32::MAX))) 31 | }}; 32 | } 33 | -------------------------------------------------------------------------------- /ndstruct-fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [[bin]] 2 | name = "coo" 3 | path = "coo.rs" 4 | required-features = ["libfuzzer-sys/link_libfuzzer"] 5 | 6 | [[bin]] 7 | name = "csl" 8 | path = "csl.rs" 9 | required-features = ["libfuzzer-sys/link_libfuzzer"] 10 | 11 | [[bin]] 12 | name = "random_coo" 13 | path = "random_coo.rs" 14 | required-features = ["libfuzzer-sys/link_libfuzzer"] 15 | 16 | [[bin]] 17 | name = "random_csl" 18 | path = "random_csl.rs" 19 | required-features = ["libfuzzer-sys/link_libfuzzer"] 20 | 21 | [dependencies] 22 | arbitrary = { default-features = false, features = ["derive"], version = "1.0" } 23 | libfuzzer-sys = { default-features = false, version = "0.4" } 24 | ndstruct = { default-features = false, features = ["alloc", "rand", "rayon"], path = "../ndstruct" } 25 | rand = { default-features = false, version = "0.9" } 26 | rayon = { default-features = false, version = "1.0" } 27 | 28 | [package] 29 | authors = ["Automatically generated"] 30 | edition = "2021" 31 | license = "Apache-2.0" 32 | name = "ndstruct-fuzz" 33 | publish = false 34 | version = "0.0.0" 35 | 36 | [package.metadata] 37 | cargo-fuzz = true 38 | -------------------------------------------------------------------------------- /rust-tools/src/macros.rs: -------------------------------------------------------------------------------- 1 | macro_rules! create_enum_with_list { 2 | ( 3 | $err:expr; 4 | 5 | $(#[$mac:meta])* 6 | $v:vis enum $enum_ident:ident { 7 | $first_variant_ident:ident, $first_variant_str:literal; 8 | $($variant_ident:ident, $variant_str:literal;)* 9 | } 10 | ) => { 11 | $(#[$mac])* 12 | $v enum $enum_ident { 13 | $first_variant_ident, 14 | $($variant_ident,)* 15 | } 16 | 17 | impl $enum_ident { 18 | #[inline] 19 | pub(crate) const fn list() -> &'static str { 20 | concat!( 21 | $first_variant_str, 22 | $(", ", $variant_str,)* 23 | ) 24 | } 25 | } 26 | 27 | impl core::str::FromStr for $enum_ident { 28 | type Err = crate::Error; 29 | 30 | #[inline] 31 | fn from_str(str: &str) -> Result { 32 | Ok(match str { 33 | $first_variant_str => Self::$first_variant_ident, 34 | $($variant_str => Self::$variant_ident,)* 35 | _ => return Err($err), 36 | }) 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cl-aux/README.md: -------------------------------------------------------------------------------- 1 | # Auxiliary elements for collections 2 | 3 | [![CI](https://github.com/c410-f3r/cl-traits/workflows/CI/badge.svg)](https://github.com/c410-f3r/cl-traits/actions?query=workflow%3ACI) 4 | [![crates.io](https://img.shields.io/crates/v/cl-traits.svg)](https://crates.io/crates/cl-traits) 5 | [![Documentation](https://docs.rs/cl-traits/badge.svg)](https://docs.rs/cl-traits) 6 | [![License](https://img.shields.io/badge/license-APACHE2-blue.svg)](./LICENSE) 7 | ![Rustc](https://img.shields.io/badge/rustc-1.52-lightgray) 8 | 9 | Provides well-defined traits with single methods that enable the achievement of maximum flexibility and freedom in several different operations instead of imposing abstract subsets. 10 | 11 | ```rust 12 | use cl_aux::Length; 13 | 14 | struct SomeCustomArray([i32; 2], [i32; 4]); 15 | 16 | impl Length for SomeCustomArray { 17 | fn length(&self) -> usize { 18 | self.0.length() + self.1.length() 19 | } 20 | } 21 | 22 | fn main() { 23 | let v = SomeCustomArray([1, 2], [3, 4, 5, 6]); 24 | assert_eq!(v.length(), 6); 25 | } 26 | ``` 27 | 28 | Also provides structures for common use-cases. 29 | 30 | ```rust 31 | use cl_aux::ArrayWrapper; 32 | 33 | fn main() { 34 | let _array: [usize; 1] = ArrayWrapper::from_fn(|idx| idx).0; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /cl-aux/src/traits/dyn_contig_coll.rs: -------------------------------------------------------------------------------- 1 | use crate::{Capacity, Clear, Push, Truncate, WithCapacity}; 2 | use core::ops::{Deref, DerefMut}; 3 | 4 | /// Dynamic Contiguous Collection 5 | /// 6 | /// A growable vector-like abstraction for generic elements. 7 | /// 8 | #[cfg_attr(feature = "alloc", doc = "```rust")] 9 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 10 | /// fn stuff(dcc: &mut T) 11 | /// where 12 | /// T: cl_aux::DynContigColl 13 | /// { 14 | /// dcc.clear(); 15 | /// dcc.extend([4, 5, 6]).unwrap(); 16 | /// dcc.truncate(1); 17 | /// } 18 | /// 19 | /// let mut dcc = vec![0, 1, 2, 3]; 20 | /// stuff(&mut dcc); 21 | /// assert_eq!(dcc, &[4]); 22 | /// ``` 23 | pub trait DynContigColl: 24 | AsRef<[T]> 25 | + Clear 26 | + Capacity 27 | + Default 28 | + Deref 29 | + DerefMut 30 | + crate::Extend 31 | + Push 32 | + Truncate 33 | + WithCapacity 34 | { 35 | } 36 | 37 | impl DynContigColl for U where 38 | U: AsRef<[T]> 39 | + Clear 40 | + Capacity 41 | + Default 42 | + Deref 43 | + DerefMut 44 | + crate::Extend 45 | + Push 46 | + Truncate 47 | + WithCapacity 48 | { 49 | } 50 | -------------------------------------------------------------------------------- /rust-tools/src/error.rs: -------------------------------------------------------------------------------- 1 | use crate::{ActionOption, CfgOption}; 2 | use core::fmt::{Debug, Display, Formatter}; 3 | 4 | pub(crate) enum Error { 5 | FailedCommand, 6 | Io(std::io::Error), 7 | UnknownAction, 8 | UnknownCfg, 9 | WrongNumberOfArgs { expected: usize, received: usize }, 10 | } 11 | 12 | impl From for Error { 13 | #[inline] 14 | fn from(from: std::io::Error) -> Self { 15 | Self::Io(from) 16 | } 17 | } 18 | 19 | impl Debug for Error { 20 | #[inline] 21 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 22 | match self { 23 | Self::FailedCommand => write!(f, "A command wasn't successful"), 24 | Self::Io(err) => write!(f, "IO: {err}"), 25 | Self::UnknownAction => write!( 26 | f, 27 | "Unknown action, please select one of the following possibilities: {}", 28 | ActionOption::list() 29 | ), 30 | Self::UnknownCfg => write!( 31 | f, 32 | "Unknown configuration, please select one of the following possibilities: {}", 33 | CfgOption::list() 34 | ), 35 | Self::WrongNumberOfArgs { expected, received } => { 36 | write!(f, "Wrong number of arguments. Expected {expected} but received {received}") 37 | } 38 | } 39 | } 40 | } 41 | 42 | impl Display for Error { 43 | #[inline] 44 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 45 | Debug::fmt(self, f) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /cl-aux/src/traits/dyn_string.rs: -------------------------------------------------------------------------------- 1 | use crate::{Capacity, Clear, Push, Truncate, WithCapacity}; 2 | use core::{ 3 | fmt::Write, 4 | ops::{Deref, DerefMut}, 5 | }; 6 | 7 | /// Dynamic String 8 | /// 9 | /// Any owned growing string-like structure that `cl-aux` knows should implement this trait. 10 | /// 11 | #[cfg_attr(feature = "alloc", doc = "```rust")] 12 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 13 | /// fn stuff(s: &mut S) 14 | /// where 15 | /// S: cl_aux::DynString 16 | /// { 17 | /// s.clear(); 18 | /// s.push("World").unwrap(); 19 | /// s.truncate(1); 20 | /// } 21 | /// 22 | /// let mut s = String::from("Hello"); 23 | /// stuff(&mut s); 24 | /// assert_eq!(s, "W"); 25 | /// ``` 26 | pub trait DynString: 27 | AsRef 28 | + Capacity 29 | + Clear 30 | + Default 31 | + Deref 32 | + DerefMut 33 | + crate::Extend 34 | + Push 35 | + for<'str> Push<&'str str, Error = crate::Error> 36 | + Truncate 37 | + WithCapacity 38 | + Write 39 | { 40 | } 41 | 42 | impl DynString for T where 43 | T: AsRef 44 | + Capacity 45 | + Clear 46 | + Default 47 | + Deref 48 | + DerefMut 49 | + crate::Extend 50 | + Push 51 | + for<'str> Push<&'str str, Error = crate::Error> 52 | + Truncate 53 | + WithCapacity 54 | + Write 55 | { 56 | } 57 | -------------------------------------------------------------------------------- /cl-aux/src/structures/auto_clear.rs: -------------------------------------------------------------------------------- 1 | use crate::Clear; 2 | use core::{ 3 | borrow::{Borrow, BorrowMut}, 4 | ops::{Deref, DerefMut}, 5 | }; 6 | 7 | /// Any mutable item wrapped in this structure is automatically cleaned when dropped. 8 | #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] 9 | pub struct AutoClear(T) 10 | where 11 | T: Clear; 12 | 13 | impl AsMut for AutoClear 14 | where 15 | T: Clear, 16 | { 17 | #[inline] 18 | fn as_mut(&mut self) -> &mut T { 19 | self 20 | } 21 | } 22 | 23 | impl AsRef for AutoClear 24 | where 25 | T: Clear, 26 | { 27 | #[inline] 28 | fn as_ref(&self) -> &T { 29 | self 30 | } 31 | } 32 | 33 | impl Borrow for AutoClear 34 | where 35 | T: Clear, 36 | { 37 | #[inline] 38 | fn borrow(&self) -> &T { 39 | self 40 | } 41 | } 42 | 43 | impl BorrowMut for AutoClear 44 | where 45 | T: Clear, 46 | { 47 | #[inline] 48 | fn borrow_mut(&mut self) -> &mut T { 49 | self 50 | } 51 | } 52 | 53 | impl Deref for AutoClear 54 | where 55 | T: Clear, 56 | { 57 | type Target = T; 58 | 59 | #[inline] 60 | fn deref(&self) -> &Self::Target { 61 | &self.0 62 | } 63 | } 64 | 65 | impl DerefMut for AutoClear 66 | where 67 | T: Clear, 68 | { 69 | #[inline] 70 | fn deref_mut(&mut self) -> &mut Self::Target { 71 | &mut self.0 72 | } 73 | } 74 | 75 | impl Drop for AutoClear 76 | where 77 | T: Clear, 78 | { 79 | #[inline] 80 | fn drop(&mut self) { 81 | self.0.clear(); 82 | } 83 | } 84 | 85 | impl From for AutoClear 86 | where 87 | T: Clear, 88 | { 89 | #[inline] 90 | fn from(from: T) -> Self { 91 | Self(from) 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ndstruct/src/error.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | coo::CooError, 3 | csl::{CslError, CslLineConstructorError}, 4 | dense::DenseError, 5 | }; 6 | use core::fmt::{Debug, Display, Formatter}; 7 | 8 | /// Contains all errors related to ndstruct 9 | #[derive(Debug, Eq, PartialEq)] 10 | #[non_exhaustive] 11 | pub enum Error { 12 | /// See [`cl_aux::Error`]. 13 | ClAux(cl_aux::Error), 14 | /// See [`CooError`] 15 | Coo(CooError), 16 | /// See [`CslError`] 17 | Csl(CslError), 18 | /// [`CslLineConstructorError`] 19 | CslLineConstructor(CslLineConstructorError), 20 | /// See [`DenseError`] 21 | Dense(DenseError), 22 | /// The internal buffer can't store all necessary data 23 | InsufficientCapacity, 24 | /// An Unknown that probably shouldn't have happened 25 | UnknownError, 26 | } 27 | 28 | impl Display for Error { 29 | #[inline] 30 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 31 | Debug::fmt(self, f) 32 | } 33 | } 34 | 35 | impl core::error::Error for Error {} 36 | 37 | impl From for Error { 38 | #[inline] 39 | fn from(from: cl_aux::Error) -> Self { 40 | Self::ClAux(from) 41 | } 42 | } 43 | 44 | impl From for Error { 45 | #[inline] 46 | fn from(from: CooError) -> Self { 47 | Self::Coo(from) 48 | } 49 | } 50 | 51 | impl From for Error { 52 | #[inline] 53 | fn from(from: CslError) -> Self { 54 | Self::Csl(from) 55 | } 56 | } 57 | 58 | impl From for Error { 59 | #[inline] 60 | fn from(from: CslLineConstructorError) -> Self { 61 | Self::CslLineConstructor(from) 62 | } 63 | } 64 | 65 | impl From for Error { 66 | #[inline] 67 | fn from(from: DenseError) -> Self { 68 | Self::Dense(from) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /cl-aux/src/traits/single_type_storage.rs: -------------------------------------------------------------------------------- 1 | use crate::SingleItemStorage; 2 | #[cfg(feature = "alloc")] 3 | use alloc::vec::Vec; 4 | 5 | /// Anything that can hold a collection of items 6 | pub trait SingleTypeStorage { 7 | /// Storage item 8 | type Item; 9 | } 10 | 11 | impl SingleTypeStorage for &T 12 | where 13 | T: SingleTypeStorage, 14 | { 15 | type Item = T::Item; 16 | } 17 | 18 | impl SingleTypeStorage for &mut T 19 | where 20 | T: SingleTypeStorage, 21 | { 22 | type Item = T::Item; 23 | } 24 | 25 | impl SingleTypeStorage for Option { 26 | type Item = T; 27 | } 28 | 29 | impl SingleTypeStorage for SingleItemStorage { 30 | type Item = T; 31 | } 32 | 33 | impl SingleTypeStorage for [T; N] { 34 | type Item = T; 35 | } 36 | 37 | impl SingleTypeStorage for &'_ [T] { 38 | type Item = T; 39 | } 40 | 41 | impl SingleTypeStorage for &'_ mut [T] { 42 | type Item = T; 43 | } 44 | 45 | #[cfg(feature = "alloc")] 46 | impl SingleTypeStorage for Vec { 47 | type Item = T; 48 | } 49 | 50 | #[cfg(feature = "arrayvec")] 51 | impl SingleTypeStorage for arrayvec::ArrayVec { 52 | type Item = T; 53 | } 54 | 55 | #[cfg(feature = "smallvec")] 56 | impl SingleTypeStorage for smallvec::SmallVec 57 | where 58 | A: smallvec::Array, 59 | { 60 | type Item = A::Item; 61 | } 62 | 63 | #[cfg(feature = "tinyvec")] 64 | impl SingleTypeStorage for tinyvec::ArrayVec 65 | where 66 | A: tinyvec::Array, 67 | A::Item: Default, 68 | { 69 | type Item = A::Item; 70 | } 71 | 72 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 73 | impl SingleTypeStorage for tinyvec::TinyVec 74 | where 75 | A: tinyvec::Array, 76 | A::Item: Default, 77 | { 78 | type Item = A::Item; 79 | } 80 | -------------------------------------------------------------------------------- /cl-aux/src/structures/full_auto_clear.rs: -------------------------------------------------------------------------------- 1 | use crate::Clear; 2 | use core::{ 3 | borrow::{Borrow, BorrowMut}, 4 | ops::{Deref, DerefMut}, 5 | }; 6 | 7 | /// Any mutable item wrapped in this structure is automatically cleaned when initialized and 8 | /// dropped. 9 | #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] 10 | pub struct FullAutoClear(T) 11 | where 12 | T: Clear; 13 | 14 | impl AsMut for FullAutoClear 15 | where 16 | T: Clear, 17 | { 18 | #[inline] 19 | fn as_mut(&mut self) -> &mut T { 20 | self 21 | } 22 | } 23 | 24 | impl AsRef for FullAutoClear 25 | where 26 | T: Clear, 27 | { 28 | #[inline] 29 | fn as_ref(&self) -> &T { 30 | self 31 | } 32 | } 33 | 34 | impl Borrow for FullAutoClear 35 | where 36 | T: Clear, 37 | { 38 | #[inline] 39 | fn borrow(&self) -> &T { 40 | self 41 | } 42 | } 43 | 44 | impl BorrowMut for FullAutoClear 45 | where 46 | T: Clear, 47 | { 48 | #[inline] 49 | fn borrow_mut(&mut self) -> &mut T { 50 | self 51 | } 52 | } 53 | 54 | impl Deref for FullAutoClear 55 | where 56 | T: Clear, 57 | { 58 | type Target = T; 59 | 60 | #[inline] 61 | fn deref(&self) -> &Self::Target { 62 | &self.0 63 | } 64 | } 65 | 66 | impl DerefMut for FullAutoClear 67 | where 68 | T: Clear, 69 | { 70 | #[inline] 71 | fn deref_mut(&mut self) -> &mut Self::Target { 72 | &mut self.0 73 | } 74 | } 75 | 76 | impl Drop for FullAutoClear 77 | where 78 | T: Clear, 79 | { 80 | #[inline] 81 | fn drop(&mut self) { 82 | self.0.clear(); 83 | } 84 | } 85 | 86 | impl From for FullAutoClear 87 | where 88 | T: Clear, 89 | { 90 | #[inline] 91 | fn from(mut from: T) -> Self { 92 | from.clear(); 93 | Self(from) 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /cl-aux/src/structures/array_wrapper_ref.rs: -------------------------------------------------------------------------------- 1 | use core::{borrow::Borrow, ops::Deref, slice::Iter}; 2 | 3 | /// Immutable array reference wrapper similar to [`crate::ArrayWrapper`]. 4 | #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] 5 | #[repr(transparent)] 6 | pub struct ArrayWrapperRef<'array, T, const N: usize>( 7 | /// The actual array reference. 8 | pub &'array [T; N], 9 | ); 10 | 11 | impl AsRef<[T; N]> for ArrayWrapperRef<'_, T, N> { 12 | #[inline] 13 | fn as_ref(&self) -> &[T; N] { 14 | self 15 | } 16 | } 17 | 18 | impl Borrow<[T; N]> for ArrayWrapperRef<'_, T, N> { 19 | #[inline] 20 | fn borrow(&self) -> &[T; N] { 21 | self 22 | } 23 | } 24 | 25 | impl Deref for ArrayWrapperRef<'_, T, N> { 26 | type Target = [T; N]; 27 | 28 | #[inline] 29 | fn deref(&self) -> &[T; N] { 30 | self.0 31 | } 32 | } 33 | 34 | impl<'array, T, const N: usize> From<&'array [T; N]> for ArrayWrapperRef<'array, T, N> { 35 | #[inline] 36 | fn from(from: &'array [T; N]) -> Self { 37 | Self(from) 38 | } 39 | } 40 | 41 | impl<'array, T, const N: usize> IntoIterator for &'array ArrayWrapperRef<'array, T, N> { 42 | type IntoIter = Iter<'array, T>; 43 | type Item = &'array T; 44 | 45 | #[inline] 46 | fn into_iter(self) -> Self::IntoIter { 47 | self.0.iter() 48 | } 49 | } 50 | 51 | #[cfg(feature = "serde")] 52 | mod serde { 53 | use crate::ArrayWrapperRef; 54 | use serde::{ser::SerializeTuple as _, Serialize, Serializer}; 55 | 56 | impl Serialize for ArrayWrapperRef<'_, T, N> 57 | where 58 | T: Serialize, 59 | { 60 | #[inline] 61 | fn serialize(&self, serializer: S) -> Result 62 | where 63 | S: Serializer, 64 | { 65 | let mut seq = serializer.serialize_tuple(N)?; 66 | for elem in self.0 { 67 | seq.serialize_element(elem)?; 68 | } 69 | seq.end() 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ndstruct/src/coo/coo_error.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{Debug, Display, Formatter}; 2 | 3 | /// Any error related to `Coo` operations 4 | #[derive(Debug, Eq, PartialEq)] 5 | #[non_exhaustive] 6 | pub enum CooError { 7 | /// Some index isn't in asceding order 8 | /// 9 | /// ```rust 10 | /// use ndstruct::coo::{CooArray, CooError}; 11 | /// let coo = CooArray::new([2, 2], [([1, 1], 8), ([0, 0], 9)]); 12 | /// assert_eq!(coo, Err(ndstruct::Error::Coo(CooError::InvalidIndcsOrder))); 13 | /// ``` 14 | InvalidIndcsOrder, 15 | 16 | /// Some index is greater than the defined dimensions 17 | /// 18 | /// ```rust 19 | /// use ndstruct::coo::{CooArray, CooError}; 20 | /// let coo = CooArray::new([2, 2], [([0, 1], 8), ([9, 9], 9)]); 21 | /// assert_eq!(coo, Err(ndstruct::Error::Coo(CooError::InvalidIndcs))); 22 | /// ``` 23 | InvalidIndcs, 24 | 25 | /// There are duplicated indices 26 | /// 27 | /// ```rust 28 | /// use ndstruct::coo::{CooArray, CooError}; 29 | /// let coo = CooArray::new([2, 2], [([0, 0], 8), ([0, 0], 9)]); 30 | /// assert_eq!(coo, Err(ndstruct::Error::Coo(CooError::DuplicatedIndices))); 31 | DuplicatedIndices, 32 | 33 | /// nnz is greater than the maximum permitted number of nnz 34 | /// 35 | #[cfg_attr(all(feature = "alloc", feature = "rand"), doc = "```rust")] 36 | #[cfg_attr(not(all(feature = "alloc", feature = "rand")), doc = "```ignore")] 37 | /// use ndstruct::coo::{CooError, CooVec}; 38 | /// use rand::{Rng, rngs::mock::StepRng}; 39 | /// let mut rng = StepRng::new(0, 1); 40 | /// let dims = [1, 2, 3]; // Max of 6 elements (1 * 2 * 3) 41 | /// let coo: ndstruct::Result>; 42 | /// coo = CooVec::new_controlled_random_rand(dims, 10, &mut rng, |r, _| r.gen()); 43 | /// assert_eq!(coo, Err(ndstruct::Error::Coo(CooError::NnzGreaterThanMaximumNnz))); 44 | /// ``` 45 | #[cfg(feature = "rand")] 46 | NnzGreaterThanMaximumNnz, 47 | } 48 | 49 | impl Display for CooError { 50 | #[inline] 51 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 52 | Debug::fmt(self, f) 53 | } 54 | } 55 | 56 | impl core::error::Error for CooError {} 57 | -------------------------------------------------------------------------------- /rust-tools/src/actions/cargo.rs: -------------------------------------------------------------------------------- 1 | use crate::{handle_cmd_output, Actions}; 2 | use std::process::Command; 3 | 4 | macro_rules! create_fns { 5 | ( 6 | $cargo_action:literal, 7 | $info:literal, 8 | $generic_fn:ident, 9 | $with_features_fn:ident 10 | $(, $additional_arg:expr)? 11 | ) => { 12 | pub(crate) fn $generic_fn(&self, package: String) -> crate::Result<()> { 13 | handle_cmd_output(Command::new("echo").args(&[ 14 | "-e", 15 | &format!( 16 | concat!(r#"\e[0;33m***** "#, $info, r#" "{}" without features *****\e[0m\n"#), 17 | package 18 | ), 19 | ]))?; 20 | handle_cmd_output(Command::new("cargo").args(&[ 21 | $cargo_action, 22 | "--manifest-path", 23 | &format!("{package}/Cargo.toml"), 24 | "--no-default-features", 25 | $($additional_arg)? 26 | ]))?; 27 | 28 | handle_cmd_output(Command::new("echo").args(&[ 29 | "-e", 30 | &format!( 31 | concat!(r#"\e[0;33m***** "#, $info, r#" "{}" with all features *****\e[0m\n"#), 32 | package 33 | ), 34 | ]))?; 35 | handle_cmd_output(Command::new("cargo").args(&[ 36 | $cargo_action, 37 | "--all-features", 38 | "--manifest-path", 39 | &format!("{package}/Cargo.toml"), 40 | $($additional_arg)? 41 | ]))?; 42 | Ok(()) 43 | } 44 | 45 | pub(crate) fn $with_features_fn(&self, package: String, features: String) -> crate::Result<()> { 46 | handle_cmd_output(Command::new("echo").args(&[ 47 | "-e", 48 | &format!( 49 | concat!(r#"\e[0;33m***** "#, $info, r#" "{}" with features "{}" *****\e[0m\n"#), 50 | package, features 51 | ), 52 | ]))?; 53 | handle_cmd_output(Command::new("cargo").args(&[ 54 | $cargo_action, 55 | "--features", 56 | &features, 57 | "--manifest-path", 58 | &format!("{package}/Cargo.toml"), 59 | "--no-default-features", 60 | $($additional_arg)? 61 | ]))?; 62 | Ok(()) 63 | } 64 | }; 65 | } 66 | 67 | impl Actions { 68 | create_fns!("build", "Building", build_generic, build_with_features); 69 | create_fns!("check", "Checking", check_generic, check_with_features, "--tests"); 70 | create_fns!("test", "Testing", test_generic, test_with_features); 71 | } 72 | -------------------------------------------------------------------------------- /ndstruct/src/utils.rs: -------------------------------------------------------------------------------- 1 | use cl_aux::ArrayWrapper; 2 | 3 | #[cfg(feature = "rayon")] 4 | /// Parallel iterator for Rayon implementation. This is mostly an internal detail. 5 | #[derive(Debug)] 6 | pub struct ParallelIteratorWrapper(pub(crate) I); 7 | 8 | #[cfg(feature = "rayon")] 9 | /// Parallel producer for Rayon implementation. This is mostly an internal detail. 10 | #[derive(Debug)] 11 | pub struct ParallelProducerWrapper(pub(crate) I); 12 | 13 | #[inline] 14 | pub(crate) fn are_in_ascending_order<'slice, T, U>( 15 | slice: &'slice [T], 16 | cb: impl Fn(&'slice T, &'slice T) -> [&'slice U; 2], 17 | ) -> bool 18 | where 19 | T: 'slice, 20 | U: PartialOrd + 'slice, 21 | { 22 | windows2(slice).all(|x| { 23 | let [a, b] = cb(x[0], x[1]); 24 | a <= b 25 | }) 26 | } 27 | 28 | #[inline] 29 | pub(crate) fn are_in_upper_bound(slice: &[T], upper_bound: &T) -> bool 30 | where 31 | T: PartialOrd, 32 | { 33 | slice.iter().all(|x| x < upper_bound) 34 | } 35 | 36 | #[inline] 37 | pub(crate) fn has_duplicates(slice: &[T]) -> bool 38 | where 39 | T: PartialEq, 40 | { 41 | for (a_idx, a) in slice.iter().enumerate() { 42 | for b in slice.iter().skip(a_idx.saturating_add(1)) { 43 | if a == b { 44 | return true; 45 | } 46 | } 47 | } 48 | false 49 | } 50 | 51 | #[inline] 52 | pub(crate) fn max_nnz(dims: &[usize; D]) -> usize { 53 | if dims == &ArrayWrapper::default().0 { 54 | return 0; 55 | } 56 | if let Some(first) = dims.first().copied() { 57 | if D == 1 { 58 | return first; 59 | } 60 | 61 | let mut product: usize = 1; 62 | for dim in dims.iter().copied().filter(|dim| dim != &0) { 63 | product = product.saturating_mul(dim); 64 | } 65 | return product; 66 | } 67 | 0 68 | } 69 | 70 | #[cfg(feature = "rand")] 71 | #[inline] 72 | pub(crate) fn valid_random_dims(rng: &mut R, upper_bound: usize) -> [usize; D] 73 | where 74 | R: rand::Rng, 75 | { 76 | let dims = ArrayWrapper::default().0; 77 | if D == 0 { 78 | return dims; 79 | } 80 | let cut_point = rng.random_range(0..D); 81 | let mut array = dims; 82 | let iter = if let Some(r) = array.get_mut(cut_point..) { 83 | r.iter_mut() 84 | } else { 85 | return dims; 86 | }; 87 | match upper_bound { 88 | 0 => {} 89 | 1 => iter.for_each(|dim| *dim = 1), 90 | _ => iter.for_each(|dim| *dim = rng.random_range(1..upper_bound)), 91 | } 92 | dims 93 | } 94 | 95 | #[inline] 96 | pub(crate) fn windows2(slice: &[T]) -> impl Iterator { 97 | slice.windows(2).filter_map(|value| Some([value.first()?, value.get(1)?])) 98 | } 99 | -------------------------------------------------------------------------------- /ndstruct/src/csl/csl_rayon.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | csl::{CslLineIterMut, CslLineIterRef, CslMut, CslRef}, 3 | ParallelIteratorWrapper, ParallelProducerWrapper, 4 | }; 5 | use rayon::iter::{ 6 | plumbing::{bridge, Consumer, Producer, ProducerCallback, UnindexedConsumer}, 7 | IndexedParallelIterator, ParallelIterator, 8 | }; 9 | 10 | macro_rules! create_rayon_iter { 11 | ($csl_rayon_iter:ident, $ref:ident) => { 12 | impl<'slices, T, const D: usize> ParallelIterator 13 | for ParallelIteratorWrapper<$csl_rayon_iter<'slices, T, D>> 14 | where 15 | T: Send + Sync + 'slices, 16 | { 17 | type Item = $ref<'slices, T, D>; 18 | 19 | #[inline] 20 | fn drive_unindexed(self, consumer: C) -> C::Result 21 | where 22 | C: UnindexedConsumer, 23 | { 24 | bridge(self, consumer) 25 | } 26 | 27 | #[inline] 28 | fn opt_len(&self) -> Option { 29 | Some(self.0.len()) 30 | } 31 | } 32 | 33 | impl<'slices, T, const D: usize> IndexedParallelIterator 34 | for ParallelIteratorWrapper<$csl_rayon_iter<'slices, T, D>> 35 | where 36 | T: Send + Sync + 'slices, 37 | { 38 | #[inline] 39 | fn drive(self, consumer: C) -> C::Result 40 | where 41 | C: Consumer, 42 | { 43 | bridge(self, consumer) 44 | } 45 | 46 | #[inline] 47 | fn len(&self) -> usize { 48 | ExactSizeIterator::len(&self.0) 49 | } 50 | 51 | #[inline] 52 | fn with_producer(self, callback: Cb) -> Cb::Output 53 | where 54 | Cb: ProducerCallback, 55 | { 56 | callback.callback(ParallelProducerWrapper(self.0)) 57 | } 58 | } 59 | 60 | impl<'slices, T, const D: usize> IntoIterator 61 | for ParallelProducerWrapper<$csl_rayon_iter<'slices, T, D>> 62 | where 63 | T: 'slices, 64 | { 65 | type IntoIter = $csl_rayon_iter<'slices, T, D>; 66 | type Item = ::Item; 67 | 68 | #[inline] 69 | fn into_iter(self) -> Self::IntoIter { 70 | self.0 71 | } 72 | } 73 | 74 | impl<'slices, T, const D: usize> Producer 75 | for ParallelProducerWrapper<$csl_rayon_iter<'slices, T, D>> 76 | where 77 | T: Send + Sync + 'slices, 78 | { 79 | type IntoIter = $csl_rayon_iter<'slices, T, D>; 80 | type Item = ::Item; 81 | 82 | #[inline] 83 | fn into_iter(self) -> Self::IntoIter { 84 | self.0 85 | } 86 | 87 | #[inline] 88 | fn split_at(self, i: usize) -> (Self, Self) { 89 | let [a, b] = self.0.split_at(i).unwrap(); 90 | (ParallelProducerWrapper(a), ParallelProducerWrapper(b)) 91 | } 92 | } 93 | }; 94 | } 95 | 96 | create_rayon_iter!(CslLineIterRef, CslRef); 97 | create_rayon_iter!(CslLineIterMut, CslMut); 98 | -------------------------------------------------------------------------------- /cl-aux/src/tuple_impls.rs: -------------------------------------------------------------------------------- 1 | use crate::{Capacity, CapacityUpperBound, Clear, Length, SizeHint, Truncate}; 2 | 3 | macro_rules! tuple_impls { 4 | ($( 5 | $tuple_len:tt { 6 | $(($idx:tt) -> $T:ident)* 7 | } 8 | )+) => { 9 | $( 10 | impl<$( $T, )*> Capacity for ($( $T, )*) { 11 | #[inline] 12 | fn capacity(&self) -> usize { 13 | $tuple_len 14 | } 15 | } 16 | 17 | impl<$( $T, )*> CapacityUpperBound for ($( $T, )*) { 18 | const CAPACITY_UPPER_BOUND: usize = $tuple_len; 19 | } 20 | 21 | #[allow(non_snake_case)] 22 | impl<$( $T: Clear, )*> Clear for ($( $T, )*) { 23 | #[inline] 24 | fn clear(&mut self) { 25 | $( self.$idx.clear(); )* 26 | } 27 | } 28 | 29 | impl<$( $T, )*> Length for ($( $T, )*) { 30 | #[inline] 31 | fn length(&self) -> usize { 32 | $tuple_len 33 | } 34 | } 35 | 36 | impl<$( $T, )*> SizeHint for ($( $T, )*) { 37 | #[inline] 38 | fn size_hint(&self) -> (usize, Option) { 39 | ($tuple_len, Some($tuple_len)) 40 | } 41 | } 42 | 43 | #[allow(non_snake_case)] 44 | impl<$( $T: Truncate, )*> Truncate for ($( $T, )*) { 45 | type Input = ($( $T::Input, )*); 46 | 47 | #[inline] 48 | fn truncate(&mut self, input: Self::Input) { 49 | $( self.$idx.truncate(input.$idx); )* 50 | } 51 | } 52 | )+ 53 | } 54 | } 55 | 56 | tuple_impls! { 57 | 1 { 58 | (0) -> A 59 | } 60 | 2 { 61 | (0) -> A 62 | (1) -> B 63 | } 64 | 3 { 65 | (0) -> A 66 | (1) -> B 67 | (2) -> C 68 | } 69 | 4 { 70 | (0) -> A 71 | (1) -> B 72 | (2) -> C 73 | (3) -> D 74 | } 75 | 5 { 76 | (0) -> A 77 | (1) -> B 78 | (2) -> C 79 | (3) -> D 80 | (4) -> E 81 | } 82 | 6 { 83 | (0) -> A 84 | (1) -> B 85 | (2) -> C 86 | (3) -> D 87 | (4) -> E 88 | (5) -> F 89 | } 90 | 7 { 91 | (0) -> A 92 | (1) -> B 93 | (2) -> C 94 | (3) -> D 95 | (4) -> E 96 | (5) -> F 97 | (6) -> G 98 | } 99 | 8 { 100 | (0) -> A 101 | (1) -> B 102 | (2) -> C 103 | (3) -> D 104 | (4) -> E 105 | (5) -> F 106 | (6) -> G 107 | (7) -> H 108 | } 109 | 9 { 110 | (0) -> A 111 | (1) -> B 112 | (2) -> C 113 | (3) -> D 114 | (4) -> E 115 | (5) -> F 116 | (6) -> G 117 | (7) -> H 118 | (8) -> I 119 | } 120 | 10 { 121 | (0) -> A 122 | (1) -> B 123 | (2) -> C 124 | (3) -> D 125 | (4) -> E 126 | (5) -> F 127 | (6) -> G 128 | (7) -> H 129 | (8) -> I 130 | (9) -> J 131 | } 132 | 11 { 133 | (0) -> A 134 | (1) -> B 135 | (2) -> C 136 | (3) -> D 137 | (4) -> E 138 | (5) -> F 139 | (6) -> G 140 | (7) -> H 141 | (8) -> I 142 | (9) -> J 143 | (10) -> K 144 | } 145 | 12 { 146 | (0) -> A 147 | (1) -> B 148 | (2) -> C 149 | (3) -> D 150 | (4) -> E 151 | (5) -> F 152 | (6) -> G 153 | (7) -> H 154 | (8) -> I 155 | (9) -> J 156 | (10) -> K 157 | (11) -> L 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /rust-tools/src/parse_cfg.rs: -------------------------------------------------------------------------------- 1 | use crate::{CfgOption, Params, TransformingParams}; 2 | use std::io::{BufRead as _, BufReader, Read}; 3 | 4 | #[allow( 5 | // False positive 6 | clippy::redundant_closure_call 7 | )] 8 | pub(crate) fn parse_cfg(read: R) -> crate::Result<(Params, TransformingParams)> 9 | where 10 | R: Read, 11 | { 12 | let mut br = BufReader::new(read); 13 | let mut overall_buffer = String::with_capacity(16); 14 | let mut params = Params::default(); 15 | let mut tp = TransformingParams::default(); 16 | 17 | iterations(&mut overall_buffer, &mut br, |_| false)?; 18 | macro_rules! push { 19 | (vec: $name:ident) => { 20 | push!($name, |rslt: &str| { 21 | for value in rslt.split(',') { 22 | tp.$name.push(value.trim().into()); 23 | } 24 | Ok(()) 25 | }) 26 | }; 27 | ($name:ident, $cb:expr) => { 28 | let name = stringify!($name); 29 | if let Some(rslt) = overall_buffer.split(name).nth(1) { 30 | let cb: crate::Result<()> = $cb(rslt); 31 | cb?; 32 | iterations(&mut overall_buffer, &mut br, |_| false)?; 33 | } 34 | }; 35 | } 36 | 37 | push!(vec: add_clippy_flags); 38 | push!(vec: rm_clippy_flags); 39 | push!(vec: add_rust_flags); 40 | push!(vec: rm_rust_flags); 41 | push!(vec: add_rustfmt_flags); 42 | push!(vec: rm_rustfmt_flags); 43 | push!(template, |rslt: &str| { 44 | params = rslt.trim().parse::()?.into_params(); 45 | Ok(()) 46 | }); 47 | push!(toolchain, |rslt: &str| { 48 | tp.toolchain = rslt.trim().into(); 49 | Ok(()) 50 | }); 51 | Ok((params, tp)) 52 | } 53 | 54 | fn iterations( 55 | overall_buffer: &mut String, 56 | br: &mut BufReader, 57 | mut cb: impl FnMut(&str) -> bool, 58 | ) -> crate::Result<()> 59 | where 60 | R: Read, 61 | { 62 | overall_buffer.clear(); 63 | let mut bytes_read = 0; 64 | 65 | loop { 66 | let curr_bytes_read = br.read_line(overall_buffer)?; 67 | 68 | if curr_bytes_read == 0 { 69 | break; 70 | } 71 | 72 | let Some(str_read) = overall_buffer.get(bytes_read..) else { 73 | break; 74 | }; 75 | let trimmed = str_read.trim(); 76 | 77 | bytes_read = bytes_read.saturating_add(curr_bytes_read); 78 | 79 | if trimmed.is_empty() || trimmed.starts_with("//") { 80 | continue; 81 | } 82 | 83 | if !cb(trimmed) { 84 | break; 85 | } 86 | } 87 | 88 | Ok(()) 89 | } 90 | 91 | #[cfg(test)] 92 | mod tests { 93 | use crate::{cfg::YouRust, parse_cfg}; 94 | 95 | #[test] 96 | fn parsed_configuration_has_correct_params() { 97 | let cfg = br#" 98 | add_clippy_flags A 99 | rm_clippy_flags B, C 100 | add_rust_flags D 101 | rm_rust_flags E 102 | add_rustfmt_flags F 103 | template you-rust 104 | toolchain nightly-2025-07-17 105 | "#; 106 | let (params, tp) = parse_cfg(&cfg[..]).unwrap(); 107 | assert_eq!(params, YouRust::default().0); 108 | assert_eq!(tp.add_clippy_flags, vec!["A"]); 109 | assert_eq!(tp.rm_clippy_flags, vec!["B", "C"]); 110 | assert_eq!(tp.add_rust_flags, vec!["D"]); 111 | assert_eq!(tp.rm_rust_flags, vec!["E"]); 112 | assert_eq!(tp.add_rustfmt_flags, vec!["F"]); 113 | assert_eq!(tp.rm_rustfmt_flags, Vec::::new()); 114 | assert_eq!(tp.toolchain, "nightly-2025-07-17"); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /cl-aux/src/traits/retain.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::vec::Vec; 3 | 4 | /// See [`Retain::retain`] for more information. 5 | pub trait Retain { 6 | /// Input 7 | type Input; 8 | 9 | /// Retains only the elements specified by the `F` predicate. 10 | fn retain(&mut self, input: Self::Input); 11 | } 12 | 13 | impl Retain for &mut T 14 | where 15 | T: Retain, 16 | { 17 | type Input = T::Input; 18 | 19 | #[inline] 20 | fn retain(&mut self, input: Self::Input) { 21 | (*self).retain(input); 22 | } 23 | } 24 | 25 | /// ```rust 26 | /// let mut opt = Some(1); 27 | /// cl_aux::Retain::retain(&mut opt, |n| n % 2 == 0); 28 | /// assert_eq!(opt, None); 29 | /// ``` 30 | impl Retain for Option { 31 | type Input = fn(&T) -> bool; 32 | 33 | #[inline] 34 | fn retain(&mut self, input: Self::Input) { 35 | if let Some(elem) = self.as_mut() { 36 | if !input(elem) { 37 | *self = None; 38 | } 39 | } 40 | } 41 | } 42 | 43 | /// ```rust 44 | /// let mut structure = cl_aux::doc_tests::vec(); 45 | /// cl_aux::Retain::retain(&mut structure, |n| n % 2 == 0); 46 | /// assert_eq!(&structure, &[2]); 47 | /// ``` 48 | #[cfg(feature = "alloc")] 49 | impl Retain for Vec { 50 | type Input = fn(&T) -> bool; 51 | 52 | #[inline] 53 | fn retain(&mut self, input: Self::Input) { 54 | self.retain(input); 55 | } 56 | } 57 | 58 | /// ```rust 59 | /// let mut structure = cl_aux::doc_tests::array_vec(); 60 | /// cl_aux::Retain::retain(&mut structure, |n| n % 2 == 0); 61 | /// assert_eq!(&structure[..], &[2]); 62 | /// ``` 63 | #[cfg(feature = "arrayvec")] 64 | impl Retain for arrayvec::ArrayVec { 65 | type Input = fn(&T) -> bool; 66 | 67 | #[inline] 68 | fn retain(&mut self, input: Self::Input) { 69 | self.retain(|i| input(i)); 70 | } 71 | } 72 | 73 | /// ```rust 74 | /// let mut structure = cl_aux::doc_tests::small_vec(); 75 | /// cl_aux::Retain::retain(&mut structure, |n| n % 2 == 0); 76 | /// assert_eq!(&structure[..], &[2]); 77 | /// ``` 78 | #[cfg(feature = "smallvec")] 79 | impl Retain for smallvec::SmallVec 80 | where 81 | A: smallvec::Array, 82 | { 83 | type Input = fn(&A::Item) -> bool; 84 | 85 | #[inline] 86 | fn retain(&mut self, input: Self::Input) { 87 | self.retain(|i| input(i)); 88 | } 89 | } 90 | 91 | /// ```rust 92 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 93 | /// cl_aux::Retain::retain(&mut structure, |n| n % 2 == 0); 94 | /// assert_eq!(&structure[..], &[2]); 95 | /// ``` 96 | #[cfg(feature = "tinyvec")] 97 | impl Retain for tinyvec::ArrayVec 98 | where 99 | A: tinyvec::Array, 100 | A::Item: Default, 101 | { 102 | type Input = fn(&A::Item) -> bool; 103 | 104 | #[inline] 105 | fn retain(&mut self, input: Self::Input) { 106 | self.retain(input); 107 | } 108 | } 109 | 110 | /// ```rust 111 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 112 | /// cl_aux::Retain::retain(&mut structure, |n| n % 2 == 0); 113 | /// assert_eq!(&structure[..], &[2]); 114 | /// ``` 115 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 116 | impl Retain for tinyvec::TinyVec 117 | where 118 | A: tinyvec::Array, 119 | A::Item: Default, 120 | { 121 | type Input = fn(&A::Item) -> bool; 122 | 123 | #[inline] 124 | fn retain(&mut self, input: Self::Input) { 125 | self.retain(input); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /cl-aux/src/traits/clear.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::{string::String, vec::Vec}; 3 | 4 | /// See [`Clear::clear`] for more information. 5 | pub trait Clear { 6 | /// "Clears" the internal buffer, "erasing" all elements. 7 | fn clear(&mut self); 8 | } 9 | 10 | impl Clear for &mut T 11 | where 12 | T: Clear, 13 | { 14 | #[inline] 15 | fn clear(&mut self) { 16 | (*self).clear(); 17 | } 18 | } 19 | 20 | impl Clear for () { 21 | #[inline] 22 | fn clear(&mut self) {} 23 | } 24 | 25 | /// ```rust 26 | /// let mut opt = Some(0); 27 | /// cl_aux::Clear::clear(&mut opt); 28 | /// assert_eq!(opt, None); 29 | /// ``` 30 | impl Clear for Option { 31 | #[inline] 32 | fn clear(&mut self) { 33 | *self = None; 34 | } 35 | } 36 | 37 | /// ```rust 38 | /// let mut structure = cl_aux::doc_tests::string(); 39 | /// cl_aux::Clear::clear(&mut structure); 40 | /// assert_eq!(structure.len(), 0); 41 | /// ``` 42 | #[cfg(feature = "alloc")] 43 | impl Clear for String { 44 | #[inline] 45 | fn clear(&mut self) { 46 | self.clear(); 47 | } 48 | } 49 | 50 | /// ```rust 51 | /// let mut structure = cl_aux::doc_tests::vec(); 52 | /// cl_aux::Clear::clear(&mut structure); 53 | /// assert_eq!(structure.len(), 0); 54 | /// ``` 55 | #[cfg(feature = "alloc")] 56 | impl Clear for Vec { 57 | #[inline] 58 | fn clear(&mut self) { 59 | self.clear(); 60 | } 61 | } 62 | 63 | /// ```rust 64 | /// let mut structure = cl_aux::doc_tests::array_string(); 65 | /// cl_aux::Clear::clear(&mut structure); 66 | /// assert_eq!(structure.len(), 0); 67 | /// ``` 68 | #[cfg(feature = "arrayvec")] 69 | impl Clear for arrayvec::ArrayString { 70 | #[inline] 71 | fn clear(&mut self) { 72 | self.clear(); 73 | } 74 | } 75 | 76 | /// ```rust 77 | /// let mut structure = cl_aux::doc_tests::array_vec(); 78 | /// cl_aux::Clear::clear(&mut structure); 79 | /// assert_eq!(structure.len(), 0); 80 | /// ``` 81 | #[cfg(feature = "arrayvec")] 82 | impl Clear for arrayvec::ArrayVec { 83 | #[inline] 84 | fn clear(&mut self) { 85 | self.clear(); 86 | } 87 | } 88 | 89 | /// ```rust 90 | /// let mut structure = cl_aux::doc_tests::small_vec(); 91 | /// cl_aux::Clear::clear(&mut structure); 92 | /// assert_eq!(structure.len(), 0); 93 | /// ``` 94 | #[cfg(feature = "smallvec")] 95 | impl Clear for smallvec::SmallVec 96 | where 97 | A: smallvec::Array, 98 | { 99 | #[inline] 100 | fn clear(&mut self) { 101 | self.clear(); 102 | } 103 | } 104 | 105 | /// ```rust 106 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 107 | /// cl_aux::Clear::clear(&mut structure); 108 | /// assert_eq!(structure.len(), 0); 109 | /// ``` 110 | #[cfg(feature = "tinyvec")] 111 | impl Clear for tinyvec::ArrayVec 112 | where 113 | A: tinyvec::Array, 114 | A::Item: Default, 115 | { 116 | #[inline] 117 | fn clear(&mut self) { 118 | self.clear(); 119 | } 120 | } 121 | 122 | /// ```rust 123 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 124 | /// cl_aux::Clear::clear(&mut structure); 125 | /// assert_eq!(structure.len(), 0); 126 | /// ``` 127 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 128 | impl Clear for tinyvec::TinyVec 129 | where 130 | A: tinyvec::Array, 131 | A::Item: Default, 132 | { 133 | #[inline] 134 | fn clear(&mut self) { 135 | self.clear(); 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /rust-tools/README.md: -------------------------------------------------------------------------------- 1 | [![CI](https://github.com/c410-f3r/rust-tools/workflows/CI/badge.svg)](https://github.com/c410-f3r/rust-tools/actions?query=workflow%3ACI) 2 | [![crates.io](https://img.shields.io/crates/v/rust-tools.svg)](https://crates.io/crates/rust-tools) 3 | [![Documentation](https://docs.rs/rust-tools/badge.svg)](https://docs.rs/rust-tools) 4 | [![License](https://img.shields.io/badge/license-APACHE2-blue.svg)](./LICENSE) 5 | [![Rustc](https://img.shields.io/badge/rustc-stable-lightgray")](https://blog.rust-lang.org/2020/03/12/Rust-stable.html) 6 | 7 | A CLI intended to aid development and CI workflows. This project can be seen as a high-level "orchestrator" or "wrapper" for tools that involve the Rust programing language. 8 | 9 | ## Configurations 10 | 11 | The application will primarily interact with a configuration (collection of rules) that defines how tools should behave and there are three different sources: 12 | 13 | ### Built-in configuration 14 | 15 | Pre-fixed set of rules found within this repository. Feel free to open a PR to create a new configuration. 16 | 17 | ```bash 18 | rust-tools --template you-rust SOME_COMMAND 19 | ``` 20 | 21 | ```txt 22 | YouRust( 23 | Params { 24 | clippy_flags: [ 25 | "-Dclippy::restriction", 26 | "-Dwarnings", 27 | "-Aclippy::implicit_return", 28 | "-Aclippy::missing_docs_in_private_items", 29 | ], 30 | rust_flags: [ 31 | "-Dbad_style", 32 | "-Dfuture_incompatible", 33 | "-Dmissing_debug_implementations", 34 | "-Dmissing_docs", 35 | "-Dnonstandard_style", 36 | "-Drust_2018_compatibility", 37 | "-Drust_2018_idioms", 38 | "-Dtrivial_casts", 39 | "-Dunused_lifetimes", 40 | "-Dunused_qualifications", 41 | "-Dwarnings", 42 | ], 43 | rustfmt_flags: [ 44 | "edition=\"2018", 45 | "tab_spaces=2", 46 | "use_field_init_shorthand=true", 47 | "use_small_heuristics=\"Max", 48 | ], 49 | toolchain: "", 50 | }, 51 | ) 52 | ``` 53 | 54 | ### Configuration file 55 | 56 | Can use a built-in configuration as a template for custom needs. Enables the addition or removal of flags. 57 | 58 | ```bash 59 | rust-tools --file SOME_CONFIGURATION_FILE.cfg SOME_COMMAND 60 | ``` 61 | 62 | ```ini 63 | add_clipy_flags -Aclippy::type_complexity 64 | rm_clippy_flags -Aclippy::implicit_return,-Aclippy::missing_docs_in_private_items 65 | template you-rust 66 | toolchain nightly-2025-07-17 67 | ``` 68 | 69 | ## CLI parameters 70 | 71 | Depending on the selected target, it is possible to define or extend certain rules; 72 | 73 | ```bash 74 | rust-tools rust-flags -Dbad_style,-Dunused_qualifications 75 | ``` 76 | 77 | The final configuration will obey the following order: `built-in` -> `file` -> `CLI`, i.e., built-in parameters are overwritten by file parameters and file parameters are overwritten by cli parameters. 78 | 79 | ## Script example 80 | 81 | ```bash 82 | #!/usr/bin/env bash 83 | 84 | set -euxo pipefail 85 | 86 | cargo install rust-tools 87 | 88 | export RUSTFLAGS="$(rust-tools rust-flags)" 89 | 90 | rust-tools clippy 91 | 92 | rust-tools check-generic SOME_CRATE 93 | rust-tools test-with-features SOME_CRATE FIRST_FEATURE,SECOND_FEATURE 94 | ``` 95 | 96 | ## Supported targets 97 | 98 | - clippy flags 99 | - rust flags 100 | - rust-toolchain file 101 | - rustfmt file and flags 102 | 103 | -------------------------------------------------------------------------------- /cl-aux/src/structures/doc_tests.rs: -------------------------------------------------------------------------------- 1 | //! Instances for documentation tests 2 | 3 | /// Mutable slice with three elements 4 | #[doc(hidden)] 5 | #[macro_export] 6 | macro_rules! slice_mut { 7 | () => { 8 | &mut [1i32, 2, 3][..] 9 | }; 10 | } 11 | 12 | use crate::SingleItemStorage; 13 | #[cfg(feature = "alloc")] 14 | use alloc::{ 15 | collections::{BTreeMap, BTreeSet}, 16 | string::String, 17 | vec::Vec, 18 | }; 19 | pub use slice_mut; 20 | #[cfg(feature = "std")] 21 | use std::collections::{HashMap, HashSet}; 22 | 23 | /// Array with three elements 24 | #[inline] 25 | #[must_use] 26 | pub fn array() -> [i32; 3] { 27 | [1, 2, 3] 28 | } 29 | 30 | /// [`arrayvec::ArrayString`] filled with "Hello" 31 | #[cfg(feature = "arrayvec")] 32 | #[inline] 33 | #[must_use] 34 | pub fn array_string() -> arrayvec::ArrayString<10> { 35 | let mut s = arrayvec::ArrayString::new(); 36 | s.push_str("Hello"); 37 | s 38 | } 39 | 40 | /// `ArrayVec` with three elements 41 | #[cfg(feature = "arrayvec")] 42 | #[inline] 43 | #[must_use] 44 | pub fn array_vec() -> arrayvec::ArrayVec { 45 | let mut vec = arrayvec::ArrayVec::new(); 46 | vec.extend([1, 2, 3].iter().copied()); 47 | vec 48 | } 49 | 50 | /// `BTreeMap` with three elements 51 | #[cfg(feature = "alloc")] 52 | #[inline] 53 | #[must_use] 54 | pub fn b_tree_map() -> BTreeMap { 55 | [(0, 1), (1, 2), (2, 3)].iter().copied().collect() 56 | } 57 | 58 | /// `BTreeSet` with three elements 59 | #[cfg(feature = "alloc")] 60 | #[inline] 61 | #[must_use] 62 | pub fn b_tree_set() -> BTreeSet { 63 | [1, 2, 3].iter().copied().collect() 64 | } 65 | 66 | /// `HashMap` with three elements 67 | #[cfg(feature = "std")] 68 | #[inline] 69 | #[must_use] 70 | pub fn hash_map() -> HashMap { 71 | [(0, 1), (1, 2), (2, 3)].iter().copied().collect() 72 | } 73 | 74 | /// `HashSet` with three elements 75 | #[cfg(feature = "std")] 76 | #[inline] 77 | #[must_use] 78 | pub fn hash_set() -> HashSet { 79 | [1, 2, 3].iter().copied().collect() 80 | } 81 | 82 | #[inline] 83 | #[must_use] 84 | /// `SingleItemStorage` containing `'1i32` 85 | pub fn single_item_storage() -> SingleItemStorage { 86 | 1i32.into() 87 | } 88 | 89 | #[inline] 90 | #[must_use] 91 | /// Slice with three elements 92 | pub fn slice() -> &'static [i32] { 93 | &[1, 2, 3] 94 | } 95 | 96 | #[cfg(feature = "smallvec")] 97 | #[inline] 98 | #[must_use] 99 | /// `SmallVec` with three elements 100 | pub fn small_vec() -> smallvec::SmallVec<[i32; 5]> { 101 | let mut vec = smallvec::SmallVec::new(); 102 | vec.extend([1, 2, 3].iter().copied()); 103 | vec 104 | } 105 | 106 | /// [String] filled with "Hello" 107 | #[cfg(feature = "alloc")] 108 | #[inline] 109 | #[must_use] 110 | pub fn string() -> String { 111 | String::from("Hello") 112 | } 113 | 114 | #[cfg(feature = "tinyvec")] 115 | #[inline] 116 | #[must_use] 117 | /// `ArrayVec` with three elements 118 | pub fn tiny_vec_array_vec() -> tinyvec::ArrayVec<[i32; 5]> { 119 | let mut vec = tinyvec::ArrayVec::new(); 120 | vec.extend([1, 2, 3].iter().copied()); 121 | vec 122 | } 123 | 124 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 125 | #[inline] 126 | #[must_use] 127 | /// `TinyVec` with three elements 128 | pub fn tiny_vec_tiny_vec() -> tinyvec::TinyVec<[i32; 5]> { 129 | let mut vec = tinyvec::TinyVec::new(); 130 | vec.extend([1, 2, 3].iter().copied()); 131 | vec 132 | } 133 | 134 | #[cfg(feature = "alloc")] 135 | #[inline] 136 | #[must_use] 137 | /// `Vec` with three elements 138 | pub fn vec() -> Vec { 139 | let mut vec = Vec::with_capacity(5); 140 | vec.extend([1, 2, 3].iter().copied()); 141 | vec 142 | } 143 | -------------------------------------------------------------------------------- /ndstruct/README.md: -------------------------------------------------------------------------------- 1 | # ndstruct 2 | 3 | [![CI](https://github.com/c410-f3r/ndstruct/workflows/CI/badge.svg)](https://github.com/c410-f3r/ndstruct/actions?query=workflow%3ACI) 4 | [![crates.io](https://img.shields.io/crates/v/ndstruct.svg)](https://crates.io/crates/ndstruct) 5 | [![Documentation](https://docs.rs/ndstruct/badge.svg)](https://docs.rs/ndstruct) 6 | [![License](https://img.shields.io/badge/license-APACHE2-blue.svg)](./LICENSE) 7 | [![Rustc](https://img.shields.io/badge/rustc-1.52-lightgray")](https://blog.rust-lang.org/2020/03/12/Rust-1.52.html) 8 | 9 | Structures to store and retrieve N-dimensional data. Well, not any `N ∈ ℕ` but any natural number that fits into the pointer size of the machine that you are using. E.g., an 8-bit microcontroller can manipulate any structure with up to 255 dimensions. 10 | 11 | For those that might be wondering about why this crate should be used, it generally comes down to space-efficiency, ergometrics and retrieving speed. The following snippet shows some use-cases for potential replacement with `_cube_of_vecs` being the most inefficient of all. 12 | 13 | ```rust 14 | let _vec_of_options: Vec> = Default::default(); 15 | let _matrix_of_options: [Option<[Option; 8]>; 16] = Default::default(); 16 | let _cube_of_vecs: Vec>> = Default::default(); 17 | // The list worsens exponentially for higher dimensions 18 | ``` 19 | 20 | ## Example 21 | 22 | ```rust 23 | use ndstruct::{coo::CooArray, csl::CslVec}; 24 | 25 | fn main() -> ndstruct::Result<()> { 26 | // A CSL and COO cube. 27 | // 28 | // ___ ___ 29 | // / / /\ 30 | // /___/___/ /\ 31 | // / 1 / /\/2/ 32 | // /_1_/___/ /\/ 33 | // \_1_\___\/ / 34 | // \___\___\/ 35 | let coo = CooArray::new([2, 2, 2], [([0, 0, 0], 1.0), ([1, 1, 1], 2.0)])?; 36 | let mut csl = CslVec::default(); 37 | csl 38 | .constructor()? 39 | .next_outermost_dim(2)? 40 | .push_line([(0, 1.0)].iter().copied())? 41 | .next_outermost_dim(2)? 42 | .push_empty_line()? 43 | .next_outermost_dim(2)? 44 | .push_empty_line()? 45 | .push_line([(1, 2.0)].iter().copied())?; 46 | assert_eq!(coo.value([0, 0, 0]), csl.value([0, 0, 0])); 47 | assert_eq!(coo.value([1, 1, 1]), csl.value([1, 1, 1])); 48 | Ok(()) 49 | } 50 | ``` 51 | 52 | ## Supported structures 53 | 54 | - Compressed Sparse Line (CSL) 55 | - Coordinate format (COO) 56 | - Dense 57 | 58 | ## Features 59 | 60 | - `no_std` 61 | - Different storages (Array, Vec, Slice and more!) 62 | - Fully documented 63 | - Fuzz testing 64 | - No unsafe 65 | 66 | ## Optional features 67 | 68 | - `alloc` and `std` 69 | - Deserialization/Serialization (serde) 70 | - Parallel iterators (rayon) 71 | - Random instances (rand) 72 | 73 | ## Future 74 | 75 | Although CSR and COO are general sparse structures, they aren't good enough for certain situations, therefore, the existence of DIA, JDS, ELL, LIL, DOK and many others. 76 | 77 | If there are enough interest, the mentioned sparse storages might be added at some point in the future. 78 | 79 | ## Algebra library 80 | 81 | This project isn't and will never be an algebra library because of its own self-contained responsibility and complexity. Futhermore, a good implementation of such library would require a titanic amount of work and research for different algorithms, operations, decompositions, solvers and hardwares. 82 | 83 | ## Alternatives 84 | 85 | One of these libraries might suit you better: 86 | 87 | * [`sprs`][sprs]: Sparse linear algebra. 88 | * [`ndarray`][ndarray]: Dense N-dimensional operations. 89 | * [`nalgebra`][nalgebra]: Dense linear algebra. 90 | 91 | [nalgebra]: https://github.com/rustsim/nalgebra 92 | [ndarray]: https://github.com/rust-ndarray/ndarray 93 | [sprs]: https://github.com/vbarrielle/sprs -------------------------------------------------------------------------------- /cl-aux/src/traits/remove.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::vec::Vec; 3 | 4 | /// See [`Remove::remove`] for more information. 5 | pub trait Remove { 6 | /// Error 7 | type Error; 8 | /// Input 9 | type Input; 10 | /// Output 11 | type Output; 12 | 13 | /// Removes an element referenced by `Input`. 14 | fn remove(&mut self, input: Self::Input) -> Result; 15 | } 16 | 17 | impl Remove for &mut T 18 | where 19 | T: Remove, 20 | { 21 | type Error = T::Error; 22 | type Input = T::Input; 23 | type Output = T::Output; 24 | 25 | #[inline] 26 | fn remove(&mut self, input: Self::Input) -> Result { 27 | (*self).remove(input) 28 | } 29 | } 30 | 31 | /// ```rust 32 | /// let mut structure = cl_aux::doc_tests::vec(); 33 | /// cl_aux::Remove::remove(&mut structure, 0); 34 | /// assert_eq!(structure.get(0), Some(&2)); 35 | /// ``` 36 | #[cfg(feature = "alloc")] 37 | impl Remove for Vec { 38 | type Error = crate::Error; 39 | type Input = usize; 40 | type Output = T; 41 | 42 | #[inline] 43 | fn remove(&mut self, input: Self::Input) -> Result { 44 | _check_indcs!(self, input); 45 | Ok(self.remove(input)) 46 | } 47 | } 48 | 49 | /// ```rust 50 | /// let mut structure = cl_aux::doc_tests::array_vec(); 51 | /// cl_aux::Remove::remove(&mut structure, 0); 52 | /// assert_eq!(structure.get(0), Some(&2)); 53 | /// ``` 54 | #[cfg(feature = "arrayvec")] 55 | impl Remove for arrayvec::ArrayVec { 56 | type Error = crate::Error; 57 | type Input = usize; 58 | type Output = T; 59 | 60 | #[inline] 61 | fn remove(&mut self, input: Self::Input) -> Result { 62 | _check_indcs!(self, input); 63 | Ok(self.remove(input)) 64 | } 65 | } 66 | 67 | /// ```rust 68 | /// let mut structure = cl_aux::doc_tests::small_vec(); 69 | /// cl_aux::Remove::remove(&mut structure, 0); 70 | /// assert_eq!(structure.get(0), Some(&2)); 71 | /// ``` 72 | #[cfg(feature = "smallvec")] 73 | impl Remove for smallvec::SmallVec 74 | where 75 | A: smallvec::Array, 76 | { 77 | type Error = crate::Error; 78 | type Input = usize; 79 | type Output = A::Item; 80 | 81 | #[inline] 82 | fn remove(&mut self, input: Self::Input) -> Result { 83 | _check_indcs!(self, input); 84 | Ok(self.remove(input)) 85 | } 86 | } 87 | 88 | /// ```rust 89 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 90 | /// cl_aux::Remove::remove(&mut structure, 0); 91 | /// assert_eq!(structure.get(0), Some(&2)); 92 | /// ``` 93 | #[cfg(feature = "tinyvec")] 94 | impl Remove for tinyvec::ArrayVec 95 | where 96 | A: tinyvec::Array, 97 | A::Item: Default, 98 | { 99 | type Error = crate::Error; 100 | type Input = usize; 101 | type Output = A::Item; 102 | 103 | #[inline] 104 | fn remove(&mut self, input: Self::Input) -> Result { 105 | _check_indcs!(self, input); 106 | Ok(self.remove(input)) 107 | } 108 | } 109 | 110 | /// ```rust 111 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 112 | /// cl_aux::Remove::remove(&mut structure, 0); 113 | /// assert_eq!(structure.get(0), Some(&2)); 114 | /// ``` 115 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 116 | impl Remove for tinyvec::TinyVec 117 | where 118 | A: tinyvec::Array, 119 | A::Item: Default, 120 | { 121 | type Error = crate::Error; 122 | type Input = usize; 123 | type Output = A::Item; 124 | 125 | #[inline] 126 | fn remove(&mut self, input: Self::Input) -> Result { 127 | _check_indcs!(self, input); 128 | Ok(self.remove(input)) 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /rust-tools/src/cfg/you_rust.rs: -------------------------------------------------------------------------------- 1 | use crate::Params; 2 | 3 | const CLIPPY_FLAGS: &[&str] = &[ 4 | "-Dclippy::pedantic", 5 | "-Dclippy::restriction", 6 | "-Dwarnings", 7 | "-Aclippy::absolute_paths", 8 | "-Aclippy::allow_attributes", 9 | "-Aclippy::arbitrary_source_item_ordering", 10 | "-Aclippy::big_endian_bytes", 11 | "-Aclippy::blanket-clippy-restriction-lints", 12 | "-Aclippy::copy_iterator", 13 | "-Aclippy::decimal_literal_representation", 14 | "-Aclippy::default_numeric_fallback", 15 | "-Aclippy::doc_include_without_cfg", 16 | "-Aclippy::enum_variant_names", 17 | "-Aclippy::error_impl_error", 18 | "-Aclippy::exhaustive_enums", 19 | "-Aclippy::exhaustive_structs", 20 | "-Aclippy::field_scoped_visibility_modifiers", 21 | "-Aclippy::host_endian_bytes", 22 | "-Aclippy::ignored_unit_patterns", 23 | "-Aclippy::impl_trait_in_params", 24 | "-Aclippy::implicit_return", 25 | "-Aclippy::inline_always", 26 | "-Aclippy::integer_division", 27 | "-Aclippy::integer_division_remainder_used", 28 | "-Aclippy::into_iter_without_iter", 29 | "-Aclippy::len_without_is_empty", 30 | "-Aclippy::let_underscore_untyped", 31 | "-Aclippy::many_single_char_names", 32 | "-Aclippy::min_ident_chars", 33 | "-Aclippy::missing_assert_message", 34 | "-Aclippy::missing_docs_in_private_items", 35 | "-Aclippy::missing_errors_doc", 36 | "-Aclippy::missing_trait_methods", 37 | "-Aclippy::module_name_repetitions", 38 | "-Aclippy::multiple_inherent_impl", 39 | "-Aclippy::must_use_candidate", 40 | "-Aclippy::needless_doctest_main", 41 | "-Aclippy::needless_else", 42 | "-Aclippy::pattern_type_mismatch", 43 | "-Aclippy::pub_use", 44 | "-Aclippy::pub_with_shorthand", 45 | "-Aclippy::question_mark_used", 46 | "-Aclippy::same_name_method", 47 | "-Aclippy::self_named_module_files", 48 | "-Aclippy::semicolon_outside_block", 49 | "-Aclippy::similar_names", 50 | "-Aclippy::single_call_fn", 51 | "-Aclippy::struct_field_names", 52 | "-Aclippy::too_long_first_doc_paragraph", 53 | "-Aclippy::unneeded_field_pattern", 54 | "-Aclippy::unseparated_literal_suffix", 55 | "-Aclippy::used_underscore_binding", 56 | "-Aclippy::wildcard_enum_match_arm", 57 | ]; 58 | 59 | const RUST_FLAGS: &[&str] = &[ 60 | "-Ddeprecated_in_future", 61 | "-Ddeprecated_safe", 62 | "-Delided_lifetimes_in_paths", 63 | "-Dexplicit_outlives_requirements", 64 | "-Dffi_unwind_calls", 65 | "-Dkeyword_idents_2018", 66 | "-Dkeyword_idents_2024", 67 | "-Dlet_underscore_drop", 68 | "-Dmacro_use_extern_crate", 69 | "-Dmeta_variable_misuse", 70 | "-Dmissing_abi", 71 | "-Dmissing_debug_implementations", 72 | "-Dmissing_docs", 73 | "-Dmissing_unsafe_on_extern", 74 | "-Dnon_ascii_idents", 75 | "-Dredundant_lifetimes", 76 | "-Drust_2021_incompatible_closure_captures", 77 | "-Drust_2021_incompatible_or_patterns", 78 | "-Drust_2021_prefixes_incompatible_syntax", 79 | "-Drust_2021_prelude_collisions", 80 | "-Dsingle_use_lifetimes", 81 | "-Dtrivial_casts", 82 | "-Dtrivial_numeric_casts", 83 | "-Dunit_bindings", 84 | "-Dunnameable_types", 85 | "-Dunreachable_pub", 86 | "-Dunsafe_code", 87 | "-Dunused_extern_crates", 88 | "-Dunused_import_braces", 89 | "-Dunused_lifetimes", 90 | "-Dunused_macro_rules", 91 | "-Dunused_qualifications", 92 | "-Dunused_results", 93 | "-Dwarnings", 94 | ]; 95 | 96 | const RUSTFMT_FLAGS: &[&str] = 97 | &[r#"edition="2021""#, "tab_spaces=2", r#"use_small_heuristics="Max""#]; 98 | 99 | #[derive(Debug, PartialEq)] 100 | pub(crate) struct YouRust(pub(crate) Params); 101 | 102 | impl Default for YouRust { 103 | fn default() -> Self { 104 | Self(Params { 105 | clippy_flags: CLIPPY_FLAGS.iter().map(|&err| err.into()).collect(), 106 | rust_flags: RUST_FLAGS.iter().map(|&err| err.into()).collect(), 107 | rustfmt_flags: RUSTFMT_FLAGS.iter().map(|&err| err.into()).collect(), 108 | toolchain: String::new(), 109 | }) 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /cl-aux/src/traits/truncate.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::{string::String, vec::Vec}; 3 | 4 | /// See [`Truncate::truncate`] for more information. 5 | pub trait Truncate { 6 | /// Input 7 | type Input; 8 | 9 | /// Truncates the storage, delimiting its length by `Input`. 10 | fn truncate(&mut self, input: Self::Input); 11 | } 12 | 13 | impl Truncate for &mut T 14 | where 15 | T: Truncate, 16 | { 17 | type Input = T::Input; 18 | 19 | #[inline] 20 | fn truncate(&mut self, input: Self::Input) { 21 | (*self).truncate(input); 22 | } 23 | } 24 | 25 | /// ```rust 26 | /// let mut structure = Some(1); 27 | /// cl_aux::Truncate::truncate(&mut structure, 0); 28 | /// assert_eq!(structure, None); 29 | /// ``` 30 | impl Truncate for Option { 31 | type Input = usize; 32 | 33 | #[inline] 34 | fn truncate(&mut self, input: Self::Input) { 35 | if input == 0 { 36 | *self = None; 37 | } 38 | } 39 | } 40 | 41 | /// ```rust 42 | /// let mut structure = cl_aux::doc_tests::string(); 43 | /// cl_aux::Truncate::truncate(&mut structure, 1); 44 | /// assert_eq!(structure.len(), 1); 45 | /// ``` 46 | #[cfg(feature = "alloc")] 47 | impl Truncate for String { 48 | type Input = usize; 49 | 50 | #[inline] 51 | fn truncate(&mut self, input: Self::Input) { 52 | self.truncate(input); 53 | } 54 | } 55 | 56 | /// ```rust 57 | /// let mut structure = cl_aux::doc_tests::vec(); 58 | /// cl_aux::Truncate::truncate(&mut structure, 1); 59 | /// assert_eq!(structure.len(), 1); 60 | /// ``` 61 | #[cfg(feature = "alloc")] 62 | impl Truncate for Vec { 63 | type Input = usize; 64 | 65 | #[inline] 66 | fn truncate(&mut self, input: Self::Input) { 67 | self.truncate(input); 68 | } 69 | } 70 | 71 | /// ```rust 72 | /// let mut structure = cl_aux::doc_tests::array_string(); 73 | /// cl_aux::Truncate::truncate(&mut structure, 1); 74 | /// assert_eq!(structure.len(), 1); 75 | /// ``` 76 | #[cfg(feature = "arrayvec")] 77 | impl Truncate for arrayvec::ArrayString { 78 | type Input = usize; 79 | 80 | #[inline] 81 | fn truncate(&mut self, input: Self::Input) { 82 | self.truncate(input); 83 | } 84 | } 85 | 86 | /// ```rust 87 | /// let mut structure = cl_aux::doc_tests::array_vec(); 88 | /// cl_aux::Truncate::truncate(&mut structure, 1); 89 | /// assert_eq!(structure.len(), 1); 90 | /// ``` 91 | #[cfg(feature = "arrayvec")] 92 | impl Truncate for arrayvec::ArrayVec { 93 | type Input = usize; 94 | 95 | #[inline] 96 | fn truncate(&mut self, input: Self::Input) { 97 | self.truncate(input); 98 | } 99 | } 100 | 101 | /// ```rust 102 | /// let mut structure = cl_aux::doc_tests::small_vec(); 103 | /// cl_aux::Truncate::truncate(&mut structure, 1); 104 | /// assert_eq!(structure.len(), 1); 105 | /// ``` 106 | #[cfg(feature = "smallvec")] 107 | impl Truncate for smallvec::SmallVec 108 | where 109 | A: smallvec::Array, 110 | { 111 | type Input = usize; 112 | 113 | #[inline] 114 | fn truncate(&mut self, input: Self::Input) { 115 | self.truncate(input); 116 | } 117 | } 118 | 119 | /// ```rust 120 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 121 | /// cl_aux::Truncate::truncate(&mut structure, 1); 122 | /// assert_eq!(structure.len(), 1); 123 | /// ``` 124 | #[cfg(feature = "tinyvec")] 125 | impl Truncate for tinyvec::ArrayVec 126 | where 127 | A: tinyvec::Array, 128 | A::Item: Default, 129 | { 130 | type Input = usize; 131 | 132 | #[inline] 133 | fn truncate(&mut self, input: Self::Input) { 134 | self.truncate(input); 135 | } 136 | } 137 | 138 | /// ```rust 139 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 140 | /// cl_aux::Truncate::truncate(&mut structure, 1); 141 | /// assert_eq!(structure.len(), 1); 142 | /// ``` 143 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 144 | impl Truncate for tinyvec::TinyVec 145 | where 146 | A: tinyvec::Array, 147 | A::Item: Default, 148 | { 149 | type Input = usize; 150 | 151 | #[inline] 152 | fn truncate(&mut self, input: Self::Input) { 153 | self.truncate(input); 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /rust-tools/src/main.rs: -------------------------------------------------------------------------------- 1 | //! Rust tools 2 | 3 | #[macro_use] 4 | mod macros; 5 | 6 | mod action_option; 7 | mod actions; 8 | mod cfg; 9 | mod cfg_option; 10 | mod error; 11 | mod params; 12 | mod parse_cfg; 13 | mod transforming_params; 14 | 15 | use action_option::ActionOption; 16 | use actions::Actions; 17 | use cfg_option::CfgOption; 18 | use error::Error; 19 | use params::Params; 20 | use parse_cfg::parse_cfg; 21 | use std::{ 22 | env::{args, Args}, 23 | fs::File, 24 | io::{stderr, stdout, BufRead as _, BufReader, Write as _}, 25 | process::Command, 26 | }; 27 | use transforming_params::TransformingParams; 28 | 29 | type Result = core::result::Result; 30 | 31 | fn main() -> Result<()> { 32 | let mut args = args(); 33 | let _first_arg = arg(&mut args)?; 34 | let mut maybe_action = arg(&mut args)?; 35 | 36 | let mut param = |name: &str| { 37 | Ok::<_, Error>(if maybe_action == name { 38 | let rslt = arg(&mut args)?; 39 | maybe_action = arg(&mut args)?; 40 | rslt 41 | } else { 42 | <_>::default() 43 | }) 44 | }; 45 | 46 | let file = param("--file")?; 47 | let (mut params, mut tp) = 48 | if file.is_empty() { Default::default() } else { parse_cfg(File::open(file)?)? }; 49 | 50 | let template = param("--template")?; 51 | if !template.is_empty() { 52 | params = template.parse::()?.into_params(); 53 | } 54 | 55 | let toolchain = param("--toolchain")?; 56 | if !toolchain.is_empty() { 57 | tp.toolchain = toolchain; 58 | } 59 | 60 | parse_action(&mut args, &maybe_action, params, tp)?; 61 | 62 | Ok(()) 63 | } 64 | 65 | fn handle_cmd_output(cmd: &mut Command) -> Result<()> { 66 | let mut buffer = String::new(); 67 | let mut child = cmd.spawn()?; 68 | macro_rules! write_stdio { 69 | ($inner:expr, $output:expr) => { 70 | let mut br = BufReader::new($inner); 71 | while br.read_line(&mut buffer)? != 0 { 72 | $output.write_all(buffer.as_bytes())?; 73 | buffer.clear(); 74 | } 75 | }; 76 | } 77 | if let Some(ref mut child_stderr) = child.stderr { 78 | write_stdio!(child_stderr, stderr()); 79 | } 80 | if let Some(ref mut child_stdout) = child.stdout { 81 | write_stdio!(child_stdout, stdout()); 82 | } 83 | if !child.wait()?.success() { 84 | return Err(Error::FailedCommand); 85 | } 86 | Ok(()) 87 | } 88 | 89 | fn opt(args: &mut Args) -> String { 90 | args.next().unwrap_or_default() 91 | } 92 | 93 | fn parse_action( 94 | args: &mut Args, 95 | action_string: &str, 96 | params: Params, 97 | mut tp: TransformingParams, 98 | ) -> Result<()> { 99 | let mut actions = Actions::new(params); 100 | match action_string.parse()? { 101 | ActionOption::BuildGeneric => { 102 | actions.params.modify(&tp); 103 | actions.build_generic(arg(args)?)?; 104 | } 105 | ActionOption::BuildWithFeatures => { 106 | actions.params.modify(&tp); 107 | actions.build_with_features(arg(args)?, opt(args))?; 108 | } 109 | ActionOption::CheckGeneric => { 110 | actions.params.modify(&tp); 111 | actions.check_generic(arg(args)?)?; 112 | } 113 | ActionOption::CheckWithFeatures => { 114 | actions.params.modify(&tp); 115 | actions.check_with_features(arg(args)?, opt(args))?; 116 | } 117 | ActionOption::Clippy => { 118 | tp.add_clippy_flags.extend(opt(args).split(',').map(Into::into)); 119 | tp.rm_clippy_flags.extend(opt(args).split(',').map(Into::into)); 120 | actions.params.modify(&tp); 121 | actions.clippy(args)?; 122 | } 123 | ActionOption::RustFlags => { 124 | tp.add_rust_flags.extend(opt(args).split(',').map(Into::into)); 125 | tp.rm_rust_flags.extend(opt(args).split(',').map(Into::into)); 126 | actions.params.modify(&tp); 127 | actions.rust_flags()?; 128 | } 129 | ActionOption::Rustfmt => { 130 | actions.params.modify(&tp); 131 | Actions::rustfmt()?; 132 | } 133 | ActionOption::SetUp => { 134 | actions.params.modify(&tp); 135 | actions.set_up()?; 136 | } 137 | ActionOption::TargetDir => { 138 | actions.params.modify(&tp); 139 | Actions::target_dir()?; 140 | } 141 | ActionOption::TestGeneric => { 142 | actions.params.modify(&tp); 143 | actions.test_generic(arg(args)?)?; 144 | } 145 | ActionOption::TestWithFeatures => { 146 | actions.params.modify(&tp); 147 | actions.test_with_features(arg(args)?, opt(args))?; 148 | } 149 | } 150 | Ok(()) 151 | } 152 | 153 | fn arg(args: &mut Args) -> Result { 154 | args.next().ok_or(Error::WrongNumberOfArgs { expected: 1, received: 0 }) 155 | } 156 | -------------------------------------------------------------------------------- /cl-aux/src/traits/with_capacity.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::{string::String, vec::Vec}; 3 | 4 | /// See [`WithCapacity::with_capacity`] for more information. 5 | pub trait WithCapacity 6 | where 7 | Self: Sized, 8 | { 9 | /// Error 10 | type Error; 11 | /// Input 12 | type Input; 13 | 14 | /// Creates a new instance based on an initial holding capacity provided by `Input`. 15 | fn with_capacity(input: Self::Input) -> Result; 16 | } 17 | 18 | /// ```rust 19 | /// use cl_aux::Capacity; 20 | /// let structure: [i32; 5]; 21 | /// structure = cl_aux::WithCapacity::with_capacity(0).unwrap(); 22 | /// assert_eq!(structure.capacity(), 5); 23 | /// ``` 24 | impl WithCapacity for [T; N] 25 | where 26 | T: Default, 27 | { 28 | type Error = crate::Error; 29 | type Input = usize; 30 | 31 | #[inline] 32 | fn with_capacity(_: Self::Input) -> Result { 33 | Ok([(); N].map(|_| T::default())) 34 | } 35 | } 36 | 37 | /// ```rust 38 | /// let structure: String = cl_aux::WithCapacity::with_capacity(2).unwrap(); 39 | /// assert_eq!(structure.capacity(), 2); 40 | /// ``` 41 | #[cfg(feature = "alloc")] 42 | impl WithCapacity for String { 43 | type Error = crate::Error; 44 | type Input = usize; 45 | 46 | #[inline] 47 | fn with_capacity(input: Self::Input) -> Result { 48 | Ok(String::with_capacity(input)) 49 | } 50 | } 51 | 52 | /// ```rust 53 | /// let structure: Vec = cl_aux::WithCapacity::with_capacity(2).unwrap(); 54 | /// assert_eq!(structure.capacity(), 2); 55 | /// ``` 56 | #[cfg(feature = "alloc")] 57 | impl WithCapacity for Vec { 58 | type Error = crate::Error; 59 | type Input = usize; 60 | 61 | #[inline] 62 | fn with_capacity(input: Self::Input) -> Result { 63 | Ok(Vec::with_capacity(input)) 64 | } 65 | } 66 | 67 | /// ```rust 68 | /// let structure: arrayvec::ArrayString<5>; 69 | /// structure = cl_aux::WithCapacity::with_capacity(0).unwrap(); 70 | /// assert_eq!(structure.capacity(), 5); 71 | /// ``` 72 | #[cfg(feature = "arrayvec")] 73 | impl WithCapacity for arrayvec::ArrayString { 74 | type Error = crate::Error; 75 | type Input = usize; 76 | 77 | #[inline] 78 | fn with_capacity(_: Self::Input) -> Result { 79 | Ok(arrayvec::ArrayString::new()) 80 | } 81 | } 82 | 83 | /// ```rust 84 | /// let structure: arrayvec::ArrayVec; 85 | /// structure = cl_aux::WithCapacity::with_capacity(0).unwrap(); 86 | /// assert_eq!(structure.capacity(), 5); 87 | /// ``` 88 | #[cfg(feature = "arrayvec")] 89 | impl WithCapacity for arrayvec::ArrayVec { 90 | type Error = crate::Error; 91 | type Input = usize; 92 | 93 | #[inline] 94 | fn with_capacity(_: Self::Input) -> Result { 95 | Ok(arrayvec::ArrayVec::new()) 96 | } 97 | } 98 | 99 | /// ```rust 100 | /// let structure: smallvec::SmallVec<[i32; 5]>; 101 | /// structure = cl_aux::WithCapacity::with_capacity(0).unwrap(); 102 | /// assert_eq!(structure.capacity(), 5); 103 | /// ``` 104 | #[cfg(feature = "smallvec")] 105 | impl WithCapacity for smallvec::SmallVec 106 | where 107 | A: smallvec::Array, 108 | { 109 | type Error = crate::Error; 110 | type Input = usize; 111 | 112 | #[inline] 113 | fn with_capacity(input: Self::Input) -> Result { 114 | Ok(smallvec::SmallVec::with_capacity(input)) 115 | } 116 | } 117 | 118 | /// ```rust 119 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 120 | /// structure = cl_aux::WithCapacity::with_capacity(0).unwrap(); 121 | /// assert_eq!(structure.capacity(), 5); 122 | /// ``` 123 | #[cfg(feature = "tinyvec")] 124 | impl WithCapacity for tinyvec::ArrayVec 125 | where 126 | A: Default + tinyvec::Array, 127 | A::Item: Default, 128 | { 129 | type Error = crate::Error; 130 | type Input = usize; 131 | 132 | #[inline] 133 | fn with_capacity(_: Self::Input) -> Result { 134 | Ok(tinyvec::ArrayVec::new()) 135 | } 136 | } 137 | 138 | /// ```rust 139 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 140 | /// structure = cl_aux::WithCapacity::with_capacity(0).unwrap(); 141 | /// assert_eq!(structure.capacity(), 5); 142 | /// ``` 143 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 144 | impl WithCapacity for tinyvec::TinyVec 145 | where 146 | A: Default + tinyvec::Array, 147 | A::Item: Default, 148 | { 149 | type Error = crate::Error; 150 | type Input = usize; 151 | 152 | #[inline] 153 | fn with_capacity(input: Self::Input) -> Result { 154 | Ok(tinyvec::TinyVec::with_capacity(input)) 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /cl-aux/src/traits/swap.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::vec::Vec; 3 | 4 | /// See [`Swap::swap`] for more information. 5 | pub trait Swap { 6 | /// Error 7 | type Error; 8 | /// Input 9 | type Input; 10 | 11 | /// Swaps two elements referencied by `Input`. 12 | fn swap(&mut self, input: Self::Input) -> Result<(), Self::Error>; 13 | } 14 | 15 | impl Swap for &mut T 16 | where 17 | T: Swap, 18 | { 19 | type Error = T::Error; 20 | type Input = T::Input; 21 | 22 | #[inline] 23 | fn swap(&mut self, input: Self::Input) -> Result<(), Self::Error> { 24 | (*self).swap(input) 25 | } 26 | } 27 | 28 | /// ```rust 29 | /// let mut structure = cl_aux::doc_tests::array(); 30 | /// cl_aux::Swap::swap(&mut structure, [0, 2]); 31 | /// assert_eq!(structure.get(0), Some(&3)); 32 | /// assert_eq!(structure.get(2), Some(&1)); 33 | /// ``` 34 | impl Swap for [T; N] { 35 | type Error = crate::Error; 36 | type Input = [usize; 2]; 37 | 38 | #[inline] 39 | fn swap(&mut self, [a, b]: Self::Input) -> Result<(), Self::Error> { 40 | manage_slice(self, a, b) 41 | } 42 | } 43 | 44 | /// ```rust 45 | /// let mut structure = cl_aux::doc_tests::slice_mut!(); 46 | /// cl_aux::Swap::swap(&mut structure, [0, 2]); 47 | /// assert_eq!(structure.get(0), Some(&3)); 48 | /// assert_eq!(structure.get(2), Some(&1)); 49 | /// ``` 50 | impl Swap for &'_ mut [T] { 51 | type Error = crate::Error; 52 | type Input = [usize; 2]; 53 | 54 | #[inline] 55 | fn swap(&mut self, [a, b]: Self::Input) -> Result<(), Self::Error> { 56 | manage_slice(self, a, b) 57 | } 58 | } 59 | 60 | /// ```rust 61 | /// let mut structure = cl_aux::doc_tests::vec(); 62 | /// cl_aux::Swap::swap(&mut structure, [0, 2]); 63 | /// assert_eq!(structure.get(0), Some(&3)); 64 | /// assert_eq!(structure.get(2), Some(&1)); 65 | /// ``` 66 | #[cfg(feature = "alloc")] 67 | impl Swap for Vec { 68 | type Error = crate::Error; 69 | type Input = [usize; 2]; 70 | 71 | #[inline] 72 | fn swap(&mut self, [a, b]: Self::Input) -> Result<(), Self::Error> { 73 | manage_slice(self, a, b) 74 | } 75 | } 76 | 77 | /// ```rust 78 | /// let mut structure = cl_aux::doc_tests::array_vec(); 79 | /// cl_aux::Swap::swap(&mut structure, [0, 2]); 80 | /// assert_eq!(structure.get(0), Some(&3)); 81 | /// assert_eq!(structure.get(2), Some(&1)); 82 | /// ``` 83 | #[cfg(feature = "arrayvec")] 84 | impl Swap for arrayvec::ArrayVec { 85 | type Error = crate::Error; 86 | type Input = [usize; 2]; 87 | 88 | #[inline] 89 | fn swap(&mut self, [a, b]: Self::Input) -> Result<(), Self::Error> { 90 | manage_slice(self, a, b) 91 | } 92 | } 93 | 94 | /// ```rust 95 | /// let mut structure = cl_aux::doc_tests::small_vec(); 96 | /// cl_aux::Swap::swap(&mut structure, [0, 2]); 97 | /// assert_eq!(structure.get(0), Some(&3)); 98 | /// assert_eq!(structure.get(2), Some(&1)); 99 | /// ``` 100 | #[cfg(feature = "smallvec")] 101 | impl Swap for smallvec::SmallVec 102 | where 103 | A: smallvec::Array, 104 | { 105 | type Error = crate::Error; 106 | type Input = [usize; 2]; 107 | 108 | #[inline] 109 | fn swap(&mut self, [a, b]: Self::Input) -> Result<(), Self::Error> { 110 | manage_slice(self, a, b) 111 | } 112 | } 113 | 114 | /// ```rust 115 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 116 | /// cl_aux::Swap::swap(&mut structure, [0, 2]); 117 | /// assert_eq!(structure.get(0), Some(&3)); 118 | /// assert_eq!(structure.get(2), Some(&1)); 119 | /// ``` 120 | #[cfg(feature = "tinyvec")] 121 | impl Swap for tinyvec::ArrayVec 122 | where 123 | A: tinyvec::Array, 124 | A::Item: Default, 125 | { 126 | type Error = crate::Error; 127 | type Input = [usize; 2]; 128 | 129 | #[inline] 130 | fn swap(&mut self, [a, b]: Self::Input) -> Result<(), Self::Error> { 131 | manage_slice(self, a, b) 132 | } 133 | } 134 | 135 | /// ```rust 136 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 137 | /// cl_aux::Swap::swap(&mut structure, [0, 2]); 138 | /// assert_eq!(structure.get(0), Some(&3)); 139 | /// assert_eq!(structure.get(2), Some(&1)); 140 | /// ``` 141 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 142 | impl Swap for tinyvec::TinyVec 143 | where 144 | A: tinyvec::Array, 145 | A::Item: Default, 146 | { 147 | type Error = crate::Error; 148 | type Input = [usize; 2]; 149 | 150 | #[inline] 151 | fn swap(&mut self, [a, b]: Self::Input) -> Result<(), Self::Error> { 152 | manage_slice(self, a, b) 153 | } 154 | } 155 | 156 | fn manage_slice(slice: &mut [T], a: usize, b: usize) -> crate::Result<()> { 157 | _check_indcs!(&slice, a, b); 158 | slice.as_mut().swap(a, b); 159 | Ok(()) 160 | } 161 | -------------------------------------------------------------------------------- /ndstruct/src/dense.rs: -------------------------------------------------------------------------------- 1 | //! Dense 2 | //! 3 | //! A fully filled contiguous space of memory. If 1d, then this structure is the same as a vector; 4 | //! if 2d, then this structure is the same as a matrix; if 3d, then this structure is the same as 5 | //! a cube and so on for higher dimensions. 6 | 7 | mod dense_error; 8 | 9 | #[cfg(feature = "alloc")] 10 | use alloc::vec::Vec; 11 | use cl_aux::{ArrayWrapper, SingleTypeStorage}; 12 | pub use dense_error::*; 13 | 14 | /// Dense backed by a static array. 15 | pub type DenseArray = Dense<[DATA; DN], D>; 16 | /// Dense backed by a mutable slice 17 | pub type DenseMut<'data, DATA, const D: usize> = Dense<&'data mut [DATA], D>; 18 | /// Dense backed by a slice 19 | pub type DenseRef<'data, DATA, const D: usize> = Dense<&'data [DATA], D>; 20 | #[cfg(feature = "alloc")] 21 | /// Dense backed by a dynamic vector. 22 | pub type DenseVec = Dense, D>; 23 | 24 | /// Base structure for all [Dense] variants. 25 | /// 26 | /// # Types 27 | /// 28 | /// * `D`: Number of dimensions 29 | /// * `DS`: Data Storage 30 | #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] 31 | #[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] 32 | pub struct Dense { 33 | pub(crate) data: DS, 34 | pub(crate) dims: ArrayWrapper, 35 | } 36 | 37 | impl Dense { 38 | /// The definitions of all dimensions. 39 | /// 40 | /// # Example 41 | /// 42 | /// ```rust 43 | /// use ndstruct::doc_tests::dense_array_3; 44 | /// assert_eq!(dense_array_3().dims(), &[4, 3, 3]); 45 | /// ``` 46 | #[inline] 47 | pub fn dims(&self) -> &[usize; D] { 48 | &self.dims 49 | } 50 | } 51 | 52 | impl Dense 53 | where 54 | DS: AsRef<[::Item]> + SingleTypeStorage, 55 | { 56 | /// Creates a valid [Dense] instance. 57 | /// 58 | /// # Arguments 59 | /// 60 | /// * `dims`: Array of dimensions 61 | /// * `data`: Data collection 62 | /// 63 | /// # Example 64 | #[cfg_attr(feature = "alloc", doc = "```rust")] 65 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 66 | /// use ndstruct::dense::{DenseArray, DenseVec}; 67 | /// // Matrix ([1, 2, 3], [4, 5, 6]) 68 | /// let mut _matrix = DenseArray::new([2, 3], [1, 2, 3, 4, 5, 6]); 69 | /// // A bunch of nothing for your overflow needs 70 | /// let _over_nine: ndstruct::Result>; 71 | /// _over_nine = DenseVec::new([0; 9001], vec![]); 72 | /// ``` 73 | #[inline] 74 | pub fn new(dims: [usize; D], data: DS) -> crate::Result { 75 | if dims.iter().copied().any(|elem| elem >= D) { 76 | return Err(DenseError::InvalidIndcs.into()); 77 | } 78 | Ok(Self { data, dims: dims.into() }) 79 | } 80 | 81 | /// The data that is being stored. 82 | /// 83 | /// # Example 84 | /// 85 | /// ```rust 86 | /// use ndstruct::doc_tests::dense_array_3; 87 | /// assert_eq!(dense_array_3().data(), &[ 88 | /// 1, 2, 3, 4, 5, 6, 7, 8, 9, 89 | /// 10, 11, 12, 13, 14, 15, 16, 17, 18, 90 | /// 19, 20, 21, 22, 23, 24, 25, 26, 27, 91 | /// 28, 29, 30, 31, 32, 33, 34, 35, 36, 92 | /// ]); 93 | /// ``` 94 | #[inline] 95 | pub fn data(&self) -> &[DATA] { 96 | self.data.as_ref() 97 | } 98 | 99 | /// If any, retrieves an immutable data reference of a given set of indices. 100 | /// 101 | /// # Arguments 102 | /// 103 | /// * `indcs`: Indices of the desired data location 104 | /// 105 | /// # Example 106 | /// 107 | /// ```rust 108 | /// use ndstruct::doc_tests::dense_array_3; 109 | /// let elem = dense_array_3(); 110 | /// assert_eq!(elem.value([0, 0, 0]), Some(&1)); 111 | /// assert_eq!(elem.value([0, 0, 2]), Some(&3)); 112 | /// assert_eq!(elem.value([0, 2, 2]), Some(&9)); 113 | /// assert_eq!(elem.value([3, 2, 2]), Some(&36)); 114 | /// assert_eq!(elem.value([3, 2, 3]), None); 115 | /// ``` 116 | #[inline] 117 | pub fn value(&self, indcs: [usize; D]) -> Option<&DATA> { 118 | self.data().get(self.idx(indcs)) 119 | } 120 | 121 | // 1 * rows * cols * z 122 | // 1 * rows * y 123 | // 1 * x 124 | fn dim_stride(&self, dim_idx: usize, target_dim_idx: usize) -> usize { 125 | self.dims.iter().copied().skip(1).rev().skip(dim_idx).chain([target_dim_idx]).product() 126 | } 127 | 128 | fn idx(&self, indcs: [usize; D]) -> usize { 129 | let mut rslt: usize = 0; 130 | for (dim_idx, target_dim_idx) in (0..self.dims.len()).zip(indcs) { 131 | rslt = rslt.wrapping_add(self.dim_stride(dim_idx, target_dim_idx)); 132 | } 133 | rslt 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /ndstruct/src/csl/csl_line_iter.rs: -------------------------------------------------------------------------------- 1 | use crate::csl::{csl_utils::outermost_offs, CslError, CslMut, CslRef}; 2 | use core::mem; 3 | 4 | macro_rules! impl_iter { 5 | ($csl_iter:ident, $data_type:ty, $split_at:ident, $ref:ident) => { 6 | /// Iterator of a CSL dimension. 7 | #[derive(Debug, Eq, PartialEq)] 8 | pub struct $csl_iter<'slices, T, const D: usize> { 9 | curr_idx: usize, 10 | data: $data_type, 11 | dims: [usize; D], 12 | indcs: &'slices [usize], 13 | max_idx: usize, 14 | offs: &'slices [usize], 15 | } 16 | 17 | impl<'slices, T, const D: usize> $csl_iter<'slices, T, D> { 18 | pub(crate) fn new( 19 | mut dims: [usize; D], 20 | data: $data_type, 21 | indcs: &'slices [usize], 22 | offs: &'slices [usize], 23 | ) -> crate::Result { 24 | if let Some(r) = dims.first_mut() { 25 | let max_idx = *r; 26 | *r = 1; 27 | Ok($csl_iter { curr_idx: 0, data, dims, indcs, max_idx, offs }) 28 | } else { 29 | Err(CslError::InvalidIterDim.into()) 30 | } 31 | } 32 | 33 | #[cfg(feature = "rayon")] 34 | pub(crate) fn split_at(self, idx: usize) -> Option<[Self; 2]> { 35 | let cut_point = self.curr_idx.checked_add(idx)?; 36 | let [_, values] = outermost_offs(&self.dims, self.offs, self.curr_idx..cut_point); 37 | let values_diff = values.end.checked_sub(values.start)?; 38 | let (data_head, data_tail) = self.data.$split_at(values_diff); 39 | let (indcs_head, indcs_tail) = self.indcs.split_at(values_diff); 40 | Some([ 41 | $csl_iter { 42 | curr_idx: self.curr_idx, 43 | data: data_head, 44 | dims: self.dims, 45 | indcs: indcs_head, 46 | max_idx: cut_point, 47 | offs: self.offs, 48 | }, 49 | $csl_iter { 50 | curr_idx: cut_point, 51 | data: data_tail, 52 | dims: self.dims, 53 | indcs: indcs_tail, 54 | max_idx: self.max_idx, 55 | offs: self.offs, 56 | }, 57 | ]) 58 | } 59 | } 60 | 61 | impl DoubleEndedIterator for $csl_iter<'_, T, D> { 62 | #[inline] 63 | fn next_back(&mut self) -> Option { 64 | if self.curr_idx == 0 { 65 | return None; 66 | } 67 | let curr_idx_less_one = self.curr_idx.checked_sub(1)?; 68 | let range = curr_idx_less_one..self.curr_idx; 69 | self.curr_idx = curr_idx_less_one; 70 | let [indcs, values] = outermost_offs(&self.dims, self.offs, range); 71 | let data = mem::take(&mut self.data); 72 | let values_diff = values.end.checked_sub(values.start)?; 73 | let (data_head, data_tail) = data.$split_at(values_diff); 74 | let (indcs_head, indcs_tail) = self.indcs.split_at(values_diff); 75 | self.data = data_tail; 76 | self.indcs = indcs_tail; 77 | Some($ref { 78 | data: data_head, 79 | dims: self.dims.into(), 80 | indcs: indcs_head, 81 | offs: self.offs.get(indcs)?, 82 | }) 83 | } 84 | } 85 | 86 | impl ExactSizeIterator for $csl_iter<'_, T, D> {} 87 | 88 | impl<'slices, T, const D: usize> Iterator for $csl_iter<'slices, T, D> { 89 | type Item = $ref<'slices, T, D>; 90 | 91 | #[inline] 92 | fn next(&mut self) -> Option { 93 | if self.curr_idx >= self.max_idx { 94 | return None; 95 | } 96 | let curr_idx_plus_one = self.curr_idx.checked_add(1)?; 97 | let range = self.curr_idx..curr_idx_plus_one; 98 | self.curr_idx = curr_idx_plus_one; 99 | let [indcs, values] = outermost_offs(&self.dims, self.offs, range); 100 | let data = mem::take(&mut self.data); 101 | let values_diff = values.end.checked_sub(values.start)?; 102 | let (data_head, data_tail) = data.$split_at(values_diff); 103 | let (indcs_head, indcs_tail) = self.indcs.split_at(values_diff); 104 | self.data = data_tail; 105 | self.indcs = indcs_tail; 106 | Some($ref { 107 | data: data_head, 108 | dims: self.dims.into(), 109 | indcs: indcs_head, 110 | offs: self.offs.get(indcs)?, 111 | }) 112 | } 113 | 114 | #[inline] 115 | fn size_hint(&self) -> (usize, Option) { 116 | (self.max_idx, Some(self.max_idx)) 117 | } 118 | } 119 | }; 120 | } 121 | 122 | impl_iter!(CslLineIterMut, &'slices mut [T], split_at_mut, CslMut); 123 | impl_iter!(CslLineIterRef, &'slices [T], split_at, CslRef); 124 | -------------------------------------------------------------------------------- /cl-aux/src/traits/capacity.rs: -------------------------------------------------------------------------------- 1 | use crate::SingleItemStorage; 2 | #[cfg(feature = "alloc")] 3 | use alloc::{string::String, vec::Vec}; 4 | 5 | /// See [`Capacity::capacity`] for more information. 6 | pub trait Capacity { 7 | /// The number of elements the implementation has pre-allocated as an internal buffer. Not 8 | /// necessarily the current number of inserted elements. 9 | fn capacity(&self) -> usize; 10 | } 11 | 12 | impl Capacity for &T 13 | where 14 | T: Capacity, 15 | { 16 | #[inline] 17 | fn capacity(&self) -> usize { 18 | (*self).capacity() 19 | } 20 | } 21 | 22 | /// ```rust 23 | /// assert_eq!(cl_aux::Capacity::capacity(&()), 0); 24 | /// ``` 25 | impl Capacity for () { 26 | #[inline] 27 | fn capacity(&self) -> usize { 28 | 0 29 | } 30 | } 31 | 32 | /// ```rust 33 | /// assert_eq!(cl_aux::Capacity::capacity(&Some(0)), 1); 34 | /// ``` 35 | impl Capacity for Option { 36 | #[inline] 37 | fn capacity(&self) -> usize { 38 | 1 39 | } 40 | } 41 | 42 | /// ```rust 43 | /// let mut structure = cl_aux::doc_tests::single_item_storage(); 44 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 1); 45 | /// ``` 46 | impl Capacity for SingleItemStorage { 47 | #[inline] 48 | fn capacity(&self) -> usize { 49 | 1 50 | } 51 | } 52 | 53 | /// ```rust 54 | /// let mut structure = cl_aux::doc_tests::array(); 55 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 3); 56 | /// ``` 57 | impl Capacity for [T; N] { 58 | #[inline] 59 | fn capacity(&self) -> usize { 60 | N 61 | } 62 | } 63 | 64 | /// ```rust 65 | /// let structure = cl_aux::doc_tests::slice(); 66 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 67 | /// ``` 68 | impl Capacity for &'_ [T] { 69 | #[inline] 70 | fn capacity(&self) -> usize { 71 | self.len() 72 | } 73 | } 74 | 75 | /// ```rust 76 | /// let mut structure = cl_aux::doc_tests::slice_mut!(); 77 | /// assert_eq!(cl_aux::Length::length(&mut structure), 3); 78 | /// ``` 79 | impl Capacity for &'_ mut [T] { 80 | #[inline] 81 | fn capacity(&self) -> usize { 82 | self.len() 83 | } 84 | } 85 | 86 | /// ```rust 87 | /// let mut structure = cl_aux::doc_tests::string(); 88 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 5); 89 | /// ``` 90 | #[cfg(feature = "alloc")] 91 | impl Capacity for String { 92 | #[inline] 93 | fn capacity(&self) -> usize { 94 | self.capacity() 95 | } 96 | } 97 | 98 | /// ```rust 99 | /// let mut structure = cl_aux::doc_tests::vec(); 100 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 5); 101 | /// ``` 102 | #[cfg(feature = "alloc")] 103 | impl Capacity for Vec { 104 | #[inline] 105 | fn capacity(&self) -> usize { 106 | self.capacity() 107 | } 108 | } 109 | 110 | /// ```rust 111 | /// let mut structure = cl_aux::doc_tests::array_string(); 112 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 10); 113 | /// ``` 114 | #[cfg(feature = "arrayvec")] 115 | impl Capacity for arrayvec::ArrayString { 116 | #[inline] 117 | fn capacity(&self) -> usize { 118 | self.capacity() 119 | } 120 | } 121 | 122 | /// ```rust 123 | /// let mut structure = cl_aux::doc_tests::array_vec(); 124 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 5); 125 | /// ``` 126 | #[cfg(feature = "arrayvec")] 127 | impl Capacity for arrayvec::ArrayVec { 128 | #[inline] 129 | fn capacity(&self) -> usize { 130 | self.capacity() 131 | } 132 | } 133 | 134 | /// ```rust 135 | /// let mut structure = cl_aux::doc_tests::small_vec(); 136 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 5); 137 | /// ``` 138 | #[cfg(feature = "smallvec")] 139 | impl Capacity for smallvec::SmallVec 140 | where 141 | A: smallvec::Array, 142 | { 143 | #[inline] 144 | fn capacity(&self) -> usize { 145 | self.capacity() 146 | } 147 | } 148 | 149 | /// ```rust 150 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 151 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 5); 152 | /// ``` 153 | #[cfg(feature = "tinyvec")] 154 | impl Capacity for tinyvec::ArrayVec 155 | where 156 | A: tinyvec::Array, 157 | A::Item: Default, 158 | { 159 | #[inline] 160 | fn capacity(&self) -> usize { 161 | self.capacity() 162 | } 163 | } 164 | 165 | /// ```rust 166 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 167 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 5); 168 | /// ``` 169 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 170 | impl Capacity for tinyvec::TinyVec 171 | where 172 | A: tinyvec::Array, 173 | A::Item: Default, 174 | { 175 | #[inline] 176 | fn capacity(&self) -> usize { 177 | self.capacity() 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /ndstruct/src/csl/csl_error.rs: -------------------------------------------------------------------------------- 1 | use core::fmt::{Debug, Display, Formatter}; 2 | 3 | /// Any error related to Csl operations 4 | #[derive(Debug, Eq, PartialEq)] 5 | #[non_exhaustive] 6 | pub enum CslError { 7 | /// Data or indices length is greater than the product of all dimensions length 8 | /// 9 | #[cfg_attr(feature = "alloc", doc = "```rust")] 10 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 11 | /// use ndstruct::csl::{CslError, CslVec}; 12 | /// let csl = CslVec::new([3], vec![8, 9, 9, 9, 9], vec![0, 5, 5, 5, 5], vec![0, 2]); 13 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::DataIndcsLengthGreaterThanDimsLength))); 14 | /// ``` 15 | DataIndcsLengthGreaterThanDimsLength, 16 | 17 | /// The data length is different than the indices length 18 | /// 19 | #[cfg_attr(feature = "alloc", doc = "```rust")] 20 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 21 | /// use ndstruct::csl::{ CslError, CslVec}; 22 | /// let csl = CslVec::new([10], vec![8, 9], vec![0], vec![0, 2]); 23 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::DiffDataIndcsLength))); 24 | /// ``` 25 | DiffDataIndcsLength, 26 | 27 | /// Duplicated indices in a line 28 | /// ```rust 29 | /// use ndstruct::csl::{CslArray, CslError}; 30 | /// let csl = CslArray::new([10], [8, 9], [0, 0], [0, 2]); 31 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::DuplicatedIndices))); 32 | /// ``` 33 | DuplicatedIndices, 34 | 35 | /// A index is greater or equal to the innermost dimension length 36 | /// 37 | /// ```rust 38 | /// use ndstruct::csl::{CslArray, CslError}; 39 | /// let csl = CslArray::new([10], [8, 9], [0, 10], [0, 2]); 40 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::IndcsGreaterThanEqualDimLength))); 41 | /// ``` 42 | IndcsGreaterThanEqualDimLength, 43 | 44 | /// Some innermost dimension length is equal to zero 45 | #[cfg_attr(feature = "alloc", doc = "```rust")] 46 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 47 | /// use ndstruct::csl::{CslError, CslVec}; 48 | /// let csl: ndstruct::Result>; 49 | /// csl = CslVec::new([1, 2, 3, 0, 5], vec![], vec![], vec![]); 50 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::InnermostDimsZero))); 51 | /// ``` 52 | InnermostDimsZero, 53 | 54 | /// Line iterator must deal with non-empty dimensions 55 | #[cfg_attr(feature = "alloc", doc = "```rust")] 56 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 57 | /// use ndstruct::csl::{CslVec, CslError}; 58 | /// let csl = CslVec::::default(); 59 | /// assert_eq!(csl.outermost_line_iter(), Err(ndstruct::Error::Csl(CslError::InvalidIterDim))); 60 | /// ``` 61 | InvalidIterDim, 62 | 63 | /// Offsets length is different than the dimensions product 64 | /// (without the innermost dimension) plus one. 65 | /// This rule doesn't not apply to an empty dimension. 66 | #[cfg_attr(feature = "alloc", doc = "```rust")] 67 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 68 | /// use ndstruct::csl::{CslError, CslVec}; 69 | /// let csl = CslVec::new([10], vec![8, 9], vec![0, 5], vec![0, 2, 4]); 70 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::InvalidOffsetsLength))); 71 | /// ``` 72 | InvalidOffsetsLength, 73 | 74 | /// Offsets aren't in ascending order 75 | /// 76 | /// ```rust 77 | /// use ndstruct::csl::{CslArray, CslError}; 78 | /// let csl = CslArray::new([10], [8, 9], [0, 5], [2, 0]); 79 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::InvalidOffsetsOrder))); 80 | /// ``` 81 | InvalidOffsetsOrder, 82 | 83 | /// Last offset is not equal to the nnz 84 | /// 85 | /// ```rust 86 | /// use ndstruct::csl::{CslArray, CslError}; 87 | /// let csl = CslArray::new([10], [8, 9], [0, 5], [0, 4]); 88 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::LastOffsetDifferentNnz))); 89 | /// ``` 90 | LastOffsetDifferentNnz, 91 | 92 | /// nnz is greater than the maximum permitted number of nnz 93 | #[cfg_attr(all(feature = "alloc", feature = "rand"), doc = "```rust")] 94 | #[cfg_attr(not(all(feature = "alloc", feature = "rand")), doc = "```ignore")] 95 | /// use ndstruct::csl::CslVec; 96 | /// use rand::{Rng, rngs::mock::StepRng}; 97 | /// let mut rng = StepRng::new(0, 1); 98 | /// let dims = [1, 2, 3]; // Max of 6 elements (1 * 2 * 3) 99 | /// let csl: ndstruct::Result>; 100 | /// csl = CslVec::new_controlled_random_rand(dims, 7, &mut rng, |r, _| r.gen()); 101 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(ndstruct::csl::CslError::NnzGreaterThanMaximumNnz))); 102 | /// ``` 103 | #[cfg(feature = "rand")] 104 | NnzGreaterThanMaximumNnz, 105 | 106 | /// It isn't possible to have more lines than [`usize::MAX`] - 2 107 | /// 108 | /// ```rust 109 | /// use ndstruct::csl::{CslArray, CslError}; 110 | /// let csl = CslArray::new([18446744073709551295, 255, 3026418949592973312], [0], [0], [0, 1]); 111 | /// assert_eq!(csl, Err(ndstruct::Error::Csl(CslError::OffsLengthOverflow))); 112 | /// ``` 113 | OffsLengthOverflow, 114 | } 115 | 116 | impl Display for CslError { 117 | #[inline] 118 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 119 | Debug::fmt(self, f) 120 | } 121 | } 122 | 123 | impl core::error::Error for CslError {} 124 | -------------------------------------------------------------------------------- /cl-aux/src/traits/capacity_upper_bound.rs: -------------------------------------------------------------------------------- 1 | use crate::SingleItemStorage; 2 | #[cfg(feature = "alloc")] 3 | use alloc::{string::String, vec::Vec}; 4 | 5 | /// See [`CapacityUpperBound::capacity_upper_bound`] for more information. 6 | pub trait CapacityUpperBound { 7 | /// The maximum theoretical number of elements a type implementation is able to store. 8 | const CAPACITY_UPPER_BOUND: usize; 9 | 10 | /// Instance method representing [`Self::CAPACITY_UPPER_BOUND`]. 11 | #[inline] 12 | fn capacity_upper_bound(&self) -> usize { 13 | Self::CAPACITY_UPPER_BOUND 14 | } 15 | } 16 | 17 | impl CapacityUpperBound for &T 18 | where 19 | T: CapacityUpperBound, 20 | { 21 | const CAPACITY_UPPER_BOUND: usize = T::CAPACITY_UPPER_BOUND; 22 | 23 | #[inline] 24 | fn capacity_upper_bound(&self) -> usize { 25 | (*self).capacity_upper_bound() 26 | } 27 | } 28 | 29 | /// ```rust 30 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&()), 0); 31 | /// ``` 32 | impl CapacityUpperBound for () { 33 | const CAPACITY_UPPER_BOUND: usize = 0; 34 | } 35 | 36 | /// ```rust 37 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&Some(0)), 1); 38 | /// ``` 39 | impl CapacityUpperBound for Option { 40 | const CAPACITY_UPPER_BOUND: usize = 1; 41 | } 42 | 43 | /// ```rust 44 | /// let mut structure = cl_aux::doc_tests::single_item_storage(); 45 | /// assert_eq!(cl_aux::Capacity::capacity(&structure), 1); 46 | /// ``` 47 | impl CapacityUpperBound for SingleItemStorage { 48 | const CAPACITY_UPPER_BOUND: usize = 1; 49 | } 50 | 51 | /// ```rust 52 | /// let mut structure = cl_aux::doc_tests::array(); 53 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 3); 54 | /// ``` 55 | impl CapacityUpperBound for [T; N] { 56 | const CAPACITY_UPPER_BOUND: usize = N; 57 | } 58 | 59 | /// ```rust 60 | /// let structure = cl_aux::doc_tests::slice(); 61 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 2305843009213693951); 62 | /// ``` 63 | impl CapacityUpperBound for &'_ [T] { 64 | const CAPACITY_UPPER_BOUND: usize = capacity_upper_bound_of_type::(); 65 | } 66 | 67 | /// ```rust 68 | /// let mut structure = cl_aux::doc_tests::slice_mut!(); 69 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&mut structure), 2305843009213693951); 70 | /// ``` 71 | impl CapacityUpperBound for &'_ mut [T] { 72 | const CAPACITY_UPPER_BOUND: usize = capacity_upper_bound_of_type::(); 73 | } 74 | 75 | /// ```rust 76 | /// let mut structure = cl_aux::doc_tests::string(); 77 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 9223372036854775807); 78 | /// ``` 79 | #[cfg(feature = "alloc")] 80 | impl CapacityUpperBound for String { 81 | const CAPACITY_UPPER_BOUND: usize = capacity_upper_bound_of_type::(); 82 | } 83 | 84 | /// ```rust 85 | /// let mut structure = cl_aux::doc_tests::vec(); 86 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 2305843009213693951); 87 | /// ``` 88 | #[cfg(feature = "alloc")] 89 | impl CapacityUpperBound for Vec { 90 | const CAPACITY_UPPER_BOUND: usize = capacity_upper_bound_of_type::(); 91 | } 92 | 93 | /// ```rust 94 | /// let mut structure = cl_aux::doc_tests::array_string(); 95 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 10); 96 | /// ``` 97 | #[cfg(feature = "arrayvec")] 98 | impl CapacityUpperBound for arrayvec::ArrayString { 99 | const CAPACITY_UPPER_BOUND: usize = N; 100 | } 101 | 102 | /// ```rust 103 | /// let mut structure = cl_aux::doc_tests::array_vec(); 104 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 5); 105 | /// ``` 106 | #[cfg(feature = "arrayvec")] 107 | impl CapacityUpperBound for arrayvec::ArrayVec { 108 | const CAPACITY_UPPER_BOUND: usize = N; 109 | } 110 | 111 | /// ```rust 112 | /// let mut structure = cl_aux::doc_tests::small_vec(); 113 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 2305843009213693951); 114 | /// ``` 115 | #[cfg(feature = "smallvec")] 116 | impl CapacityUpperBound for smallvec::SmallVec 117 | where 118 | A: smallvec::Array, 119 | { 120 | const CAPACITY_UPPER_BOUND: usize = capacity_upper_bound_of_type::(); 121 | } 122 | 123 | /// ```rust 124 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 125 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 5); 126 | /// ``` 127 | #[cfg(feature = "tinyvec")] 128 | impl CapacityUpperBound for tinyvec::ArrayVec 129 | where 130 | A: tinyvec::Array, 131 | A::Item: Default, 132 | { 133 | const CAPACITY_UPPER_BOUND: usize = A::CAPACITY; 134 | } 135 | 136 | /// ```rust 137 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 138 | /// assert_eq!(cl_aux::CapacityUpperBound::capacity_upper_bound(&structure), 2305843009213693951); 139 | /// ``` 140 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 141 | impl CapacityUpperBound for tinyvec::TinyVec 142 | where 143 | A: tinyvec::Array, 144 | A::Item: Default, 145 | { 146 | const CAPACITY_UPPER_BOUND: usize = capacity_upper_bound_of_type::(); 147 | } 148 | 149 | #[inline] 150 | const fn capacity_upper_bound_of_type() -> usize { 151 | let isize_max_usize = isize::MAX.unsigned_abs(); 152 | if let Some(elem) = isize_max_usize.checked_div(size_of::()) { 153 | elem 154 | } else { 155 | 0 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /cl-aux/src/traits/get_mut.rs: -------------------------------------------------------------------------------- 1 | use crate::SingleItemStorage; 2 | #[cfg(feature = "alloc")] 3 | use alloc::vec::Vec; 4 | 5 | /// See [`GetMut::get_mut`] for more information. 6 | pub trait GetMut { 7 | /// Error 8 | type Error; 9 | /// Input 10 | type Input; 11 | /// Output 12 | type Output<'output> 13 | where 14 | Self: 'output; 15 | 16 | /// Returns an mutable inner reference of a derived element. 17 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error>; 18 | } 19 | 20 | impl GetMut for &mut T 21 | where 22 | T: GetMut, 23 | { 24 | type Error = T::Error; 25 | type Input = T::Input; 26 | type Output<'output> 27 | = T::Output<'output> 28 | where 29 | Self: 'output; 30 | 31 | #[inline] 32 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 33 | (*self).get_mut(input) 34 | } 35 | } 36 | 37 | /// ```rust 38 | /// let mut structure = cl_aux::doc_tests::single_item_storage(); 39 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 40 | /// ``` 41 | impl GetMut for SingleItemStorage { 42 | type Error = crate::Error; 43 | type Input = usize; 44 | type Output<'output> 45 | = &'output mut T 46 | where 47 | Self: 'output; 48 | 49 | #[inline] 50 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 51 | _get_mut!(self.as_mut(), input) 52 | } 53 | } 54 | 55 | /// ```rust 56 | /// let mut structure = cl_aux::doc_tests::array(); 57 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 58 | /// ``` 59 | impl GetMut for [T; N] { 60 | type Error = crate::Error; 61 | type Input = usize; 62 | type Output<'output> 63 | = &'output mut T 64 | where 65 | Self: 'output; 66 | 67 | #[inline] 68 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 69 | _get_mut!(self.as_mut(), input) 70 | } 71 | } 72 | 73 | /// ```rust 74 | /// let mut structure = cl_aux::doc_tests::slice_mut!(); 75 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 76 | /// ``` 77 | impl GetMut for &'_ mut [T] { 78 | type Error = crate::Error; 79 | type Input = usize; 80 | type Output<'output> 81 | = &'output mut T 82 | where 83 | Self: 'output; 84 | 85 | #[inline] 86 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 87 | _get_mut!(self.as_mut(), input) 88 | } 89 | } 90 | 91 | /// ```rust 92 | /// let mut structure = cl_aux::doc_tests::vec(); 93 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 94 | /// ``` 95 | #[cfg(feature = "alloc")] 96 | impl GetMut for Vec { 97 | type Error = crate::Error; 98 | type Input = usize; 99 | type Output<'output> 100 | = &'output mut T 101 | where 102 | Self: 'output; 103 | 104 | #[inline] 105 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 106 | _get_mut!(self.as_mut_slice(), input) 107 | } 108 | } 109 | 110 | /// ```rust 111 | /// let mut structure = cl_aux::doc_tests::array_vec(); 112 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 113 | /// ``` 114 | #[cfg(feature = "arrayvec")] 115 | impl GetMut for arrayvec::ArrayVec { 116 | type Error = crate::Error; 117 | type Input = usize; 118 | type Output<'output> 119 | = &'output mut T 120 | where 121 | Self: 'output; 122 | 123 | #[inline] 124 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 125 | _get_mut!(self.as_mut(), input) 126 | } 127 | } 128 | 129 | /// ```rust 130 | /// let mut structure = cl_aux::doc_tests::small_vec(); 131 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 132 | /// ``` 133 | #[cfg(feature = "smallvec")] 134 | impl GetMut for smallvec::SmallVec 135 | where 136 | A: smallvec::Array, 137 | { 138 | type Error = crate::Error; 139 | type Input = usize; 140 | type Output<'output> 141 | = &'output mut A::Item 142 | where 143 | Self: 'output; 144 | 145 | #[inline] 146 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 147 | _get_mut!(self.as_mut(), input) 148 | } 149 | } 150 | 151 | /// ```rust 152 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 153 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 154 | /// ``` 155 | #[cfg(feature = "tinyvec")] 156 | impl GetMut for tinyvec::ArrayVec 157 | where 158 | A: tinyvec::Array, 159 | { 160 | type Error = crate::Error; 161 | type Input = usize; 162 | type Output<'output> 163 | = &'output mut A::Item 164 | where 165 | Self: 'output; 166 | 167 | #[inline] 168 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 169 | _get_mut!(self.as_mut(), input) 170 | } 171 | } 172 | 173 | /// ```rust 174 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 175 | /// assert_eq!(cl_aux::GetMut::get_mut(&mut structure, 0), Ok(&mut 1)); 176 | /// ``` 177 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 178 | impl GetMut for tinyvec::TinyVec 179 | where 180 | A: tinyvec::Array, 181 | A::Item: Default, 182 | { 183 | type Error = crate::Error; 184 | type Input = usize; 185 | type Output<'output> 186 | = &'output mut A::Item 187 | where 188 | Self: 'output; 189 | 190 | #[inline] 191 | fn get_mut(&mut self, input: Self::Input) -> Result, Self::Error> { 192 | _get_mut!(self.as_mut(), input) 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /cl-aux/src/traits/get.rs: -------------------------------------------------------------------------------- 1 | use crate::SingleItemStorage; 2 | #[cfg(feature = "alloc")] 3 | use alloc::vec::Vec; 4 | 5 | /// See [`Get::get`] for more information. 6 | pub trait Get { 7 | /// Error 8 | type Error; 9 | /// Input 10 | type Input; 11 | /// Output 12 | type Output<'output> 13 | where 14 | Self: 'output; 15 | 16 | /// Returns an immutable inner reference of a derived element. 17 | fn get(&self, input: Self::Input) -> Result, Self::Error>; 18 | } 19 | 20 | impl Get for &T 21 | where 22 | T: Get, 23 | { 24 | type Error = T::Error; 25 | type Input = T::Input; 26 | type Output<'output> 27 | = T::Output<'output> 28 | where 29 | Self: 'output; 30 | 31 | #[inline] 32 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 33 | (*self).get(input) 34 | } 35 | } 36 | 37 | /// ```rust 38 | /// let structure = cl_aux::doc_tests::single_item_storage(); 39 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 40 | /// ``` 41 | impl Get for SingleItemStorage { 42 | type Error = crate::Error; 43 | type Input = usize; 44 | type Output<'output> 45 | = &'output T 46 | where 47 | Self: 'output; 48 | 49 | #[inline] 50 | fn get(&self, _: Self::Input) -> Result, Self::Error> { 51 | _get!(self.as_ref(), 0) 52 | } 53 | } 54 | 55 | /// ```rust 56 | /// let structure = cl_aux::doc_tests::array(); 57 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 58 | /// ``` 59 | impl Get for [T; N] { 60 | type Error = crate::Error; 61 | type Input = usize; 62 | type Output<'output> 63 | = &'output T 64 | where 65 | Self: 'output; 66 | 67 | #[inline] 68 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 69 | _get!(self.as_ref(), input) 70 | } 71 | } 72 | 73 | /// ```rust 74 | /// let structure = cl_aux::doc_tests::slice(); 75 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 76 | /// ``` 77 | impl Get for &'_ [T] { 78 | type Error = crate::Error; 79 | type Input = usize; 80 | type Output<'output> 81 | = &'output T 82 | where 83 | Self: 'output; 84 | 85 | #[inline] 86 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 87 | _get!(self.as_ref(), input) 88 | } 89 | } 90 | 91 | /// ```rust 92 | /// let mut structure = cl_aux::doc_tests::slice_mut!(); 93 | /// assert_eq!(cl_aux::Get::get(&mut structure, 0), Ok(&1)); 94 | /// ``` 95 | impl Get for &'_ mut [T] { 96 | type Error = crate::Error; 97 | type Input = usize; 98 | type Output<'output> 99 | = &'output T 100 | where 101 | Self: 'output; 102 | 103 | #[inline] 104 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 105 | _get!(self.as_ref(), input) 106 | } 107 | } 108 | 109 | /// ```rust 110 | /// let structure = cl_aux::doc_tests::vec(); 111 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 112 | /// ``` 113 | #[cfg(feature = "alloc")] 114 | impl Get for Vec { 115 | type Error = crate::Error; 116 | type Input = usize; 117 | type Output<'output> 118 | = &'output T 119 | where 120 | Self: 'output; 121 | 122 | #[inline] 123 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 124 | _get!(self.as_slice(), input) 125 | } 126 | } 127 | 128 | /// ```rust 129 | /// let structure = cl_aux::doc_tests::array_vec(); 130 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 131 | /// ``` 132 | #[cfg(feature = "arrayvec")] 133 | impl Get for arrayvec::ArrayVec { 134 | type Error = crate::Error; 135 | type Input = usize; 136 | type Output<'output> 137 | = &'output T 138 | where 139 | Self: 'output; 140 | 141 | #[inline] 142 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 143 | _get!(self.as_ref(), input) 144 | } 145 | } 146 | 147 | /// ```rust 148 | /// let structure = cl_aux::doc_tests::small_vec(); 149 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 150 | /// ``` 151 | #[cfg(feature = "smallvec")] 152 | impl Get for smallvec::SmallVec 153 | where 154 | A: smallvec::Array, 155 | { 156 | type Error = crate::Error; 157 | type Input = usize; 158 | type Output<'output> 159 | = &'output A::Item 160 | where 161 | Self: 'output; 162 | 163 | #[inline] 164 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 165 | _get!(self.as_ref(), input) 166 | } 167 | } 168 | 169 | /// ```rust 170 | /// let structure = cl_aux::doc_tests::tiny_vec_array_vec(); 171 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 172 | /// ``` 173 | #[cfg(feature = "tinyvec")] 174 | impl Get for tinyvec::ArrayVec 175 | where 176 | A: tinyvec::Array, 177 | A::Item: Default, 178 | { 179 | type Error = crate::Error; 180 | type Input = usize; 181 | type Output<'output> 182 | = &'output A::Item 183 | where 184 | Self: 'output; 185 | 186 | #[inline] 187 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 188 | _get!(self.as_ref(), input) 189 | } 190 | } 191 | 192 | /// ```rust 193 | /// let structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 194 | /// assert_eq!(cl_aux::Get::get(&structure, 0), Ok(&1)); 195 | /// ``` 196 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 197 | impl Get for tinyvec::TinyVec 198 | where 199 | A: tinyvec::Array, 200 | A::Item: Default, 201 | { 202 | type Error = crate::Error; 203 | type Input = usize; 204 | type Output<'output> 205 | = &'output A::Item 206 | where 207 | Self: 'output; 208 | 209 | #[inline] 210 | fn get(&self, input: Self::Input) -> Result, Self::Error> { 211 | _get!(self.as_ref(), input) 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /cl-aux/src/traits/iter.rs: -------------------------------------------------------------------------------- 1 | use crate::SingleItemStorage; 2 | #[cfg(feature = "alloc")] 3 | use alloc::{string::String, vec::Vec}; 4 | use core::{option, slice}; 5 | 6 | /// See [`Iter::iter`] for more information. 7 | pub trait Iter { 8 | /// Iterator 9 | type Output<'iter>: Iterator 10 | where 11 | Self: 'iter; 12 | 13 | /// Returns a new iterator that refers inner elements. 14 | fn iter(&self) -> Self::Output<'_>; 15 | } 16 | 17 | impl Iter for &T 18 | where 19 | T: Iter, 20 | { 21 | type Output<'iter> 22 | = T::Output<'iter> 23 | where 24 | Self: 'iter; 25 | 26 | #[inline] 27 | fn iter(&self) -> Self::Output<'_> { 28 | (*self).iter() 29 | } 30 | } 31 | 32 | /// ```rust 33 | /// assert_eq!(cl_aux::Iter::iter(&()).next(), None); 34 | /// ``` 35 | impl Iter for () { 36 | type Output<'iter> = slice::Iter<'iter, ()>; 37 | 38 | #[inline] 39 | fn iter(&self) -> Self::Output<'_> { 40 | [].as_ref().iter() 41 | } 42 | } 43 | 44 | /// ```rust 45 | /// assert_eq!(cl_aux::Iter::iter(&Some(0)).next().unwrap(), &0); 46 | /// ``` 47 | impl Iter for Option { 48 | type Output<'iter> 49 | = option::Iter<'iter, T> 50 | where 51 | T: 'iter; 52 | 53 | #[inline] 54 | fn iter(&self) -> Self::Output<'_> { 55 | self.iter() 56 | } 57 | } 58 | 59 | /// ```rust 60 | /// let structure = cl_aux::doc_tests::single_item_storage(); 61 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 62 | /// ``` 63 | impl Iter for SingleItemStorage { 64 | type Output<'iter> 65 | = slice::Iter<'iter, T> 66 | where 67 | T: 'iter; 68 | 69 | #[inline] 70 | fn iter(&self) -> Self::Output<'_> { 71 | slice::from_ref(&self.0).iter() 72 | } 73 | } 74 | 75 | /// ```rust 76 | /// let mut structure = cl_aux::doc_tests::array(); 77 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 78 | /// ``` 79 | impl Iter for [T; N] { 80 | type Output<'iter> 81 | = slice::Iter<'iter, T> 82 | where 83 | T: 'iter; 84 | 85 | #[inline] 86 | fn iter(&self) -> Self::Output<'_> { 87 | self.as_ref().iter() 88 | } 89 | } 90 | 91 | /// ```rust 92 | /// let structure = cl_aux::doc_tests::slice(); 93 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 94 | /// ``` 95 | impl Iter for &'_ [T] { 96 | type Output<'iter> 97 | = slice::Iter<'iter, T> 98 | where 99 | Self: 'iter; 100 | 101 | #[inline] 102 | fn iter(&self) -> Self::Output<'_> { 103 | self.as_ref().iter() 104 | } 105 | } 106 | 107 | /// ```rust 108 | /// let mut structure = cl_aux::doc_tests::string(); 109 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), 'H'); 110 | /// ``` 111 | #[cfg(feature = "alloc")] 112 | impl Iter for String { 113 | type Output<'iter> = core::str::Chars<'iter>; 114 | 115 | #[inline] 116 | fn iter(&self) -> Self::Output<'_> { 117 | self.chars() 118 | } 119 | } 120 | 121 | /// ```rust 122 | /// let mut structure = cl_aux::doc_tests::vec(); 123 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 124 | /// ``` 125 | #[cfg(feature = "alloc")] 126 | impl Iter for Vec { 127 | type Output<'iter> 128 | = slice::Iter<'iter, T> 129 | where 130 | T: 'iter; 131 | 132 | #[inline] 133 | fn iter(&self) -> Self::Output<'_> { 134 | self.as_slice().iter() 135 | } 136 | } 137 | 138 | /// ```rust 139 | /// let mut structure = cl_aux::doc_tests::array_string(); 140 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), 'H'); 141 | /// ``` 142 | #[cfg(feature = "arrayvec")] 143 | impl Iter for arrayvec::ArrayString { 144 | type Output<'iter> = core::str::Chars<'iter>; 145 | 146 | #[inline] 147 | fn iter(&self) -> Self::Output<'_> { 148 | self.chars() 149 | } 150 | } 151 | 152 | /// ```rust 153 | /// let mut structure = cl_aux::doc_tests::array_vec(); 154 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 155 | /// ``` 156 | #[cfg(feature = "arrayvec")] 157 | impl Iter for arrayvec::ArrayVec { 158 | type Output<'iter> 159 | = slice::Iter<'iter, T> 160 | where 161 | T: 'iter; 162 | 163 | #[inline] 164 | fn iter(&self) -> Self::Output<'_> { 165 | self.as_slice().iter() 166 | } 167 | } 168 | 169 | /// ```rust 170 | /// let mut structure = cl_aux::doc_tests::small_vec(); 171 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 172 | /// ``` 173 | #[cfg(feature = "smallvec")] 174 | impl Iter for smallvec::SmallVec 175 | where 176 | A: smallvec::Array, 177 | { 178 | type Output<'iter> 179 | = slice::Iter<'iter, A::Item> 180 | where 181 | A: 'iter; 182 | 183 | #[inline] 184 | fn iter(&self) -> Self::Output<'_> { 185 | self.as_slice().iter() 186 | } 187 | } 188 | 189 | /// ```rust 190 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 191 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 192 | /// ``` 193 | #[cfg(feature = "tinyvec")] 194 | impl Iter for tinyvec::ArrayVec 195 | where 196 | A: tinyvec::Array, 197 | A::Item: Default, 198 | { 199 | type Output<'iter> 200 | = slice::Iter<'iter, A::Item> 201 | where 202 | A: 'iter; 203 | 204 | #[inline] 205 | fn iter(&self) -> Self::Output<'_> { 206 | self.as_slice().iter() 207 | } 208 | } 209 | 210 | /// ```rust 211 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 212 | /// assert_eq!(cl_aux::Iter::iter(&structure).next().unwrap(), &1); 213 | /// ``` 214 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 215 | impl Iter for tinyvec::TinyVec 216 | where 217 | A: tinyvec::Array, 218 | A::Item: Default, 219 | { 220 | type Output<'iter> 221 | = slice::Iter<'iter, A::Item> 222 | where 223 | A: 'iter; 224 | 225 | #[inline] 226 | fn iter(&self) -> Self::Output<'_> { 227 | self.as_slice().iter() 228 | } 229 | } 230 | -------------------------------------------------------------------------------- /cl-aux/src/traits/extend.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::{string::String, vec::Vec}; 3 | 4 | /// See [`Extend::extend`] for more information. 5 | pub trait Extend { 6 | /// Error 7 | type Error; 8 | 9 | /// Returns an mutable inner reference of a derived element. 10 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error>; 11 | } 12 | 13 | impl Extend for &mut T 14 | where 15 | T: Extend, 16 | { 17 | type Error = T::Error; 18 | 19 | #[inline] 20 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 21 | (*self).extend(into_iter) 22 | } 23 | } 24 | 25 | impl Extend for () { 26 | type Error = crate::Error; 27 | 28 | #[inline] 29 | fn extend(&mut self, _: impl IntoIterator) -> Result<(), Self::Error> { 30 | Ok(()) 31 | } 32 | } 33 | 34 | /// ```rust 35 | /// let mut opt = None; 36 | /// cl_aux::Extend::extend(&mut opt, [3]).unwrap(); 37 | /// assert_eq!(opt, Some(3)); 38 | /// ``` 39 | impl Extend for Option { 40 | type Error = crate::Error; 41 | 42 | #[inline] 43 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 44 | _check_capacity!(self); 45 | let err = || crate::Error::InsufficientCapacity(1); 46 | let mut iter = into_iter.into_iter(); 47 | let next = iter.next().ok_or_else(err)?; 48 | *self = Some(next); 49 | if iter.next().is_some() { 50 | Err(err()) 51 | } else { 52 | Ok(()) 53 | } 54 | } 55 | } 56 | 57 | /// ```rust 58 | /// let mut structure = cl_aux::doc_tests::string(); 59 | /// cl_aux::Extend::extend(&mut structure, ['!']); 60 | /// assert_eq!(structure.as_str(), "Hello!"); 61 | /// ``` 62 | #[cfg(feature = "alloc")] 63 | impl Extend for String { 64 | type Error = crate::Error; 65 | 66 | #[inline] 67 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 68 | core::iter::Extend::extend(self, into_iter); 69 | Ok(()) 70 | } 71 | } 72 | 73 | /// ```rust 74 | /// let mut structure = cl_aux::doc_tests::vec(); 75 | /// cl_aux::Extend::extend(&mut structure, [20]); 76 | /// assert_eq!(&structure[..], &[1, 2, 3, 20][..]); 77 | /// ``` 78 | #[cfg(feature = "alloc")] 79 | impl Extend for Vec { 80 | type Error = crate::Error; 81 | 82 | #[inline] 83 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 84 | core::iter::Extend::extend(self, into_iter); 85 | Ok(()) 86 | } 87 | } 88 | 89 | /// ```rust 90 | /// let mut structure = cl_aux::doc_tests::array_string(); 91 | /// cl_aux::Extend::extend(&mut structure, "!".chars()); 92 | /// assert_eq!(structure.as_str(), "Hello!"); 93 | /// ``` 94 | #[cfg(feature = "arrayvec")] 95 | impl Extend for arrayvec::ArrayString 96 | where 97 | Self: crate::Push, 98 | { 99 | type Error = >::Error; 100 | 101 | #[inline] 102 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 103 | for elem in into_iter { 104 | crate::Push::push(self, elem)?; 105 | } 106 | Ok(()) 107 | } 108 | } 109 | 110 | /// ```rust 111 | /// let mut structure = cl_aux::doc_tests::array_vec(); 112 | /// cl_aux::Extend::extend(&mut structure, [20]); 113 | /// assert_eq!(&structure[..], &[1, 2, 3, 20][..]); 114 | /// ``` 115 | #[cfg(feature = "arrayvec")] 116 | impl Extend for arrayvec::ArrayVec 117 | where 118 | Self: crate::Push, 119 | { 120 | type Error = >::Error; 121 | 122 | #[inline] 123 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 124 | for elem in into_iter { 125 | crate::Push::push(self, elem)?; 126 | } 127 | Ok(()) 128 | } 129 | } 130 | 131 | /// ```rust 132 | /// let mut structure = cl_aux::doc_tests::small_vec(); 133 | /// cl_aux::Extend::extend(&mut structure, [20]); 134 | /// assert_eq!(&structure[..], &[1, 2, 3, 20][..]); 135 | /// ``` 136 | #[cfg(feature = "smallvec")] 137 | impl Extend for smallvec::SmallVec 138 | where 139 | A: smallvec::Array, 140 | Self: crate::Push, 141 | { 142 | type Error = >::Error; 143 | 144 | #[inline] 145 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 146 | for elem in into_iter { 147 | crate::Push::push(self, elem)?; 148 | } 149 | Ok(()) 150 | } 151 | } 152 | 153 | /// ```rust 154 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 155 | /// cl_aux::Extend::extend(&mut structure, [20]); 156 | /// assert_eq!(&structure[..], &[1, 2, 3, 20][..]); 157 | /// ``` 158 | #[cfg(feature = "tinyvec")] 159 | impl Extend for tinyvec::ArrayVec 160 | where 161 | A: tinyvec::Array, 162 | Self: crate::Push, 163 | { 164 | type Error = >::Error; 165 | 166 | #[inline] 167 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 168 | for elem in into_iter { 169 | crate::Push::push(self, elem)?; 170 | } 171 | Ok(()) 172 | } 173 | } 174 | 175 | /// ```rust 176 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 177 | /// cl_aux::Extend::extend(&mut structure, [20]); 178 | /// assert_eq!(&structure[..], &[1, 2, 3, 20][..]); 179 | /// ``` 180 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 181 | impl Extend for tinyvec::TinyVec 182 | where 183 | A: tinyvec::Array, 184 | A::Item: Default, 185 | Self: crate::Push, 186 | { 187 | type Error = >::Error; 188 | 189 | #[inline] 190 | fn extend(&mut self, into_iter: impl IntoIterator) -> Result<(), Self::Error> { 191 | for elem in into_iter { 192 | crate::Push::push(self, elem)?; 193 | } 194 | Ok(()) 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /ndstruct/src/csl/csl_rnd.rs: -------------------------------------------------------------------------------- 1 | use crate::csl::{ 2 | csl_utils::{correct_offs_len, manage_last_offset, outermost_stride}, 3 | Csl, CslError, 4 | }; 5 | use cl_aux::{Push, SingleTypeStorage}; 6 | use core::cmp::Ordering; 7 | use rand::{ 8 | distr::{Distribution as _, Uniform}, 9 | Rng, 10 | }; 11 | 12 | #[derive(Debug)] 13 | pub(crate) struct CslRnd<'csl, DS, IS, OS, R, const D: usize> { 14 | csl: &'csl mut Csl, 15 | nnz: usize, 16 | rng: &'csl mut R, 17 | } 18 | 19 | impl<'csl, DATA, DS, IS, OS, R, const D: usize> CslRnd<'csl, DS, IS, OS, R, D> 20 | where 21 | DS: AsMut<[DATA]> + AsRef<[DATA]> + Push + SingleTypeStorage, 22 | IS: AsMut<[usize]> + AsRef<[usize]> + Push, 23 | R: Rng, 24 | OS: AsMut<[usize]> + AsRef<[usize]> + Push, 25 | { 26 | #[inline] 27 | pub(crate) fn new( 28 | csl: &'csl mut Csl, 29 | nnz: usize, 30 | rng: &'csl mut R, 31 | ) -> crate::Result { 32 | if nnz > crate::utils::max_nnz(&csl.dims) { 33 | return Err(CslError::NnzGreaterThanMaximumNnz.into()); 34 | } 35 | let _ = manage_last_offset(&mut csl.offs)?; 36 | Ok(Self { csl, nnz, rng }) 37 | } 38 | 39 | #[inline] 40 | pub(crate) fn fill(mut self, cb: impl FnMut(&mut R, [usize; D]) -> DATA) -> Option<()> { 41 | let last_dim_idx = if self.csl.dims.is_empty() { 42 | return Some(()); 43 | } else { 44 | self.csl.dims.len().checked_sub(1)? 45 | }; 46 | self.fill_offs(last_dim_idx)?; 47 | self.fill_indcs(last_dim_idx)?; 48 | self.fill_data(cb, last_dim_idx)?; 49 | Some(()) 50 | } 51 | 52 | fn fill_data( 53 | &mut self, 54 | mut cb: impl FnMut(&mut R, [usize; D]) -> DATA, 55 | last_dim_idx: usize, 56 | ) -> Option<()> { 57 | let data = &mut self.csl.data; 58 | let indcs = self.csl.indcs.as_ref(); 59 | let orig_dims = self.csl.dims.0; 60 | let outermost_stride = outermost_stride(&orig_dims); 61 | 62 | for (line_idx, offset) in self.csl.offs.as_ref().windows(2).enumerate() { 63 | let mut dims = orig_dims; 64 | *dims.first_mut()? = 65 | if outermost_stride == 0 { 0 } else { line_idx.checked_rem(outermost_stride)? }; 66 | let iter = dims.iter_mut().zip(orig_dims.iter()).skip(1).rev().skip(1); 67 | for (dim, &orig_dim) in iter { 68 | *dim = if orig_dim == 0 { 0 } else { line_idx.checked_rem(orig_dim)? }; 69 | } 70 | let range = *offset.first()?..*offset.get(1)?; 71 | for innermost_idx in indcs.get(range)?.iter().copied() { 72 | *dims.get_mut(last_dim_idx)? = innermost_idx; 73 | data.push(cb(self.rng, dims)).ok()?; 74 | } 75 | } 76 | 77 | Some(()) 78 | } 79 | 80 | fn fill_indcs(&mut self, last_dim_idx: usize) -> Option<()> { 81 | let dims = &self.csl.dims; 82 | let indcs = &mut self.csl.indcs; 83 | for offset in self.csl.offs.as_ref().windows(2) { 84 | let mut counter = 0; 85 | let line_nnz = offset.get(1)?.checked_sub(*offset.first()?)?; 86 | while counter < line_nnz { 87 | let rnd = self.rng.random_range(0..*dims.get(last_dim_idx)?); 88 | if !indcs.as_ref().get(*offset.first()?..)?.contains(&rnd) { 89 | indcs.push(rnd).ok()?; 90 | counter = counter.checked_add(1)?; 91 | } 92 | } 93 | indcs.as_mut().get_mut(*offset.first()?..)?.sort_unstable(); 94 | } 95 | Some(()) 96 | } 97 | 98 | fn fill_offs(&mut self, last_dim_idx: usize) -> Option<()> { 99 | let nnz = self.nnz; 100 | for _ in 1..correct_offs_len(&self.csl.dims).ok()? { 101 | self.csl.offs.push(0).ok()?; 102 | } 103 | let fun = |idl, _, s: &mut Self| { 104 | Some(Uniform::new_inclusive(0, idl).map(|el| el.sample(s.rng)).unwrap_or_default()) 105 | }; 106 | let mut last_visited_off = self.do_fill_offs(last_dim_idx, fun)?; 107 | loop { 108 | if *self.csl.offs.as_ref().get(last_visited_off)? >= nnz { 109 | if let Some(slice) = self.csl.offs.as_mut().get_mut(last_visited_off..) { 110 | for off in slice.iter_mut() { 111 | *off = nnz; 112 | } 113 | } 114 | break; 115 | } 116 | let mut offs_adjustment = 0; 117 | last_visited_off = self.do_fill_offs(last_dim_idx, |idl, idx, s| { 118 | let offs = s.csl.offs.as_mut(); 119 | let curr = offs.get(idx)?.checked_add(offs_adjustment)?; 120 | let prev = *offs.get(idx.checked_sub(1)?)?; 121 | let start = curr.checked_sub(prev)?; 122 | let line_nnz = 123 | Uniform::new_inclusive(start, idl).map(|el| el.sample(s.rng)).unwrap_or_default(); 124 | let offs_adjustment_addition = line_nnz.checked_add(prev)?.checked_sub(curr)?; 125 | offs_adjustment = offs_adjustment.checked_add(offs_adjustment_addition)?; 126 | Some(line_nnz) 127 | })?; 128 | } 129 | Some(()) 130 | } 131 | 132 | fn do_fill_offs( 133 | &mut self, 134 | last_dim_idx: usize, 135 | mut f: impl FnMut(usize, usize, &mut Self) -> Option, 136 | ) -> Option { 137 | let nnz = self.nnz; 138 | let mut idx = 1; 139 | let mut previous_nnz = *self.csl.offs.as_ref().first()?; 140 | loop { 141 | if idx >= self.csl.offs.as_ref().len() { 142 | break; 143 | } 144 | match previous_nnz.cmp(&nnz) { 145 | Ordering::Equal => { 146 | break; 147 | } 148 | Ordering::Greater => { 149 | let idx_minus_one = idx.checked_sub(1)?; 150 | *self.csl.offs.as_mut().get_mut(idx_minus_one)? = nnz; 151 | break; 152 | } 153 | Ordering::Less => { 154 | let innermost_dim_len = *self.csl.dims.get(last_dim_idx)?; 155 | let line_nnz = f(innermost_dim_len, idx, self)?; 156 | let new_nnz = previous_nnz.checked_add(line_nnz)?; 157 | *self.csl.offs.as_mut().get_mut(idx)? = new_nnz; 158 | previous_nnz = new_nnz; 159 | } 160 | } 161 | idx = idx.checked_add(1)?; 162 | } 163 | idx.checked_sub(1) 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /cl-aux/src/traits/length.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::{ 3 | collections::{BTreeMap, BTreeSet}, 4 | string::String, 5 | vec::Vec, 6 | }; 7 | #[cfg(feature = "std")] 8 | use std::collections::{HashMap, HashSet}; 9 | 10 | use crate::SingleItemStorage; 11 | 12 | /// See [`Length::length`] for more information. 13 | pub trait Length { 14 | /// Holds a certain number of elements. 15 | fn length(&self) -> usize; 16 | } 17 | 18 | impl Length for &T 19 | where 20 | T: Length, 21 | { 22 | #[inline] 23 | fn length(&self) -> usize { 24 | (*self).length() 25 | } 26 | } 27 | 28 | /// ```rust 29 | /// assert_eq!(cl_aux::Length::length(&()), 0); 30 | /// ``` 31 | impl Length for () { 32 | #[inline] 33 | fn length(&self) -> usize { 34 | 0 35 | } 36 | } 37 | 38 | /// ```rust 39 | /// let mut opt = Some(0); 40 | /// assert_eq!(cl_aux::Length::length(&opt), 1); 41 | /// opt.take(); 42 | /// assert_eq!(cl_aux::Length::length(&opt), 0); 43 | /// ``` 44 | impl Length for Option { 45 | #[inline] 46 | fn length(&self) -> usize { 47 | usize::from(self.is_some()) 48 | } 49 | } 50 | 51 | /// ```rust 52 | /// let structure = cl_aux::doc_tests::single_item_storage(); 53 | /// assert_eq!(cl_aux::Length::length(&structure), 1); 54 | /// ``` 55 | impl Length for SingleItemStorage { 56 | #[inline] 57 | fn length(&self) -> usize { 58 | 1 59 | } 60 | } 61 | 62 | /// ```rust 63 | /// let structure = cl_aux::doc_tests::slice(); 64 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 65 | /// ``` 66 | impl Length for &'_ [T] { 67 | #[inline] 68 | fn length(&self) -> usize { 69 | self.len() 70 | } 71 | } 72 | 73 | /// ```rust 74 | /// let mut structure = cl_aux::doc_tests::slice_mut!(); 75 | /// assert_eq!(cl_aux::Length::length(&mut structure), 3); 76 | /// ``` 77 | impl Length for &'_ mut [T] { 78 | #[inline] 79 | fn length(&self) -> usize { 80 | self.len() 81 | } 82 | } 83 | 84 | /// ```rust 85 | /// let structure = cl_aux::doc_tests::array(); 86 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 87 | /// ``` 88 | impl Length for [T; N] { 89 | #[inline] 90 | fn length(&self) -> usize { 91 | self.len() 92 | } 93 | } 94 | 95 | /// ```rust 96 | /// let mut structure = cl_aux::doc_tests::b_tree_map(); 97 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 98 | /// ``` 99 | #[cfg(feature = "alloc")] 100 | impl Length for BTreeMap { 101 | #[inline] 102 | fn length(&self) -> usize { 103 | self.len() 104 | } 105 | } 106 | 107 | /// ```rust 108 | /// let mut structure = cl_aux::doc_tests::b_tree_set(); 109 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 110 | /// ``` 111 | #[cfg(feature = "alloc")] 112 | impl Length for BTreeSet { 113 | #[inline] 114 | fn length(&self) -> usize { 115 | self.len() 116 | } 117 | } 118 | 119 | /// ```rust 120 | /// let mut structure = cl_aux::doc_tests::hash_map(); 121 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 122 | /// ``` 123 | #[cfg(feature = "std")] 124 | impl Length for HashMap 125 | where 126 | S: core::hash::BuildHasher, 127 | { 128 | #[inline] 129 | fn length(&self) -> usize { 130 | self.len() 131 | } 132 | } 133 | 134 | /// ```rust 135 | /// let mut structure = cl_aux::doc_tests::hash_set(); 136 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 137 | /// ``` 138 | #[cfg(feature = "std")] 139 | impl Length for HashSet 140 | where 141 | S: core::hash::BuildHasher, 142 | { 143 | #[inline] 144 | fn length(&self) -> usize { 145 | self.len() 146 | } 147 | } 148 | 149 | /// ```rust 150 | /// let structure = cl_aux::doc_tests::string(); 151 | /// assert_eq!(cl_aux::Length::length(&structure), 5); 152 | /// ``` 153 | #[cfg(feature = "alloc")] 154 | impl Length for String { 155 | #[inline] 156 | fn length(&self) -> usize { 157 | self.len() 158 | } 159 | } 160 | 161 | /// ```rust 162 | /// let structure = cl_aux::doc_tests::vec(); 163 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 164 | /// ``` 165 | #[cfg(feature = "alloc")] 166 | impl Length for Vec { 167 | #[inline] 168 | fn length(&self) -> usize { 169 | self.len() 170 | } 171 | } 172 | 173 | /// ```rust 174 | /// let structure = cl_aux::doc_tests::array_string(); 175 | /// assert_eq!(cl_aux::Length::length(&structure), 5); 176 | /// ``` 177 | #[cfg(feature = "arrayvec")] 178 | impl Length for arrayvec::ArrayString { 179 | #[inline] 180 | fn length(&self) -> usize { 181 | self.len() 182 | } 183 | } 184 | 185 | /// ```rust 186 | /// let structure = cl_aux::doc_tests::array_vec(); 187 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 188 | /// ``` 189 | #[cfg(feature = "arrayvec")] 190 | impl Length for arrayvec::ArrayVec { 191 | #[inline] 192 | fn length(&self) -> usize { 193 | self.len() 194 | } 195 | } 196 | 197 | /// ```rust 198 | /// let structure = cl_aux::doc_tests::small_vec(); 199 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 200 | /// ``` 201 | #[cfg(feature = "smallvec")] 202 | impl Length for smallvec::SmallVec 203 | where 204 | A: smallvec::Array, 205 | { 206 | #[inline] 207 | fn length(&self) -> usize { 208 | self.len() 209 | } 210 | } 211 | 212 | /// ```rust 213 | /// let structure = cl_aux::doc_tests::tiny_vec_array_vec(); 214 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 215 | /// ``` 216 | #[cfg(feature = "tinyvec")] 217 | impl Length for tinyvec::ArrayVec 218 | where 219 | A: tinyvec::Array, 220 | A::Item: Default, 221 | { 222 | #[inline] 223 | fn length(&self) -> usize { 224 | self.len() 225 | } 226 | } 227 | 228 | /// ```rust 229 | /// let structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 230 | /// assert_eq!(cl_aux::Length::length(&structure), 3); 231 | /// ``` 232 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 233 | impl Length for tinyvec::TinyVec 234 | where 235 | A: tinyvec::Array, 236 | A::Item: Default, 237 | { 238 | #[inline] 239 | fn length(&self) -> usize { 240 | self.len() 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /cl-aux/src/traits/push.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | use alloc::{string::String, vec::Vec}; 3 | 4 | /// See [`Push::push`] for more information. 5 | pub trait Push { 6 | /// Error 7 | type Error; 8 | 9 | /// Pushes an element, increasing the storage length. 10 | fn push(&mut self, input: I) -> Result<(), Self::Error>; 11 | } 12 | 13 | impl Push for &mut T 14 | where 15 | T: Push, 16 | { 17 | type Error = T::Error; 18 | 19 | #[inline] 20 | fn push(&mut self, input: I) -> Result<(), Self::Error> { 21 | (*self).push(input) 22 | } 23 | } 24 | 25 | /// ```rust 26 | /// let mut opt = None; 27 | /// cl_aux::Push::push(&mut opt, 3); 28 | /// assert_eq!(opt, Some(3)); 29 | /// ``` 30 | impl Push for () { 31 | type Error = crate::Error; 32 | 33 | #[inline] 34 | fn push(&mut self, _: T) -> Result<(), Self::Error> { 35 | Ok(()) 36 | } 37 | } 38 | 39 | /// ```rust 40 | /// let mut opt = None; 41 | /// cl_aux::Push::push(&mut opt, 3); 42 | /// assert_eq!(opt, Some(3)); 43 | /// ``` 44 | impl Push for Option { 45 | type Error = crate::Error; 46 | 47 | #[inline] 48 | fn push(&mut self, input: T) -> Result<(), Self::Error> { 49 | if self.is_some() { 50 | Err(crate::Error::InsufficientCapacity(1)) 51 | } else { 52 | *self = Some(input); 53 | Ok(()) 54 | } 55 | } 56 | } 57 | 58 | /// ```rust 59 | /// let mut structure = cl_aux::doc_tests::string(); 60 | /// cl_aux::Push::push(&mut structure, '!'); 61 | /// assert_eq!(structure.as_str(), "Hello!"); 62 | /// ``` 63 | #[cfg(feature = "alloc")] 64 | impl Push for String { 65 | type Error = crate::Error; 66 | 67 | #[inline] 68 | fn push(&mut self, input: char) -> Result<(), Self::Error> { 69 | _check_capacity!(self); 70 | self.push(input); 71 | Ok(()) 72 | } 73 | } 74 | 75 | /// ```rust 76 | /// let mut structure = cl_aux::doc_tests::string(); 77 | /// cl_aux::Push::push(&mut structure, "!!"); 78 | /// assert_eq!(structure.as_str(), "Hello!!"); 79 | /// ``` 80 | #[cfg(feature = "alloc")] 81 | impl<'input> Push<&'input str> for String { 82 | type Error = crate::Error; 83 | 84 | #[inline] 85 | fn push(&mut self, input: &'input str) -> Result<(), Self::Error> { 86 | _check_capacity!(self); 87 | self.push_str(input); 88 | Ok(()) 89 | } 90 | } 91 | 92 | /// ```rust 93 | /// let mut structure = cl_aux::doc_tests::vec(); 94 | /// cl_aux::Push::push(&mut structure, 20); 95 | /// assert_eq!(structure.get(3), Some(&20)); 96 | /// ``` 97 | #[cfg(feature = "alloc")] 98 | impl Push for Vec { 99 | type Error = crate::Error; 100 | 101 | #[inline] 102 | fn push(&mut self, input: T) -> Result<(), Self::Error> { 103 | _check_capacity!(self); 104 | self.push(input); 105 | Ok(()) 106 | } 107 | } 108 | 109 | /// ```rust 110 | /// let mut structure = cl_aux::doc_tests::array_string(); 111 | /// cl_aux::Push::push(&mut structure, '!'); 112 | /// assert_eq!(structure.as_str(), "Hello!"); 113 | /// ``` 114 | #[cfg(feature = "arrayvec")] 115 | impl Push for arrayvec::ArrayString { 116 | type Error = crate::Error; 117 | 118 | #[inline] 119 | fn push(&mut self, input: char) -> Result<(), Self::Error> { 120 | _check_capacity!(self); 121 | self.push(input); 122 | Ok(()) 123 | } 124 | } 125 | 126 | /// ```rust 127 | /// let mut structure = cl_aux::doc_tests::array_string(); 128 | /// cl_aux::Push::push(&mut structure, "!!"); 129 | /// assert_eq!(structure.as_str(), "Hello!!"); 130 | /// ``` 131 | #[cfg(feature = "arrayvec")] 132 | impl<'input, const N: usize> Push<&'input str> for arrayvec::ArrayString { 133 | type Error = crate::Error; 134 | 135 | #[inline] 136 | fn push(&mut self, input: &'input str) -> Result<(), Self::Error> { 137 | _check_capacity!(self); 138 | self.push_str(input); 139 | Ok(()) 140 | } 141 | } 142 | 143 | /// ```rust 144 | /// let mut structure = cl_aux::doc_tests::array_vec(); 145 | /// cl_aux::Push::push(&mut structure, 20); 146 | /// assert_eq!(structure.get(3), Some(&20)); 147 | /// ``` 148 | #[cfg(feature = "arrayvec")] 149 | impl Push for arrayvec::ArrayVec { 150 | type Error = crate::Error; 151 | 152 | #[inline] 153 | fn push(&mut self, input: T) -> Result<(), Self::Error> { 154 | _check_capacity!(self); 155 | self.push(input); 156 | Ok(()) 157 | } 158 | } 159 | 160 | /// ```rust 161 | /// let mut structure = cl_aux::doc_tests::small_vec(); 162 | /// cl_aux::Push::push(&mut structure, 20); 163 | /// assert_eq!(structure.get(3), Some(&20)); 164 | /// ``` 165 | #[cfg(feature = "smallvec")] 166 | impl Push for smallvec::SmallVec 167 | where 168 | A: smallvec::Array, 169 | { 170 | type Error = crate::Error; 171 | 172 | #[inline] 173 | fn push(&mut self, input: A::Item) -> Result<(), Self::Error> { 174 | _check_capacity!(self); 175 | self.push(input); 176 | Ok(()) 177 | } 178 | } 179 | 180 | /// ```rust 181 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 182 | /// cl_aux::Push::push(&mut structure, 20); 183 | /// assert_eq!(structure.get(3), Some(&20)); 184 | /// ``` 185 | #[cfg(feature = "tinyvec")] 186 | impl Push for tinyvec::ArrayVec 187 | where 188 | A: tinyvec::Array, 189 | A::Item: Default, 190 | { 191 | type Error = crate::Error; 192 | 193 | #[inline] 194 | fn push(&mut self, input: A::Item) -> Result<(), Self::Error> { 195 | _check_capacity!(self); 196 | self.push(input); 197 | Ok(()) 198 | } 199 | } 200 | 201 | /// ```rust 202 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 203 | /// cl_aux::Push::push(&mut structure, 20); 204 | /// assert_eq!(structure.get(3), Some(&20)); 205 | /// ``` 206 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 207 | impl Push for tinyvec::TinyVec 208 | where 209 | A: tinyvec::Array, 210 | A::Item: Default, 211 | { 212 | type Error = crate::Error; 213 | 214 | #[inline] 215 | fn push(&mut self, input: A::Item) -> Result<(), Self::Error> { 216 | _check_capacity!(self); 217 | self.push(input); 218 | Ok(()) 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /ndstruct/src/doc_tests.rs: -------------------------------------------------------------------------------- 1 | //! Instances for documentation tests or tests. 2 | 3 | use crate::{coo::CooArray, csl::CslArray, dense::DenseArray}; 4 | #[cfg(feature = "alloc")] 5 | use crate::{coo::CooVec, csl::CslVec}; 6 | 7 | /// As odd as it may seem, this illustration is just a guide to get a grasp of 8 | /// a 5D structure. 9 | /// 10 | /// ```rust 11 | /// // ___ ___ ___ ___ ___ ___ ___ ___ ___ 12 | /// // / / / /\ / 3 / / /\ / / / /\ 13 | /// // /___/___/___/ /\ /_3_/___/___/ /\ /___/___/___/ /\ 14 | /// // / / / /\/ /\ / / / /\/ /\ / / 4 / /\/ /\ 15 | /// // /___/___/___/ /\/ / /___/___/___/ /\/ / /___/_4_/___/ /\/ / 16 | /// // / / / /\/ /\/ / / / /\/ /\/ / / / /\/ /\/ 17 | /// // /___/___/___/ /\/ / /___/___/___/ /\/ / /___/___/___/ /\/ / 18 | /// // / / / /\/1/\/ / / / /\/ /\/ / / / /\/ /\/ 19 | /// // /___/___/___/ /\/ / /___/___/___/ /\/ / /___/___/___/ /\/ / 20 | /// // \___\___\___\/ /\/ \___\___\___\/ /\/ \___\___\___\/ /\/ 21 | /// // \___\___\___\/ / \___\_2_\___\/ / \___\___\___\/ / 22 | /// // \___\___\___\/ \___\___\___\/ \___\___\___\/ 23 | /// // 24 | /// // ___ ___ ___ ___ ___ ___ ___ ___ ___ 25 | /// // / / / /\ / / / /\ / / / 6 /\ 26 | /// // /___/___/___/ /\ /___/___/___/ /\ /___/___/_6_/6/\ 27 | /// // / / / /\/ /\ / / / /\/ /\ / / / /\/ /\ 28 | /// // /___/___/___/ /\/ / /___/___/___/ /\/ / /___/___/___/ /\/7/ 29 | /// // / / / /\/ /\/ / / / /\/ /\/ / / / /\/ /\/ 30 | /// // /___/___/___/ /\/ / /___/___/___/ /\/ / /___/___/___/ /\/ / 31 | /// // / / / /\/ /\/ / / / /\/ /\/ / / / /\/ /\/ 32 | /// // /___/___/___/ /\/ / /___/___/___/ /\/ / /___/___/___/ /\/ / 33 | /// // \___\___\___\/ /\/ \___\___\___\/ /\/ \___\___\___\/ /\/ 34 | /// // \___\___\___\/ / \___\___\___\/ / \___\___\___\/ / 35 | /// // \___\___\___\/ \___\_5_\___\/ \___\___\___\/ 36 | /// use ndstruct::coo::CooArray; 37 | /// let _ = CooArray::new( 38 | /// [2, 3, 4, 3, 3], 39 | /// [ 40 | /// ([0, 0, 1, 1, 2], 1), 41 | /// ([0, 1, 0, 1, 1], 2), 42 | /// ([0, 1, 3, 0, 0], 3), 43 | /// ([0, 2, 2, 0, 1], 4), 44 | /// ([1, 1, 0, 2, 1], 5), 45 | /// ([1, 2, 3, 0, 2], 6), 46 | /// ([1, 2, 3, 2, 2], 7), 47 | /// ], 48 | /// ); 49 | /// ``` 50 | #[inline] 51 | #[must_use] 52 | pub fn coo_array_5() -> CooArray { 53 | CooArray { 54 | dims: [2, 3, 4, 3, 3].into(), 55 | data: [ 56 | ([0, 0, 1, 1, 2], 1), 57 | ([0, 1, 0, 1, 1], 2), 58 | ([0, 1, 3, 0, 0], 3), 59 | ([0, 2, 2, 0, 1], 4), 60 | ([1, 1, 0, 2, 1], 5), 61 | ([1, 2, 3, 0, 2], 6), 62 | ([1, 2, 3, 2, 2], 7), 63 | ], 64 | } 65 | } 66 | 67 | /// [`alloc::vec::Vec`] version of [`coo_array_5`]. 68 | #[cfg(feature = "alloc")] 69 | #[inline] 70 | #[must_use] 71 | pub fn coo_vec_5() -> CooVec { 72 | let coo = coo_array_5(); 73 | CooVec { dims: coo.dims, data: coo.data.to_vec() } 74 | } 75 | 76 | /// Two cuboids illustrating a [2, 3, 4, 5] 4D in a [w, y, z, x] order, i.e., each "line" 77 | /// or 1D representation is a left to right row and each "matrix" or 2D representation 78 | /// is filled in a top-down manner. 79 | /// 80 | /// ```rust 81 | /// // w: left to right 82 | /// // y: top to bottom 83 | /// // z: front to back 84 | /// // x: left to right 85 | /// // 86 | /// // ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ 87 | /// // / / / / 4 / 5 /\ / / / / / /\ 88 | /// // /___/___/___/_4_/_5_/5/\ /___/___/___/___/___/ /\ 89 | /// // / / / / / /\/ /\ / / / 9 / / /\/ /\ 90 | /// // /___/___/___/___/___/ /\/ / /___/___/_9_/___/___/ /\/ / 91 | /// // / / 3 / / / /\/ /\/ / / / / / /\/ /\/ 92 | /// // /___/_3_/___/___/___/ /\/ / /___/_ _/___/___/___/ /\/ / 93 | /// // / 1 / / / 2 / /\/ /\/ / / / / / /\/ /\/ 94 | /// // /_1_/___/___/_2_/___/ /\/8/ /___/___/___/___/___/ /\/ / 95 | /// // \_1_\___\___\_2_\___\/ /\/ \___\___\___\___\___\/ /\/ 96 | /// // \___\___\_6_\___\___\/ / \___\___\___\___\___\/ / 97 | /// // \___\___\_7_\___\___\/ \___\___\___\___\___\/ 98 | /// use ndstruct::csl::CslArray; 99 | /// let _ = CslArray::new( 100 | /// [2, 3, 4, 5], 101 | /// [1, 2, 3, 4, 5, 6, 7, 8, 9], 102 | /// [0, 3, 1, 3, 4, 2, 2, 4, 2], 103 | /// [0, 2, 3, 3, 5, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9], 104 | /// ); 105 | /// ``` 106 | #[inline] 107 | #[must_use] 108 | pub fn csl_array_4() -> CslArray { 109 | CslArray { 110 | data: [1, 2, 3, 4, 5, 6, 7, 8, 9], 111 | dims: [2, 3, 4, 5].into(), 112 | indcs: [0, 3, 1, 3, 4, 2, 2, 4, 2], 113 | offs: [0, 2, 3, 3, 5, 6, 6, 6, 6, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9], 114 | } 115 | } 116 | 117 | /// [`alloc::vec::Vec`] version of [`csl_array_4`]. 118 | #[cfg(feature = "alloc")] 119 | #[inline] 120 | #[must_use] 121 | pub fn csl_vec_4() -> CslVec { 122 | let csl = csl_array_4(); 123 | CslVec { 124 | data: csl.data.to_vec(), 125 | dims: csl.dims, 126 | indcs: csl.indcs.to_vec(), 127 | offs: csl.offs.to_vec(), 128 | } 129 | } 130 | 131 | /// A dense cube, i.e., a fully filled cube. 132 | /// 133 | /// ```rust 134 | /// // ___ ___ ___ 135 | /// // / 28/ 29/ 30/\ 136 | /// // /___/___/___/0/\ 137 | /// // / 19/ 20/ 21/\/3/\ 138 | /// // /___/___/___/1/\/6/ 139 | /// // / 10/ 11/ 12/\/4/\/ 140 | /// // /___/___/___/2/\/7/ 141 | /// // / 1 / 2 / 3 /\/5/\/ 142 | /// // /___/___/___/3/\/8/ 143 | /// // \_1_\_2_\_3_\/6/\/ 144 | /// // \_4_\_5_\_6_\/9/ 145 | /// // \_7_\_8_\_9_\/ 146 | /// use ndstruct::dense::DenseArray; 147 | /// let _ = DenseArray::new( 148 | /// [4, 3, 3], 149 | /// [ 150 | /// 1, 2, 3, 4, 5, 6, 7, 8, 9, 151 | /// 10, 11, 12, 13, 14, 15, 16, 17, 18, 152 | /// 19, 20, 21, 22, 23, 24, 25, 26, 27, 153 | /// 28, 29, 30, 31, 32, 33, 34, 35, 36, 154 | /// ] 155 | /// ); 156 | /// ``` 157 | #[inline] 158 | #[must_use] 159 | pub fn dense_array_3() -> DenseArray { 160 | DenseArray { 161 | dims: [4, 3, 3].into(), 162 | data: [ 163 | 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, 164 | 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 165 | ], 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /ndstruct/src/csl/csl_utils.rs: -------------------------------------------------------------------------------- 1 | use crate::csl::{Csl, CslError, CslMut, CslRef}; 2 | use cl_aux::{ArrayWrapper, Push}; 3 | use core::ops::Range; 4 | 5 | macro_rules! create_sub_dim { 6 | ( 7 | $trait:ident 8 | $trait_fn:ident 9 | $ref:ident 10 | $get:ident 11 | $line_fn:ident 12 | $sub_dim_fn:ident 13 | $([$mut:tt])? 14 | ) => { 15 | 16 | #[inline] 17 | pub(crate) fn $line_fn<'csl, 'ret, DATA, DS, IS, OS, const D: usize>( 18 | csl: &'csl $($mut)? Csl, 19 | indcs: [usize; D] 20 | ) -> Option<$ref<'ret, DATA, 1>> 21 | where 22 | 'csl: 'ret, 23 | DATA: 'csl, 24 | DS: $trait<[DATA]>, 25 | IS: AsRef<[usize]>, 26 | OS: AsRef<[usize]>, 27 | { 28 | let last_dim = if let Some(r) = csl.dims.last() { 29 | *r 30 | } 31 | else { 32 | return None; 33 | }; 34 | let [offs_indcs, offs_values] = line_offs(&csl.dims, &indcs, csl.offs.as_ref())?; 35 | Some($ref { 36 | data: csl.data.$trait_fn().$get(offs_values.clone())?, 37 | dims: [last_dim].into(), 38 | indcs: &csl.indcs.as_ref().get(offs_values)?, 39 | offs: &csl.offs.as_ref().get(offs_indcs)?, 40 | }) 41 | } 42 | 43 | #[inline] 44 | pub(crate) fn $sub_dim_fn<'csl, 'ret, DATA: 'csl, DS, IS, OS, const FD: usize, const TD: usize>( 45 | csl: &'csl $($mut)? Csl, 46 | range: Range, 47 | ) -> Option<$ref<'ret, DATA, TD>> 48 | where 49 | 'csl: 'ret, 50 | DS: $trait<[DATA]>, 51 | IS: AsRef<[usize]>, 52 | OS: AsRef<[usize]>, 53 | { 54 | if range.start > range.end || TD > FD { 55 | return None; 56 | } 57 | let data_ref = csl.data.$trait_fn(); 58 | let dims_ref = &csl.dims; 59 | let indcs_ref = csl.indcs.as_ref(); 60 | let offs_ref = csl.offs.as_ref(); 61 | match TD { 62 | 0 => None, 63 | 1 => { 64 | let first = *offs_ref.first()?; 65 | let second = offs_ref.get(1)?; 66 | let [start_off_value, end_off_value] = [0, second.checked_sub(first)?]; 67 | let indcs = indcs_ref.get(start_off_value..end_off_value)?; 68 | let start = indcs.binary_search(&range.start).unwrap_or_else(|x| x); 69 | let end = indcs.get(start..)?.binary_search(&range.end).unwrap_or_else(|x| x); 70 | let dims_ref_idx = FD.checked_sub(TD)?; 71 | let dims_array = ArrayWrapper::try_from_fn(|_| { 72 | dims_ref.get(dims_ref_idx).copied().ok_or(()) 73 | }).ok()?; 74 | Some($ref { 75 | data: data_ref.$get(start..)?.$get(..end)?, 76 | dims: dims_array.into(), 77 | indcs: &indcs_ref.get(start..)?.get(..end)?, 78 | offs: &offs_ref.get(0..2)? 79 | }) 80 | }, 81 | _ => { 82 | let dims_ref_lower_bound = FD.checked_sub(TD)?; 83 | let mut dims = ArrayWrapper::try_from_fn(|idx| { 84 | let fun = || Some(*dims_ref.get(dims_ref_lower_bound..)?.get(idx)?); 85 | fun().ok_or(()) 86 | }).ok()?; 87 | *dims.first_mut()? = range.end.checked_sub(range.start)?; 88 | let [offs_indcs, offs_values] = outermost_offs(&dims, offs_ref, range); 89 | Some($ref { 90 | data: data_ref.$get(offs_values.clone())?, 91 | dims, 92 | indcs: &indcs_ref.get(offs_values)?, 93 | offs: &offs_ref.get(offs_indcs)?, 94 | }) 95 | }, 96 | } 97 | } 98 | 99 | }; 100 | } 101 | 102 | create_sub_dim!(AsMut as_mut CslMut get_mut line_mut sub_dim_mut [mut]); 103 | create_sub_dim!(AsRef as_ref CslRef get line sub_dim); 104 | 105 | // Max offset length is usize::MAX - 1 106 | #[inline] 107 | pub(crate) fn correct_offs_len(dims: &[usize; D]) -> crate::Result { 108 | match D { 109 | 0 => Ok(1), 110 | 1 => Ok(2), 111 | _ if dims == &ArrayWrapper::default().0 => Ok(1), 112 | _ => { 113 | let mut offs_len: usize = 1; 114 | for dim in dims.iter().copied().rev().skip(1).filter(|dim| dim != &0) { 115 | offs_len = offs_len.saturating_mul(dim); 116 | } 117 | offs_len.checked_add(1).ok_or_else(|| CslError::OffsLengthOverflow.into()) 118 | } 119 | } 120 | } 121 | 122 | #[inline] 123 | pub(crate) fn data_idx( 124 | csl: &Csl, 125 | indcs: [usize; D], 126 | ) -> Option 127 | where 128 | DS: AsRef<[DATA]>, 129 | IS: AsRef<[usize]>, 130 | OS: AsRef<[usize]>, 131 | { 132 | let innermost_idx = indcs.last()?; 133 | let [_, offs_values] = line_offs(&csl.dims, &indcs, csl.offs.as_ref())?; 134 | let start = offs_values.start; 135 | if let Ok(x) = csl.indcs.as_ref().get(offs_values)?.binary_search(innermost_idx) { 136 | start.checked_add(x) 137 | } else { 138 | None 139 | } 140 | } 141 | 142 | #[inline] 143 | pub(crate) fn line_offs( 144 | dims: &[usize; D], 145 | indcs: &[usize; D], 146 | offs: &[usize], 147 | ) -> Option<[Range; 2]> { 148 | match D { 149 | 0 => None, 150 | 1 => Some({ 151 | let off_end = offs.get(1)?.saturating_sub(*offs.first()?); 152 | [0..2, 0..off_end] 153 | }), 154 | _ => { 155 | let diff = indcs.len().saturating_sub(2); 156 | let mut lines: usize = 0; 157 | for (idx, curr_idx) in indcs.iter().copied().enumerate().take(diff) { 158 | let skip = idx.checked_add(1)?; 159 | let product = dims.iter().skip(skip).rev().skip(1).product::(); 160 | lines = lines.saturating_add(product.saturating_mul(curr_idx)); 161 | } 162 | let line_idx = dims.len().checked_sub(2)?; 163 | lines = lines.saturating_add(*indcs.get(line_idx)?); 164 | if lines > usize::MAX.saturating_sub(2) { 165 | return None; 166 | } 167 | let first = *offs.first()?; 168 | let off_start = offs.get(lines)?.saturating_sub(first); 169 | let lines_plus_one = lines.checked_add(1)?; 170 | let off_end = offs.get(lines_plus_one)?.saturating_sub(first); 171 | Some([lines..lines.saturating_add(2), off_start..off_end]) 172 | } 173 | } 174 | } 175 | 176 | #[inline] 177 | pub(crate) fn outermost_offs( 178 | dims: &[usize; D], 179 | offs: &[usize], 180 | range: Range, 181 | ) -> [Range; 2] { 182 | let outermost_stride = outermost_stride(dims); 183 | let start_off_idx = outermost_stride.saturating_mul(range.start); 184 | let end_off_idx = outermost_stride.saturating_mul(range.end); 185 | let off_start = *offs.get(start_off_idx).unwrap_or(&0); 186 | let off_end = *offs.get(end_off_idx).unwrap_or(&0); 187 | [start_off_idx..end_off_idx.saturating_add(1), off_start..off_end] 188 | } 189 | 190 | #[inline] 191 | pub(crate) fn outermost_stride(dims: &[usize; D]) -> usize { 192 | dims.iter().skip(1).rev().skip(1).product::() 193 | } 194 | 195 | #[inline] 196 | pub(crate) fn manage_last_offset(offs: &mut OS) -> crate::Result 197 | where 198 | OS: AsRef<[usize]> + Push, 199 | { 200 | Ok(if let Some(rslt) = offs.as_ref().last() { 201 | *rslt 202 | } else { 203 | offs.push(0).map_err(|_err| crate::Error::InsufficientCapacity)?; 204 | 0 205 | }) 206 | } 207 | -------------------------------------------------------------------------------- /ndstruct/src/csl/csl_line_constructor.rs: -------------------------------------------------------------------------------- 1 | use crate::csl::{csl_utils::manage_last_offset, Csl}; 2 | use cl_aux::{Push, SingleTypeStorage}; 3 | use core::fmt::{Debug, Display, Formatter}; 4 | 5 | /// Constructs valid lines in a easy and interactive manner, abstracting away the complexity 6 | /// of the compressed sparse format. 7 | #[derive(Debug, Eq, PartialEq)] 8 | pub struct CslLineConstructor<'csl, DS, IS, OS, const D: usize> { 9 | csl: &'csl mut Csl, 10 | curr_dim_idx: usize, 11 | last_off: usize, 12 | } 13 | 14 | impl<'csl, DATA, DS, IS, OS, const D: usize> CslLineConstructor<'csl, DS, IS, OS, D> 15 | where 16 | DS: AsRef<[DATA]> + Push + SingleTypeStorage, 17 | IS: AsRef<[usize]> + Push, 18 | OS: AsRef<[usize]> + Push, 19 | { 20 | #[inline] 21 | pub(crate) fn new(csl: &'csl mut Csl) -> crate::Result { 22 | if D == 0 { 23 | return Err(CslLineConstructorError::EmptyDimension.into()); 24 | } 25 | let curr_dim_idx = if let Some(idx) = csl.dims.iter().copied().position(|x| x != 0) { 26 | idx 27 | } else { 28 | csl.dims.len() 29 | }; 30 | let last_off = manage_last_offset(&mut csl.offs)?; 31 | Ok(Self { csl, curr_dim_idx, last_off }) 32 | } 33 | 34 | /// Jumps to the next outermost dimension, i.e., from right to left. 35 | /// 36 | /// # Example 37 | #[cfg_attr(feature = "alloc", doc = "```rust")] 38 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 39 | /// # fn main() -> ndstruct::Result<()> { 40 | /// use ndstruct::csl::{CslRef, CslVec}; 41 | /// let mut csl = CslVec::::default(); 42 | /// csl 43 | /// .constructor()? 44 | /// .next_outermost_dim(3)? 45 | /// .push_line([(0, 1)].iter().copied())? 46 | /// .next_outermost_dim(4)? 47 | /// .push_line([(1, 2)].iter().copied())? 48 | /// .push_empty_line()? 49 | /// .push_line([(0, 3), (1,4)].iter().copied())?; 50 | /// assert_eq!( 51 | /// csl.sub_dim(0..4), 52 | /// CslRef::new([4, 3], &[1, 2, 3, 4][..], &[0, 1, 0, 1][..], &[0, 1, 2, 2, 4][..]).ok() 53 | /// ); 54 | /// # Ok(()) } 55 | #[inline] 56 | pub fn next_outermost_dim(mut self, len: usize) -> crate::Result { 57 | self.curr_dim_idx = 58 | self.curr_dim_idx.checked_sub(1).ok_or(CslLineConstructorError::DimsOverflow)?; 59 | *self.curr_dim() = len; 60 | Ok(self) 61 | } 62 | 63 | /// This is the same as `push_line([].iter(), [].iter())`. 64 | /// 65 | /// # Example 66 | #[cfg_attr(feature = "alloc", doc = "```rust")] 67 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 68 | /// # fn main() -> ndstruct::Result<()> { 69 | /// use ndstruct::csl::{CslRef, CslVec}; 70 | /// let mut csl = CslVec::::default(); 71 | /// let constructor = csl.constructor()?.next_outermost_dim(3)?; 72 | /// constructor.push_empty_line()?.next_outermost_dim(2)?.push_empty_line()?; 73 | /// assert_eq!(csl.line([0, 0, 0]), CslRef::new([3], &[][..], &[][..], &[0, 0][..]).ok()); 74 | /// # Ok(()) } 75 | #[inline] 76 | pub fn push_empty_line(self) -> crate::Result { 77 | self.csl.offs.push(self.last_off).map_err(|_err| crate::Error::InsufficientCapacity)?; 78 | Ok(self) 79 | } 80 | 81 | /// Pushes a new compressed line, modifying the internal structure and if applicable, 82 | /// increases the current dimension length. 83 | /// 84 | /// The iterator will be truncated to (`usize::MAX` - last offset value + 1) or (last dimension value) 85 | /// and it can lead to a situation where no values will be inserted. 86 | /// 87 | /// # Arguments 88 | /// 89 | /// * `data`: Iterator of cloned items. 90 | /// * `indcs`: Iterator of the respective indices of each item. 91 | /// 92 | /// # Example 93 | #[cfg_attr(feature = "alloc", doc = "```rust")] 94 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 95 | /// # fn main() -> ndstruct::Result<()> { 96 | /// use ndstruct::csl::{CslRef, CslVec}; 97 | /// let mut csl = CslVec::::default(); 98 | /// csl.constructor()?.next_outermost_dim(50)?.push_line([(1, 1), (40, 2)].iter().copied())?; 99 | /// let line = csl.line([0, 0, 0]); 100 | /// assert_eq!(line, CslRef::new([50], &[1, 2][..], &[1, 40][..], &[0, 2][..]).ok()); 101 | /// # Ok(()) } 102 | #[inline] 103 | pub fn push_line(mut self, di: impl Iterator) -> crate::Result { 104 | let nnz_iter = 1..self.last_dim().saturating_add(1); 105 | let off_iter = self.last_off.saturating_add(1)..; 106 | let mut iter = off_iter.zip(nnz_iter.zip(di)); 107 | let mut last_off = self.last_off; 108 | let mut nnz = 0; 109 | 110 | let mut push = |curr_last_off, curr_nnz, idx, value| { 111 | self.csl.indcs.push(idx).map_err(|_err| crate::Error::InsufficientCapacity)?; 112 | self.csl.data.push(value).map_err(|_err| crate::Error::InsufficientCapacity)?; 113 | nnz = curr_nnz; 114 | last_off = curr_last_off; 115 | Ok::<(), crate::Error>(()) 116 | }; 117 | 118 | let mut last_line_idx = if let Some((curr_last_off, (curr_nnz, (idx, value)))) = iter.next() { 119 | push(curr_last_off, curr_nnz, idx, value)?; 120 | idx 121 | } else { 122 | return self.push_empty_line(); 123 | }; 124 | 125 | for (curr_last_off, (curr_nnz, (idx, value))) in iter { 126 | if idx <= last_line_idx { 127 | return Err(CslLineConstructorError::UnsortedIndices.into()); 128 | } 129 | push(curr_last_off, curr_nnz, idx, value)?; 130 | last_line_idx = idx; 131 | } 132 | 133 | if nnz == 0 { 134 | return self.push_empty_line(); 135 | } 136 | self.csl.offs.push(last_off).map_err(|_err| crate::Error::InsufficientCapacity)?; 137 | self.last_off = last_off; 138 | Ok(self) 139 | } 140 | 141 | #[expect(clippy::unwrap_used, reason = "`self.curr_dim_idx` always points to a valid reference")] 142 | fn curr_dim(&mut self) -> &mut usize { 143 | self.csl.dims.get_mut(self.curr_dim_idx).unwrap() 144 | } 145 | 146 | #[expect(clippy::unwrap_used, reason = "Constructor doesn't contain empty dimensions")] 147 | fn last_dim(&mut self) -> usize { 148 | *self.csl.dims.last().unwrap() 149 | } 150 | } 151 | 152 | /// Contains all errors related to [`CslLineConstructor`]. 153 | #[derive(Debug, Eq, PartialEq)] 154 | #[non_exhaustive] 155 | pub enum CslLineConstructorError { 156 | /// The maximum number of dimenstions has been reached 157 | DimsOverflow, 158 | /// All indices must be in ascending order 159 | UnsortedIndices, 160 | /// It isn't possible to construct new elements in an empty dimension 161 | EmptyDimension, 162 | /// The maximum number of lines for the currention dimension has been reached 163 | MaxNumOfLines, 164 | } 165 | 166 | impl Display for CslLineConstructorError { 167 | #[inline] 168 | fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { 169 | Debug::fmt(self, f) 170 | } 171 | } 172 | 173 | impl core::error::Error for CslLineConstructorError {} 174 | -------------------------------------------------------------------------------- /cl-aux/src/traits/insert.rs: -------------------------------------------------------------------------------- 1 | #![allow( 2 | // `_manage_hash` is also used by BTreeMap 3 | clippy::map_entry 4 | )] 5 | 6 | macro_rules! _manage_hash { 7 | ($hash:expr, $key:expr, $value:expr) => {{ 8 | if $hash.contains_key(&$key) { 9 | Err(crate::Error::AlreadyExistingElement) 10 | } else { 11 | let _maybe_discarded = $hash.insert($key, $value); 12 | Ok(()) 13 | } 14 | }}; 15 | } 16 | 17 | macro_rules! _manage_set { 18 | ($set:expr, $value:expr) => {{ 19 | if $set.contains(&$value) { 20 | Err(crate::Error::AlreadyExistingElement) 21 | } else { 22 | let _ = $set.insert($value); 23 | Ok(()) 24 | } 25 | }}; 26 | } 27 | 28 | #[cfg(feature = "alloc")] 29 | use alloc::{ 30 | collections::{BTreeMap, BTreeSet}, 31 | vec::Vec, 32 | }; 33 | #[cfg(feature = "std")] 34 | use std::collections::{HashMap, HashSet}; 35 | 36 | /// See [`Insert::insert`] for more information. 37 | pub trait Insert { 38 | /// Error 39 | type Error; 40 | /// Input 41 | type Input; 42 | 43 | /// Inserts an `Input` element. 44 | fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error>; 45 | } 46 | 47 | impl Insert for &mut T 48 | where 49 | T: Insert, 50 | { 51 | type Error = T::Error; 52 | type Input = T::Input; 53 | 54 | #[inline] 55 | fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error> { 56 | (*self).insert(input) 57 | } 58 | } 59 | 60 | /// ```rust 61 | /// let mut structure = cl_aux::doc_tests::b_tree_map(); 62 | /// cl_aux::Insert::insert(&mut structure, (10, 100)); 63 | /// assert_eq!(structure.iter().find(|(k, v)| **k == 10), Some((&10, &100))); 64 | /// ``` 65 | #[cfg(feature = "alloc")] 66 | impl Insert for BTreeMap 67 | where 68 | K: Ord, 69 | { 70 | type Error = crate::Error; 71 | type Input = (K, V); 72 | 73 | #[inline] 74 | fn insert(&mut self, (key, val): Self::Input) -> Result<(), Self::Error> { 75 | _manage_hash!(self, key, val) 76 | } 77 | } 78 | 79 | /// ```rust 80 | /// let mut structure = cl_aux::doc_tests::b_tree_set(); 81 | /// cl_aux::Insert::insert(&mut structure, 10); 82 | /// assert_eq!(structure.iter().find(|&&e| e == 10), Some(&10)); 83 | /// ``` 84 | #[cfg(feature = "alloc")] 85 | impl Insert for BTreeSet 86 | where 87 | V: Ord, 88 | { 89 | type Error = crate::Error; 90 | type Input = V; 91 | 92 | #[inline] 93 | fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error> { 94 | _manage_set!(self, input) 95 | } 96 | } 97 | 98 | /// ```rust 99 | /// let mut structure = cl_aux::doc_tests::hash_map(); 100 | /// cl_aux::Insert::insert(&mut structure, (10, 100)); 101 | /// assert_eq!(structure.iter().find(|(k, v)| **k == 10), Some((&10, &100))); 102 | /// ``` 103 | #[cfg(feature = "std")] 104 | impl Insert for HashMap 105 | where 106 | K: Eq + core::hash::Hash, 107 | S: core::hash::BuildHasher, 108 | { 109 | type Error = crate::Error; 110 | type Input = (K, V); 111 | 112 | #[inline] 113 | fn insert(&mut self, (k, v): Self::Input) -> Result<(), Self::Error> { 114 | _manage_hash!(self, k, v) 115 | } 116 | } 117 | 118 | /// ```rust 119 | /// let mut structure = cl_aux::doc_tests::hash_set(); 120 | /// cl_aux::Insert::insert(&mut structure, 10); 121 | /// assert_eq!(structure.iter().find(|&&e| e == 10), Some(&10)); 122 | /// ``` 123 | #[cfg(feature = "std")] 124 | impl Insert for HashSet 125 | where 126 | V: core::hash::Hash + Eq, 127 | S: core::hash::BuildHasher, 128 | { 129 | type Error = crate::Error; 130 | type Input = V; 131 | 132 | #[inline] 133 | fn insert(&mut self, v: Self::Input) -> Result<(), Self::Error> { 134 | _manage_set!(self, v) 135 | } 136 | } 137 | 138 | /// ```rust 139 | /// let mut opt = None; 140 | /// cl_aux::Insert::insert(&mut opt, 3); 141 | /// assert_eq!(opt, Some(3)); 142 | /// ``` 143 | impl Insert for Option { 144 | type Error = crate::Error; 145 | type Input = T; 146 | 147 | #[inline] 148 | fn insert(&mut self, input: Self::Input) -> Result<(), Self::Error> { 149 | if self.is_some() { 150 | Err(crate::Error::InsufficientCapacity(1)) 151 | } else { 152 | *self = Some(input); 153 | Ok(()) 154 | } 155 | } 156 | } 157 | 158 | /// ```rust 159 | /// let mut structure = cl_aux::doc_tests::vec(); 160 | /// cl_aux::Insert::insert(&mut structure, (0, 10)); 161 | /// assert_eq!(structure.get(0), Some(&10)); 162 | /// ``` 163 | #[cfg(feature = "alloc")] 164 | impl Insert for Vec { 165 | type Error = crate::Error; 166 | type Input = (usize, T); 167 | 168 | #[inline] 169 | fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> { 170 | _check_indcs!(self, idx); 171 | self.insert(idx, elem); 172 | Ok(()) 173 | } 174 | } 175 | 176 | /// ```rust 177 | /// let mut structure = cl_aux::doc_tests::array_vec(); 178 | /// cl_aux::Insert::insert(&mut structure, (0, 10)); 179 | /// assert_eq!(structure.get(0), Some(&10)); 180 | /// ``` 181 | #[cfg(feature = "arrayvec")] 182 | impl Insert for arrayvec::ArrayVec { 183 | type Error = crate::Error; 184 | type Input = (usize, T); 185 | 186 | #[inline] 187 | fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> { 188 | _check_indcs!(self, idx); 189 | self.insert(idx, elem); 190 | Ok(()) 191 | } 192 | } 193 | 194 | /// ```rust 195 | /// let mut structure = cl_aux::doc_tests::small_vec(); 196 | /// cl_aux::Insert::insert(&mut structure, (0, 10)); 197 | /// assert_eq!(structure.get(0), Some(&10)); 198 | /// ``` 199 | #[cfg(feature = "smallvec")] 200 | impl Insert for smallvec::SmallVec 201 | where 202 | A: smallvec::Array, 203 | { 204 | type Error = crate::Error; 205 | type Input = (usize, A::Item); 206 | 207 | #[inline] 208 | fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> { 209 | _check_indcs!(self, idx); 210 | self.insert(idx, elem); 211 | Ok(()) 212 | } 213 | } 214 | 215 | /// ```rust 216 | /// let mut structure = cl_aux::doc_tests::tiny_vec_array_vec(); 217 | /// cl_aux::Insert::insert(&mut structure, (0, 10)); 218 | /// assert_eq!(structure.get(0), Some(&10)); 219 | /// ``` 220 | #[cfg(feature = "tinyvec")] 221 | impl Insert for tinyvec::ArrayVec 222 | where 223 | A: tinyvec::Array, 224 | A::Item: Default, 225 | { 226 | type Error = crate::Error; 227 | type Input = (usize, A::Item); 228 | 229 | #[inline] 230 | fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> { 231 | _check_indcs!(self, idx); 232 | self.insert(idx, elem); 233 | Ok(()) 234 | } 235 | } 236 | 237 | /// ```rust 238 | /// let mut structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 239 | /// cl_aux::Insert::insert(&mut structure, (0, 10)); 240 | /// assert_eq!(structure.get(0), Some(&10)); 241 | /// ``` 242 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 243 | impl Insert for tinyvec::TinyVec 244 | where 245 | A: tinyvec::Array, 246 | A::Item: Default, 247 | { 248 | type Error = crate::Error; 249 | type Input = (usize, A::Item); 250 | 251 | #[inline] 252 | fn insert(&mut self, (idx, elem): Self::Input) -> Result<(), Self::Error> { 253 | _check_indcs!(self, idx); 254 | self.insert(idx, elem); 255 | Ok(()) 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /cl-aux/src/traits/size_hint.rs: -------------------------------------------------------------------------------- 1 | use crate::{IterWrapper, Length as _, SingleItemStorage}; 2 | #[cfg(feature = "alloc")] 3 | use alloc::{ 4 | collections::{BTreeMap, BTreeSet}, 5 | string::String, 6 | vec::Vec, 7 | }; 8 | #[cfg(feature = "std")] 9 | use std::collections::{HashMap, HashSet}; 10 | 11 | /// See [`SizeHint::size_hint`] for more information. 12 | pub trait SizeHint { 13 | /// Has the same semantics of [`Iterator::size_hint`]. 14 | fn size_hint(&self) -> (usize, Option); 15 | } 16 | 17 | impl SizeHint for &T 18 | where 19 | T: SizeHint, 20 | { 21 | #[inline] 22 | fn size_hint(&self) -> (usize, Option) { 23 | (*self).size_hint() 24 | } 25 | } 26 | 27 | impl SizeHint for IterWrapper 28 | where 29 | T: Iterator, 30 | { 31 | #[inline] 32 | fn size_hint(&self) -> (usize, Option) { 33 | self.0.size_hint() 34 | } 35 | } 36 | 37 | /// ```rust 38 | /// assert_eq!(cl_aux::SizeHint::size_hint(&()), (0, Some(0))); 39 | /// ``` 40 | impl SizeHint for () { 41 | #[inline] 42 | fn size_hint(&self) -> (usize, Option) { 43 | (0, Some(0)) 44 | } 45 | } 46 | 47 | /// ```rust 48 | /// let mut opt = Some(0); 49 | /// assert_eq!(cl_aux::SizeHint::size_hint(&opt), (1, Some(1))); 50 | /// opt.take(); 51 | /// assert_eq!(cl_aux::SizeHint::size_hint(&opt), (0, Some(0))); 52 | /// ``` 53 | impl SizeHint for Option { 54 | #[inline] 55 | fn size_hint(&self) -> (usize, Option) { 56 | (self.length(), Some(self.length())) 57 | } 58 | } 59 | 60 | /// ```rust 61 | /// let structure = cl_aux::doc_tests::single_item_storage(); 62 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (1, Some(1))); 63 | /// ``` 64 | impl SizeHint for SingleItemStorage { 65 | #[inline] 66 | fn size_hint(&self) -> (usize, Option) { 67 | (1, Some(1)) 68 | } 69 | } 70 | 71 | /// ```rust 72 | /// let structure = cl_aux::doc_tests::slice(); 73 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 74 | /// ``` 75 | impl SizeHint for [T] { 76 | #[inline] 77 | fn size_hint(&self) -> (usize, Option) { 78 | (self.len(), Some(self.len())) 79 | } 80 | } 81 | 82 | /// ```rust 83 | /// let structure = cl_aux::doc_tests::slice(); 84 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 85 | /// ``` 86 | impl SizeHint for &'_ [T] { 87 | #[inline] 88 | fn size_hint(&self) -> (usize, Option) { 89 | (self.len(), Some(self.len())) 90 | } 91 | } 92 | 93 | /// ```rust 94 | /// let mut structure = cl_aux::doc_tests::slice_mut!(); 95 | /// assert_eq!(cl_aux::SizeHint::size_hint(&mut structure), (3, Some(3))); 96 | /// ``` 97 | impl SizeHint for &'_ mut [T] { 98 | #[inline] 99 | fn size_hint(&self) -> (usize, Option) { 100 | (self.len(), Some(self.len())) 101 | } 102 | } 103 | 104 | /// ```rust 105 | /// let structure = cl_aux::doc_tests::array(); 106 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 107 | /// ``` 108 | impl SizeHint for [T; N] { 109 | #[inline] 110 | fn size_hint(&self) -> (usize, Option) { 111 | (self.len(), Some(self.len())) 112 | } 113 | } 114 | 115 | /// ```rust 116 | /// let mut structure = cl_aux::doc_tests::b_tree_map(); 117 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 118 | /// ``` 119 | #[cfg(feature = "alloc")] 120 | impl SizeHint for BTreeMap { 121 | #[inline] 122 | fn size_hint(&self) -> (usize, Option) { 123 | (self.len(), Some(self.len())) 124 | } 125 | } 126 | 127 | /// ```rust 128 | /// let mut structure = cl_aux::doc_tests::b_tree_set(); 129 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 130 | /// ``` 131 | #[cfg(feature = "alloc")] 132 | impl SizeHint for BTreeSet { 133 | #[inline] 134 | fn size_hint(&self) -> (usize, Option) { 135 | (self.len(), Some(self.len())) 136 | } 137 | } 138 | 139 | /// ```rust 140 | /// let mut structure = cl_aux::doc_tests::hash_map(); 141 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 142 | /// ``` 143 | #[cfg(feature = "std")] 144 | impl SizeHint for HashMap 145 | where 146 | S: core::hash::BuildHasher, 147 | { 148 | #[inline] 149 | fn size_hint(&self) -> (usize, Option) { 150 | (self.len(), Some(self.len())) 151 | } 152 | } 153 | 154 | /// ```rust 155 | /// let mut structure = cl_aux::doc_tests::hash_set(); 156 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 157 | /// ``` 158 | #[cfg(feature = "std")] 159 | impl SizeHint for HashSet 160 | where 161 | S: core::hash::BuildHasher, 162 | { 163 | #[inline] 164 | fn size_hint(&self) -> (usize, Option) { 165 | (self.len(), Some(self.len())) 166 | } 167 | } 168 | 169 | /// ```rust 170 | /// let structure = cl_aux::doc_tests::string(); 171 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (5, Some(5))); 172 | /// ``` 173 | #[cfg(feature = "alloc")] 174 | impl SizeHint for String { 175 | #[inline] 176 | fn size_hint(&self) -> (usize, Option) { 177 | (self.len(), Some(self.len())) 178 | } 179 | } 180 | 181 | /// ```rust 182 | /// let structure = cl_aux::doc_tests::vec(); 183 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 184 | /// ``` 185 | #[cfg(feature = "alloc")] 186 | impl SizeHint for Vec { 187 | #[inline] 188 | fn size_hint(&self) -> (usize, Option) { 189 | (self.len(), Some(self.len())) 190 | } 191 | } 192 | 193 | /// ```rust 194 | /// let structure = cl_aux::doc_tests::array_string(); 195 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (5, Some(5))); 196 | /// ``` 197 | #[cfg(feature = "arrayvec")] 198 | impl SizeHint for arrayvec::ArrayString { 199 | #[inline] 200 | fn size_hint(&self) -> (usize, Option) { 201 | (self.len(), Some(self.len())) 202 | } 203 | } 204 | 205 | /// ```rust 206 | /// let structure = cl_aux::doc_tests::array_vec(); 207 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 208 | /// ``` 209 | #[cfg(feature = "arrayvec")] 210 | impl SizeHint for arrayvec::ArrayVec { 211 | #[inline] 212 | fn size_hint(&self) -> (usize, Option) { 213 | (self.len(), Some(self.len())) 214 | } 215 | } 216 | 217 | /// ```rust 218 | /// let structure = cl_aux::doc_tests::small_vec(); 219 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 220 | /// ``` 221 | #[cfg(feature = "smallvec")] 222 | impl SizeHint for smallvec::SmallVec 223 | where 224 | A: smallvec::Array, 225 | { 226 | #[inline] 227 | fn size_hint(&self) -> (usize, Option) { 228 | (self.len(), Some(self.len())) 229 | } 230 | } 231 | 232 | /// ```rust 233 | /// let structure = cl_aux::doc_tests::tiny_vec_array_vec(); 234 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 235 | /// ``` 236 | #[cfg(feature = "tinyvec")] 237 | impl SizeHint for tinyvec::ArrayVec 238 | where 239 | A: tinyvec::Array, 240 | A::Item: Default, 241 | { 242 | #[inline] 243 | fn size_hint(&self) -> (usize, Option) { 244 | (self.len(), Some(self.len())) 245 | } 246 | } 247 | 248 | /// ```rust 249 | /// let structure = cl_aux::doc_tests::tiny_vec_tiny_vec(); 250 | /// assert_eq!(cl_aux::SizeHint::size_hint(&structure), (3, Some(3))); 251 | /// ``` 252 | #[cfg(all(feature = "alloc", feature = "tinyvec"))] 253 | impl SizeHint for tinyvec::TinyVec 254 | where 255 | A: tinyvec::Array, 256 | A::Item: Default, 257 | { 258 | #[inline] 259 | fn size_hint(&self) -> (usize, Option) { 260 | (self.len(), Some(self.len())) 261 | } 262 | } 263 | -------------------------------------------------------------------------------- /ndstruct/src/coo.rs: -------------------------------------------------------------------------------- 1 | //! COO (Coordinate) format for N-dimensions. 2 | 3 | mod coo_error; 4 | mod coo_utils; 5 | 6 | #[cfg(feature = "alloc")] 7 | use alloc::vec::Vec; 8 | use cl_aux::{ArrayWrapper, SingleTypeStorage}; 9 | pub use coo_error::*; 10 | use coo_utils::{does_not_have_duplicates_sorted, value, value_mut}; 11 | 12 | /// COO backed by a static array. 13 | pub type CooArray = Coo<[([usize; D], DATA); DN], D>; 14 | /// COO backed by a mutable slice 15 | pub type CooMut<'data, DATA, const D: usize> = Coo<&'data mut [([usize; D], DATA)], D>; 16 | /// COO backed by a slice 17 | pub type CooRef<'data, DATA, const D: usize> = Coo<&'data [([usize; D], DATA)], D>; 18 | #[cfg(feature = "alloc")] 19 | /// COO backed by a dynamic vector. 20 | pub type CooVec = Coo, D>; 21 | 22 | /// Base structure for all [Coo] variants. 23 | /// 24 | /// # Types 25 | /// 26 | /// * `D`: Number of dimensions 27 | /// * `DS`: Data Storage 28 | #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] 29 | #[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd)] 30 | pub struct Coo { 31 | pub(crate) data: DS, 32 | pub(crate) dims: ArrayWrapper, 33 | } 34 | 35 | impl Coo { 36 | /// The definitions of all dimensions. 37 | /// 38 | /// # Example 39 | /// 40 | /// ```rust 41 | /// use ndstruct::doc_tests::coo_array_5; 42 | /// assert_eq!(coo_array_5().dims(), &[2, 3, 4, 3, 3]); 43 | /// ``` 44 | #[inline] 45 | pub fn dims(&self) -> &[usize; D] { 46 | &self.dims 47 | } 48 | } 49 | 50 | impl Coo 51 | where 52 | DS: AsRef<[::Item]> + SingleTypeStorage, 53 | { 54 | /// Creates a valid COO instance. 55 | /// 56 | /// # Arguments 57 | /// 58 | /// * `dims`: Array of dimensions 59 | /// * `data`: Data collection 60 | /// 61 | /// # Example 62 | #[cfg_attr(feature = "alloc", doc = "```rust")] 63 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 64 | /// use ndstruct::coo::{CooArray, CooVec}; 65 | /// // Sparse array ([8, _, _, _, _, 9, _, _, _, _]) 66 | /// let mut _sparse_array = CooArray::new([10], [([0], 8.0), ([5], 9.0)]); 67 | /// // A bunch of nothing for your overflow needs 68 | /// let mut _over_nine: ndstruct::Result>; 69 | /// _over_nine = CooVec::new([0; 9001], vec![]); 70 | /// ``` 71 | #[inline] 72 | pub fn new(dims: [usize; D], data: DS) -> crate::Result { 73 | if !crate::utils::are_in_ascending_order(data.as_ref(), |a, b| [&a.0, &b.0]) { 74 | return Err(CooError::InvalidIndcsOrder.into()); 75 | } 76 | let has_invalid_indcs = !data.as_ref().iter().all(|&(indcs, _)| { 77 | indcs.iter().zip(dims.iter()).all( 78 | |(data_idx, dim)| { 79 | if dim == &0 { 80 | true 81 | } else { 82 | data_idx < dim 83 | } 84 | }, 85 | ) 86 | }); 87 | if has_invalid_indcs { 88 | return Err(CooError::InvalidIndcs.into()); 89 | } 90 | if !does_not_have_duplicates_sorted(data.as_ref(), |a, b| a.0[..] != b.0[..]) { 91 | return Err(CooError::DuplicatedIndices.into()); 92 | } 93 | Ok(Self { data, dims: dims.into() }) 94 | } 95 | 96 | /// The data that is being stored. 97 | /// 98 | /// # Example 99 | /// 100 | /// ```rust 101 | /// use ndstruct::doc_tests::coo_array_5; 102 | /// assert_eq!(coo_array_5().data().first(), Some(&([0, 0, 1, 1, 2].into(), 1))); 103 | /// ``` 104 | #[inline] 105 | pub fn data(&self) -> &[([usize; D], DATA)] { 106 | self.data.as_ref() 107 | } 108 | 109 | /// If any, retrieves an immutable data reference of a given set of indices. 110 | /// 111 | /// # Arguments 112 | /// 113 | /// * `indcs`: Indices of the desired data location 114 | /// 115 | /// # Example 116 | /// 117 | /// ```rust 118 | /// use ndstruct::doc_tests::coo_array_5; 119 | /// let coo = coo_array_5(); 120 | /// assert_eq!(coo.value([0, 0, 0, 0, 0]), None); 121 | /// assert_eq!(coo.value([0, 2, 2, 0, 1]), Some(&4)); 122 | /// ``` 123 | #[inline] 124 | pub fn value(&self, indcs: [usize; D]) -> Option<&DATA> { 125 | value(indcs, self.data.as_ref()) 126 | } 127 | } 128 | 129 | impl Coo 130 | where 131 | DS: AsMut<[::Item]> + SingleTypeStorage, 132 | { 133 | /// Mutable version of [`value`](#method.value). 134 | #[inline] 135 | pub fn value_mut(&mut self, indcs: [usize; D]) -> Option<&mut DATA> { 136 | value_mut(indcs, self.data.as_mut()) 137 | } 138 | } 139 | 140 | #[cfg(feature = "rand")] 141 | impl Coo 142 | where 143 | DS: AsMut<[::Item]> 144 | + AsRef<[::Item]> 145 | + Default 146 | + SingleTypeStorage 147 | + cl_aux::CapacityUpperBound 148 | + cl_aux::Push<::Item>, 149 | { 150 | /// Creates a new random and valid instance delimited by the passed arguments. 151 | /// 152 | /// # Arguments 153 | /// 154 | /// * `dims`: Array of dimensions 155 | /// * `nnz`: Number of Non-Zero elements 156 | /// * `rng`: `rand::Rng` trait 157 | /// * `cb`: Callback to control data creation 158 | /// 159 | /// # Example 160 | #[cfg_attr(feature = "alloc", doc = "```rust")] 161 | #[cfg_attr(not(feature = "alloc"), doc = "```ignore")] 162 | /// use ndstruct::coo::CooVec; 163 | /// use rand::{Rng, rngs::mock::StepRng}; 164 | /// let mut rng = StepRng::new(0, 1); 165 | /// let dims = [1, 2, 3]; 166 | /// let mut _random: ndstruct::Result>; 167 | /// _random = CooVec::new_controlled_random_rand(dims, 3, &mut rng, |r, _| r.gen()); 168 | /// ``` 169 | #[inline] 170 | pub fn new_controlled_random_rand( 171 | dims: [usize; D], 172 | nnz: usize, 173 | rng: &mut R, 174 | mut cb: impl FnMut(&mut R, &[usize; D]) -> DATA, 175 | ) -> crate::Result 176 | where 177 | R: rand::Rng, 178 | { 179 | use rand::distr::Distribution as _; 180 | if nnz > crate::utils::max_nnz(&dims) { 181 | return Err(CooError::NnzGreaterThanMaximumNnz.into()); 182 | } 183 | let mut data: DS = Default::default(); 184 | if nnz > data.as_ref().len() { 185 | return Err(crate::Error::InsufficientCapacity); 186 | } 187 | for _ in 0..nnz { 188 | let indcs: [usize; D] = ArrayWrapper::from_fn(|idx| { 189 | let dim = *dims.get(idx).unwrap_or(&0); 190 | if dim == 0 { 191 | 0 192 | } else { 193 | rand::distr::Uniform::new(0, dim).ok().map(|el| el.sample(rng)).unwrap_or_default() 194 | } 195 | }) 196 | .0; 197 | if data.as_ref().iter().all(|value| value.0 != indcs) { 198 | data 199 | .push({ 200 | let element = cb(rng, &indcs); 201 | (indcs, element) 202 | }) 203 | .map_err(|_err| crate::Error::InsufficientCapacity)?; 204 | } 205 | } 206 | data.as_mut().sort_unstable_by(|a, b| a.0.cmp(&b.0)); 207 | Coo::new(dims, data) 208 | } 209 | 210 | /// Creates a new random and valid instance. 211 | /// 212 | /// # Arguments 213 | /// 214 | /// * `rng`: `rand::Rng` trait 215 | /// * `upper_bound`: The maximum allowed exclusive dimension 216 | #[inline] 217 | pub fn new_random_rand(rng: &mut R, upper_bound: usize) -> crate::Result 218 | where 219 | R: rand::Rng, 220 | rand::distr::StandardUniform: rand::distr::Distribution, 221 | { 222 | let dims = crate::utils::valid_random_dims(rng, upper_bound); 223 | let max_nnz = crate::utils::max_nnz(&dims); 224 | let nnz = if max_nnz == 0 { 0 } else { rng.random_range(0..max_nnz) }; 225 | Self::new_controlled_random_rand(dims, nnz, rng, |r, _| r.random()) 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "arbitrary" 7 | version = "1.4.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" 10 | dependencies = [ 11 | "derive_arbitrary", 12 | ] 13 | 14 | [[package]] 15 | name = "arrayvec" 16 | version = "0.7.6" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 19 | 20 | [[package]] 21 | name = "bitflags" 22 | version = "2.9.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" 25 | 26 | [[package]] 27 | name = "cc" 28 | version = "1.2.34" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" 31 | dependencies = [ 32 | "jobserver", 33 | "libc", 34 | "shlex", 35 | ] 36 | 37 | [[package]] 38 | name = "cfg-if" 39 | version = "1.0.3" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" 42 | 43 | [[package]] 44 | name = "cl-aux" 45 | version = "5.1.0" 46 | dependencies = [ 47 | "arrayvec", 48 | "serde", 49 | "smallvec", 50 | "tinyvec", 51 | ] 52 | 53 | [[package]] 54 | name = "crossbeam-deque" 55 | version = "0.8.6" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" 58 | dependencies = [ 59 | "crossbeam-epoch", 60 | "crossbeam-utils", 61 | ] 62 | 63 | [[package]] 64 | name = "crossbeam-epoch" 65 | version = "0.9.18" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 68 | dependencies = [ 69 | "crossbeam-utils", 70 | ] 71 | 72 | [[package]] 73 | name = "crossbeam-utils" 74 | version = "0.8.21" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 77 | 78 | [[package]] 79 | name = "derive_arbitrary" 80 | version = "1.4.2" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" 83 | dependencies = [ 84 | "proc-macro2", 85 | "quote", 86 | "syn", 87 | ] 88 | 89 | [[package]] 90 | name = "either" 91 | version = "1.15.0" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" 94 | 95 | [[package]] 96 | name = "getrandom" 97 | version = "0.3.3" 98 | source = "registry+https://github.com/rust-lang/crates.io-index" 99 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 100 | dependencies = [ 101 | "cfg-if", 102 | "libc", 103 | "r-efi", 104 | "wasi", 105 | ] 106 | 107 | [[package]] 108 | name = "jobserver" 109 | version = "0.1.33" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" 112 | dependencies = [ 113 | "getrandom", 114 | "libc", 115 | ] 116 | 117 | [[package]] 118 | name = "libc" 119 | version = "0.2.175" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" 122 | 123 | [[package]] 124 | name = "libfuzzer-sys" 125 | version = "0.4.10" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" 128 | dependencies = [ 129 | "arbitrary", 130 | "cc", 131 | ] 132 | 133 | [[package]] 134 | name = "ndstruct" 135 | version = "2.3.0" 136 | dependencies = [ 137 | "cl-aux", 138 | "rand", 139 | "rayon", 140 | "serde", 141 | ] 142 | 143 | [[package]] 144 | name = "ndstruct-fuzz" 145 | version = "0.0.0" 146 | dependencies = [ 147 | "arbitrary", 148 | "libfuzzer-sys", 149 | "ndstruct", 150 | "rand", 151 | "rayon", 152 | ] 153 | 154 | [[package]] 155 | name = "proc-macro2" 156 | version = "1.0.101" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" 159 | dependencies = [ 160 | "unicode-ident", 161 | ] 162 | 163 | [[package]] 164 | name = "quote" 165 | version = "1.0.40" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 168 | dependencies = [ 169 | "proc-macro2", 170 | ] 171 | 172 | [[package]] 173 | name = "r-efi" 174 | version = "5.3.0" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 177 | 178 | [[package]] 179 | name = "rand" 180 | version = "0.9.2" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" 183 | dependencies = [ 184 | "rand_core", 185 | ] 186 | 187 | [[package]] 188 | name = "rand_core" 189 | version = "0.9.3" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 192 | 193 | [[package]] 194 | name = "rayon" 195 | version = "1.11.0" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" 198 | dependencies = [ 199 | "either", 200 | "rayon-core", 201 | ] 202 | 203 | [[package]] 204 | name = "rayon-core" 205 | version = "1.13.0" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" 208 | dependencies = [ 209 | "crossbeam-deque", 210 | "crossbeam-utils", 211 | ] 212 | 213 | [[package]] 214 | name = "rust-tools" 215 | version = "1.0.3" 216 | 217 | [[package]] 218 | name = "serde" 219 | version = "1.0.219" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 222 | dependencies = [ 223 | "serde_derive", 224 | ] 225 | 226 | [[package]] 227 | name = "serde_derive" 228 | version = "1.0.219" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 231 | dependencies = [ 232 | "proc-macro2", 233 | "quote", 234 | "syn", 235 | ] 236 | 237 | [[package]] 238 | name = "shlex" 239 | version = "1.3.0" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 242 | 243 | [[package]] 244 | name = "smallvec" 245 | version = "1.15.1" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" 248 | 249 | [[package]] 250 | name = "syn" 251 | version = "2.0.106" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" 254 | dependencies = [ 255 | "proc-macro2", 256 | "quote", 257 | "unicode-ident", 258 | ] 259 | 260 | [[package]] 261 | name = "tinyvec" 262 | version = "1.10.0" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" 265 | dependencies = [ 266 | "tinyvec_macros", 267 | ] 268 | 269 | [[package]] 270 | name = "tinyvec_macros" 271 | version = "0.1.1" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 274 | 275 | [[package]] 276 | name = "unicode-ident" 277 | version = "1.0.18" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 280 | 281 | [[package]] 282 | name = "wasi" 283 | version = "0.14.2+wasi-0.2.4" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 286 | dependencies = [ 287 | "wit-bindgen-rt", 288 | ] 289 | 290 | [[package]] 291 | name = "wit-bindgen-rt" 292 | version = "0.39.0" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 295 | dependencies = [ 296 | "bitflags", 297 | ] 298 | --------------------------------------------------------------------------------