No bug - Revendor rust dependencies

This commit is contained in:
Servo VCS Sync 2018-02-28 20:07:52 +00:00
Родитель 68043719a2
Коммит f5b5dab005
41 изменённых файлов: 2513 добавлений и 1019 удалений

Просмотреть файл

@ -1 +1 @@
{"files":{".travis.yml":"5edd53edc70be60b7c6797204b540780d0ca2550d5b073eb99ee5255f3059682","Cargo.toml":"ba266ea33473c807fffe8e176bd1ec4297f5eb0b5fb583387f504ceb6f3fa896","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","Makefile":"13f1c5b88a7b946b5813f7231df2933b6b19b223e9e2d3fa63ad681192f984b5","README.rst":"2764f3dec0b6bc8270fdad6b765354b99da9996dacb58e2c2f706621d223c5ce","benches/bench1.rs":"982de314e181dc6d4da9530d37b72c4f8d8a02e3e204a90f91ea72bb22937cf7","benches/extra/mod.rs":"4c5b03e74fc5b02383500c9da9fd6550262706ee569d70d085700f6d0b5749ba","benches/extra/zipslices.rs":"108dd488de366b2d83fb6bcc603ecbf9a017e165ac19d03440074fa244af3fb2","benches/tuple_combinations.rs":"8c14e9341d92e5cfd5f9a067d11088b37b003e82635d1ab3a8e5290e3ef83eed","benches/tuples.rs":"412a952f08bb03695952d5cfd57949dcf28be8b99e3c6653994bdb8af9654653","custom.css":"03d2316d325a09f03f0fae54d24b64f784518a8249432edbd60e01436be900d5","examples/iris.data":"596ffd580471ca4d4880f8e439c7281f3b50d8249a5960353cb200b1490f63a0","examples/iris.rs":"74387bb7e81d4b975f796aa855788ff5b8e3c9ff69c42898ecf76c4a74e8504b","src/adaptors/mod.rs":"af2c2b96fb4d1c6024af78d2faf766e9870180622e1c5b603d1799564fffaa34","src/adaptors/multipeek.rs":"2b2f3b796b5664e3561a9ffabd16ea2971020cea13e1fb2ce5fd6e995934b4ab","src/cons_tuples_impl.rs":"371d58a3e0aaa9552219450863afd685b75fb7d4f2be69e14138e2c5d602591c","src/diff.rs":"921e2b867d7b32ffedc72a5eb780811322d14d1e0883a608b9028a2afcad0df2","src/format.rs":"412fbe02f12311c6fbcec1044f57ad6991783f5a3f323b9c391accfe4915106f","src/free.rs":"2c3e853dda297f4227cd7ecd37402a99c36169884ffbdfe823d296b0c8d16d33","src/groupbylazy.rs":"62957f8b15dd3083ac7077edc357a0bc0954828f467b60697a8801de57028d2d","src/impl_macros.rs":"eb0bb3f70ec1bcaffa6110ae4134c777951ed1e5f48d8c811dbf0a597dc48faa","src/intersperse.rs":"8338a5b61ff5d2eb306ef7142578406f3ae4e4c7b2a8adcaa293a07c2299735b","src/kmerge_impl.rs":"e7902ccf6b811417e4dd9314964944beb08c2908e76396ff977227a7a350a16f","src/lib.rs":"adb75487a37790bd086880b44fc65eff990ea3d7897ae323adf6967d87be8cf7","src/minmax.rs":"4668a7f824fbc133599f43ffb6f7283e5bd603e07df2d8176abc6f25d6af9db0","src/pad_tail.rs":"2b4c8961a18bc9685cfa4ac674b77f1f313e953e1398d08d681255b9e5f60ad7","src/peeking_take_while.rs":"e44361e2793db239d367ae3d052376b4fbc9dec472e7f89f10347cdd1e197de4","src/rciter_impl.rs":"9ecde85b56122db166ffd0a6cc8e9d819b3a2c4322c880ccd9bf0b77f5a8c985","src/repeatn.rs":"e60885e395eb8a348248fe8c0d05c325c74056198cc0242d25530c93520f9b25","src/size_hint.rs":"c624ab3ff04836372d98cbd597be134da283280be5378d06747759febe5c2ee7","src/sources.rs":"d6d4ac8980ede2975363a27431b6584af43cc495c10a21d6dfe2dcee6393716d","src/tee.rs":"86b1da0697360091ae5de53a64cd8efb927b88c41c7fff5dec5814702c5bac31","src/tuple_impl.rs":"767624e7c7db930fabf22542a3b48926e48a0b485bdbf03cfa131286bc6988de","src/with_position.rs":"8af04f26d9b89a2597fc10ad52c0feb61cb852dbf988b93d397f3300a6e70965","src/zip_eq_impl.rs":"95e493deeadd640751f5c49f55008bd31218978f38396967bc4a356f6f11d209","src/zip_longest.rs":"e463c58d5feebe5a0ed7964705ffedc6ec9a89ca2567a374cc8ceaf206249d5a","src/ziptuple.rs":"463f102add23ffa0702ec5ef110aae6c132267151fad66566b724fff7ebfa458","tests/peeking_take_while.rs":"a2ae6474e09620a47bb8a6e3c62929261e72c52881370adb2d22e89aa9e9aec8","tests/quick.rs":"a4f9faafbf2ee7fa76048634c84422c24e31a8c65489964017d1b100f9e1bbc0","tests/tests.rs":"a1fa1f0e5e70e6ef78ffce2e145422941e5aea18a1a5b66ef7365e7962511368","tests/tuples.rs":"f8c8892c3c44dde0910eaf26f1756ddc62e264498245e5b0070a6912dc8c101c","tests/zip.rs":"00749b70157da84dc3f0681b5fb8aaabfe412ab930da5fbaa3b4571f4c662fe9"},"package":"4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"}
{"files":{".travis.yml":"c3dc3f05ae5a558675996efeec1bcdc1f51be7abe519f2e3489b4c3974af851f","Cargo.toml":"9aee0be6b22b8323448a4af38d5b923a0fe47245a3e01573d0ad51fa1c81ffa2","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","Makefile":"13f1c5b88a7b946b5813f7231df2933b6b19b223e9e2d3fa63ad681192f984b5","README.rst":"5d457160aa59d3e9ea1c7ad92e1f450ac43c867a72b854baa2e536152c1335c1","benches/bench1.rs":"695e4b00addf2e8e44a09d85a588cb333c97109829e59739bdab01e7342d47b5","benches/extra/mod.rs":"4c5b03e74fc5b02383500c9da9fd6550262706ee569d70d085700f6d0b5749ba","benches/extra/zipslices.rs":"108dd488de366b2d83fb6bcc603ecbf9a017e165ac19d03440074fa244af3fb2","benches/tuple_combinations.rs":"8c14e9341d92e5cfd5f9a067d11088b37b003e82635d1ab3a8e5290e3ef83eed","benches/tuples.rs":"412a952f08bb03695952d5cfd57949dcf28be8b99e3c6653994bdb8af9654653","custom.css":"03d2316d325a09f03f0fae54d24b64f784518a8249432edbd60e01436be900d5","examples/iris.data":"596ffd580471ca4d4880f8e439c7281f3b50d8249a5960353cb200b1490f63a0","examples/iris.rs":"3996ca0a62762aec2b102f0f4244fe90d4b4354286d68d80cdc40e35f4352ba3","src/adaptors/mod.rs":"63da1c2f3cf9a33cbfd19721c955b3c2f052b4f5cf8c609dcb37b2698f30720c","src/adaptors/multi_product.rs":"e51e36b6f6ff3bb820c3544f7f80f700b0d1a2c4c7a51cff4e39b78750341d3c","src/combinations.rs":"a9a3fc78eb5c9f3933ff60275a635d0c81f4864a73515dc052aeb2add4ad4909","src/concat_impl.rs":"276339b00588f54c25f8ffbe0ae3c0031f7e52fb53c6578554a0bde1681b58a5","src/cons_tuples_impl.rs":"24511088aa946fec4ed4c46cf2d64c0928eea9e8bc410d2fbc3e344b6c63074d","src/diff.rs":"921e2b867d7b32ffedc72a5eb780811322d14d1e0883a608b9028a2afcad0df2","src/either_or_both.rs":"4739b8644fa932b7992e565be6a6bc64dff9f93e345c52f90b3e1f8a67e6d18e","src/format.rs":"412fbe02f12311c6fbcec1044f57ad6991783f5a3f323b9c391accfe4915106f","src/free.rs":"ced78d79c0c78398ac53bf628e77ae84f214972d0dad0507b6687c2f88873aaa","src/groupbylazy.rs":"4de00767e6ec2aa27419bcf7a88a2e45f41a5e73103227d99e8b2d9d147dcf6b","src/impl_macros.rs":"eb0bb3f70ec1bcaffa6110ae4134c777951ed1e5f48d8c811dbf0a597dc48faa","src/intersperse.rs":"8f4053a203068b0d7ddab480d454910b508bec227bdf2c0d66f6f7ed7e56ce96","src/kmerge_impl.rs":"a15ed167c535f2a5700b1efd021adbc0b793a001773cd1f6648a5068b8a32245","src/lib.rs":"729a0718daad88348d32d623255a90a7656bf1a27301817108e8829debc18548","src/merge_join.rs":"d6952726da870aab6ee0607822384aad30cc4ff0ffc7223c9a707b125b1b8b5b","src/minmax.rs":"4668a7f824fbc133599f43ffb6f7283e5bd603e07df2d8176abc6f25d6af9db0","src/multipeek_impl.rs":"ebe9544d94d0bf7200f7625241a3b5a291b7b564091a08cad40ff08b51f1b1bf","src/pad_tail.rs":"078615a2892f8c6db665074cf6f1be1bef4cf5ee418bc174edcfd4dc703e163f","src/peeking_take_while.rs":"6aea3bb40fb480e9f3695ce2a7a3a2e2346d437ca846d20e6bb3c09beb0934f4","src/process_results_impl.rs":"214608f9a67a5a55b3c9c8e136355f78d0f8a9e0000c4523faaa44a05f070961","src/put_back_n_impl.rs":"d35858184c525372b22d14d42cdf63726cf0fd50f5bd42ec7a82d55a8e180e9f","src/rciter_impl.rs":"449262cb5c2d1e9affe0b4020f1c28aa316a3718afe094667b79bbff1557d5e6","src/repeatn.rs":"5192191b87efe68f60353f742114da33e4d490a302671036f1b262d1f0a004c1","src/size_hint.rs":"c1d35b422a696cf3d63e7c90d8f9fdf01a304cf8156e914287c4ef48fea62dd3","src/sources.rs":"9d7eb4dbd87f659d04b4980238c5fc72b71472e16861d17a32cab9b77a3df06a","src/tee.rs":"f8cf7fb07506b3a1f2d59a1ec5a6b858534af90df1dad745f38761e73eab6baf","src/tuple_impl.rs":"0a26201089b3ee6546e174fc7f89aadde415f4eb201160f3d9b42fe857d03946","src/unique_impl.rs":"601a231786f61b503e55c22def380fa8b026b615125bcf90356587c761892bc8","src/with_position.rs":"d922f045f6fa090a431be928f3221c6dc37ac6f9bb54461b3b84f99a7e91244a","src/zip_eq_impl.rs":"95e493deeadd640751f5c49f55008bd31218978f38396967bc4a356f6f11d209","src/zip_longest.rs":"8ab899b3bf0295cbc076770b003499b91e93310f02ce05d15b91d39aa218bdd2","src/ziptuple.rs":"bd75c3f9493a7b9f949f27310c2f0a7a3504baac988fd7399dd252389be1b39d","tests/merge_join.rs":"546eaffae40010f15a7bcf95bc53f5e9b67424c5b93df6ffb0aaa1e48e8b90c0","tests/peeking_take_while.rs":"a2ae6474e09620a47bb8a6e3c62929261e72c52881370adb2d22e89aa9e9aec8","tests/quick.rs":"f80a6d47fc233fd23efaa0a3358419b403869d273cc0c82049e09114d0e0bcb5","tests/test_core.rs":"21037f9af8b5a69ebc02636fe2128f4d36a46ca9241c6bee74f32f6446afcaa8","tests/test_std.rs":"756db4247a7dae7ae599ab2796d6e1e2fc740102cc2e57a73bec0a2ead3335e8","tests/tuples.rs":"5323d15a7abf6545b2655167d3206b6cf6a947e9409a244ea6a8cf4ad8ceac64","tests/zip.rs":"fe213d70c4fa114cb4d1930a6b971f4af617a239041ddb87e6b5a9bbe62261b8"},"package":"b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"}

3
third_party/rust/itertools/.travis.yml поставляемый
Просмотреть файл

@ -2,7 +2,7 @@ language: rust
sudo: false
matrix:
include:
- rust: 1.11.0
- rust: 1.12.0
- rust: stable
- rust: beta
- rust: nightly
@ -13,6 +13,7 @@ branches:
- master
script:
- |
cargo build --verbose --no-default-features &&
cargo build --verbose --features "$FEATURES" &&
cargo test --verbose --features "$FEATURES" &&
([ "$BENCH" != 1 ] || cargo bench --verbose --features "$FEATURES")

50
third_party/rust/itertools/Cargo.toml поставляемый
Просмотреть файл

@ -1,35 +1,43 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "itertools"
version = "0.5.10"
license = "MIT/Apache-2.0"
repository = "https://github.com/bluss/rust-itertools"
documentation = "https://docs.rs/itertools/"
version = "0.7.6"
authors = ["bluss"]
description = "Extra iterator adaptors, iterator methods, free functions, and macros."
documentation = "https://docs.rs/itertools/"
keywords = ["iterator", "data-structure", "zip", "product", "group-by"]
categories = ["algorithms", "rust-patterns"]
license = "MIT/Apache-2.0"
repository = "https://github.com/bluss/rust-itertools"
[package.metadata.release]
no-dev-version = true
[profile.bench]
debug = true
[lib]
bench = false
test = false
[dependencies]
either = { version = "1.0", default-features = false }
[dev-dependencies.quickcheck]
version = "0.4"
bench = false
[dependencies.either]
version = "1.0"
default-features = false
[dev-dependencies.permutohedron]
version = "0.2"
[dev-dependencies.quickcheck]
version = "0.5"
default-features = false
[features]
[profile]
bench = { debug = true }
[package.metadata.release]
no-dev-version = true
default = ["use_std"]
use_std = []

98
third_party/rust/itertools/README.rst поставляемый
Просмотреть файл

@ -2,7 +2,7 @@
Itertools
=========
Extra iterator adaptors, functions and macros. Requires Rust 1.11 or later.
Extra iterator adaptors, functions and macros.
Please read the `API documentation here`__
@ -21,7 +21,7 @@ How to use with cargo:
.. code:: toml
[dependencies]
itertools = "0.5.9"
itertools = "0.7.3"
How to use in your crate:
@ -41,6 +41,100 @@ How to contribute:
Recent Changes
--------------
- 0.7.6
- Add new adaptor ``.multi_cartesian_product()`` which is an n-ary product
iterator by @tobz1000
- Add new method ``.sorted_by_key()`` by @Xion
- Provide simpler and faster ``.count()`` for ``.unique()`` and ``.unique_by()``
- 0.7.5
- ``.multipeek()`` now implements ``PeekingNext``, by @nicopap.
- 0.7.4
- Add new adaptor ``.update()`` by @lucasem; this adaptor is used
to modify an element before passing it on in an iterator chain.
- 0.7.3
- Add new method ``.collect_tuple()`` by @matklad; it makes a tuple out of
the iterator's elements if the number of them matches **exactly**.
- Implement ``fold`` and ``collect`` for ``.map_results()`` which means
it reuses the code of the standard ``.map()`` for these methods.
- 0.7.2
- Add new adaptor ``.merge_join_by`` by @srijs; a heterogeneous merge join
for two ordered sequences.
- 0.7.1
- Iterator adaptors and iterators in itertools now use the same ``must_use``
reminder that the standard library adaptors do, by @matematikaedit and @bluss
*“iterator adaptors are lazy and do nothing unless consumed”*.
- 0.7.0
- Faster ``izip!()`` by @krdln
- ``izip!()`` is now a wrapper for repeated regular ``.zip()`` and
a single ``.map()``. This means it optimizes as well as the standard
library ``.zip()`` it uses.
**Note:** ``multizip`` and ``izip!()`` are now different! The former
has a named type but the latter optimizes better.
- Faster ``.unique()``
- ``no_std`` support, which is opt-in!
- Many lovable features are still there without std, like ``izip!()``
or ``.format()`` or ``.merge()``, but not those that use collections.
- Trait bounds were required up front instead of just on the type:
``group_by``'s ``PartialEq`` by @Phlosioneer and ``repeat_call``'s
``FnMut``.
- Removed deprecated constructor ``Zip::new`` — use ``izip!()`` or ``multizip()``
- 0.6.5
- Fix bug in ``.cartesian_product()``'s fold (which only was visible for
unfused iterators).
- 0.6.4
- Add specific ``fold`` implementations for ``.cartesian_product()`` and
``cons_tuples()``, which improves their performance in fold, foreach, and
iterator consumers derived from them.
- 0.6.3
- Add iterator adaptor ``.positions(predicate)`` by @tmccombs
- 0.6.2
- Add function ``process_results`` which can “lift” a function of the regular
values of an iterator so that it can process the ``Ok`` values from an
iterator of ``Results`` instead, by @shepmaster
- Add iterator method ``.concat()`` which combines all iterator elements
into a single collection using the ``Extend`` trait, by @srijs
- 0.6.1
- Better size hint testing and subsequent size hint bugfixes by @rkarp.
Fixes bugs in product, interleave_shortest size hints.
- New iterator method ``.all_equal()`` by @phimuemue
- 0.6.0
- Deprecated names were removed in favour of their replacements
- ``.flatten()`` does not implement double ended iteration anymore
- ``.fold_while()`` uses ``&mut self`` and returns ``FoldWhile<T>``, for
composability (#168)
- ``.foreach()`` and ``.fold1()`` use ``self``, like ``.fold()`` does.
- ``.combinations(0)`` now produces a single empty vector. (#174)
- 0.5.10
- Add itertools method ``.kmerge_by()`` (and corresponding free function)

86
third_party/rust/itertools/benches/bench1.rs поставляемый
Просмотреть файл

@ -1,7 +1,7 @@
#![feature(test)]
extern crate test;
extern crate itertools;
#[macro_use] extern crate itertools;
use test::{black_box};
use itertools::Itertools;
@ -649,3 +649,87 @@ fn step_range_10(b: &mut test::Bencher) {
fast_integer_sum(v.clone().step(10))
});
}
#[bench]
fn cartesian_product_iterator(b: &mut test::Bencher)
{
let xs = vec![0; 16];
b.iter(|| {
let mut sum = 0;
for (&x, &y, &z) in iproduct!(&xs, &xs, &xs) {
sum += x;
sum += y;
sum += z;
}
sum
})
}
#[bench]
fn cartesian_product_fold(b: &mut test::Bencher)
{
let xs = vec![0; 16];
b.iter(|| {
let mut sum = 0;
iproduct!(&xs, &xs, &xs).fold((), |(), (&x, &y, &z)| {
sum += x;
sum += y;
sum += z;
});
sum
})
}
#[bench]
fn multi_cartesian_product_iterator(b: &mut test::Bencher)
{
let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
b.iter(|| {
let mut sum = 0;
for x in xs.into_iter().multi_cartesian_product() {
sum += x[0];
sum += x[1];
sum += x[2];
}
sum
})
}
#[bench]
fn multi_cartesian_product_fold(b: &mut test::Bencher)
{
let xs = [vec![0; 16], vec![0; 16], vec![0; 16]];
b.iter(|| {
let mut sum = 0;
xs.into_iter().multi_cartesian_product().fold((), |(), x| {
sum += x[0];
sum += x[1];
sum += x[2];
});
sum
})
}
#[bench]
fn cartesian_product_nested_for(b: &mut test::Bencher)
{
let xs = vec![0; 16];
b.iter(|| {
let mut sum = 0;
for &x in &xs {
for &y in &xs {
for &z in &xs {
sum += x;
sum += y;
sum += z;
}
}
}
sum
})
}

4
third_party/rust/itertools/examples/iris.rs поставляемый
Просмотреть файл

@ -110,11 +110,11 @@ fn main() {
// using Itertools::set_from
plot.iter_mut().set_from(repeat(' '));
// using Itertools::minmax_by
// using Itertools::minmax
let min_max = |data: &[Iris], col| {
data.iter()
.map(|iris| iris.data[col])
.minmax_by(|a, b| f32::partial_cmp(a, b).unwrap())
.minmax()
.into_option()
.expect("Can't find min/max of empty iterator")
};

645
third_party/rust/itertools/src/adaptors/mod.rs поставляемый
Просмотреть файл

@ -4,20 +4,17 @@
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.
use std::cmp;
mod multi_product;
#[cfg(feature = "use_std")]
pub use self::multi_product::*;
use std::fmt;
use std::mem::replace;
use std::ops::Index;
use std::iter::{Fuse, Peekable};
use std::collections::HashSet;
use std::hash::Hash;
use std::iter::{Fuse, Peekable, FromIterator};
use std::marker::PhantomData;
use size_hint;
use fold;
pub mod multipeek;
pub use self::multipeek::MultiPeek;
macro_rules! clone_fields {
($name:ident, $base:expr, $($field:ident),+) => (
$name {
@ -28,7 +25,6 @@ macro_rules! clone_fields {
);
}
/// An iterator adaptor that alternates elements from two iterators until both
/// run out.
///
@ -36,6 +32,7 @@ macro_rules! clone_fields {
///
/// See [`.interleave()`](../trait.Itertools.html#method.interleave) for more information.
#[derive(Clone, Debug)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Interleave<I, J> {
a: Fuse<I>,
b: Fuse<J>,
@ -98,6 +95,7 @@ impl<I, J> Iterator for Interleave<I, J>
/// See [`.interleave_shortest()`](../trait.Itertools.html#method.interleave_shortest)
/// for more information.
#[derive(Clone, Debug)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct InterleaveShortest<I, J>
where I: Iterator,
J: Iterator<Item = I::Item>
@ -147,24 +145,38 @@ impl<I, J> Iterator for InterleaveShortest<I, J>
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let bound = |a: usize, b: usize| -> Option<usize> {
use std::cmp::min;
2usize.checked_mul(min(a, b))
.and_then(|lhs| lhs.checked_add(if !self.phase && a > b || (self.phase && a < b) { 1 } else { 0 }))
let (curr_hint, next_hint) = {
let it0_hint = self.it0.size_hint();
let it1_hint = self.it1.size_hint();
if self.phase {
(it1_hint, it0_hint)
} else {
(it0_hint, it1_hint)
}
};
let (l0, u0) = self.it0.size_hint();
let (l1, u1) = self.it1.size_hint();
let lb = bound(l0, l1).unwrap_or(usize::max_value());
let ub = match (u0, u1) {
(None, None) => None,
(Some(u0), None) => Some(u0 * 2 + self.phase as usize),
(None, Some(u1)) => Some(u1 * 2 + !self.phase as usize),
(Some(u0), Some(u1)) => Some(cmp::min(u0, u1) * 2 +
(u0 > u1 && !self.phase ||
(u0 < u1 && self.phase)) as usize),
let (curr_lower, curr_upper) = curr_hint;
let (next_lower, next_upper) = next_hint;
let (combined_lower, combined_upper) =
size_hint::mul_scalar(size_hint::min(curr_hint, next_hint), 2);
let lower =
if curr_lower > next_lower {
combined_lower + 1
} else {
combined_lower
};
(lb, ub)
let upper = {
let extra_elem = match (curr_upper, next_upper) {
(_, None) => false,
(None, Some(_)) => true,
(Some(curr_max), Some(next_max)) => curr_max > next_max,
};
if extra_elem {
combined_upper.and_then(|x| x.checked_add(1))
} else {
combined_upper
}
};
(lower, upper)
}
}
@ -193,16 +205,6 @@ pub fn put_back<I>(iterable: I) -> PutBack<I::IntoIter>
impl<I> PutBack<I>
where I: Iterator
{
#[doc(hidden)]
#[deprecated(note = "replaced by put_back")]
#[inline]
pub fn new(it: I) -> Self {
PutBack {
top: None,
iter: it,
}
}
/// put back value `value` (builder method)
pub fn with_value(mut self, value: I::Item) -> Self {
self.put_back(value);
@ -264,74 +266,6 @@ impl<I> Iterator for PutBack<I>
}
}
/// An iterator adaptor that allows putting multiple
/// items in front of the iterator.
///
/// Iterator element type is `I::Item`.
#[derive(Debug, Clone)]
pub struct PutBackN<I: Iterator> {
top: Vec<I::Item>,
iter: I,
}
/// Create an iterator where you can put back multiple values to the front
/// of the iteration.
///
/// Iterator element type is `I::Item`.
pub fn put_back_n<I>(iterable: I) -> PutBackN<I::IntoIter>
where I: IntoIterator
{
PutBackN {
top: Vec::new(),
iter: iterable.into_iter(),
}
}
impl<I: Iterator> PutBackN<I> {
#[doc(hidden)]
#[deprecated(note = "replaced by put_back_n")]
#[inline]
pub fn new(it: I) -> Self {
put_back_n(it)
}
/// Puts x in front of the iterator.
/// The values are yielded in order of the most recently put back
/// values first.
///
/// ```rust
/// use itertools::PutBackN;
///
/// let mut it = PutBackN::new(1..5);
/// it.next();
/// it.put_back(1);
/// it.put_back(0);
///
/// assert!(itertools::equal(it, 0..5));
/// ```
#[inline]
pub fn put_back(&mut self, x: I::Item) {
self.top.push(x);
}
}
impl<I: Iterator> Iterator for PutBackN<I> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
if self.top.is_empty() {
self.iter.next()
} else {
self.top.pop()
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
size_hint::add_scalar(self.iter.size_hint(), self.top.len())
}
}
#[derive(Debug, Clone)]
/// An iterator adaptor that iterates over the cartesian product of
/// the element sets of two iterators `I` and `J`.
@ -339,6 +273,7 @@ impl<I: Iterator> Iterator for PutBackN<I> {
/// Iterator element type is `(I::Item, J::Item)`.
///
/// See [`.cartesian_product()`](../trait.Itertools.html#method.cartesian_product) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Product<I, J>
where I: Iterator
{
@ -396,12 +331,34 @@ impl<I, J> Iterator for Product<I, J>
fn size_hint(&self) -> (usize, Option<usize>) {
let has_cur = self.a_cur.is_some() as usize;
// Not ExactSizeIterator because size may be larger than usize
let (b, _) = self.b.size_hint();
let (b_min, b_max) = self.b.size_hint();
// Compute a * b_orig + b for both lower and upper bound
size_hint::add_scalar(
size_hint::add(
size_hint::mul(self.a.size_hint(), self.b_orig.size_hint()),
b * has_cur)
(b_min * has_cur, b_max.map(move |x| x * has_cur)))
}
fn fold<Acc, G>(mut self, mut accum: Acc, mut f: G) -> Acc
where G: FnMut(Acc, Self::Item) -> Acc,
{
// use a split loop to handle the loose a_cur as well as avoiding to
// clone b_orig at the end.
if let Some(mut a) = self.a_cur.take() {
let mut b = self.b;
loop {
accum = b.fold(accum, |acc, elt| f(acc, (a.clone(), elt)));
// we can only continue iterating a if we had a first element;
if let Some(next_a) = self.a.next() {
b = self.b_orig.clone();
a = next_a;
} else {
break;
}
}
}
accum
}
}
@ -412,6 +369,7 @@ impl<I, J> Iterator for Product<I, J>
///
/// See [`.batching()`](../trait.Itertools.html#method.batching) for more information.
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Batching<I, F> {
f: F,
iter: I,
@ -451,6 +409,7 @@ impl<B, F, I> Iterator for Batching<I, F>
///
/// See [`.step()`](../trait.Itertools.html#method.step) for more information.
#[derive(Clone, Debug)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Step<I> {
iter: Fuse<I>,
skip: usize,
@ -564,6 +523,7 @@ impl<I, J> MergeCore<I, J>
/// Iterator element type is `I::Item`.
///
/// See [`.merge()`](../trait.Itertools.html#method.merge_by) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Merge<I, J>
where I: Iterator,
J: Iterator<Item = I::Item>
@ -636,6 +596,7 @@ impl<I, J> Iterator for Merge<I, J>
/// Iterator element type is `I::Item`.
///
/// See [`.merge_by()`](../trait.Itertools.html#method.merge_by) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MergeBy<I, J, F>
where I: Iterator,
J: Iterator<Item = I::Item>
@ -736,6 +697,7 @@ impl<I> CoalesceCore<I>
/// An iterator adaptor that may join together adjacent elements.
///
/// See [`.coalesce()`](../trait.Itertools.html#method.coalesce) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Coalesce<I, F>
where I: Iterator
{
@ -790,6 +752,7 @@ impl<I, F> Iterator for Coalesce<I, F>
/// An iterator adaptor that removes repeated duplicates.
///
/// See [`.dedup()`](../trait.Itertools.html#method.dedup) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Dedup<I>
where I: Iterator
{
@ -862,6 +825,7 @@ impl<I> Iterator for Dedup<I>
/// to only pick off elements while the predicate returns `true`.
///
/// See [`.take_while_ref()`](../trait.Itertools.html#method.take_while_ref) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct TakeWhileRef<'a, I: 'a, F> {
iter: &'a mut I,
f: F,
@ -912,6 +876,7 @@ impl<'a, I, F> Iterator for TakeWhileRef<'a, I, F>
///
/// See [`.while_some()`](../trait.Itertools.html#method.while_some) for more information.
#[derive(Clone, Debug)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct WhileSome<I> {
iter: I,
}
@ -945,6 +910,7 @@ impl<I, A> Iterator for WhileSome<I>
/// See [`.tuple_combinations()`](../trait.Itertools.html#method.tuple_combinations) for more
/// information.
#[derive(Debug)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct TupleCombinations<I, T>
where I: Iterator,
T: HasCombination<I>
@ -1068,289 +1034,15 @@ impl_tuple_combination!(Tuple2Combination Tuple1Combination ; A, A, A ; a);
impl_tuple_combination!(Tuple3Combination Tuple2Combination ; A, A, A, A ; a b);
impl_tuple_combination!(Tuple4Combination Tuple3Combination ; A, A, A, A, A; a b c);
#[derive(Debug)]
struct LazyBuffer<I: Iterator> {
it: I,
done: bool,
buffer: Vec<I::Item>,
}
impl<I> LazyBuffer<I>
where I: Iterator
{
pub fn new(it: I) -> LazyBuffer<I> {
let mut it = it;
let mut buffer = Vec::new();
let done;
if let Some(first) = it.next() {
buffer.push(first);
done = false;
} else {
done = true;
}
LazyBuffer {
it: it,
done: done,
buffer: buffer,
}
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn is_done(&self) -> bool {
self.done
}
pub fn get_next(&mut self) -> bool {
if self.done {
return false;
}
let next_item = self.it.next();
match next_item {
Some(x) => {
self.buffer.push(x);
true
}
None => {
self.done = true;
false
}
}
}
}
impl<I> Index<usize> for LazyBuffer<I>
where I: Iterator,
I::Item: Sized
{
type Output = I::Item;
fn index<'b>(&'b self, _index: usize) -> &'b I::Item {
self.buffer.index(_index)
}
}
/// An iterator to iterate through all the `n`-length combinations in an iterator.
///
/// See [`.combinations()`](../trait.Itertools.html#method.combinations) for more information.
pub struct Combinations<I: Iterator> {
n: usize,
indices: Vec<usize>,
pool: LazyBuffer<I>,
first: bool,
}
impl<I> fmt::Debug for Combinations<I>
where I: Iterator + fmt::Debug,
I::Item: fmt::Debug,
{
debug_fmt_fields!(Combinations, n, indices, pool, first);
}
/// Create a new `Combinations` from a clonable iterator.
///
/// **Panics** if `n` is zero.
pub fn combinations<I>(iter: I, n: usize) -> Combinations<I>
where I: Iterator
{
assert!(n != 0);
let mut indices: Vec<usize> = Vec::with_capacity(n);
for i in 0..n {
indices.push(i);
}
let mut pool: LazyBuffer<I> = LazyBuffer::new(iter);
for _ in 0..n {
if !pool.get_next() {
break;
}
}
Combinations {
n: n,
indices: indices,
pool: pool,
first: true,
}
}
impl<I> Iterator for Combinations<I>
where I: Iterator,
I::Item: Clone
{
type Item = Vec<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
let mut pool_len = self.pool.len();
if self.pool.is_done() {
if pool_len == 0 || self.n > pool_len {
return None;
}
}
if self.first {
self.first = false;
} else {
// Scan from the end, looking for an index to increment
let mut i: usize = self.n - 1;
// Check if we need to consume more from the iterator
if self.indices[i] == pool_len - 1 && !self.pool.is_done() {
if self.pool.get_next() {
pool_len += 1;
}
}
while self.indices[i] == i + pool_len - self.n {
if i > 0 {
i -= 1;
} else {
// Reached the last combination
return None;
}
}
// Increment index, and reset the ones to its right
self.indices[i] += 1;
let mut j = i + 1;
while j < self.n {
self.indices[j] = self.indices[j - 1] + 1;
j += 1;
}
}
// Create result vector based on the indices
let mut result = Vec::with_capacity(self.n);
for i in self.indices.iter() {
result.push(self.pool[*i].clone());
}
Some(result)
}
}
/// An iterator adapter to filter out duplicate elements.
///
/// See [`.unique_by()`](../trait.Itertools.html#method.unique) for more information.
#[derive(Clone)]
pub struct UniqueBy<I: Iterator, V, F> {
iter: I,
used: HashSet<V>,
f: F,
}
impl<I, V, F> fmt::Debug for UniqueBy<I, V, F>
where I: Iterator + fmt::Debug,
V: fmt::Debug + Hash + Eq,
{
debug_fmt_fields!(UniqueBy, iter, used);
}
/// Create a new `UniqueBy` iterator.
pub fn unique_by<I, V, F>(iter: I, f: F) -> UniqueBy<I, V, F>
where V: Eq + Hash,
F: FnMut(&I::Item) -> V,
I: Iterator,
{
UniqueBy {
iter: iter,
used: HashSet::new(),
f: f,
}
}
impl<I, V, F> Iterator for UniqueBy<I, V, F>
where I: Iterator,
V: Eq + Hash,
F: FnMut(&I::Item) -> V
{
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
loop {
match self.iter.next() {
None => return None,
Some(v) => {
let key = (self.f)(&v);
if self.used.insert(key) {
return Some(v);
}
}
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, hi) = self.iter.size_hint();
((low > 0 && self.used.is_empty()) as usize, hi)
}
}
impl<I> Iterator for Unique<I>
where I: Iterator,
I::Item: Eq + Hash + Clone
{
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
loop {
match self.iter.iter.next() {
None => return None,
Some(v) => {
if !self.iter.used.contains(&v) {
// FIXME: Avoid this double lookup when the entry api allows
self.iter.used.insert(v.clone());
return Some(v);
}
}
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, hi) = self.iter.iter.size_hint();
((low > 0 && self.iter.used.is_empty()) as usize, hi)
}
}
/// An iterator adapter to filter out duplicate elements.
///
/// See [`.unique()`](../trait.Itertools.html#method.unique) for more information.
#[derive(Clone)]
pub struct Unique<I: Iterator> {
iter: UniqueBy<I, I::Item, ()>,
}
impl<I> fmt::Debug for Unique<I>
where I: Iterator + fmt::Debug,
I::Item: Hash + Eq + fmt::Debug,
{
debug_fmt_fields!(Unique, iter);
}
pub fn unique<I>(iter: I) -> Unique<I>
where I: Iterator,
I::Item: Eq + Hash,
{
Unique {
iter: UniqueBy {
iter: iter,
used: HashSet::new(),
f: (),
}
}
}
/// An iterator adapter to simply flatten a structure.
///
/// See [`.flatten()`](../trait.Itertools.html#method.flatten) for more information.
#[derive(Clone, Debug)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Flatten<I, J> {
iter: I,
front: Option<J>,
back: Option<J>,
}
/// Create a new `Flatten` iterator.
@ -1358,7 +1050,6 @@ pub fn flatten<I, J>(iter: I) -> Flatten<I, J> {
Flatten {
iter: iter,
front: None,
back: None,
}
}
@ -1382,12 +1073,6 @@ impl<I, J> Iterator for Flatten<I, J>
break;
}
}
if let Some(ref mut b) = self.back {
match b.next() {
elt @ Some(_) => return elt,
None => { }
}
}
None
}
@ -1399,48 +1084,15 @@ impl<I, J> Iterator for Flatten<I, J>
if let Some(iter) = self.front {
accum = fold(iter, accum, &mut f);
}
for iter in self.iter {
accum = fold(iter, accum, &mut f);
self.iter.fold(accum, move |accum, iter| fold(iter, accum, &mut f))
}
if let Some(iter) = self.back {
accum = fold(iter, accum, &mut f);
}
accum
}
}
impl<I, J> DoubleEndedIterator for Flatten<I, J>
where I: DoubleEndedIterator,
I::Item: IntoIterator<IntoIter=J, Item=J::Item>,
J: DoubleEndedIterator,
{
fn next_back(&mut self) -> Option<Self::Item> {
loop {
if let Some(ref mut b) = self.back {
match b.next_back() {
elt @ Some(_) => return elt,
None => { }
}
}
if let Some(next_back) = self.iter.next_back() {
self.back = Some(next_back.into_iter());
} else {
break;
}
}
if let Some(ref mut f) = self.front {
match f.next_back() {
elt @ Some(_) => return elt,
None => { }
}
}
None
}
}
/// An iterator adapter to apply a transformation within a nested `Result`.
///
/// See [`.map_results()`](../trait.Itertools.html#method.map_results) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MapResults<I, F> {
iter: I,
f: F
@ -1470,4 +1122,151 @@ impl<I, F, T, U, E> Iterator for MapResults<I, F>
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn fold<Acc, Fold>(self, init: Acc, mut fold_f: Fold) -> Acc
where Fold: FnMut(Acc, Self::Item) -> Acc,
{
let mut f = self.f;
self.iter.fold(init, move |acc, v| fold_f(acc, v.map(&mut f)))
}
fn collect<C>(self) -> C
where C: FromIterator<Self::Item>
{
let mut f = self.f;
self.iter.map(move |v| v.map(&mut f)).collect()
}
}
/// An iterator adapter to get the positions of each element that matches a predicate.
///
/// See [`.positions()`](../trait.Itertools.html#method.positions) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Positions<I, F> {
iter: I,
f: F,
count: usize,
}
/// Create a new `Positions` iterator.
pub fn positions<I, F>(iter: I, f: F) -> Positions<I, F>
where I: Iterator,
F: FnMut(I::Item) -> bool,
{
Positions {
iter: iter,
f: f,
count: 0
}
}
impl<I, F> Iterator for Positions<I, F>
where I: Iterator,
F: FnMut(I::Item) -> bool,
{
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
while let Some(v) = self.iter.next() {
let i = self.count;
self.count = i + 1;
if (self.f)(v) {
return Some(i);
}
}
None
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.iter.size_hint().1)
}
}
impl<I, F> DoubleEndedIterator for Positions<I, F>
where I: DoubleEndedIterator + ExactSizeIterator,
F: FnMut(I::Item) -> bool,
{
fn next_back(&mut self) -> Option<Self::Item> {
while let Some(v) = self.iter.next_back() {
if (self.f)(v) {
return Some(self.count + self.iter.len())
}
}
None
}
}
/// An iterator adapter to apply a mutating function to each element before yielding it.
///
/// See [`.update()`](../trait.Itertools.html#method.update) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Update<I, F> {
iter: I,
f: F,
}
/// Create a new `Update` iterator.
pub fn update<I, F>(iter: I, f: F) -> Update<I, F>
where
I: Iterator,
F: FnMut(&mut I::Item),
{
Update { iter: iter, f: f }
}
impl<I, F> Iterator for Update<I, F>
where
I: Iterator,
F: FnMut(&mut I::Item),
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
if let Some(mut v) = self.iter.next() {
(self.f)(&mut v);
Some(v)
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn fold<Acc, G>(self, init: Acc, mut g: G) -> Acc
where G: FnMut(Acc, Self::Item) -> Acc,
{
let mut f = self.f;
self.iter.fold(init, move |acc, mut v| { f(&mut v); g(acc, v) })
}
// if possible, re-use inner iterator specializations in collect
fn collect<C>(self) -> C
where C: FromIterator<Self::Item>
{
let mut f = self.f;
self.iter.map(move |mut v| { f(&mut v); v }).collect()
}
}
impl<I, F> ExactSizeIterator for Update<I, F>
where
I: ExactSizeIterator,
F: FnMut(&mut I::Item),
{}
impl<I, F> DoubleEndedIterator for Update<I, F>
where
I: DoubleEndedIterator,
F: FnMut(&mut I::Item),
{
fn next_back(&mut self) -> Option<Self::Item> {
if let Some(mut v) = self.iter.next_back() {
(self.f)(&mut v);
Some(v)
} else {
None
}
}
}

219
third_party/rust/itertools/src/adaptors/multi_product.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,219 @@
#![cfg(feature = "use_std")]
use size_hint;
use Itertools;
#[derive(Clone)]
/// An iterator adaptor that iterates over the cartesian product of
/// multiple iterators of type `I`.
///
/// An iterator element type is `Vec<I>`.
///
/// See [`.multi_cartesian_product()`](../trait.Itertools.html#method.multi_cartesian_product)
/// for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MultiProduct<I>(Vec<MultiProductIter<I>>)
where I: Iterator + Clone,
I::Item: Clone;
/// Create a new cartesian product iterator over an arbitrary number
/// of iterators of the same type.
///
/// Iterator element is of type `Vec<H::Item::Item>`.
pub fn multi_cartesian_product<H>(iters: H) -> MultiProduct<<H::Item as IntoIterator>::IntoIter>
where H: Iterator,
H::Item: IntoIterator,
<H::Item as IntoIterator>::IntoIter: Clone,
<H::Item as IntoIterator>::Item: Clone
{
MultiProduct(iters.map(|i| MultiProductIter::new(i.into_iter())).collect())
}
#[derive(Clone)]
/// Holds the state of a single iterator within a MultiProduct.
struct MultiProductIter<I>
where I: Iterator + Clone,
I::Item: Clone
{
cur: Option<I::Item>,
iter: I,
iter_orig: I,
}
/// Holds the current state during an iteration of a MultiProduct.
enum MultiProductIterState {
StartOfIter,
MidIter { on_first_iter: bool },
}
impl<I> MultiProduct<I>
where I: Iterator + Clone,
I::Item: Clone
{
/// Iterates the rightmost iterator, then recursively iterates iterators
/// to the left if necessary.
///
/// Returns true if the iteration succeeded, else false.
fn iterate_last(
multi_iters: &mut [MultiProductIter<I>],
mut state: MultiProductIterState
) -> bool {
use self::MultiProductIterState::*;
if let Some((last, rest)) = multi_iters.split_last_mut() {
let on_first_iter = match state {
StartOfIter => {
let on_first_iter = !last.in_progress();
state = MidIter { on_first_iter: on_first_iter };
on_first_iter
},
MidIter { on_first_iter } => on_first_iter
};
if !on_first_iter {
last.iterate();
}
if last.in_progress() {
true
} else if MultiProduct::iterate_last(rest, state) {
last.reset();
last.iterate();
// If iterator is None twice consecutively, then iterator is
// empty; whole product is empty.
last.in_progress()
} else {
false
}
} else {
// Reached end of iterator list. On initialisation, return true.
// At end of iteration (final iterator finishes), finish.
match state {
StartOfIter => false,
MidIter { on_first_iter } => on_first_iter
}
}
}
/// Returns the unwrapped value of the next iteration.
fn curr_iterator(&self) -> Vec<I::Item> {
self.0.iter().map(|multi_iter| {
multi_iter.cur.clone().unwrap()
}).collect()
}
/// Returns true if iteration has started and has not yet finished; false
/// otherwise.
fn in_progress(&self) -> bool {
if let Some(last) = self.0.last() {
last.in_progress()
} else {
false
}
}
}
impl<I> MultiProductIter<I>
where I: Iterator + Clone,
I::Item: Clone
{
fn new(iter: I) -> Self {
MultiProductIter {
cur: None,
iter: iter.clone(),
iter_orig: iter
}
}
/// Iterate the managed iterator.
fn iterate(&mut self) {
self.cur = self.iter.next();
}
/// Reset the managed iterator.
fn reset(&mut self) {
self.iter = self.iter_orig.clone();
}
/// Returns true if the current iterator has been started and has not yet
/// finished; false otherwise.
fn in_progress(&self) -> bool {
self.cur.is_some()
}
}
impl<I> Iterator for MultiProduct<I>
where I: Iterator + Clone,
I::Item: Clone
{
type Item = Vec<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
if MultiProduct::iterate_last(
&mut self.0,
MultiProductIterState::StartOfIter
) {
Some(self.curr_iterator())
} else {
None
}
}
fn count(self) -> usize {
if self.0.len() == 0 {
return 0;
}
if !self.in_progress() {
return self.0.into_iter().fold(1, |acc, multi_iter| {
acc * multi_iter.iter.count()
});
}
self.0.into_iter().fold(
0,
|acc, MultiProductIter { iter, iter_orig, cur: _ }| {
let total_count = iter_orig.count();
let cur_count = iter.count();
acc * total_count + cur_count
}
)
}
fn size_hint(&self) -> (usize, Option<usize>) {
// Not ExactSizeIterator because size may be larger than usize
if self.0.len() == 0 {
return (0, Some(0));
}
if !self.in_progress() {
return self.0.iter().fold((1, Some(1)), |acc, multi_iter| {
size_hint::mul(acc, multi_iter.iter.size_hint())
});
}
self.0.iter().fold(
(0, Some(0)),
|acc, &MultiProductIter { ref iter, ref iter_orig, cur: _ }| {
let cur_size = iter.size_hint();
let total_size = iter_orig.size_hint();
size_hint::add(size_hint::mul(acc, total_size), cur_size)
}
)
}
fn last(self) -> Option<Self::Item> {
let iter_count = self.0.len();
let lasts: Self::Item = self.0.into_iter()
.map(|multi_iter| multi_iter.iter.last())
.while_some()
.collect();
if lasts.len() == iter_count {
Some(lasts)
} else {
None
}
}
}

165
third_party/rust/itertools/src/combinations.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,165 @@
use std::ops::Index;
use std::fmt;
/// An iterator to iterate through all the `n`-length combinations in an iterator.
///
/// See [`.combinations()`](../trait.Itertools.html#method.combinations) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Combinations<I: Iterator> {
n: usize,
indices: Vec<usize>,
pool: LazyBuffer<I>,
first: bool,
}
impl<I> fmt::Debug for Combinations<I>
where I: Iterator + fmt::Debug,
I::Item: fmt::Debug,
{
debug_fmt_fields!(Combinations, n, indices, pool, first);
}
/// Create a new `Combinations` from a clonable iterator.
pub fn combinations<I>(iter: I, n: usize) -> Combinations<I>
where I: Iterator
{
let mut indices: Vec<usize> = Vec::with_capacity(n);
for i in 0..n {
indices.push(i);
}
let mut pool: LazyBuffer<I> = LazyBuffer::new(iter);
for _ in 0..n {
if !pool.get_next() {
break;
}
}
Combinations {
n: n,
indices: indices,
pool: pool,
first: true,
}
}
impl<I> Iterator for Combinations<I>
where I: Iterator,
I::Item: Clone
{
type Item = Vec<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
let mut pool_len = self.pool.len();
if self.pool.is_done() {
if pool_len == 0 || self.n > pool_len {
return None;
}
}
if self.first {
self.first = false;
} else if self.n == 0 {
return None;
} else {
// Scan from the end, looking for an index to increment
let mut i: usize = self.n - 1;
// Check if we need to consume more from the iterator
if self.indices[i] == pool_len - 1 && !self.pool.is_done() {
if self.pool.get_next() {
pool_len += 1;
}
}
while self.indices[i] == i + pool_len - self.n {
if i > 0 {
i -= 1;
} else {
// Reached the last combination
return None;
}
}
// Increment index, and reset the ones to its right
self.indices[i] += 1;
let mut j = i + 1;
while j < self.n {
self.indices[j] = self.indices[j - 1] + 1;
j += 1;
}
}
// Create result vector based on the indices
let mut result = Vec::with_capacity(self.n);
for i in self.indices.iter() {
result.push(self.pool[*i].clone());
}
Some(result)
}
}
#[derive(Debug)]
struct LazyBuffer<I: Iterator> {
it: I,
done: bool,
buffer: Vec<I::Item>,
}
impl<I> LazyBuffer<I>
where I: Iterator
{
pub fn new(it: I) -> LazyBuffer<I> {
let mut it = it;
let mut buffer = Vec::new();
let done;
if let Some(first) = it.next() {
buffer.push(first);
done = false;
} else {
done = true;
}
LazyBuffer {
it: it,
done: done,
buffer: buffer,
}
}
pub fn len(&self) -> usize {
self.buffer.len()
}
pub fn is_done(&self) -> bool {
self.done
}
pub fn get_next(&mut self) -> bool {
if self.done {
return false;
}
let next_item = self.it.next();
match next_item {
Some(x) => {
self.buffer.push(x);
true
}
None => {
self.done = true;
false
}
}
}
}
impl<I> Index<usize> for LazyBuffer<I>
where I: Iterator,
I::Item: Sized
{
type Output = I::Item;
fn index<'b>(&'b self, _index: usize) -> &'b I::Item {
self.buffer.index(_index)
}
}

22
third_party/rust/itertools/src/concat_impl.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,22 @@
use Itertools;
/// Combine all an iterator's elements into one element by using `Extend`.
///
/// `IntoIterator`-enabled version of `.concat()`
///
/// This combinator will extend the first item with each of the rest of the
/// items of the iterator. If the iterator is empty, the default value of
/// `I::Item` is returned.
///
/// ```rust
/// use itertools::concat;
///
/// let input = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
/// assert_eq!(concat(input), vec![1, 2, 3, 4, 5, 6]);
/// ```
pub fn concat<I>(iterable: I) -> I::Item
where I: IntoIterator,
I::Item: Extend<<<I as IntoIterator>::Item as IntoIterator>::Item> + IntoIterator + Default
{
iterable.into_iter().fold1(|mut a, b| { a.extend(b); a }).unwrap_or_else(|| <_>::default())
}

Просмотреть файл

@ -16,6 +16,11 @@ macro_rules! impl_cons_iter(
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
fn fold<Acc, Fold>(self, accum: Acc, mut f: Fold) -> Acc
where Fold: FnMut(Acc, Self::Item) -> Acc,
{
self.iter.fold(accum, move |acc, (($($B,)*), x)| f(acc, ($($B,)* x, )))
}
}
#[allow(non_snake_case)]
@ -36,6 +41,7 @@ impl_cons_iter!(A, B, C, D, E, F, G, H,);
/// `((A, B), C)` to an iterator of `(A, B, C)`.
///
/// Used by the `iproduct!()` macro.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct ConsTuples<I, J>
where I: Iterator<Item=J>,
{

10
third_party/rust/itertools/src/either_or_both.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,10 @@
/// Value that either holds a single A or B, or both.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum EitherOrBoth<A, B> {
/// Both values are present.
Both(A, B),
/// Only the left value of type `A` is present.
Left(A),
/// Only the right value of type `B` is present.
Right(B),
}

13
third_party/rust/itertools/src/free.rs поставляемый
Просмотреть файл

@ -3,19 +3,26 @@
//! 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")]
use std::fmt::Display;
use std::iter::{self, Zip};
#[cfg(feature = "use_std")]
use Itertools;
pub use adaptors::{
interleave,
merge,
put_back,
put_back_n,
};
pub use adaptors::multipeek::multipeek;
#[cfg(feature = "use_std")]
pub use put_back_n_impl::put_back_n;
#[cfg(feature = "use_std")]
pub use multipeek_impl::multipeek;
#[cfg(feature = "use_std")]
pub use kmerge_impl::kmerge;
pub use zip_eq_impl::zip_eq;
pub use merge_join::merge_join_by;
#[cfg(feature = "use_std")]
pub use rciter_impl::rciter;
/// Iterate `iterable` with a running index.
@ -196,6 +203,7 @@ pub fn min<I>(iterable: I) -> Option<I::Item>
///
/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
/// ```
#[cfg(feature = "use_std")]
pub fn join<I>(iterable: I, sep: &str) -> String
where I: IntoIterator,
I::Item: Display
@ -213,6 +221,7 @@ pub fn join<I>(iterable: I, sep: &str) -> String
///
/// assert_equal(sorted("rust".chars()), "rstu".chars());
/// ```
#[cfg(feature = "use_std")]
pub fn sorted<I>(iterable: I) -> Vec<I::Item>
where I: IntoIterator,
I::Item: Ord

91
third_party/rust/itertools/src/groupbylazy.rs поставляемый
Просмотреть файл

@ -60,13 +60,14 @@ struct GroupInner<K, I, F>
/// flag set if iterator is exhausted
done: bool,
/// Index of group we are currently buffering or visiting
top: usize,
top_group: usize,
/// Least index for which we still have elements buffered
bot: usize,
/// Group index for `buffer[0]` -- the slots bufbot..bot are unused
/// and will be erased when that range is large enough.
bufbot: usize,
/// Buffered groups, from `bufbot` (index 0) to `top`.
oldest_buffered_group: usize,
/// Group index for `buffer[0]` -- the slots
/// bottom_group..oldest_buffered_group are unused and will be erased when
/// that range is large enough.
bottom_group: usize,
/// Buffered groups, from `bottom_group` (index 0) to `top_group`.
buffer: Vec<vec::IntoIter<I::Item>>,
/// index of last group iter that was dropped, usize::MAX == none
dropped_group: usize,
@ -81,19 +82,21 @@ impl<K, I, F> GroupInner<K, I, F>
#[inline(always)]
fn step(&mut self, client: usize) -> Option<I::Item> {
/*
println!("client={}, bufbot={}, bot={}, top={}, buffers=[{}]",
client, self.bufbot, self.bot, self.top,
println!("client={}, bottom_group={}, oldest_buffered_group={}, top_group={}, buffers=[{}]",
client, self.bottom_group, self.oldest_buffered_group,
self.top_group,
self.buffer.iter().map(|elt| elt.len()).format(", "));
*/
if client < self.bot {
if client < self.oldest_buffered_group {
None
} else if client < self.top ||
(client == self.top && self.buffer.len() > self.top - self.bufbot)
} else if client < self.top_group ||
(client == self.top_group &&
self.buffer.len() > self.top_group - self.bottom_group)
{
self.lookup_buffer(client)
} else if self.done {
None
} else if self.top == client {
} else if self.top_group == client {
self.step_current()
} else {
self.step_buffering(client)
@ -103,24 +106,24 @@ impl<K, I, F> GroupInner<K, I, F>
#[inline(never)]
fn lookup_buffer(&mut self, client: usize) -> Option<I::Item> {
// if `bufidx` doesn't exist in self.buffer, it might be empty
let bufidx = client - self.bufbot;
if client < self.bot {
let bufidx = client - self.bottom_group;
if client < self.oldest_buffered_group {
return None;
}
let elt = self.buffer.get_mut(bufidx).and_then(|queue| queue.next());
if elt.is_none() && client == self.bot {
if elt.is_none() && client == self.oldest_buffered_group {
// FIXME: VecDeque is unfortunately not zero allocation when empty,
// so we do this job manually.
// `bufbot..bot` is unused, and if it's large enough, erase it.
self.bot += 1;
// `bottom_group..oldest_buffered_group` is unused, and if it's large enough, erase it.
self.oldest_buffered_group += 1;
// skip forward further empty queues too
while self.buffer.get(self.bot - self.bufbot)
while self.buffer.get(self.oldest_buffered_group - self.bottom_group)
.map_or(false, |buf| buf.len() == 0)
{
self.bot += 1;
self.oldest_buffered_group += 1;
}
let nclear = self.bot - self.bufbot;
let nclear = self.oldest_buffered_group - self.bottom_group;
if nclear > 0 && nclear >= self.buffer.len() / 2 {
let mut i = 0;
self.buffer.retain(|buf| {
@ -128,7 +131,7 @@ impl<K, I, F> GroupInner<K, I, F>
debug_assert!(buf.len() == 0 || i > nclear);
i > nclear
});
self.bufbot = self.bot;
self.bottom_group = self.oldest_buffered_group;
}
}
elt
@ -152,12 +155,12 @@ impl<K, I, F> GroupInner<K, I, F>
// the requested group index, and buffer the elements (unless
// the group is marked as dropped).
// Because the `Groups` iterator is always the first to request
// each group index, client is the next index efter top.
debug_assert!(self.top + 1 == client);
// each group index, client is the next index efter top_group.
debug_assert!(self.top_group + 1 == client);
let mut group = Vec::new();
if let Some(elt) = self.current_elt.take() {
if self.top != self.dropped_group {
if self.top_group != self.dropped_group {
group.push(elt);
}
}
@ -174,33 +177,33 @@ impl<K, I, F> GroupInner<K, I, F>
},
}
self.current_key = Some(key);
if self.top != self.dropped_group {
if self.top_group != self.dropped_group {
group.push(elt);
}
}
if self.top != self.dropped_group {
if self.top_group != self.dropped_group {
self.push_next_group(group);
}
if first_elt.is_some() {
self.top += 1;
debug_assert!(self.top == client);
self.top_group += 1;
debug_assert!(self.top_group == client);
}
first_elt
}
fn push_next_group(&mut self, group: Vec<I::Item>) {
// When we add a new buffered group, fill up slots between bot and top
while self.top - self.bufbot > self.buffer.len() {
// When we add a new buffered group, fill up slots between oldest_buffered_group and top_group
while self.top_group - self.bottom_group > self.buffer.len() {
if self.buffer.is_empty() {
self.bufbot += 1;
self.bot += 1;
self.bottom_group += 1;
self.oldest_buffered_group += 1;
} else {
self.buffer.push(Vec::new().into_iter());
}
}
self.buffer.push(group.into_iter());
debug_assert!(self.top + 1 - self.bufbot == self.buffer.len());
debug_assert!(self.top_group + 1 - self.bottom_group == self.buffer.len());
}
/// This is the immediate case, where we use no buffering
@ -219,7 +222,7 @@ impl<K, I, F> GroupInner<K, I, F>
Some(old_key) => if old_key != key {
self.current_key = Some(key);
self.current_elt = Some(elt);
self.top += 1;
self.top_group += 1;
return None;
},
}
@ -240,14 +243,14 @@ impl<K, I, F> GroupInner<K, I, F>
// Perform this by simply buffering one more element, grabbing the
// next key.
debug_assert!(!self.done);
debug_assert!(client == self.top);
debug_assert!(client == self.top_group);
debug_assert!(self.current_key.is_some());
debug_assert!(self.current_elt.is_none());
let old_key = self.current_key.take().unwrap();
if let Some(elt) = self.next_element() {
let key = self.key.call_mut(&elt);
if old_key != key {
self.top += 1;
self.top_group += 1;
}
self.current_key = Some(key);
self.current_elt = Some(elt);
@ -281,6 +284,7 @@ impl<K, I, F> GroupInner<K, I, F>
/// iterated.
///
/// See [`.group_by()`](../trait.Itertools.html#method.group_by) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct GroupBy<K, I, F>
where I: Iterator,
{
@ -302,9 +306,9 @@ pub fn new<K, J, F>(iter: J, f: F) -> GroupBy<K, J::IntoIter, F>
current_key: None,
current_elt: None,
done: false,
top: 0,
bot: 0,
bufbot: 0,
top_group: 0,
oldest_buffered_group: 0,
bottom_group: 0,
buffer: Vec::new(),
dropped_group: !0,
}),
@ -350,6 +354,7 @@ impl<'a, K, I, F> IntoIterator for &'a GroupBy<K, I, F>
/// the group's key `K` and the group's iterator.
///
/// See [`.group_by()`](../trait.Itertools.html#method.group_by) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Groups<'a, K: 'a, I: 'a, F: 'a>
where I: Iterator,
I::Item: 'a
@ -431,9 +436,9 @@ pub fn new_chunks<J>(iter: J, size: usize) -> IntoChunks<J::IntoIter>
current_key: None,
current_elt: None,
done: false,
top: 0,
bot: 0,
bufbot: 0,
top_group: 0,
oldest_buffered_group: 0,
bottom_group: 0,
buffer: Vec::new(),
dropped_group: !0,
}),
@ -455,6 +460,7 @@ pub fn new_chunks<J>(iter: J, size: usize) -> IntoChunks<J::IntoIter>
/// Iterator element type is `Chunk`, each chunk's iterator.
///
/// See [`.chunks()`](../trait.Itertools.html#method.chunks) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct IntoChunks<I>
where I: Iterator,
{
@ -499,6 +505,7 @@ impl<'a, I> IntoIterator for &'a IntoChunks<I>
/// Iterator element type is `Chunk`.
///
/// See [`.chunks()`](../trait.Itertools.html#method.chunks) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Chunks<'a, I: 'a>
where I: Iterator,
I::Item: 'a,

Просмотреть файл

@ -10,6 +10,7 @@ use super::size_hint;
/// This iterator is *fused*.
///
/// See [`.intersperse()`](../trait.Itertools.html#method.intersperse) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Intersperse<I>
where I: Iterator
{

Просмотреть файл

@ -109,6 +109,7 @@ fn sift_down<T, S>(heap: &mut [T], index: usize, mut less_than: S)
/// Iterator element type is `I::Item`.
///
/// See [`.kmerge()`](../trait.Itertools.html#method.kmerge) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct KMerge<I>
where I: Iterator
{
@ -183,6 +184,7 @@ impl<I> Iterator for KMerge<I>
///
/// See [`.kmerge_by()`](../trait.Itertools.html#method.kmerge_by) for more
/// information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct KMergeBy<I, F>
where I: Iterator,
{

549
third_party/rust/itertools/src/lib.rs поставляемый Executable file → Normal file
Просмотреть файл

@ -1,45 +1,51 @@
#![warn(missing_docs)]
#![crate_name="itertools"]
#![cfg_attr(not(feature = "use_std"), no_std)]
//! Itertools — extra iterator adaptors, functions and macros.
//!
//! To use the iterator methods in this crate, import the [`Itertools` trait](./trait.Itertools.html):
//!
//! ```ignore
//! ```
//! use itertools::Itertools;
//! ```
//!
//! To enable the macros in this crate, use the `#[macro_use]` attribute:
//! ## Crate Features
//!
//! ```ignore
//! #[macro_use] extern crate itertools;
//! ```
//! - `use_std`
//! - Enabled by default.
//! - Disable to compile itertools using `#![no_std]`. This disables
//! any items that depend on collections (like `group_by`, `unique`,
//! `kmerge`, `join` and many more).
//!
//! ## License
//! Dual-licensed to be compatible with the Rust project.
//! ## Rust Version
//!
//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.
//! This version of itertools requires Rust 1.12 or later.
//!
//!
#![doc(html_root_url="https://docs.rs/itertools/")]
#![doc(html_root_url="https://docs.rs/itertools/0.7/")]
extern crate either;
#[cfg(not(feature = "use_std"))]
extern crate core as std;
pub use either::Either;
use std::iter::{IntoIterator};
use std::fmt::Write;
use std::cmp::Ordering;
use std::fmt;
#[cfg(feature = "use_std")]
use std::hash::Hash;
#[cfg(feature = "use_std")]
use std::fmt::Write;
#[macro_use]
mod impl_macros;
// for compatibility with no std and macros
#[doc(hidden)]
pub use std::iter as __std_iter;
/// The concrete iterator types.
pub mod structs {
pub use adaptors::{
@ -48,71 +54,103 @@ pub mod structs {
InterleaveShortest,
Product,
PutBack,
PutBackN,
Batching,
Step,
MapResults,
Merge,
MergeBy,
MultiPeek,
TakeWhileRef,
WhileSome,
Coalesce,
TupleCombinations,
Combinations,
Unique,
UniqueBy,
Flatten,
Positions,
Update,
};
#[cfg(feature = "use_std")]
pub use adaptors::MultiProduct;
#[cfg(feature = "use_std")]
pub use combinations::Combinations;
pub use cons_tuples_impl::ConsTuples;
pub use format::{Format, FormatWith};
#[cfg(feature = "use_std")]
pub use groupbylazy::{IntoChunks, Chunk, Chunks, GroupBy, Group, Groups};
pub use intersperse::Intersperse;
#[cfg(feature = "use_std")]
pub use kmerge_impl::{KMerge, KMergeBy};
pub use merge_join::MergeJoinBy;
#[cfg(feature = "use_std")]
pub use multipeek_impl::MultiPeek;
pub use pad_tail::PadUsing;
pub use peeking_take_while::PeekingTakeWhile;
pub use process_results_impl::ProcessResults;
#[cfg(feature = "use_std")]
pub use put_back_n_impl::PutBackN;
#[cfg(feature = "use_std")]
pub use rciter_impl::RcIter;
pub use repeatn::RepeatN;
pub use sources::{RepeatCall, Unfold, Iterate};
#[cfg(feature = "use_std")]
pub use tee::Tee;
pub use tuple_impl::{TupleBuffer, TupleWindows, Tuples};
#[cfg(feature = "use_std")]
pub use unique_impl::{Unique, UniqueBy};
pub use with_position::WithPosition;
pub use zip_eq_impl::ZipEq;
pub use zip_longest::ZipLongest;
pub use ziptuple::Zip;
}
pub use structs::*;
pub use concat_impl::concat;
pub use cons_tuples_impl::cons_tuples;
pub use diff::diff_with;
pub use diff::Diff;
#[cfg(feature = "use_std")]
pub use kmerge_impl::{kmerge_by};
pub use minmax::MinMaxResult;
pub use peeking_take_while::PeekingNext;
pub use process_results_impl::process_results;
pub use repeatn::repeat_n;
pub use sources::{repeat_call, unfold, iterate};
pub use with_position::Position;
pub use zip_longest::EitherOrBoth;
pub use ziptuple::multizip;
mod adaptors;
mod either_or_both;
pub use either_or_both::EitherOrBoth;
#[doc(hidden)]
pub mod free;
#[doc(inline)]
pub use free::*;
mod concat_impl;
mod cons_tuples_impl;
#[cfg(feature = "use_std")]
mod combinations;
mod diff;
mod format;
#[cfg(feature = "use_std")]
mod groupbylazy;
mod intersperse;
#[cfg(feature = "use_std")]
mod kmerge_impl;
mod merge_join;
mod minmax;
#[cfg(feature = "use_std")]
mod multipeek_impl;
mod pad_tail;
mod peeking_take_while;
mod process_results_impl;
#[cfg(feature = "use_std")]
mod put_back_n_impl;
#[cfg(feature = "use_std")]
mod rciter_impl;
mod repeatn;
mod size_hint;
mod sources;
#[cfg(feature = "use_std")]
mod tee;
mod tuple_impl;
#[cfg(feature = "use_std")]
mod unique_impl;
mod with_position;
mod zip_eq_impl;
mod zip_longest;
@ -134,6 +172,14 @@ mod ziptuple;
/// }
/// # }
/// ```
///
/// **Note:** To enable the macros in this crate, use the `#[macro_use]`
/// attribute when importing the crate:
///
/// ```
/// #[macro_use] extern crate itertools;
/// # fn main() { }
/// ```
macro_rules! iproduct {
(@flatten $I:expr,) => (
$I
@ -142,7 +188,7 @@ macro_rules! iproduct {
iproduct!(@flatten $crate::cons_tuples(iproduct!($I, $J)), $($K,)*)
);
($I:expr) => (
(::std::iter::IntoIterator::into_iter($I))
$crate::__std_iter::IntoIterator::into_iter($I)
);
($I:expr, $J:expr) => (
$crate::Itertools::cartesian_product(iproduct!($I), iproduct!($J))
@ -155,37 +201,66 @@ macro_rules! iproduct {
#[macro_export]
/// Create an iterator running multiple iterators in lockstep.
///
/// The izip! iterator yields elements until any subiterator
/// The `izip!` iterator yields elements until any subiterator
/// returns `None`.
///
/// Iterator element type is like `(A, B, ..., E)` if formed
/// from iterators `(I, J, ..., M)` implementing `I: Iterator<A>`,
/// `J: Iterator<B>`, ..., `M: Iterator<E>`
/// This is a version of the standard ``.zip()`` that's supporting more than
/// two iterators. The iterator elment type is a tuple with one element
/// from each of the input iterators. Just like ``.zip()``, the iteration stops
/// when the shortest of the inputs reaches its end.
///
/// **Note:** The result of this macro is an iterator composed of
/// repeated `.zip()` and a `.map()`; it has an anonymous type.
/// Prefer this macro `izip!()` over [`multizip`] for the performance benefits
/// of using the standard library `.zip()`.
///
/// [`multizip`]: fn.multizip.html
///
/// ```
/// #[macro_use] extern crate itertools;
/// # fn main() {
///
/// // Iterate over three sequences side-by-side
/// let mut xs = [0, 0, 0];
/// let ys = [69, 107, 101];
/// // iterate over three sequences side-by-side
/// let mut results = [0, 0, 0, 0];
/// let inputs = [3, 7, 9, 6];
///
/// for (i, a, b) in izip!(0..100, &mut xs, &ys) {
/// *a = i ^ *b;
/// for (r, index, input) in izip!(&mut results, 0..10, &inputs) {
/// *r = index * 10 + input;
/// }
///
/// assert_eq!(xs, [69, 106, 103]);
/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
/// # }
/// ```
///
/// **Note:** To enable the macros in this crate, use the `#[macro_use]`
/// attribute when importing the crate:
///
/// ```
/// #[macro_use] extern crate itertools;
/// # fn main() { }
/// ```
macro_rules! izip {
($I:expr) => (
(::std::iter::IntoIterator::into_iter($I))
);
($($I:expr),*) => (
{
$crate::multizip(($(izip!($I)),*))
}
);
// @closure creates a tuple-flattening closure for .map() call. usage:
// @closure partial_pattern => partial_tuple , rest , of , iterators
// eg. izip!( @closure ((a, b), c) => (a, b, c) , dd , ee )
( @closure $p:pat => $tup:expr ) => {
|$p| $tup
};
// The "b" identifier is a different identifier on each recursion level thanks to hygiene.
( @closure $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )* ) => {
izip!(@closure ($p, b) => ( $($tup)*, b ) $( , $tail )*)
};
( $first:expr $( , $rest:expr )* $(,)* ) => {
$crate::__std_iter::IntoIterator::into_iter($first)
$(
.zip($rest)
)*
.map(
izip!(@closure a => (a) $( , $rest )*)
)
};
}
/// The trait `Itertools`: extra iterator adaptors and methods for iterators.
@ -203,8 +278,7 @@ macro_rules! izip {
pub trait Itertools : Iterator {
// adaptors
/// Alternate elements from two iterators until both
/// run out.
/// Alternate elements from two iterators until both have run out.
///
/// Iterator element type is `Self::Item`.
///
@ -213,8 +287,8 @@ pub trait Itertools : Iterator {
/// ```
/// use itertools::Itertools;
///
/// let it = (0..3).interleave(vec![7, 8]);
/// itertools::assert_equal(it, vec![0, 7, 1, 8, 2]);
/// let it = (1..7).interleave(vec![-1, -2]);
/// itertools::assert_equal(it, vec![1, -1, 2, -2, 3, 4, 5, 6]);
/// ```
fn interleave<J>(self, other: J) -> Interleave<Self, J::IntoIter>
where J: IntoIterator<Item = Self::Item>,
@ -223,15 +297,16 @@ pub trait Itertools : Iterator {
interleave(self, other)
}
/// Alternate elements from two iterators until one of them runs out.
/// Alternate elements from two iterators until at least one of them has run
/// out.
///
/// Iterator element type is `Self::Item`.
///
/// ```
/// use itertools::Itertools;
///
/// let it = (0..5).interleave_shortest(vec![7, 8]);
/// itertools::assert_equal(it, vec![0, 7, 1, 8, 2]);
/// let it = (1..7).interleave_shortest(vec![-1, -2]);
/// itertools::assert_equal(it, vec![1, -1, 2, -2, 3]);
/// ```
fn interleave_shortest<J>(self, other: J) -> InterleaveShortest<Self, J::IntoIter>
where J: IntoIterator<Item = Self::Item>,
@ -264,6 +339,15 @@ pub trait Itertools : Iterator {
///
/// This iterator is *fused*.
///
/// As long as neither input iterator is exhausted yet, it yields two values
/// via `EitherOrBoth::Both`.
///
/// When the parameter iterator is exhausted, it only yields a value from the
/// `self` iterator via `EitherOrBoth::Left`.
///
/// When the `self` iterator is exhausted, it only yields a value from the
/// parameter iterator via `EitherOrBoth::Right`.
///
/// When both iterators return `None`, all further invocations of `.next()`
/// will return `None`.
///
@ -306,8 +390,8 @@ pub trait Itertools : Iterator {
/// ```
/// use itertools::Itertools;
///
/// // An adaptor that gathers elements up in pairs
/// let pit = (0..4).batching(|mut it| {
/// // An adaptor that gathers elements in pairs
/// let pit = (0..4).batching(|it| {
/// match it.next() {
/// None => None,
/// Some(x) => match it.next() {
@ -360,22 +444,15 @@ pub trait Itertools : Iterator {
/// assert_eq!(4, group.sum::<i32>().abs());
/// }
/// ```
#[cfg(feature = "use_std")]
fn group_by<K, F>(self, key: F) -> GroupBy<K, Self, F>
where Self: Sized,
F: FnMut(&Self::Item) -> K,
K: PartialEq,
{
groupbylazy::new(self, key)
}
///
#[deprecated(note = "renamed to .group_by()")]
fn group_by_lazy<K, F>(self, key: F) -> GroupBy<K, Self, F>
where Self: Sized,
F: FnMut(&Self::Item) -> K,
{
self.group_by(key)
}
/// Return an *iterable* that can chunk the iterator.
///
/// Yield subiterators (chunks) that each yield a fixed number elements,
@ -403,6 +480,7 @@ pub trait Itertools : Iterator {
/// assert_eq!(4, chunk.sum());
/// }
/// ```
#[cfg(feature = "use_std")]
fn chunks(self, size: usize) -> IntoChunks<Self>
where Self: Sized,
{
@ -410,14 +488,6 @@ pub trait Itertools : Iterator {
groupbylazy::new_chunks(self, size)
}
///
#[deprecated(note = "renamed to .chunks()")]
fn chunks_lazy(self, size: usize) -> IntoChunks<Self>
where Self: Sized,
{
self.chunks(size)
}
/// Return an iterator over all contiguous windows producing tuples of
/// a specific size (up to 4).
///
@ -512,6 +582,7 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(t2, 0..4);
/// itertools::assert_equal(t1, 1..4);
/// ```
#[cfg(feature = "use_std")]
fn tee(self) -> (Tee<Self>, Tee<Self>)
where Self: Sized,
Self::Item: Clone
@ -605,6 +676,47 @@ pub trait Itertools : Iterator {
adaptors::merge_by_new(self, other.into_iter(), is_first)
}
/// Create an iterator that merges items from both this and the specified
/// iterator in ascending order.
///
/// It chooses whether to pair elements based on the `Ordering` returned by the
/// specified compare function. At any point, inspecting the tip of the
/// iterators `I` and `J` as items `i` of type `I::Item` and `j` of type
/// `J::Item` respectively, the resulting iterator will:
///
/// - Emit `EitherOrBoth::Left(i)` when `i < j`,
/// and remove `i` from its source iterator
/// - Emit `EitherOrBoth::Right(j)` when `i > j`,
/// and remove `j` from its source iterator
/// - Emit `EitherOrBoth::Both(i, j)` when `i == j`,
/// and remove both `i` and `j` from their respective source iterators
///
/// ```
/// use itertools::Itertools;
/// use itertools::EitherOrBoth::{Left, Right, Both};
///
/// let ki = (0..10).step(3);
/// let ku = (0..10).step(5);
/// let ki_ku = ki.merge_join_by(ku, |i, j| i.cmp(j)).map(|either| {
/// match either {
/// Left(_) => "Ki",
/// Right(_) => "Ku",
/// Both(_, _) => "KiKu"
/// }
/// });
///
/// itertools::assert_equal(ki_ku, vec!["KiKu", "Ki", "Ku", "Ki", "Ki"]);
/// ```
#[inline]
fn merge_join_by<J, F>(self, other: J, cmp_fn: F) -> MergeJoinBy<Self, J::IntoIter, F>
where J: IntoIterator,
F: FnMut(&Self::Item, &J::Item) -> std::cmp::Ordering,
Self: Sized
{
merge_join_by(self, other, cmp_fn)
}
/// Return an iterator adaptor that flattens an iterator of iterators by
/// merging them in ascending order.
///
@ -621,10 +733,11 @@ pub trait Itertools : Iterator {
/// let it = vec![a, b, c].into_iter().kmerge();
/// itertools::assert_equal(it, vec![0, 1, 2, 3, 4, 5]);
/// ```
fn kmerge(self) -> KMerge<<<Self as Iterator>::Item as IntoIterator>::IntoIter>
#[cfg(feature = "use_std")]
fn kmerge(self) -> KMerge<<Self::Item as IntoIterator>::IntoIter>
where Self: Sized,
Self::Item: IntoIterator,
<<Self as Iterator>::Item as IntoIterator>::Item: PartialOrd,
<Self::Item as IntoIterator>::Item: PartialOrd,
{
kmerge(self)
}
@ -649,12 +762,13 @@ pub trait Itertools : Iterator {
/// assert_eq!(it.next(), Some(0.));
/// assert_eq!(it.last(), Some(-7.));
/// ```
#[cfg(feature = "use_std")]
fn kmerge_by<F>(self, first: F)
-> KMergeBy<<<Self as Iterator>::Item as IntoIterator>::IntoIter, F>
-> KMergeBy<<Self::Item as IntoIterator>::IntoIter, F>
where Self: Sized,
Self::Item: IntoIterator,
F: FnMut(&<<Self as Iterator>::Item as IntoIterator>::Item,
&<<Self as Iterator>::Item as IntoIterator>::Item) -> bool
F: FnMut(&<Self::Item as IntoIterator>::Item,
&<Self::Item as IntoIterator>::Item) -> bool
{
kmerge_by(self, first)
}
@ -679,14 +793,51 @@ pub trait Itertools : Iterator {
adaptors::cartesian_product(self, other.into_iter())
}
/// Return an iterator adaptor that iterates over the cartesian product of
/// all subiterators returned by meta-iterator `self`.
///
/// All provided iterators must yield the same `Item` type. To generate
/// the product of iterators yielding multiple types, use the
/// [`iproduct`](macro.iproduct.html) macro instead.
///
///
/// The iterator element type is `Vec<T>`, where `T` is the iterator element
/// of the subiterators.
///
/// ```
/// use itertools::Itertools;
/// let mut multi_prod = (0..3).map(|i| (i * 2)..(i * 2 + 2))
/// .multi_cartesian_product();
/// assert_eq!(multi_prod.next(), Some(vec![0, 2, 4]));
/// assert_eq!(multi_prod.next(), Some(vec![0, 2, 5]));
/// assert_eq!(multi_prod.next(), Some(vec![0, 3, 4]));
/// assert_eq!(multi_prod.next(), Some(vec![0, 3, 5]));
/// assert_eq!(multi_prod.next(), Some(vec![1, 2, 4]));
/// assert_eq!(multi_prod.next(), Some(vec![1, 2, 5]));
/// assert_eq!(multi_prod.next(), Some(vec![1, 3, 4]));
/// assert_eq!(multi_prod.next(), Some(vec![1, 3, 5]));
/// assert_eq!(multi_prod.next(), None);
/// ```
#[cfg(feature = "use_std")]
fn multi_cartesian_product(self) -> MultiProduct<<Self::Item as IntoIterator>::IntoIter>
where Self: Iterator + Sized,
Self::Item: IntoIterator,
<Self::Item as IntoIterator>::IntoIter: Clone,
<Self::Item as IntoIterator>::Item: Clone
{
adaptors::multi_cartesian_product(self)
}
/// Return an iterator adaptor that uses the passed-in closure to
/// optionally merge together consecutive elements.
///
/// The closure `f` is passed two elements, `x`, `y` and may return either
/// (1) `Ok(z)` to merge the two values or (2) `Err((x', y'))` to indicate
/// they can't be merged. In (2), the value `x'` is emitted by the iterator.
/// Coalesce continues with either `z` (1) or `y'` (2), and the next
/// iterator element as the next pair of elements to merge.
/// The closure `f` is passed two elements, `previous` and `current` and may
/// return either (1) `Ok(combined)` to merge the two values or
/// (2) `Err((previous', current'))` to indicate they can't be merged.
/// In (2), the value `previous'` is emitted by the iterator.
/// Either (1) `combined` or (2) `current'` becomes the previous value
/// when coalesce continues with the next pair of elements to merge. The
/// value that remains at the end is also emitted by the iterator.
///
/// Iterator element type is `Self::Item`.
///
@ -748,11 +899,12 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(data.into_iter().unique(),
/// vec![10, 20, 30, 40, 50]);
/// ```
#[cfg(feature = "use_std")]
fn unique(self) -> Unique<Self>
where Self: Sized,
Self::Item: Clone + Eq + Hash
{
adaptors::unique(self)
unique_impl::unique(self)
}
/// Return an iterator adaptor that filters out elements that have
@ -769,12 +921,13 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(data.into_iter().unique_by(|s| s.len()),
/// vec!["a", "bb", "ccc"]);
/// ```
#[cfg(feature = "use_std")]
fn unique_by<V, F>(self, f: F) -> UniqueBy<Self, V, F>
where Self: Sized,
V: Eq + Hash,
F: FnMut(&Self::Item) -> V
{
adaptors::unique_by(self, f)
unique_impl::unique_by(self, f)
}
/// Return an iterator adaptor that borrows from this iterator and
@ -888,8 +1041,6 @@ pub trait Itertools : Iterator {
/// Iterator element type is `Vec<Self::Item>`. The iterator produces a new Vec per iteration,
/// and clones the iterator elements.
///
/// **Panics** if `n` is zero.
///
/// ```
/// use itertools::Itertools;
///
@ -901,11 +1052,12 @@ pub trait Itertools : Iterator {
/// vec![2, 3, 4],
/// ]);
/// ```
#[cfg(feature = "use_std")]
fn combinations(self, n: usize) -> Combinations<Self>
where Self: Sized,
Self::Item: Clone
{
adaptors::combinations(self, n)
combinations::combinations(self, n)
}
/// Return an iterator adaptor that pads the sequence to a minimum length of
@ -934,17 +1086,18 @@ pub trait Itertools : Iterator {
/// Unravel a nested iterator.
///
/// This is a shortcut for `it.flat_map(|x| x)`.
/// This is more or less equivalent to `.flat_map` with an identity
/// function.
///
/// ```
/// use itertools::Itertools;
///
/// let data = vec![vec![1, 2, 3], vec![4, 5, 6]];
/// let flattened = data.into_iter().flatten();
/// let flattened = data.iter().flatten();
///
/// itertools::assert_equal(flattened, vec![1, 2, 3, 4, 5, 6]);
/// itertools::assert_equal(flattened, &[1, 2, 3, 4, 5, 6]);
/// ```
fn flatten(self) -> Flatten<Self, <<Self as Iterator>::Item as IntoIterator>::IntoIter>
fn flatten(self) -> Flatten<Self, <Self::Item as IntoIterator>::IntoIter>
where Self: Sized,
Self::Item: IntoIterator
{
@ -976,6 +1129,43 @@ pub trait Itertools : Iterator {
with_position::with_position(self)
}
/// Return an iterator adaptor that yields the indices of all elements
/// satisfying a predicate, counted from the start of the iterator.
///
/// Equivalent to `iter.enumerate().filter(|(_, v)| predicate(v)).map(|(i, _)| i)`.
///
/// ```
/// use itertools::Itertools;
///
/// let data = vec![1, 2, 3, 3, 4, 6, 7, 9];
/// itertools::assert_equal(data.iter().positions(|v| v % 2 == 0), vec![1, 4, 5]);
///
/// itertools::assert_equal(data.iter().positions(|v| v % 2 == 1).rev(), vec![7, 6, 3, 2, 0]);
/// ```
fn positions<P>(self, predicate: P) -> Positions<Self, P>
where Self: Sized,
P: FnMut(Self::Item) -> bool,
{
adaptors::positions(self, predicate)
}
/// Return an iterator adaptor that applies a mutating function
/// to each element before yielding it.
///
/// ```
/// use itertools::Itertools;
///
/// let input = vec![vec![1], vec![3, 2, 1]];
/// let it = input.into_iter().update(|mut v| v.push(0));
/// itertools::assert_equal(it, vec![vec![1, 0], vec![3, 2, 1, 0]]);
/// ```
fn update<F>(self, updater: F) -> Update<Self, F>
where Self: Sized,
F: FnMut(&mut Self::Item),
{
adaptors::update(self, updater)
}
// non-adaptor methods
/// Advances the iterator and returns the next items grouped in a tuple of
/// a specific size (up to 4).
@ -997,6 +1187,37 @@ pub trait Itertools : Iterator {
T::collect_from_iter_no_buf(self)
}
/// Collects all items from the iterator into a tuple of a specific size
/// (up to 4).
///
/// If the number of elements inside the iterator is **exactly** equal to
/// the tuple size, then the tuple is returned inside `Some`, otherwise
/// `None` is returned.
///
/// ```
/// use itertools::Itertools;
///
/// let iter = 1..3;
///
/// if let Some((x, y)) = iter.collect_tuple() {
/// assert_eq!((x, y), (1, 2))
/// } else {
/// panic!("Expected two elements")
/// }
/// ```
fn collect_tuple<T>(mut self) -> Option<T>
where Self: Sized + Iterator<Item = T::Item>,
T: tuple_impl::TupleCollect
{
match self.next_tuple() {
elt @ Some(_) => match self.next() {
Some(_) => None,
None => elt,
},
_ => None
}
}
/// Find the position and value of the first element satisfying a predicate.
///
@ -1021,6 +1242,28 @@ pub trait Itertools : Iterator {
None
}
/// Check whether all elements compare equal.
///
/// Empty iterators are considered to have equal elements:
///
/// ```
/// use itertools::Itertools;
///
/// let data = vec![1, 1, 1, 2, 2, 3, 3, 3, 4, 5, 5];
/// assert!(!data.iter().all_equal());
/// assert!(data[0..3].iter().all_equal());
/// assert!(data[3..5].iter().all_equal());
/// assert!(data[5..8].iter().all_equal());
///
/// let data : Option<usize> = None;
/// assert!(data.into_iter().all_equal());
/// ```
fn all_equal(&mut self) -> bool
where Self::Item: PartialEq,
{
self.dedup().nth(1).is_none()
}
/// Consume the first `n` elements from the iterator eagerly,
/// and return the same iterator again.
///
@ -1087,16 +1330,36 @@ pub trait Itertools : Iterator {
///
/// itertools::assert_equal(rx.iter(), vec![1, 3, 5, 7, 9]);
/// ```
fn foreach<F>(&mut self, mut f: F)
where F: FnMut(Self::Item)
fn foreach<F>(self, mut f: F)
where F: FnMut(Self::Item),
Self: Sized,
{
// FIXME: This use of fold doesn't actually do any iterator
// specific traversal (fold requries `self`)
self.fold((), move |(), element| f(element))
}
/// Combine all an iterator's elements into one element by using `Extend`.
///
/// This combinator will extend the first item with each of the rest of the
/// items of the iterator. If the iterator is empty, the default value of
/// `I::Item` is returned.
///
/// ```rust
/// use itertools::Itertools;
///
/// let input = vec![vec![1], vec![2, 3], vec![4, 5, 6]];
/// assert_eq!(input.into_iter().concat(),
/// vec![1, 2, 3, 4, 5, 6]);
/// ```
fn concat(self) -> Self::Item
where Self: Sized,
Self::Item: Extend<<<Self as Iterator>::Item as IntoIterator>::Item> + IntoIterator + Default
{
concat(self)
}
/// `.collect_vec()` is simply a type specialization of `.collect()`,
/// for convenience.
#[cfg(feature = "use_std")]
fn collect_vec(self) -> Vec<Self::Item>
where Self: Sized
{
@ -1144,6 +1407,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")]
fn join(&mut self, sep: &str) -> String
where Self::Item: std::fmt::Display
{
@ -1184,14 +1448,6 @@ pub trait Itertools : Iterator {
format::new_format_default(self, sep)
}
///
#[deprecated(note = "renamed to .format()")]
fn format_default(self, sep: &str) -> Format<Self>
where Self: Sized,
{
format::new_format_default(self, sep)
}
/// Format all iterator elements, separated by `sep`.
///
/// This is a customizable version of `.format()`.
@ -1330,18 +1586,11 @@ pub trait Itertools : Iterator {
/// assert_eq!((0..10).fold1(|x, y| x + y).unwrap_or(0), 45);
/// assert_eq!((0..0).fold1(|x, y| x * y), None);
/// ```
fn fold1<F>(&mut self, mut f: F) -> Option<Self::Item>
where F: FnMut(Self::Item, Self::Item) -> Self::Item
fn fold1<F>(mut self, f: F) -> Option<Self::Item>
where F: FnMut(Self::Item, Self::Item) -> Self::Item,
Self: Sized,
{
match self.next() {
None => None,
Some(mut x) => {
for y in self {
x = f(x, y);
}
Some(x)
}
}
self.next().map(move |x| self.fold(x, f))
}
/// An iterator method that applies a function, producing a single, final value.
@ -1373,7 +1622,7 @@ pub trait Itertools : Iterator {
/// // fold_while:
/// let result3 = numbers.iter().fold_while(0, |acc, x| {
/// if *x > 5 { Done(acc) } else { Continue(acc + x) }
/// });
/// }).into_inner();
///
/// // they're the same
/// assert_eq!(result, result2);
@ -1383,23 +1632,18 @@ pub trait Itertools : Iterator {
/// The big difference between the computations of `result2` and `result3` is that while
/// `fold()` called the provided closure for every item of the callee iterator,
/// `fold_while()` actually stopped iterating as soon as it encountered `Fold::Done(_)`.
fn fold_while<B, F>(self, init: B, mut f: F) -> B
fn fold_while<B, F>(&mut self, init: B, mut f: F) -> FoldWhile<B>
where Self: Sized,
F: FnMut(B, Self::Item) -> FoldWhile<B>
{
let mut accum = init;
for item in self {
match f(accum, item) {
FoldWhile::Continue(res) => {
accum = res;
}
FoldWhile::Done(res) => {
accum = res;
break;
let mut acc = init;
while let Some(item) = self.next() {
match f(acc, item) {
FoldWhile::Continue(res) => acc = res,
res @ FoldWhile::Done(_) => return res,
}
}
}
accum
FoldWhile::Continue(acc)
}
/// Collect all iterator elements into a sorted vector in ascending order.
@ -1415,6 +1659,7 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(text.chars().sorted(),
/// "abcdef".chars());
/// ```
#[cfg(feature = "use_std")]
fn sorted(self) -> Vec<Self::Item>
where Self: Sized,
Self::Item: Ord
@ -1442,6 +1687,7 @@ pub trait Itertools : Iterator {
/// itertools::assert_equal(oldest_people_first,
/// vec!["Jill", "Jack", "Jane", "John"]);
/// ```
#[cfg(feature = "use_std")]
fn sorted_by<F>(self, cmp: F) -> Vec<Self::Item>
where Self: Sized,
F: FnMut(&Self::Item, &Self::Item) -> Ordering,
@ -1452,6 +1698,38 @@ pub trait Itertools : Iterator {
v
}
/// Collect all iterator elements into a sorted vector.
///
/// **Note:** This consumes the entire iterator, uses the
/// `slice::sort_by_key()` method and returns the sorted vector.
///
/// ```
/// use itertools::Itertools;
///
/// // sort people in descending order by age
/// let people = vec![("Jane", 20), ("John", 18), ("Jill", 30), ("Jack", 27)];
///
/// let oldest_people_first = people
/// .into_iter()
/// .sorted_by_key(|x| -x.1)
/// .into_iter()
/// .map(|(person, _age)| person);
///
/// itertools::assert_equal(oldest_people_first,
/// vec!["Jill", "Jack", "Jane", "John"]);
/// ```
#[cfg(feature = "use_std")]
fn sorted_by_key<K, F>(self, f: F) -> Vec<Self::Item>
where Self: Sized,
K: Ord,
F: FnMut(&Self::Item) -> K,
{
let mut v: Vec<Self::Item> = self.collect();
v.sort_by_key(f);
v
}
/// Collect all iterator elements into one of two
/// partitions. Unlike `Iterator::partition`, each partition may
/// have a distinct type.
@ -1571,12 +1849,12 @@ pub trait Itertools : Iterator {
impl<T: ?Sized> Itertools for T where T: Iterator { }
/// Return `true` if both iterators produce equal sequences
/// Return `true` if both iterables produce equal sequences
/// (elements pairwise equal and sequences of the same length),
/// `false` otherwise.
///
/// **Note:** the standard library method `Iterator::eq` now provides
/// the same functionality.
/// This is an `IntoIterator` enabled function that is similar to the standard
/// library method `Iterator::eq`.
///
/// ```
/// assert!(itertools::equal(vec![1, 2, 3], 1..4));
@ -1591,8 +1869,8 @@ pub fn equal<I, J>(a: I, b: J) -> bool
let mut ib = b.into_iter();
loop {
match ia.next() {
Some(ref x) => match ib.next() {
Some(ref y) => if x != y { return false; },
Some(x) => match ib.next() {
Some(y) => if x != y { return false; },
None => return false,
},
None => return ib.next().is_none()
@ -1600,7 +1878,7 @@ pub fn equal<I, J>(a: I, b: J) -> bool
}
}
/// Assert that two iterators produce equal sequences, with the same
/// Assert that two iterables produce equal sequences, with the same
/// semantics as *equal(a, b)*.
///
/// **Panics** on assertion failure with a message that shows the
@ -1679,6 +1957,7 @@ pub fn partition<'a, A: 'a, I, F>(iter: I, mut pred: F) -> usize
/// An enum used for controlling the execution of `.fold_while()`.
///
/// See [`.fold_while()`](trait.Itertools.html#method.fold_while) for more information.
#[derive(Copy, Clone, Debug)]
pub enum FoldWhile<T> {
/// Continue folding with this value
Continue(T),
@ -1686,3 +1965,19 @@ pub enum FoldWhile<T> {
Done(T),
}
impl<T> FoldWhile<T> {
/// Return the value in the continue or done.
pub fn into_inner(self) -> T {
match self {
FoldWhile::Continue(x) | FoldWhile::Done(x) => x,
}
}
/// Return true if `self` is `Done`, false if it is `Continue`.
pub fn is_done(&self) -> bool {
match *self {
FoldWhile::Continue(_) => false,
FoldWhile::Done(_) => true,
}
}
}

77
third_party/rust/itertools/src/merge_join.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,77 @@
use std::cmp::Ordering;
use std::iter::Fuse;
use super::adaptors::{PutBack, put_back};
use either_or_both::EitherOrBoth;
/// Return an iterator adaptor that merge-joins items from the two base iterators in ascending order.
///
/// See [`.merge_join_by()`](trait.Itertools.html#method.merge_join_by) for more information.
pub fn merge_join_by<I, J, F>(left: I, right: J, cmp_fn: F)
-> MergeJoinBy<I::IntoIter, J::IntoIter, F>
where I: IntoIterator,
J: IntoIterator,
F: FnMut(&I::Item, &J::Item) -> Ordering
{
MergeJoinBy {
left: put_back(left.into_iter().fuse()),
right: put_back(right.into_iter().fuse()),
cmp_fn: cmp_fn
}
}
/// An iterator adaptor that merge-joins items from the two base iterators in ascending order.
///
/// See [`.merge_join_by()`](../trait.Itertools.html#method.merge_join_by) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct MergeJoinBy<I: Iterator, J: Iterator, F> {
left: PutBack<Fuse<I>>,
right: PutBack<Fuse<J>>,
cmp_fn: F
}
impl<I, J, F> Iterator for MergeJoinBy<I, J, F>
where I: Iterator,
J: Iterator,
F: FnMut(&I::Item, &J::Item) -> Ordering
{
type Item = EitherOrBoth<I::Item, J::Item>;
fn next(&mut self) -> Option<Self::Item> {
match (self.left.next(), self.right.next()) {
(None, None) => None,
(Some(left), None) =>
Some(EitherOrBoth::Left(left)),
(None, Some(right)) =>
Some(EitherOrBoth::Right(right)),
(Some(left), Some(right)) => {
match (self.cmp_fn)(&left, &right) {
Ordering::Equal =>
Some(EitherOrBoth::Both(left, right)),
Ordering::Less => {
self.right.put_back(right);
Some(EitherOrBoth::Left(left))
},
Ordering::Greater => {
self.left.put_back(left);
Some(EitherOrBoth::Right(right))
}
}
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_lower, a_upper) = self.left.size_hint();
let (b_lower, b_upper) = self.right.size_hint();
let lower = ::std::cmp::max(a_lower, b_lower);
let upper = match (a_upper, b_upper) {
(Some(x), Some(y)) => Some(x + y),
_ => None,
};
(lower, upper)
}
}

Просмотреть файл

@ -3,6 +3,7 @@
use std::iter::Fuse;
use std::collections::VecDeque;
use size_hint;
use PeekingNext;
/// See [`multipeek()`](../fn.multipeek.html) for more information.
#[derive(Clone, Debug)]
@ -57,6 +58,25 @@ impl<I: Iterator> MultiPeek<I> {
}
}
impl<I> PeekingNext for MultiPeek<I>
where I: Iterator,
{
fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
where F: FnOnce(&Self::Item) -> bool
{
if self.buf.is_empty() {
if let Some(r) = self.peek() {
if !accept(r) { return None }
}
} else {
if let Some(r) = self.buf.get(0) {
if !accept(r) { return None }
}
}
self.next()
}
}
impl<I> Iterator for MultiPeek<I>
where I: Iterator
{

3
third_party/rust/itertools/src/pad_tail.rs поставляемый
Просмотреть файл

@ -8,6 +8,7 @@ use size_hint;
///
/// See [`.pad_using()`](../trait.Itertools.html#method.pad_using) for more information.
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct PadUsing<I, F> {
iter: Fuse<I>,
min: usize,
@ -77,6 +78,6 @@ impl<I, F> DoubleEndedIterator for PadUsing<I, F>
}
impl<I, F> ExactSizeIterator for PadUsing<I, F>
where I: Iterator,
where I: ExactSizeIterator,
F: FnMut(usize) -> I::Item
{}

Просмотреть файл

@ -1,6 +1,7 @@
use std::iter::Peekable;
use PutBack;
#[cfg(feature = "use_std")]
use PutBackN;
/// An iterator that allows peeking at an element before deciding to accept it.
@ -52,6 +53,7 @@ impl<I> PeekingNext for PutBack<I>
}
}
#[cfg(feature = "use_std")]
impl<I> PeekingNext for PutBackN<I>
where I: Iterator,
{
@ -74,6 +76,7 @@ impl<I> PeekingNext for PutBackN<I>
///
/// See [`.peeking_take_while()`](../trait.Itertools.html#method.peeking_take_while)
/// for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct PeekingTakeWhile<'a, I: 'a, F>
where I: Iterator,
{
@ -110,10 +113,7 @@ impl<'a, I, F> Iterator for PeekingTakeWhile<'a, I, F>
// Some iterators are so lightweight we can simply clone them to save their
// state and use that for peeking.
macro_rules! peeking_next_by_clone {
(@as_item $x:item) => ($x);
([$($typarm:tt)*] $type_:ty) => {
// FIXME: Ast coercion is dead as soon as we can dep on Rust 1.12
peeking_next_by_clone! { @as_item
impl<$($typarm)*> PeekingNext for $type_ {
fn peeking_next<F>(&mut self, accept: F) -> Option<Self::Item>
where F: FnOnce(&Self::Item) -> bool
@ -130,7 +130,6 @@ macro_rules! peeking_next_by_clone {
}
}
}
}
}
peeking_next_by_clone! { ['a, T] ::std::slice::Iter<'a, T> }
@ -140,7 +139,9 @@ 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<T> }
#[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> }
// cloning a Rev has no extra overhead; peekable and put backs are never DEI.

80
third_party/rust/itertools/src/process_results_impl.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,80 @@
/// An iterator that produces only the `T` values as long as the
/// inner iterator produces `Ok(T)`.
///
/// Used by [`process_results`](../fn.process_results.html), see its docs
/// for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct ProcessResults<'a, I, E: 'a> {
error: &'a mut Result<(), E>,
iter: I,
}
impl<'a, I, T, E> Iterator for ProcessResults<'a, I, E>
where I: Iterator<Item = Result<T, E>>
{
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
Some(Ok(x)) => Some(x),
Some(Err(e)) => {
*self.error = Err(e);
None
}
None => None,
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, hi) = self.iter.size_hint();
(0, hi)
}
}
/// “Lift” a function of the values of an iterator so that it can process
/// an iterator of `Result` values instead.
///
/// `iterable` is an iterator or iterable with `Result<T, E>` elements, where
/// `T` is the value type and `E` the error type.
///
/// `processor` is a closure that receives an adapted version of the iterable
/// as the only argument — the adapted iterator produces elements of type `T`,
/// as long as the original iterator produces `Ok` values.
///
/// If the original iterable produces an error at any point, the adapted
/// iterator ends and the `process_results` function will return the
/// error iself.
///
/// Otherwise, the return value from the closure is returned wrapped
/// inside `Ok`.
///
/// # Example
///
/// ```
/// use itertools::process_results;
///
/// type R = Result<i32, &'static str>;
///
/// let first_values: Vec<R> = vec![Ok(1), Ok(0), Ok(3)];
/// let second_values: Vec<R> = vec![Ok(2), Ok(1), Err("overflow")];
///
/// // “Lift” the iterator .max() method to work on the values in Results using process_results
///
/// let first_max = process_results(first_values, |iter| iter.max().unwrap_or(0));
/// let second_max = process_results(second_values, |iter| iter.max().unwrap_or(0));
///
/// assert_eq!(first_max, Ok(3));
/// assert!(second_max.is_err());
/// ```
pub fn process_results<I, F, T, E, R>(iterable: I, processor: F) -> Result<R, E>
where I: IntoIterator<Item = Result<T, E>>,
F: FnOnce(ProcessResults<I::IntoIter, E>) -> R
{
let iter = iterable.into_iter();
let mut error = Ok(());
let result = processor(ProcessResults { error: &mut error, iter: iter });
error.map(|_| result)
}

63
third_party/rust/itertools/src/put_back_n_impl.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
use size_hint;
/// An iterator adaptor that allows putting multiple
/// items in front of the iterator.
///
/// Iterator element type is `I::Item`.
#[derive(Debug, Clone)]
pub struct PutBackN<I: Iterator> {
top: Vec<I::Item>,
iter: I,
}
/// Create an iterator where you can put back multiple values to the front
/// of the iteration.
///
/// Iterator element type is `I::Item`.
pub fn put_back_n<I>(iterable: I) -> PutBackN<I::IntoIter>
where I: IntoIterator
{
PutBackN {
top: Vec::new(),
iter: iterable.into_iter(),
}
}
impl<I: Iterator> PutBackN<I> {
/// Puts x in front of the iterator.
/// The values are yielded in order of the most recently put back
/// values first.
///
/// ```rust
/// use itertools::put_back_n;
///
/// let mut it = put_back_n(1..5);
/// it.next();
/// it.put_back(1);
/// it.put_back(0);
///
/// assert!(itertools::equal(it, 0..5));
/// ```
#[inline]
pub fn put_back(&mut self, x: I::Item) {
self.top.push(x);
}
}
impl<I: Iterator> Iterator for PutBackN<I> {
type Item = I::Item;
#[inline]
fn next(&mut self) -> Option<I::Item> {
if self.top.is_empty() {
self.iter.next()
} else {
self.top.pop()
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
size_hint::add_scalar(self.iter.size_hint(), self.top.len())
}
}

24
third_party/rust/itertools/src/rciter_impl.rs поставляемый
Просмотреть файл

@ -15,27 +15,34 @@ pub struct RcIter<I> {
/// same original iterator.
///
/// `RcIter` allows doing interesting things like using `.zip()` on an iterator with
/// itself, at the cost of runtime borrow checking.
/// (If it is not obvious: this has a performance penalty.)
/// itself, at the cost of runtime borrow checking which may have a performance
/// penalty.
///
/// Iterator element type is `Self::Item`.
///
/// ```
/// use itertools::rciter;
/// use itertools::zip;
///
/// // In this example a range iterator is created and we iterate it using
/// // three separate handles (two of them given to zip).
/// // We also use the IntoIterator implementation for `&RcIter`.
///
/// let mut iter = rciter(0..9);
/// let mut z = zip(&iter, &iter);
///
/// let mut rit = rciter(0..9);
/// let mut z = rit.clone().zip(rit.clone());
/// assert_eq!(z.next(), Some((0, 1)));
/// assert_eq!(z.next(), Some((2, 3)));
/// assert_eq!(z.next(), Some((4, 5)));
/// assert_eq!(rit.next(), Some(6));
/// assert_eq!(iter.next(), Some(6));
/// assert_eq!(z.next(), Some((7, 8)));
/// assert_eq!(z.next(), None);
/// ```
///
/// **Panics** in iterator methods if a borrow error is encountered,
/// but it can only happen if the `RcIter` is reentered in for example `.next()`,
/// i.e. if it somehow participates in an “iterator knot” where it is an adaptor of itself.
/// **Panics** in iterator methods if a borrow error is encountered in the
/// iterator methods. It can only happen if the `RcIter` is reentered in
/// `.next()`, i.e. if it somehow participates in an “iterator knot”
/// where it is an adaptor of itself.
pub fn rciter<I>(iterable: I) -> RcIter<I::IntoIter>
where I: IntoIterator
{
@ -76,6 +83,7 @@ impl<I> DoubleEndedIterator for RcIter<I>
self.rciter.borrow_mut().next_back()
}
}
/// Return an iterator from `&RcIter<I>` (by simply cloning it).
impl<'a, I> IntoIterator for &'a RcIter<I>
where I: Iterator

18
third_party/rust/itertools/src/repeatn.rs поставляемый
Просмотреть файл

@ -2,6 +2,7 @@
/// An iterator that produces *n* repetitions of an element.
///
/// See [`repeat_n()`](../fn.repeat_n.html) for more information.
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct RepeatN<A> {
elt: Option<A>,
n: usize,
@ -18,23 +19,6 @@ pub fn repeat_n<A>(element: A, n: usize) -> RepeatN<A>
}
}
impl<A> RepeatN<A> {
#[deprecated(note = "The ::new constructor is deprecated. Use `repeat_n`")]
///
pub fn new(elt: A, n: usize) -> Self {
// The code is duplicated here because the new version uses
// the proper A: Clone bound.
if n == 0 {
RepeatN { elt: None, n: n }
} else {
RepeatN {
elt: Some(elt),
n: n,
}
}
}
}
impl<A> Iterator for RepeatN<A>
where A: Clone
{

9
third_party/rust/itertools/src/size_hint.rs поставляемый
Просмотреть файл

@ -65,6 +65,15 @@ pub fn mul(a: SizeHint, b: SizeHint) -> SizeHint {
(low, hi)
}
/// Multiply **x** correctly with a **SizeHint**.
#[inline]
pub fn mul_scalar(sh: SizeHint, x: usize) -> SizeHint {
let (mut low, mut hi) = sh;
low = low.saturating_mul(x);
hi = hi.and_then(|elt| elt.checked_mul(x));
(low, hi)
}
/// Return the maximum
#[inline]
pub fn max(a: SizeHint, b: SizeHint) -> SizeHint {

21
third_party/rust/itertools/src/sources.rs поставляемый
Просмотреть файл

@ -36,7 +36,9 @@ impl<F> fmt::Debug for RepeatCall<F>
/// vec![1, 1, 1, 1, 1]
/// );
/// ```
pub fn repeat_call<F>(function: F) -> RepeatCall<F> {
pub fn repeat_call<F, A>(function: F) -> RepeatCall<F>
where F: FnMut() -> A
{
RepeatCall { f: function }
}
@ -70,19 +72,18 @@ impl<A, F> Iterator for RepeatCall<F>
///
/// use itertools::unfold;
///
/// let mut fibonacci = unfold((1_u32, 1_u32), |state| {
/// let (ref mut x1, ref mut x2) = *state;
///
/// let (mut x1, mut x2) = (1u32, 1u32);
/// let mut fibonacci = unfold((), move |_| {
/// // Attempt to get the next Fibonacci number
/// let next = x1.saturating_add(*x2);
/// let next = x1.saturating_add(x2);
///
/// // Shift left: ret <- x1 <- x2 <- next
/// let ret = *x1;
/// *x1 = *x2;
/// *x2 = next;
/// let ret = x1;
/// x1 = x2;
/// x2 = next;
///
/// // If addition has saturated at the maximum, we are finished
/// if ret == *x1 && ret > 1 {
/// if ret == x1 && ret > 1 {
/// return None;
/// }
///
@ -110,6 +111,7 @@ impl<St, F> fmt::Debug for Unfold<St, F>
/// See [`unfold`](../fn.unfold.html) for more information.
#[derive(Clone)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Unfold<St, F> {
f: F,
/// Internal state that will be passed to the closure on the next iteration
@ -139,6 +141,7 @@ impl<A, St, F> Iterator for Unfold<St, F>
///
/// [`iterate()`]: ../fn.iterate.html
#[derive(Clone)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct Iterate<St, F> {
state: St,
f: F,

1
third_party/rust/itertools/src/tee.rs поставляемый
Просмотреть файл

@ -15,6 +15,7 @@ struct TeeBuffer<A, I> {
/// One half of an iterator pair where both return the same elements.
///
/// See [`.tee()`](../trait.Itertools.html#method.tee) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Tee<I>
where I: Iterator
{

Просмотреть файл

@ -60,6 +60,7 @@ impl<T> ExactSizeIterator for TupleBuffer<T>
/// An iterator that groups the items in tuples of a specific size.
///
/// See [`.tuples()`](../trait.Itertools.html#method.tuples) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Tuples<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
@ -114,6 +115,7 @@ impl<I, T> Tuples<I, T>
///
/// See [`.tuple_windows()`](../trait.Itertools.html#method.tuple_windows) for more
/// information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct TupleWindows<I, T>
where I: Iterator<Item = T::Item>,
T: TupleCollect
@ -189,7 +191,7 @@ macro_rules! impl_tuple_collect {
type Item = $A;
type Buffer = [Option<$A>; $N - 1];
#[allow(unused_assignments)]
#[allow(unused_assignments, unused_mut)]
fn collect_from_iter<I>(iter: I, buf: &mut Self::Buffer) -> Option<Self>
where I: IntoIterator<Item = $A>
{

145
third_party/rust/itertools/src/unique_impl.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,145 @@
use std::collections::HashMap;
use std::collections::hash_map::{Entry};
use std::hash::Hash;
use std::fmt;
/// An iterator adapter to filter out duplicate elements.
///
/// See [`.unique_by()`](../trait.Itertools.html#method.unique) for more information.
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct UniqueBy<I: Iterator, V, F> {
iter: I,
// Use a hashmap for the entry API
used: HashMap<V, ()>,
f: F,
}
impl<I, V, F> fmt::Debug for UniqueBy<I, V, F>
where I: Iterator + fmt::Debug,
V: fmt::Debug + Hash + Eq,
{
debug_fmt_fields!(UniqueBy, iter, used);
}
/// Create a new `UniqueBy` iterator.
pub fn unique_by<I, V, F>(iter: I, f: F) -> UniqueBy<I, V, F>
where V: Eq + Hash,
F: FnMut(&I::Item) -> V,
I: Iterator,
{
UniqueBy {
iter: iter,
used: HashMap::new(),
f: f,
}
}
// count the number of new unique keys in iterable (`used` is the set already seen)
fn count_new_keys<I, K>(mut used: HashMap<K, ()>, iterable: I) -> usize
where I: IntoIterator<Item=K>,
K: Hash + Eq,
{
let iter = iterable.into_iter();
let current_used = used.len();
used.extend(iter.map(|key| (key, ())));
used.len() - current_used
}
impl<I, V, F> Iterator for UniqueBy<I, V, F>
where I: Iterator,
V: Eq + Hash,
F: FnMut(&I::Item) -> V
{
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
loop {
match self.iter.next() {
None => return None,
Some(v) => {
let key = (self.f)(&v);
if self.used.insert(key, ()).is_none() {
return Some(v);
}
}
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, hi) = self.iter.size_hint();
((low > 0 && self.used.is_empty()) as usize, hi)
}
fn count(self) -> usize {
let mut key_f = self.f;
count_new_keys(self.used, self.iter.map(move |elt| key_f(&elt)))
}
}
impl<I> Iterator for Unique<I>
where I: Iterator,
I::Item: Eq + Hash + Clone
{
type Item = I::Item;
fn next(&mut self) -> Option<I::Item> {
loop {
match self.iter.iter.next() {
None => return None,
Some(v) => {
match self.iter.used.entry(v) {
Entry::Occupied(_) => { }
Entry::Vacant(entry) => {
let elt = entry.key().clone();
entry.insert(());
return Some(elt);
}
}
}
}
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (low, hi) = self.iter.iter.size_hint();
((low > 0 && self.iter.used.is_empty()) as usize, hi)
}
fn count(self) -> usize {
count_new_keys(self.iter.used, self.iter.iter)
}
}
/// An iterator adapter to filter out duplicate elements.
///
/// See [`.unique()`](../trait.Itertools.html#method.unique) for more information.
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Unique<I: Iterator> {
iter: UniqueBy<I, I::Item, ()>,
}
impl<I> fmt::Debug for Unique<I>
where I: Iterator + fmt::Debug,
I::Item: Hash + Eq + fmt::Debug,
{
debug_fmt_fields!(Unique, iter);
}
pub fn unique<I>(iter: I) -> Unique<I>
where I: Iterator,
I::Item: Eq + Hash,
{
Unique {
iter: UniqueBy {
iter: iter,
used: HashMap::new(),
f: (),
}
}
}

Просмотреть файл

@ -5,6 +5,7 @@ use std::iter::{Fuse,Peekable};
/// Iterator element type is `Position<I::Item>`.
///
/// See [`.with_position()`](../trait.Itertools.html#method.with_position) for more information.
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct WithPosition<I>
where I: Iterator,
{

36
third_party/rust/itertools/src/zip_longest.rs поставляемый
Просмотреть файл

@ -1,7 +1,8 @@
use std::cmp::Ordering::{Equal, Greater, Less};
use super::size_hint;
use std::iter::Fuse;
use self::EitherOrBoth::{Right, Left, Both};
use either_or_both::EitherOrBoth;
// ZipLongest originally written by SimonSapin,
// and dedicated to itertools https://github.com/rust-lang/rust/pull/19283
@ -39,9 +40,9 @@ impl<T, U> Iterator for ZipLongest<T, U>
fn next(&mut self) -> Option<Self::Item> {
match (self.a.next(), self.b.next()) {
(None, None) => None,
(Some(a), None) => Some(Left(a)),
(None, Some(b)) => Some(Right(b)),
(Some(a), Some(b)) => Some(Both(a, b)),
(Some(a), None) => Some(EitherOrBoth::Left(a)),
(None, Some(b)) => Some(EitherOrBoth::Right(b)),
(Some(a), Some(b)) => Some(EitherOrBoth::Both(a, b)),
}
}
@ -60,13 +61,13 @@ impl<T, U> DoubleEndedIterator for ZipLongest<T, U>
match self.a.len().cmp(&self.b.len()) {
Equal => match (self.a.next_back(), self.b.next_back()) {
(None, None) => None,
(Some(a), Some(b)) => Some(Both(a, b)),
(Some(a), Some(b)) => Some(EitherOrBoth::Both(a, b)),
// These can only happen if .len() is inconsistent with .next_back()
(Some(a), None) => Some(Left(a)),
(None, Some(b)) => Some(Right(b)),
(Some(a), None) => Some(EitherOrBoth::Left(a)),
(None, Some(b)) => Some(EitherOrBoth::Right(b)),
},
Greater => self.a.next_back().map(Left),
Less => self.b.next_back().map(Right),
Greater => self.a.next_back().map(EitherOrBoth::Left),
Less => self.b.next_back().map(EitherOrBoth::Right),
}
}
}
@ -75,20 +76,3 @@ impl<T, U> ExactSizeIterator for ZipLongest<T, U>
where T: ExactSizeIterator,
U: ExactSizeIterator
{}
/// A value yielded by `ZipLongest`.
/// Contains one or two values, depending on which of the input iterators are exhausted.
///
/// See [`.zip_longest()`](trait.Itertools.html#method.zip_longest) for more information.
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum EitherOrBoth<A, B> {
/// Neither input iterator is exhausted yet, yielding two values.
Both(A, B),
/// The parameter iterator of `.zip_longest()` is exhausted,
/// only yielding a value from the `self` iterator.
Left(A),
/// The `self` iterator of `.zip_longest()` is exhausted,
/// only yielding a value from the parameter iterator.
Right(B),
}

33
third_party/rust/itertools/src/ziptuple.rs поставляемый
Просмотреть файл

@ -2,21 +2,11 @@ use super::size_hint;
/// See [`multizip`](../fn.multizip.html) for more information.
#[derive(Clone)]
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
pub struct Zip<T> {
t: T,
}
impl<T> Zip<T> {
/// Deprecated: renamed to multizip
#[deprecated(note = "Renamed to multizip")]
pub fn new<U>(t: U) -> Zip<T>
where Zip<T>: From<U>,
Zip<T>: Iterator,
{
multizip(t)
}
}
/// An iterator that generalizes *.zip()* and allows running multiple iterators in lockstep.
///
/// The iterator `Zip<(I, J, ..., M)>` is formed from a tuple of iterators (or values that
@ -26,18 +16,27 @@ impl<T> Zip<T> {
/// The iterator element type is a tuple like like `(A, B, ..., E)` where `A` to `E` are the
/// element types of the subiterator.
///
/// **Note:** The result of this macro is a value of a named type (`Zip<(I, J,
/// ..)>` of each component iterator `I, J, ...`) if each component iterator is
/// nameable.
///
/// Prefer [`izip!()`] over `multizip` for the performance benefits of using the
/// standard library `.zip()`. Prefer `multizip` if a nameable type is needed.
///
/// [`izip!()`]: macro.izip.html
///
/// ```
/// use itertools::multizip;
///
/// // Iterate over three sequences side-by-side
/// let mut xs = [0, 0, 0];
/// let ys = [69, 107, 101];
/// // iterate over three sequences side-by-side
/// let mut results = [0, 0, 0, 0];
/// let inputs = [3, 7, 9, 6];
///
/// for (i, a, b) in multizip((0..100, &mut xs, &ys)) {
/// *a = i ^ *b;
/// for (r, index, input) in multizip((&mut results, 0..10, &inputs)) {
/// *r = index * 10 + input;
/// }
///
/// assert_eq!(xs, [69, 106, 103]);
/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
/// ```
pub fn multizip<T, U>(t: U) -> Zip<T>
where Zip<T>: From<U>,

110
third_party/rust/itertools/tests/merge_join.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,110 @@
extern crate itertools;
use itertools::EitherOrBoth;
use itertools::free::merge_join_by;
#[test]
fn empty() {
let left: Vec<u32> = vec![];
let right: Vec<u32> = vec![];
let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![];
let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
.collect::<Vec<_>>();
assert_eq!(expected_result, actual_result);
}
#[test]
fn left_only() {
let left: Vec<u32> = vec![1,2,3];
let right: Vec<u32> = vec![];
let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
EitherOrBoth::Left(1),
EitherOrBoth::Left(2),
EitherOrBoth::Left(3)
];
let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
.collect::<Vec<_>>();
assert_eq!(expected_result, actual_result);
}
#[test]
fn right_only() {
let left: Vec<u32> = vec![];
let right: Vec<u32> = vec![1,2,3];
let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
EitherOrBoth::Right(1),
EitherOrBoth::Right(2),
EitherOrBoth::Right(3)
];
let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
.collect::<Vec<_>>();
assert_eq!(expected_result, actual_result);
}
#[test]
fn first_left_then_right() {
let left: Vec<u32> = vec![1,2,3];
let right: Vec<u32> = vec![4,5,6];
let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
EitherOrBoth::Left(1),
EitherOrBoth::Left(2),
EitherOrBoth::Left(3),
EitherOrBoth::Right(4),
EitherOrBoth::Right(5),
EitherOrBoth::Right(6)
];
let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
.collect::<Vec<_>>();
assert_eq!(expected_result, actual_result);
}
#[test]
fn first_right_then_left() {
let left: Vec<u32> = vec![4,5,6];
let right: Vec<u32> = vec![1,2,3];
let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
EitherOrBoth::Right(1),
EitherOrBoth::Right(2),
EitherOrBoth::Right(3),
EitherOrBoth::Left(4),
EitherOrBoth::Left(5),
EitherOrBoth::Left(6)
];
let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
.collect::<Vec<_>>();
assert_eq!(expected_result, actual_result);
}
#[test]
fn interspersed_left_and_right() {
let left: Vec<u32> = vec![1,3,5];
let right: Vec<u32> = vec![2,4,6];
let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
EitherOrBoth::Left(1),
EitherOrBoth::Right(2),
EitherOrBoth::Left(3),
EitherOrBoth::Right(4),
EitherOrBoth::Left(5),
EitherOrBoth::Right(6)
];
let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
.collect::<Vec<_>>();
assert_eq!(expected_result, actual_result);
}
#[test]
fn overlapping_left_and_right() {
let left: Vec<u32> = vec![1,3,4,6];
let right: Vec<u32> = vec![2,3,4,5];
let expected_result: Vec<EitherOrBoth<u32, u32>> = vec![
EitherOrBoth::Left(1),
EitherOrBoth::Right(2),
EitherOrBoth::Both(3, 3),
EitherOrBoth::Both(4, 4),
EitherOrBoth::Right(5),
EitherOrBoth::Left(6)
];
let actual_result = merge_join_by(left, right, |l, r| l.cmp(r))
.collect::<Vec<_>>();
assert_eq!(expected_result, actual_result);
}

285
third_party/rust/itertools/tests/quick.rs поставляемый
Просмотреть файл

@ -30,34 +30,115 @@ use itertools::free::{
use quickcheck::TestResult;
/// Trait for size hint modifier types
trait HintKind: Copy + Send + qc::Arbitrary {
fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>);
}
/// Exact size hint variant that leaves hints unchanged
#[derive(Clone, Copy, Debug)]
struct Exact {}
impl HintKind for Exact {
fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
org_hint
}
}
impl qc::Arbitrary for Exact {
fn arbitrary<G: qc::Gen>(_: &mut G) -> Self {
Exact {}
}
}
/// Inexact size hint variant to simulate imprecise (but valid) size hints
///
/// Will always decrease the lower bound and increase the upper bound
/// of the size hint by set amounts.
#[derive(Clone, Copy, Debug)]
struct Inexact {
underestimate: usize,
overestimate: usize,
}
impl HintKind for Inexact {
fn loosen_bounds(&self, org_hint: (usize, Option<usize>)) -> (usize, Option<usize>) {
let (org_lower, org_upper) = org_hint;
(org_lower.saturating_sub(self.underestimate),
org_upper.and_then(move |x| x.checked_add(self.overestimate)))
}
}
impl qc::Arbitrary for Inexact {
fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
let ue_value = usize::arbitrary(g);
let oe_value = usize::arbitrary(g);
// Compensate for quickcheck using extreme values too rarely
let ue_choices = &[0, ue_value, usize::max_value()];
let oe_choices = &[0, oe_value, usize::max_value()];
Inexact {
underestimate: *g.choose(ue_choices).unwrap(),
overestimate: *g.choose(oe_choices).unwrap(),
}
}
fn shrink(&self) -> Box<Iterator<Item=Self>> {
let underestimate_value = self.underestimate;
let overestimate_value = self.overestimate;
Box::new(
underestimate_value.shrink().flat_map(move |ue_value|
overestimate_value.shrink().map(move |oe_value|
Inexact {
underestimate: ue_value,
overestimate: oe_value,
}
)
)
)
}
}
/// Our base iterator that we can impl Arbitrary for
///
/// By default we'll return inexact bounds estimates for size_hint
/// to make tests harder to pass.
///
/// NOTE: Iter is tricky and is not fused, to help catch bugs.
/// At the end it will return None once, then return Some(0),
/// then return None again.
#[derive(Clone, Debug)]
struct Iter<T>(Range<T>, i32); // with fuse/done flag
struct Iter<T, SK: HintKind = Inexact> {
iterator: Range<T>,
// fuse/done flag
fuse_flag: i32,
hint_kind: SK,
}
impl<T> Iter<T>
impl<T, HK> Iter<T, HK> where HK: HintKind
{
fn new(it: Range<T>) -> Self
{
Iter(it, 0)
fn new(it: Range<T>, hint_kind: HK) -> Self {
Iter {
iterator: it,
fuse_flag: 0,
hint_kind: hint_kind
}
}
}
impl<T> Iterator for Iter<T> where Range<T>: Iterator,
impl<T, HK> Iterator for Iter<T, HK>
where Range<T>: Iterator,
<Range<T> as Iterator>::Item: Default,
HK: HintKind,
{
type Item = <Range<T> as Iterator>::Item;
fn next(&mut self) -> Option<Self::Item>
{
let elt = self.0.next();
let elt = self.iterator.next();
if elt.is_none() {
self.1 += 1;
self.fuse_flag += 1;
// check fuse flag
if self.1 == 2 {
if self.fuse_flag == 2 {
return Some(Default::default())
}
}
@ -66,36 +147,101 @@ impl<T> Iterator for Iter<T> where Range<T>: Iterator,
fn size_hint(&self) -> (usize, Option<usize>)
{
self.0.size_hint()
let org_hint = self.iterator.size_hint();
self.hint_kind.loosen_bounds(org_hint)
}
}
impl<T> DoubleEndedIterator for Iter<T> where Range<T>: DoubleEndedIterator,
impl<T, HK> DoubleEndedIterator for Iter<T, HK>
where Range<T>: DoubleEndedIterator,
<Range<T> as Iterator>::Item: Default,
HK: HintKind
{
fn next_back(&mut self) -> Option<Self::Item> { self.0.next_back() }
fn next_back(&mut self) -> Option<Self::Item> { self.iterator.next_back() }
}
impl<T> ExactSizeIterator for Iter<T> where Range<T>: ExactSizeIterator,
impl<T> ExactSizeIterator for Iter<T, Exact> where Range<T>: ExactSizeIterator,
<Range<T> as Iterator>::Item: Default,
{ }
impl<T> qc::Arbitrary for Iter<T> where T: qc::Arbitrary
impl<T, HK> qc::Arbitrary for Iter<T, HK>
where T: qc::Arbitrary,
HK: HintKind,
{
fn arbitrary<G: qc::Gen>(g: &mut G) -> Self
{
Iter::new(T::arbitrary(g)..T::arbitrary(g))
Iter::new(T::arbitrary(g)..T::arbitrary(g), HK::arbitrary(g))
}
fn shrink(&self) -> Box<Iterator<Item=Iter<T>>>
fn shrink(&self) -> Box<Iterator<Item=Iter<T, HK>>>
{
let r = self.0.clone();
let r = self.iterator.clone();
let hint_kind = self.hint_kind;
Box::new(
r.start.shrink().flat_map(move |x| {
r.end.shrink().map(move |y| (x.clone(), y))
})
.map(|(a, b)| Iter::new(a..b))
r.start.shrink().flat_map(move |a|
r.end.shrink().map(move |b|
Iter::new(a.clone()..b, hint_kind)
)
)
)
}
}
/// A meta-iterator which yields `Iter<i32>`s whose start/endpoints are
/// increased or decreased linearly on each iteration.
#[derive(Clone, Debug)]
struct ShiftRange<HK = Inexact> {
range_start: i32,
range_end: i32,
start_step: i32,
end_step: i32,
iter_count: u32,
hint_kind: HK,
}
impl<HK> Iterator for ShiftRange<HK> where HK: HintKind {
type Item = Iter<i32, HK>;
fn next(&mut self) -> Option<Self::Item> {
if self.iter_count == 0 {
return None;
}
let iter = Iter::new(self.range_start..self.range_end, self.hint_kind);
self.range_start += self.start_step;
self.range_end += self.end_step;
self.iter_count -= 1;
Some(iter)
}
}
impl ExactSizeIterator for ShiftRange<Exact> { }
impl<HK> qc::Arbitrary for ShiftRange<HK>
where HK: HintKind
{
fn arbitrary<G: qc::Gen>(g: &mut G) -> Self {
const MAX_STARTING_RANGE_DIFF: i32 = 32;
const MAX_STEP_MODULO: i32 = 8;
const MAX_ITER_COUNT: u32 = 3;
let range_start = qc::Arbitrary::arbitrary(g);
let range_end = range_start + g.gen_range(0, MAX_STARTING_RANGE_DIFF + 1);
let start_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
let end_step = g.gen_range(-MAX_STEP_MODULO, MAX_STEP_MODULO + 1);
let iter_count = g.gen_range(0, MAX_ITER_COUNT + 1);
let hint_kind = qc::Arbitrary::arbitrary(g);
ShiftRange {
range_start: range_start,
range_end: range_end,
start_step: start_step,
end_step: end_step,
iter_count: iter_count,
hint_kind: hint_kind
}
}
}
@ -179,7 +325,6 @@ macro_rules! quickcheck {
// The property functions can use pattern matching and `mut` as usual
// in the function arguments, but the functions can not be generic.
{$($(#$attr:tt)* fn $fn_name:ident($($arg:tt)*) -> $ret:ty { $($code:tt)* })*} => (
quickcheck!{@as_items
$(
#[test]
$(#$attr)*
@ -190,11 +335,10 @@ macro_rules! quickcheck {
::quickcheck::quickcheck(quickcheck!(@fn prop [] $($arg)*));
}
)*
}
);
// parse argument list (with patterns allowed) into prop as fn(_, _) -> _
(@fn $f:ident [$($t:tt)*]) => {
quickcheck!(@as_expr $f as fn($($t),*) -> _)
$f as fn($($t),*) -> _
};
(@fn $f:ident [$($p:tt)*] : $($tail:tt)*) => {
quickcheck!(@fn $f [$($p)* _] $($tail)*)
@ -202,8 +346,6 @@ macro_rules! quickcheck {
(@fn $f:ident [$($p:tt)*] $t:tt $($tail:tt)*) => {
quickcheck!(@fn $f [$($p)*] $($tail)*)
};
(@as_items $($i:item)*) => ($($i)*);
(@as_expr $i:expr) => ($i);
}
quickcheck! {
@ -215,7 +357,52 @@ quickcheck! {
correct_size_hint(iproduct!(a, b, c))
}
fn size_step(a: Iter<i16>, s: usize) -> bool {
fn correct_cartesian_product3(a: Iter<u16>, b: Iter<u16>, c: Iter<u16>,
take_manual: usize) -> ()
{
// test correctness of iproduct through regular iteration (take)
// and through fold.
let ac = a.clone();
let br = &b.clone();
let cr = &c.clone();
let answer: Vec<_> = ac.flat_map(move |ea| br.clone().flat_map(move |eb| cr.clone().map(move |ec| (ea, eb, ec)))).collect();
let mut product_iter = iproduct!(a, b, c);
let mut actual = Vec::new();
actual.extend((&mut product_iter).take(take_manual));
if actual.len() == take_manual {
product_iter.fold((), |(), elt| actual.push(elt));
}
assert_eq!(answer, actual);
}
fn size_multi_product(a: ShiftRange) -> bool {
correct_size_hint(a.multi_cartesian_product())
}
fn correct_multi_product3(a: ShiftRange, take_manual: usize) -> () {
// Fix no. of iterators at 3
let a = ShiftRange { iter_count: 3, ..a };
// test correctness of MultiProduct through regular iteration (take)
// and through fold.
let mut iters = a.clone();
let i0 = iters.next().unwrap();
let i1r = &iters.next().unwrap();
let i2r = &iters.next().unwrap();
let answer: Vec<_> = i0.flat_map(move |ei0| i1r.clone().flat_map(move |ei1| i2r.clone().map(move |ei2| vec![ei0, ei1, ei2]))).collect();
let mut multi_product = a.clone().multi_cartesian_product();
let mut actual = Vec::new();
actual.extend((&mut multi_product).take(take_manual));
if actual.len() == take_manual {
multi_product.fold((), |(), elt| actual.push(elt));
}
assert_eq!(answer, actual);
assert_eq!(answer.into_iter().last(), a.clone().multi_cartesian_product().last());
}
fn size_step(a: Iter<i16, Exact>, s: usize) -> bool {
let mut s = s;
if s == 0 {
s += 1; // never zero
@ -249,7 +436,7 @@ quickcheck! {
}))
}
fn size_multipeek(a: Iter<u16>, s: u8) -> bool {
fn size_multipeek(a: Iter<u16, Exact>, s: u8) -> bool {
let mut it = multipeek(a);
// peek a few times
for _ in 0..s {
@ -271,7 +458,7 @@ quickcheck! {
fn size_merge(a: Iter<u16>, b: Iter<u16>) -> bool {
correct_size_hint(a.merge(b))
}
fn size_zip(a: Iter<i16>, b: Iter<i16>, c: Iter<i16>) -> bool {
fn size_zip(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
let filt = a.clone().dedup();
correct_size_hint(multizip((filt, b.clone(), c.clone()))) &&
exact_size(multizip((a, b, c)))
@ -281,6 +468,11 @@ quickcheck! {
correct_size_hint(multizip((&rc, &rc, b)))
}
fn size_zip_macro(a: Iter<i16, Exact>, b: Iter<i16, Exact>, c: Iter<i16, Exact>) -> bool {
let filt = a.clone().dedup();
correct_size_hint(izip!(filt, b.clone(), c.clone())) &&
exact_size(izip!(a, b, c))
}
fn equal_kmerge(a: Vec<i16>, b: Vec<i16>, c: Vec<i16>) -> bool {
use itertools::free::kmerge;
let mut sa = a.clone();
@ -355,7 +547,7 @@ quickcheck! {
let b = &b[..len];
itertools::equal(zip_eq(a, b), zip(a, b))
}
fn size_zip_longest(a: Iter<i16>, b: Iter<i16>) -> bool {
fn size_zip_longest(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
let filt = a.clone().dedup();
let filt2 = b.clone().dedup();
correct_size_hint(filt.zip_longest(b.clone())) &&
@ -384,7 +576,7 @@ quickcheck! {
fn size_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
correct_size_hint(a.interleave(b))
}
fn exact_interleave(a: Iter<i16>, b: Iter<i16>) -> bool {
fn exact_interleave(a: Iter<i16, Exact>, b: Iter<i16, Exact>) -> bool {
exact_size_for_this(a.interleave(b))
}
fn size_interleave_shortest(a: Iter<i16>, b: Iter<i16>) -> bool {
@ -420,19 +612,20 @@ quickcheck! {
itertools::equal(a.iter().flatten(),
a.iter().flat_map(|x| x))
}
fn equal_flatten_vec_rev(a: Vec<Vec<u8>>) -> bool {
itertools::equal(a.iter().flatten().rev(),
a.iter().flat_map(|x| x).rev())
}
fn equal_combinations_2(a: Vec<u8>) -> bool {
let mut v = Vec::new();
for (i, &x) in enumerate(&a) {
for &y in &a[i + 1..] {
for (i, x) in enumerate(&a) {
for y in &a[i + 1..] {
v.push((x, y));
}
}
itertools::equal(cloned(&a).tuple_combinations::<(_, _)>(), cloned(&v))
itertools::equal(a.iter().tuple_combinations::<(_, _)>(), v)
}
fn collect_tuple_matches_size(a: Iter<i16>) -> bool {
let size = a.clone().count();
a.collect_tuple::<(_, _, _)>().is_some() == (size == 3)
}
}
@ -548,7 +741,7 @@ quickcheck! {
}
quickcheck! {
fn size_pad_tail2(it: Iter<i8>, pad: u8) -> bool {
fn size_pad_tail2(it: Iter<i8, Exact>, pad: u8) -> bool {
exact_size(it.pad_using(pad as usize, |_| 0))
}
}
@ -557,6 +750,18 @@ quickcheck! {
fn size_unique(it: Iter<i8>) -> bool {
correct_size_hint(it.unique())
}
fn count_unique(it: Vec<i8>, take_first: u8) -> () {
let answer = {
let mut v = it.clone();
v.sort(); v.dedup();
v.len()
};
let mut iter = cloned(&it).unique();
let first_count = (&mut iter).take(take_first as usize).count();
let rest_count = iter.count();
assert_eq!(answer, first_count + rest_count);
}
}
quickcheck! {
@ -698,7 +903,7 @@ quickcheck! {
fn with_position_exact_size_1(a: Vec<u8>) -> bool {
exact_size_for_this(a.iter().with_position())
}
fn with_position_exact_size_2(a: Iter<u8>) -> bool {
fn with_position_exact_size_2(a: Iter<u8, Exact>) -> bool {
exact_size_for_this(a.with_position())
}
}

234
third_party/rust/itertools/tests/test_core.rs поставляемый Normal file
Просмотреть файл

@ -0,0 +1,234 @@
//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.
#![no_std]
#[macro_use] extern crate itertools as it;
use it::Itertools;
use it::interleave;
use it::multizip;
use it::free::put_back;
#[test]
fn product2() {
let s = "αβ";
let mut prod = iproduct!(s.chars(), 0..2);
assert!(prod.next() == Some(('α', 0)));
assert!(prod.next() == Some(('α', 1)));
assert!(prod.next() == Some(('β', 0)));
assert!(prod.next() == Some(('β', 1)));
assert!(prod.next() == None);
}
#[test]
fn product_temporary() {
for (_x, _y, _z) in iproduct!(
[0, 1, 2].iter().cloned(),
[0, 1, 2].iter().cloned(),
[0, 1, 2].iter().cloned())
{
// ok
}
}
#[test]
fn izip_macro() {
let mut zip = izip!(2..3);
assert!(zip.next() == Some(2));
assert!(zip.next().is_none());
let mut zip = izip!(0..3, 0..2, 0..2i8);
for i in 0..2 {
assert!((i as usize, i, i as i8) == zip.next().unwrap());
}
assert!(zip.next().is_none());
let xs: [isize; 0] = [];
let mut zip = izip!(0..3, 0..2, 0..2i8, &xs);
assert!(zip.next().is_none());
}
#[test]
fn izip3() {
let mut zip = multizip((0..3, 0..2, 0..2i8));
for i in 0..2 {
assert!((i as usize, i, i as i8) == zip.next().unwrap());
}
assert!(zip.next().is_none());
let xs: [isize; 0] = [];
let mut zip = multizip((0..3, 0..2, 0..2i8, xs.iter()));
assert!(zip.next().is_none());
for (_, _, _, _, _) in multizip((0..3, 0..2, xs.iter(), &xs, xs.to_vec())) {
/* test compiles */
}
}
#[test]
fn write_to() {
let xs = [7, 9, 8];
let mut ys = [0; 5];
let cnt = ys.iter_mut().set_from(xs.iter().map(|x| *x));
assert!(cnt == xs.len());
assert!(ys == [7, 9, 8, 0, 0]);
let cnt = ys.iter_mut().set_from(0..10);
assert!(cnt == ys.len());
assert!(ys == [0, 1, 2, 3, 4]);
}
#[test]
fn test_interleave() {
let xs: [u8; 0] = [];
let ys = [7u8, 9, 8, 10];
let zs = [2u8, 77];
let it = interleave(xs.iter(), ys.iter());
it::assert_equal(it, ys.iter());
let rs = [7u8, 2, 9, 77, 8, 10];
let it = interleave(ys.iter(), zs.iter());
it::assert_equal(it, rs.iter());
}
#[test]
fn foreach() {
let xs = [1i32, 2, 3];
let mut sum = 0;
xs.iter().foreach(|elt| sum += *elt);
assert!(sum == 6);
}
#[test]
fn dropping() {
let xs = [1, 2, 3];
let mut it = xs.iter().dropping(2);
assert_eq!(it.next(), Some(&3));
assert!(it.next().is_none());
let mut it = xs.iter().dropping(5);
assert!(it.next().is_none());
}
#[test]
fn batching() {
let xs = [0, 1, 2, 1, 3];
let ys = [(0, 1), (2, 1)];
// An iterator that gathers elements up in pairs
let pit = xs.iter().cloned().batching(|it| {
match it.next() {
None => None,
Some(x) => match it.next() {
None => None,
Some(y) => Some((x, y)),
}
}
});
it::assert_equal(pit, ys.iter().cloned());
}
#[test]
fn test_put_back() {
let xs = [0, 1, 1, 1, 2, 1, 3, 3];
let mut pb = put_back(xs.iter().cloned());
pb.next();
pb.put_back(1);
pb.put_back(0);
it::assert_equal(pb, xs.iter().cloned());
}
#[test]
fn step() {
it::assert_equal((0..10).step(1), (0..10));
it::assert_equal((0..10).step(2), (0..10).filter(|x: &i32| *x % 2 == 0));
it::assert_equal((0..10).step(10), 0..1);
}
#[test]
fn merge() {
it::assert_equal((0..10).step(2).merge((1..10).step(2)), (0..10));
}
#[test]
fn repeatn() {
let s = "α";
let mut it = it::repeat_n(s, 3);
assert_eq!(it.len(), 3);
assert_eq!(it.next(), Some(s));
assert_eq!(it.next(), Some(s));
assert_eq!(it.next(), Some(s));
assert_eq!(it.next(), None);
assert_eq!(it.next(), None);
}
#[test]
fn count_clones() {
// Check that RepeatN only clones N - 1 times.
use core::cell::Cell;
#[derive(PartialEq, Debug)]
struct Foo {
n: Cell<usize>
}
impl Clone for Foo
{
fn clone(&self) -> Self
{
let n = self.n.get();
self.n.set(n + 1);
Foo { n: Cell::new(n + 1) }
}
}
for n in 0..10 {
let f = Foo{n: Cell::new(0)};
let it = it::repeat_n(f, n);
// drain it
let last = it.last();
if n == 0 {
assert_eq!(last, None);
} else {
assert_eq!(last, Some(Foo{n: Cell::new(n - 1)}));
}
}
}
#[test]
fn part() {
let mut data = [7, 1, 1, 9, 1, 1, 3];
let i = it::partition(&mut data, |elt| *elt >= 3);
assert_eq!(i, 3);
assert_eq!(data, [7, 3, 9, 1, 1, 1, 1]);
let i = it::partition(&mut data, |elt| *elt == 1);
assert_eq!(i, 4);
assert_eq!(data, [1, 1, 1, 1, 9, 3, 7]);
let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let i = it::partition(&mut data, |elt| *elt % 3 == 0);
assert_eq!(i, 3);
assert_eq!(data, [9, 6, 3, 4, 5, 2, 7, 8, 1]);
}
#[test]
fn flatten_clone() {
let data = &[
&[1,2,3],
&[4,5,6]
];
let flattened1 = data.into_iter().cloned().flatten();
let flattened2 = flattened1.clone();
it::assert_equal(flattened1, &[1,2,3,4,5,6]);
it::assert_equal(flattened2, &[1,2,3,4,5,6]);
}

Просмотреть файл

@ -1,34 +1,15 @@
//! Licensed under the Apache License, Version 2.0
//! http://www.apache.org/licenses/LICENSE-2.0 or the MIT license
//! http://opensource.org/licenses/MIT, at your
//! option. This file may not be copied, modified, or distributed
//! except according to those terms.
#[macro_use] extern crate itertools as it;
extern crate permutohedron;
use it::Itertools;
use it::interleave;
use it::multizip;
use it::multipeek;
use it::FoldWhile;
use it::free::rciter;
use it::free::put_back;
use it::free::put_back_n;
use it::FoldWhile;
use it::cloned;
#[test]
fn product2() {
let s = "αβ";
let mut prod = iproduct!(s.chars(), 0..2);
assert!(prod.next() == Some(('α', 0)));
assert!(prod.next() == Some(('α', 1)));
assert!(prod.next() == Some(('β', 0)));
assert!(prod.next() == Some(('β', 1)));
assert!(prod.next() == None);
}
#[test]
fn product3() {
let prod = iproduct!(0..3, 0..2, 0..2);
@ -46,74 +27,6 @@ fn product3() {
}
}
#[test]
fn product_temporary() {
for (_x, _y, _z) in iproduct!(
[0, 1, 2].iter().cloned(),
[0, 1, 2].iter().cloned(),
[0, 1, 2].iter().cloned())
{
// ok
}
}
#[test]
fn izip_macro() {
let mut zip = izip!(0..3, 0..2, 0..2i8);
for i in 0..2 {
assert!((i as usize, i, i as i8) == zip.next().unwrap());
}
assert!(zip.next().is_none());
let xs: [isize; 0] = [];
let mut zip = izip!(0..3, 0..2, 0..2i8, &xs);
assert!(zip.next().is_none());
}
#[test]
fn izip3() {
let mut zip = multizip((0..3, 0..2, 0..2i8));
for i in 0..2 {
assert!((i as usize, i, i as i8) == zip.next().unwrap());
}
assert!(zip.next().is_none());
let xs: [isize; 0] = [];
let mut zip = multizip((0..3, 0..2, 0..2i8, xs.iter()));
assert!(zip.next().is_none());
for (_, _, _, _, _) in multizip((0..3, 0..2, xs.iter(), &xs, xs.to_vec())) {
/* test compiles */
}
}
#[test]
fn write_to() {
let xs = [7, 9, 8];
let mut ys = [0; 5];
let cnt = ys.iter_mut().set_from(xs.iter().map(|x| *x));
assert!(cnt == xs.len());
assert!(ys == [7, 9, 8, 0, 0]);
let cnt = ys.iter_mut().set_from(0..10);
assert!(cnt == ys.len());
assert!(ys == [0, 1, 2, 3, 4]);
}
#[test]
fn test_interleave() {
let xs: [u8; 0] = [];
let ys = [7u8, 9, 8, 10];
let zs = [2u8, 77];
let it = interleave(xs.iter(), ys.iter());
it::assert_equal(it, ys.iter());
let rs = [7u8, 2, 9, 77, 8, 10];
let it = interleave(ys.iter(), zs.iter());
it::assert_equal(it, rs.iter());
}
#[test]
fn interleave_shortest() {
let v0: Vec<i32> = vec![0, 2, 4];
@ -139,22 +52,22 @@ fn interleave_shortest() {
assert_eq!(it.size_hint(), (6, Some(6)));
}
#[test]
fn foreach() {
let xs = [1i32, 2, 3];
let mut sum = 0;
xs.iter().foreach(|elt| sum += *elt);
assert!(sum == 6);
fn unique_by() {
let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
let ys = ["aaa", "bbbbb", "ccc"];
it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string()));
}
#[test]
fn dropping() {
let xs = [1, 2, 3];
let mut it = xs.iter().dropping(2);
assert_eq!(it.next(), Some(&3));
assert!(it.next().is_none());
let mut it = xs.iter().dropping(5);
assert!(it.next().is_none());
fn unique() {
let xs = [0, 1, 2, 3, 2, 1, 3];
let ys = [0, 1, 2, 3];
it::assert_equal(ys.iter(), xs.iter().unique());
let xs = [0, 1];
let ys = [0, 1];
it::assert_equal(ys.iter(), xs.iter().unique());
}
#[test]
@ -186,48 +99,12 @@ fn dedup() {
}
#[test]
fn unique_by() {
let xs = ["aaa", "bbbbb", "aa", "ccc", "bbbb", "aaaaa", "cccc"];
let ys = ["aaa", "bbbbb", "ccc"];
it::assert_equal(ys.iter(), xs.iter().unique_by(|x| x[..2].to_string()));
}
#[test]
fn unique() {
let xs = [0, 1, 2, 3, 2, 1, 3];
let ys = [0, 1, 2, 3];
it::assert_equal(ys.iter(), xs.iter().unique());
let xs = [0, 1];
let ys = [0, 1];
it::assert_equal(ys.iter(), xs.iter().unique());
}
#[test]
fn batching() {
let xs = [0, 1, 2, 1, 3];
let ys = [(0, 1), (2, 1)];
// An iterator that gathers elements up in pairs
let pit = xs.iter().cloned().batching(|mut it| {
match it.next() {
None => None,
Some(x) => match it.next() {
None => None,
Some(y) => Some((x, y)),
fn all_equal() {
assert!(!"AABBCCC".chars().all_equal());
assert!("AAAAAAA".chars().all_equal());
for (_key, mut sub) in &"AABBCCC".chars().group_by(|&x| x) {
assert!(sub.all_equal());
}
}
});
it::assert_equal(pit, ys.iter().cloned());
}
#[test]
fn test_put_back() {
let xs = [0, 1, 1, 1, 2, 1, 3, 3];
let mut pb = put_back(xs.iter().cloned());
pb.next();
pb.put_back(1);
pb.put_back(0);
it::assert_equal(pb, xs.iter().cloned());
}
#[test]
@ -288,13 +165,6 @@ fn test_rciter() {
assert_eq!(z.next(), Some((0, 1)));
}
#[test]
fn step() {
it::assert_equal((0..10).step(1), (0..10));
it::assert_equal((0..10).step(2), (0..10).filter(|x: &i32| *x % 2 == 0));
it::assert_equal((0..10).step(10), 0..1);
}
#[test]
fn trait_pointers() {
struct ByRef<'r, I: ?Sized>(&'r mut I) where I: 'r;
@ -314,7 +184,7 @@ fn trait_pointers() {
{
/* make sure foreach works on non-Sized */
let mut jt: &mut Iterator<Item=i32> = &mut *it;
let jt: &mut Iterator<Item = i32> = &mut *it;
assert_eq!(jt.next(), Some(1));
{
@ -327,11 +197,6 @@ fn trait_pointers() {
}
}
#[test]
fn merge() {
it::assert_equal((0..10).step(2).merge((1..10).step(2)), (0..10));
}
#[test]
fn merge_by() {
let odd : Vec<(u32, &str)> = vec![(1, "hello"), (3, "world"), (5, "!")];
@ -409,6 +274,15 @@ fn sorted_by() {
assert_eq!(v, vec![4, 3, 2, 1, 0]);
}
#[test]
fn sorted_by_key() {
let sc = [3, 4, 1, 2].iter().cloned().sorted_by_key(|&x| x);
assert_eq!(sc, vec![1, 2, 3, 4]);
let v = (0..5).sorted_by_key(|&x| -x);
assert_eq!(v, vec![4, 3, 2, 1, 0]);
}
#[test]
fn test_multipeek() {
let nums = vec![1u8,2,3,4,5];
@ -428,6 +302,8 @@ fn test_multipeek() {
assert_eq!(mp.peek(), None);
assert_eq!(mp.next(), Some(3));
assert_eq!(mp.next(), Some(4));
assert_eq!(mp.peek(), Some(&5));
assert_eq!(mp.peek(), None);
assert_eq!(mp.next(), Some(5));
assert_eq!(mp.next(), None);
assert_eq!(mp.peek(), None);
@ -449,66 +325,29 @@ fn test_multipeek_reset() {
}
#[test]
fn repeatn() {
let s = "α";
let mut it = it::repeat_n(s, 3);
assert_eq!(it.len(), 3);
assert_eq!(it.next(), Some(s));
assert_eq!(it.next(), Some(s));
assert_eq!(it.next(), Some(s));
assert_eq!(it.next(), None);
assert_eq!(it.next(), None);
}
fn test_multipeek_peeking_next() {
use it::PeekingNext;
let nums = vec![1u8,2,3,4,5,6,7];
#[test]
fn count_clones() {
// Check that RepeatN only clones N - 1 times.
use std::cell::Cell;
#[derive(PartialEq, Debug)]
struct Foo {
n: Cell<usize>
}
impl Clone for Foo
{
fn clone(&self) -> Self
{
let n = self.n.get();
self.n.set(n + 1);
Foo { n: Cell::new(n + 1) }
}
}
for n in 0..10 {
let f = Foo{n: Cell::new(0)};
let it = it::repeat_n(f, n);
// drain it
let last = it.last();
if n == 0 {
assert_eq!(last, None);
} else {
assert_eq!(last, Some(Foo{n: Cell::new(n - 1)}));
}
}
}
#[test]
fn part() {
let mut data = [7, 1, 1, 9, 1, 1, 3];
let i = it::partition(&mut data, |elt| *elt >= 3);
assert_eq!(i, 3);
assert_eq!(data, [7, 3, 9, 1, 1, 1, 1]);
let i = it::partition(&mut data, |elt| *elt == 1);
assert_eq!(i, 4);
assert_eq!(data, [1, 1, 1, 1, 9, 3, 7]);
let mut data = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let i = it::partition(&mut data, |elt| *elt % 3 == 0);
assert_eq!(i, 3);
assert_eq!(data, [9, 6, 3, 4, 5, 2, 7, 8, 1]);
let mut mp = multipeek(nums.iter().map(|&x| x));
assert_eq!(mp.peeking_next(|&x| x != 0), Some(1));
assert_eq!(mp.next(), Some(2));
assert_eq!(mp.peek(), Some(&3));
assert_eq!(mp.peek(), Some(&4));
assert_eq!(mp.peeking_next(|&x| x == 3), Some(3));
assert_eq!(mp.peek(), Some(&4));
assert_eq!(mp.peeking_next(|&x| x != 4), None);
assert_eq!(mp.peeking_next(|&x| x == 4), Some(4));
assert_eq!(mp.peek(), Some(&5));
assert_eq!(mp.peek(), Some(&6));
assert_eq!(mp.peeking_next(|&x| x != 5), None);
assert_eq!(mp.peek(), Some(&7));
assert_eq!(mp.peeking_next(|&x| x == 5), Some(5));
assert_eq!(mp.peeking_next(|&x| x == 6), Some(6));
assert_eq!(mp.peek(), Some(&7));
assert_eq!(mp.peek(), None);
assert_eq!(mp.next(), Some(7));
assert_eq!(mp.peek(), None);
}
#[test]
@ -524,13 +363,6 @@ fn pad_using() {
it::assert_equal(r, vec![0, 1, 2]);
}
#[test]
fn while_some() {
let ns = (1..10).map(|x| if x % 5 != 0 { Some(x) } else { None })
.while_some();
it::assert_equal(ns, vec![1, 2, 3, 4]);
}
#[test]
fn group_by() {
for (ch1, sub) in &"AABBCCC".chars().group_by(|&x| x) {
@ -693,6 +525,18 @@ fn chunks() {
}
}
#[test]
fn concat_empty() {
let data: Vec<Vec<()>> = Vec::new();
assert_eq!(data.into_iter().concat(), Vec::new())
}
#[test]
fn concat_non_empty() {
let data = vec![vec![1,2,3], vec![4,5,6], vec![7,8,9]];
assert_eq!(data.into_iter().concat(), vec![1,2,3,4,5,6,7,8,9])
}
#[test]
fn flatten_iter() {
let data = vec![vec![1,2,3], vec![4,5,6]];
@ -701,26 +545,6 @@ fn flatten_iter() {
it::assert_equal(flattened, vec![1,2,3,4,5,6]);
}
#[test]
fn flatten_rev() {
let data = vec![vec![1,2,3].into_iter(), vec![4,5,6].into_iter()];
let flattened = data.into_iter().flatten().rev();
it::assert_equal(flattened, vec![6,5,4,3,2,1]);
}
#[test]
fn flatten_clone() {
let data = &[
&[1,2,3],
&[4,5,6]
];
let flattened1 = data.into_iter().cloned().flatten();
let flattened2 = flattened1.clone();
it::assert_equal(flattened1, &[1,2,3,4,5,6]);
it::assert_equal(flattened2, &[1,2,3,4,5,6]);
}
#[test]
fn flatten_fold() {
let xs = [0, 1, 1, 1, 2, 1, 3, 3];
@ -770,10 +594,9 @@ fn combinations_of_too_short() {
}
#[should_panic]
#[test]
fn combinations_zero() {
(1..3).combinations(0);
it::assert_equal((1..3).combinations(0), vec![vec![]]);
}
#[test]
@ -817,23 +640,6 @@ fn diff_shorter() {
});
}
#[test]
fn fold_while() {
let mut iterations = 0;
let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = vec.into_iter().fold_while(0, |acc, item| {
iterations += 1;
let new_sum = acc.clone() + item;
if new_sum <= 20 {
FoldWhile::Continue(new_sum)
} else {
FoldWhile::Done(acc)
}
});
assert_eq!(iterations, 6);
assert_eq!(sum, 15);
}
#[test]
fn minmax() {
use std::cmp::Ordering;
@ -889,3 +695,28 @@ fn format() {
let t3 = format!("{:.2e}", dataf.iter().format(", "));
assert_eq!(t3, "1.10e0, 2.72e0, -2.20e1");
}
#[test]
fn while_some() {
let ns = (1..10).map(|x| if x % 5 != 0 { Some(x) } else { None })
.while_some();
it::assert_equal(ns, vec![1, 2, 3, 4]);
}
#[test]
fn fold_while() {
let mut iterations = 0;
let vec = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let sum = vec.into_iter().fold_while(0, |acc, item| {
iterations += 1;
let new_sum = acc.clone() + item;
if new_sum <= 20 {
FoldWhile::Continue(new_sum)
} else {
FoldWhile::Done(acc)
}
}).into_inner();
assert_eq!(iterations, 6);
assert_eq!(sum, 15);
}

15
third_party/rust/itertools/tests/tuples.rs поставляемый
Просмотреть файл

@ -71,3 +71,18 @@ fn next_tuple() {
assert_eq!(iter.next_tuple().map(|(&x, &y)| (x, y)), Some((3, 4)));
assert_eq!(iter.next_tuple::<(_, _)>(), None);
}
#[test]
fn collect_tuple() {
let v = [1, 2];
let iter = v.iter().cloned();
assert_eq!(iter.collect_tuple(), Some((1, 2)));
let v = [1];
let iter = v.iter().cloned();
assert_eq!(iter.collect_tuple::<(_, _)>(), None);
let v = [1, 2, 3];
let iter = v.iter().cloned();
assert_eq!(iter.collect_tuple::<(_, _)>(), None);
}

5
third_party/rust/itertools/tests/zip.rs поставляемый
Просмотреть файл

@ -5,12 +5,11 @@ use itertools::EitherOrBoth::{Both, Left, Right};
use itertools::free::zip_eq;
#[test]
fn zip_longest_fused()
{
fn zip_longest_fused() {
let a = [Some(1), None, Some(3), Some(4)];
let b = [1, 2, 3];
let unfused = a.iter().batching(|mut it| *it.next().unwrap())
let unfused = a.iter().batching(|it| *it.next().unwrap())
.zip_longest(b.iter().cloned());
itertools::assert_equal(unfused,
vec![Both(1, 1), Right(2), Right(3)]);

6
toolkit/library/gtest/rust/Cargo.lock сгенерированный
Просмотреть файл

@ -733,7 +733,7 @@ dependencies = [
[[package]]
name = "itertools"
version = "0.5.10"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1378,7 +1378,7 @@ dependencies = [
"fallible 0.0.1",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hashglobe 0.1.0",
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1860,7 +1860,7 @@ dependencies = [
"checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
"checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum khronos_api 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867c645cfeb8a7fec503731679eac03ac11b7105aa5a71cb8f8ee5271636add"

6
toolkit/library/rust/Cargo.lock сгенерированный
Просмотреть файл

@ -731,7 +731,7 @@ dependencies = [
[[package]]
name = "itertools"
version = "0.5.10"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1369,7 +1369,7 @@ dependencies = [
"fallible 0.0.1",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"hashglobe 0.1.0",
"itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1863,7 +1863,7 @@ dependencies = [
"checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
"checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394"
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum khronos_api 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867c645cfeb8a7fec503731679eac03ac11b7105aa5a71cb8f8ee5271636add"