From e4ac4629a577de8588921d75ee04eecea8eca2ef Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Fri, 4 Sep 2020 14:45:49 -0400 Subject: [PATCH 1/3] introduce use_alloc --- Cargo.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3ec0f56f8..3de576bc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,8 @@ version = "0.2" [features] default = ["use_std"] -use_std = [] +use_std = ["use_alloc"] +use_alloc = [] [profile] bench = { debug = true } From 450ec0c76db31cdfdaf11824d945fb5695f66a26 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Fri, 4 Sep 2020 14:53:30 -0400 Subject: [PATCH 2/3] use_std -> use_alloc, when possible --- src/adaptors/mod.rs | 2 +- src/adaptors/multi_product.rs | 4 +- src/combinations.rs | 1 + src/combinations_with_replacement.rs | 3 +- src/free.rs | 27 ++++---- src/groupbylazy.rs | 2 +- src/kmerge_impl.rs | 1 + src/lazy_buffer.rs | 1 + src/lib.rs | 97 +++++++++++++++------------- src/multipeek_impl.rs | 2 +- src/peek_nth.rs | 2 +- src/peeking_take_while.rs | 12 ++-- src/permutations.rs | 1 + src/put_back_n_impl.rs | 2 + src/rciter_impl.rs | 2 +- src/tee.rs | 4 +- 16 files changed, 93 insertions(+), 70 deletions(-) diff --git a/src/adaptors/mod.rs b/src/adaptors/mod.rs index 0b9d1185f..e77bbf032 100644 --- a/src/adaptors/mod.rs +++ b/src/adaptors/mod.rs @@ -11,7 +11,7 @@ pub use self::coalesce::*; pub use self::map::{map_into, map_ok, MapInto, MapOk}; #[allow(deprecated)] pub use self::map::MapResults; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub use self::multi_product::*; use std::fmt; diff --git a/src/adaptors/multi_product.rs b/src/adaptors/multi_product.rs index 532333a48..6938014ce 100644 --- a/src/adaptors/multi_product.rs +++ b/src/adaptors/multi_product.rs @@ -1,8 +1,10 @@ -#![cfg(feature = "use_std")] +#![cfg(feature = "use_alloc")] use crate::size_hint; use crate::Itertools; +use alloc::vec::Vec; + #[derive(Clone)] /// An iterator adaptor that iterates over the cartesian product of /// multiple iterators of type `I`. diff --git a/src/combinations.rs b/src/combinations.rs index a8b612f17..9231a7b41 100644 --- a/src/combinations.rs +++ b/src/combinations.rs @@ -1,6 +1,7 @@ use std::fmt; use super::lazy_buffer::LazyBuffer; +use alloc::vec::Vec; /// An iterator to iterate through all the `k`-length combinations in an iterator. /// diff --git a/src/combinations_with_replacement.rs b/src/combinations_with_replacement.rs index d51154521..38556c039 100644 --- a/src/combinations_with_replacement.rs +++ b/src/combinations_with_replacement.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use std::fmt; use super::lazy_buffer::LazyBuffer; @@ -44,7 +45,7 @@ where I: Iterator, I::Item: Clone, { - let indices: Vec = vec![0; k]; + let indices: Vec = alloc::vec![0; k]; let pool: LazyBuffer = LazyBuffer::new(iter); CombinationsWithReplacement { diff --git a/src/free.rs b/src/free.rs index a9008537b..bfc5ab422 100644 --- a/src/free.rs +++ b/src/free.rs @@ -3,13 +3,18 @@ //! The benefit of free functions is that they accept any `IntoIterator` as //! argument, so the resulting code may be easier to read. -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] use std::fmt::Display; use std::iter::{self, Zip}; -#[cfg(feature = "use_std")] -type VecIntoIter = ::std::vec::IntoIter; +#[cfg(feature = "use_alloc")] +type VecIntoIter = alloc::vec::IntoIter; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] +use alloc::{ + string::String, +}; + +#[cfg(feature = "use_alloc")] use crate::Itertools; pub use crate::adaptors::{ @@ -17,17 +22,17 @@ pub use crate::adaptors::{ merge, put_back, }; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub use crate::put_back_n_impl::put_back_n; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub use crate::multipeek_impl::multipeek; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub use crate::peek_nth::peek_nth; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub use crate::kmerge_impl::kmerge; pub use crate::zip_eq_impl::zip_eq; pub use crate::merge_join::merge_join_by; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub use crate::rciter_impl::rciter; /// Iterate `iterable` with a running index. @@ -208,7 +213,7 @@ pub fn min(iterable: I) -> Option /// /// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3"); /// ``` -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub fn join(iterable: I, sep: &str) -> String where I: IntoIterator, I::Item: Display @@ -228,7 +233,7 @@ pub fn join(iterable: I, sep: &str) -> String /// /// assert_equal(sorted("rust".chars()), "rstu".chars()); /// ``` -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub fn sorted(iterable: I) -> VecIntoIter where I: IntoIterator, I::Item: Ord diff --git a/src/groupbylazy.rs b/src/groupbylazy.rs index bf6e3c7a1..5d4a0c92e 100644 --- a/src/groupbylazy.rs +++ b/src/groupbylazy.rs @@ -1,5 +1,5 @@ use std::cell::{Cell, RefCell}; -use std::vec; +use alloc::vec::{self, Vec}; /// A trait to unify FnMut for GroupBy with the chunk key in IntoChunks trait KeyFunction { diff --git a/src/kmerge_impl.rs b/src/kmerge_impl.rs index 8f68aeb25..a1b3d8e6c 100644 --- a/src/kmerge_impl.rs +++ b/src/kmerge_impl.rs @@ -1,6 +1,7 @@ use crate::size_hint; use crate::Itertools; +use alloc::vec::Vec; use std::mem::replace; use std::fmt; diff --git a/src/lazy_buffer.rs b/src/lazy_buffer.rs index 01123d473..931755aa5 100644 --- a/src/lazy_buffer.rs +++ b/src/lazy_buffer.rs @@ -1,4 +1,5 @@ use std::ops::Index; +use alloc::vec::Vec; #[derive(Debug, Clone)] pub struct LazyBuffer { diff --git a/src/lib.rs b/src/lib.rs index 4c10178fd..00264e466 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,6 +50,15 @@ #[cfg(not(feature = "use_std"))] extern crate core as std; +#[cfg(feature = "use_alloc")] +extern crate alloc; + +#[cfg(feature = "use_alloc")] +use alloc::{ + string::String, + vec::Vec, +}; + pub use either::Either; #[cfg(feature = "use_std")] @@ -59,11 +68,11 @@ use std::cmp::Ordering; use std::fmt; #[cfg(feature = "use_std")] use std::hash::Hash; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] use std::fmt::Write; -#[cfg(feature = "use_std")] -type VecIntoIter = ::std::vec::IntoIter; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] +type VecIntoIter = alloc::vec::IntoIter; +#[cfg(feature = "use_alloc")] use std::iter::FromIterator; #[macro_use] @@ -100,38 +109,38 @@ pub mod structs { }; #[allow(deprecated)] pub use crate::adaptors::{MapResults, Step}; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::adaptors::MultiProduct; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::combinations::Combinations; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::combinations_with_replacement::CombinationsWithReplacement; pub use crate::cons_tuples_impl::ConsTuples; pub use crate::exactly_one_err::ExactlyOneError; pub use crate::format::{Format, FormatWith}; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::groupbylazy::{IntoChunks, Chunk, Chunks, GroupBy, Group, Groups}; pub use crate::intersperse::{Intersperse, IntersperseWith}; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::kmerge_impl::{KMerge, KMergeBy}; pub use crate::merge_join::MergeJoinBy; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::multipeek_impl::MultiPeek; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::peek_nth::PeekNth; pub use crate::pad_tail::PadUsing; pub use crate::peeking_take_while::PeekingTakeWhile; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::permutations::Permutations; pub use crate::process_results_impl::ProcessResults; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::put_back_n_impl::PutBackN; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::rciter_impl::RcIter; pub use crate::repeatn::RepeatN; #[allow(deprecated)] pub use crate::sources::{RepeatCall, Unfold, Iterate}; - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] pub use crate::tee::Tee; pub use crate::tuple_impl::{TupleBuffer, TupleWindows, CircularTupleWindows, Tuples}; #[cfg(feature = "use_std")] @@ -153,7 +162,7 @@ pub use crate::concat_impl::concat; pub use crate::cons_tuples_impl::cons_tuples; pub use crate::diff::diff_with; pub use crate::diff::Diff; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] pub use crate::kmerge_impl::{kmerge_by}; pub use crate::minmax::MinMaxResult; pub use crate::peeking_take_while::PeekingNext; @@ -172,41 +181,41 @@ pub mod free; pub use crate::free::*; mod concat_impl; mod cons_tuples_impl; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod combinations; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod combinations_with_replacement; mod exactly_one_err; mod diff; mod format; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod group_map; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod groupbylazy; mod intersperse; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod kmerge_impl; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod lazy_buffer; mod merge_join; mod minmax; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod multipeek_impl; mod pad_tail; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod peek_nth; mod peeking_take_while; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod permutations; mod process_results_impl; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod put_back_n_impl; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod rciter_impl; mod repeatn; mod size_hint; mod sources; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] mod tee; mod tuple_impl; #[cfg(feature = "use_std")] @@ -530,7 +539,7 @@ pub trait Itertools : Iterator { /// } /// assert_eq!(data_grouped, vec![(true, vec![1, 3]), (false, vec![-2, -2]), (true, vec![1, 0, 1, 2])]); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn group_by(self, key: F) -> GroupBy where Self: Sized, F: FnMut(&Self::Item) -> K, @@ -566,7 +575,7 @@ pub trait Itertools : Iterator { /// assert_eq!(4, chunk.sum()); /// } /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn chunks(self, size: usize) -> IntoChunks where Self: Sized, { @@ -704,7 +713,7 @@ pub trait Itertools : Iterator { /// itertools::assert_equal(t2, 0..4); /// itertools::assert_equal(t1, 1..4); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn tee(self) -> (Tee, Tee) where Self: Sized, Self::Item: Clone @@ -911,7 +920,7 @@ pub trait Itertools : Iterator { /// let it = vec![a, b, c].into_iter().kmerge(); /// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 5]); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn kmerge(self) -> KMerge<::IntoIter> where Self: Sized, Self::Item: IntoIterator, @@ -940,7 +949,7 @@ pub trait Itertools : Iterator { /// assert_eq!(it.next(), Some(0.)); /// assert_eq!(it.last(), Some(-7.)); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn kmerge_by(self, first: F) -> KMergeBy<::IntoIter, F> where Self: Sized, @@ -996,7 +1005,7 @@ pub trait Itertools : Iterator { /// assert_eq!(multi_prod.next(), Some(vec![1, 3, 5])); /// assert_eq!(multi_prod.next(), None); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn multi_cartesian_product(self) -> MultiProduct<::IntoIter> where Self: Iterator + Sized, Self::Item: IntoIterator, @@ -1316,7 +1325,7 @@ pub trait Itertools : Iterator { /// vec![2, 2], /// ]); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn combinations(self, k: usize) -> Combinations where Self: Sized, Self::Item: Clone @@ -1343,7 +1352,7 @@ pub trait Itertools : Iterator { /// vec![3, 3], /// ]); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn combinations_with_replacement(self, k: usize) -> CombinationsWithReplacement where Self: Sized, @@ -1389,7 +1398,7 @@ pub trait Itertools : Iterator { /// /// Note: The source iterator is collected lazily, and will not be /// re-iterated if the permutations adaptor is completed and re-iterated. - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn permutations(self, k: usize) -> Permutations where Self: Sized, Self::Item: Clone @@ -1681,7 +1690,7 @@ pub trait Itertools : Iterator { /// `.collect_vec()` is simply a type specialization of `.collect()`, /// for convenience. - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn collect_vec(self) -> Vec where Self: Sized { @@ -1708,7 +1717,7 @@ pub trait Itertools : Iterator { /// Ok(()) /// } /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn try_collect(self) -> Result where Self: Sized + Iterator>, @@ -1758,7 +1767,7 @@ pub trait Itertools : Iterator { /// assert_eq!(["a", "b", "c"].iter().join(", "), "a, b, c"); /// assert_eq!([1, 2, 3].iter().join(", "), "1, 2, 3"); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn join(&mut self, sep: &str) -> String where Self::Item: std::fmt::Display { @@ -2189,7 +2198,7 @@ pub trait Itertools : Iterator { /// itertools::assert_equal(text.chars().sorted(), /// "abcdef".chars()); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn sorted(self) -> VecIntoIter where Self: Sized, Self::Item: Ord @@ -2224,7 +2233,7 @@ pub trait Itertools : Iterator { /// itertools::assert_equal(oldest_people_first, /// vec!["Jill", "Jack", "Jane", "John"]); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn sorted_by(self, cmp: F) -> VecIntoIter where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, @@ -2257,7 +2266,7 @@ pub trait Itertools : Iterator { /// itertools::assert_equal(oldest_people_first, /// vec!["Jill", "Jack", "Jane", "John"]); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn sorted_by_key(self, f: F) -> VecIntoIter where Self: Sized, K: Ord, @@ -2800,7 +2809,7 @@ pub trait Itertools : Iterator { /// assert_eq!(iter.next(), Some(0)); /// assert_eq!(iter.peek(), Some(&1)); /// ``` - #[cfg(feature = "use_std")] + #[cfg(feature = "use_alloc")] fn multipeek(self) -> MultiPeek where Self: Sized, diff --git a/src/multipeek_impl.rs b/src/multipeek_impl.rs index 16327eacc..986e5b405 100644 --- a/src/multipeek_impl.rs +++ b/src/multipeek_impl.rs @@ -1,5 +1,5 @@ use std::iter::Fuse; -use std::collections::VecDeque; +use alloc::collections::VecDeque; use crate::size_hint; use crate::PeekingNext; diff --git a/src/peek_nth.rs b/src/peek_nth.rs index 83abac8b9..d22258b35 100644 --- a/src/peek_nth.rs +++ b/src/peek_nth.rs @@ -1,6 +1,6 @@ use crate::size_hint; use crate::PeekingNext; -use std::collections::VecDeque; +use alloc::collections::VecDeque; use std::iter::Fuse; /// See [`peek_nth()`](../fn.peek_nth.html) for more information. diff --git a/src/peeking_take_while.rs b/src/peeking_take_while.rs index 5fadf76c5..70ef988f1 100644 --- a/src/peeking_take_while.rs +++ b/src/peeking_take_while.rs @@ -1,6 +1,6 @@ use std::iter::Peekable; use crate::PutBack; -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] use crate::PutBackN; /// An iterator that allows peeking at an element before deciding to accept it. @@ -52,7 +52,7 @@ impl PeekingNext for PutBack } } -#[cfg(feature = "use_std")] +#[cfg(feature = "use_alloc")] impl PeekingNext for PutBackN where I: Iterator, { @@ -137,10 +137,10 @@ peeking_next_by_clone! { ['a] ::std::str::Bytes<'a> } peeking_next_by_clone! { ['a, T] ::std::option::Iter<'a, T> } peeking_next_by_clone! { ['a, T] ::std::result::Iter<'a, T> } peeking_next_by_clone! { [T] ::std::iter::Empty } -#[cfg(feature = "use_std")] -peeking_next_by_clone! { ['a, T] ::std::collections::linked_list::Iter<'a, T> } -#[cfg(feature = "use_std")] -peeking_next_by_clone! { ['a, T] ::std::collections::vec_deque::Iter<'a, T> } +#[cfg(feature = "use_alloc")] +peeking_next_by_clone! { ['a, T] alloc::collections::linked_list::Iter<'a, T> } +#[cfg(feature = "use_alloc")] +peeking_next_by_clone! { ['a, T] alloc::collections::vec_deque::Iter<'a, T> } // cloning a Rev has no extra overhead; peekable and put backs are never DEI. peeking_next_by_clone! { [I: Clone + PeekingNext + DoubleEndedIterator] diff --git a/src/permutations.rs b/src/permutations.rs index fb4dd5085..45126ffbd 100644 --- a/src/permutations.rs +++ b/src/permutations.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use std::fmt; use std::iter::once; diff --git a/src/put_back_n_impl.rs b/src/put_back_n_impl.rs index 21e733fe4..60ea8e649 100644 --- a/src/put_back_n_impl.rs +++ b/src/put_back_n_impl.rs @@ -1,3 +1,5 @@ +use alloc::vec::Vec; + use crate::size_hint; /// An iterator adaptor that allows putting multiple diff --git a/src/rciter_impl.rs b/src/rciter_impl.rs index 9d044d3c5..9122dadc9 100644 --- a/src/rciter_impl.rs +++ b/src/rciter_impl.rs @@ -1,6 +1,6 @@ use std::iter::IntoIterator; -use std::rc::Rc; +use alloc::rc::Rc; use std::cell::RefCell; /// A wrapper for `Rc>`, that implements the `Iterator` trait. diff --git a/src/tee.rs b/src/tee.rs index 18337b1e6..0b003027d 100644 --- a/src/tee.rs +++ b/src/tee.rs @@ -1,8 +1,8 @@ use super::size_hint; use std::cell::RefCell; -use std::collections::VecDeque; -use std::rc::Rc; +use alloc::collections::VecDeque; +use alloc::rc::Rc; /// Common buffer object for the two tee halves #[derive(Debug)] From 70a62b367e42bcfa591caffbd90da3c714866134 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Fri, 4 Sep 2020 15:27:02 -0400 Subject: [PATCH 3/3] use_alloc build for Travis CI; increase MSRV to 1.36.0 --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 276d13aec..0811ef0dc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,15 +2,17 @@ language: rust sudo: false matrix: include: - - rust: 1.32.0 + - rust: 1.36.0 script: - | cargo build --verbose --no-default-features && + cargo build --verbose --no-default-features --features "use_alloc" && cargo build --verbose --features "$FEATURES" - rust: stable script: - | cargo build --verbose --no-default-features && + cargo build --verbose --no-default-features --features "use_alloc" && cargo build --verbose --features "$FEATURES" && cargo test --verbose --features "$FEATURES" && cargo bench --no-run --verbose --features "$FEATURES" @@ -18,6 +20,7 @@ matrix: script: - | cargo build --verbose --no-default-features && + cargo build --verbose --no-default-features --features "use_alloc" && cargo build --verbose --features "$FEATURES" && cargo test --verbose --features "$FEATURES" && cargo bench --no-run --verbose --features "$FEATURES"