diff --git a/Cargo.toml b/Cargo.toml index 1d9dc8b..7549b13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,8 +3,8 @@ name = "cantrip" version = "0.0.0" edition = "2021" -[build] -incremental = true +[badges] +maintenance = { status = "actively-developed" } [profile.dev] opt-level = 1 @@ -16,9 +16,9 @@ lto = true codegen-units = 1 panic = "unwind" -[lints.clippy] +[lints.rust] all = "deny" -[env] -RUSTFLAGS = "-D warnings -W absolute-paths-not-starting-with-crate -W box_pointers -W dead_code -W elided-lifetimes-in-paths -W explicit-outlives-requirements -W ffi-unwind-calls -W keyword-idents -W let-underscore-drop -W macro-use-extern-crate -W meta-variable-misuse -W missing-abi -W missing-copy-implementations -W missing-debug-implementations -W missing-docs -W non_ascii_idents -W noop_method_call -W pointer_structural_match -W rust_2021_incompatible_closure_captures -W rust_2021_incompatible_or_patterns -W rust_2021_prefixes_incompatible_syntax -W rust_2021_prelude_collisions -W single_use_lifetimes -W trivial_casts -W trivial_numeric_casts -W unreachable_pub -W unsafe_code -W unsafe_op_in_unsafe_fn -W unstable_features -W unused_crate_dependencies -W unused_extern_crates -W unused_import_braces -W unused_lifetimes -W unused_macro_rules -W unused_qualifications -W unused_results -W variant_size_differences" +[lints.clippy] +all = "deny" diff --git a/src/extensions/collectible.rs b/src/extensions/collectible.rs index de9ad34..534fc0b 100644 --- a/src/extensions/collectible.rs +++ b/src/extensions/collectible.rs @@ -2,7 +2,7 @@ use crate::extensions::iterable::Iterable; use crate::extensions::util::unfold::unfold; use crate::extensions::{collect_by_index, frequencies}; use std::cmp::Reverse; -use std::collections::{BinaryHeap, HashMap, HashSet}; +use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList}; use std::hash::Hash; use std::iter; use std::iter::{Product, Sum}; @@ -38,7 +38,7 @@ pub trait Collectible: IntoIterator { } /// Creates a new collection by appending all elements of another collection to - /// the this collection. + /// this collection. /// /// # Example /// @@ -1038,7 +1038,7 @@ pub trait Collectible: IntoIterator { /// Creates a new collection containing all sub-collections of this collection. /// /// Sub-collections for sequences are generated based on element positions, not values. - /// Therefore, if an sequence contains duplicate elements, the resulting sub-collections will too. + /// Therefore, if a sequence contains duplicate elements, the resulting sub-collections will too. /// To obtain combinations of unique elements for sequences, use `.unique().powerset()`. /// /// The order of sub-collection values is preserved for sequences. @@ -1236,19 +1236,16 @@ pub trait Collectible: IntoIterator { Item: Eq + Hash + 'a, Self: IntoIterator + FromIterator, { - let mut replaced: HashMap<&Item, usize> = frequencies(elements.iterator()); - let mut replacement_items = replacements.into_iter(); + let elements_iterator = elements.iterator(); + let mut replaced_items: HashMap<&Item, LinkedList> = HashMap::with_capacity(elements_iterator.size_hint().0); + for (item, replacement) in elements_iterator.zip(replacements.into_iter()) { + replaced_items.entry(item).or_default().push_back(replacement); + } self .into_iter() - .flat_map(|item| { - if let Some(count) = replaced.get_mut(&item) { - if *count > 0 { - *count -= 1; - return replacement_items.next().or(Some(item)); - } - } - Some(item) - }) + .map( + |item| if let Some(items) = replaced_items.get_mut(&item) { items.pop_front().unwrap_or(item) } else { item }, + ) .collect() } diff --git a/src/extensions/ordered.rs b/src/extensions/ordered.rs index 68ed48b..8718723 100644 --- a/src/extensions/ordered.rs +++ b/src/extensions/ordered.rs @@ -313,7 +313,7 @@ pub trait Ordered { /// /// After finding a starting element of specified sequence in this sequence, /// `position_seq()` compares each element of this sequence with the specified value, - /// and if all of them matche, then `position_seq()` returns [`Some(start_index)`]. + /// and if all of them match, then `position_seq()` returns [`Some(start_index)`]. /// If any of the elements do not match, it returns [`None`]. /// /// `position_seq()` is short-circuiting; in other words, it will stop diff --git a/src/extensions/sequence.rs b/src/extensions/sequence.rs index 9636459..6a5be22 100644 --- a/src/extensions/sequence.rs +++ b/src/extensions/sequence.rs @@ -2178,19 +2178,19 @@ pub(crate) fn combinations_multi<'a, Item: Clone + 'a, Collection: FromIterator< ) -> Vec { let values = Vec::from_iter(iterator); let size = values.len(); - let mut multicombination = Vec::from_iter(iter::once(i64::MIN).chain(iter::repeat(0).take(k))); + let mut multi_combination = Vec::from_iter(iter::once(i64::MIN).chain(iter::repeat(0).take(k))); let mut current_slot = (size + 1).saturating_sub(k); unfold(|| { if current_slot == 0 { return None; } current_slot = k; - let result = Some(collect_by_index(&values, &multicombination[1..])); - while multicombination[current_slot] >= (size - 1) as i64 { + let result = Some(collect_by_index(&values, &multi_combination[1..])); + while multi_combination[current_slot] >= (size - 1) as i64 { current_slot -= 1; } - let new_index = multicombination[current_slot] + 1; - for index in &mut multicombination[current_slot..=k] { + let new_index = multi_combination[current_slot] + 1; + for index in &mut multi_combination[current_slot..=k] { *index = new_index; } result