Skip to content

Commit ec2fb66

Browse files
committed
FIX: Remove itertools as a dependency
We use `izip!()` as the only major feature from itertools, and can remove it to save build time and two small crates as deps. `izip!()` is license compatible and originally written by @krdln (Michał Krasnoborski) and @bluss in itertools, so we copy it into the crate. The free functions zip(i, j) and enumerate(i) are just style preferences, written by me, and simple to copy. Itertools is still used as a dev-dependency.
1 parent 14ca050 commit ec2fb66

File tree

10 files changed

+145
-23
lines changed

10 files changed

+145
-23
lines changed

Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ test = true
3131
num-integer = "0.1.39"
3232
num-traits = "0.2"
3333
num-complex = "0.2"
34-
itertools = { version = "0.8.0", default-features = false }
3534

3635
rayon = { version = "1.0.3", optional = true }
3736

src/dimension/dim.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use itertools::zip;
109
use std::fmt;
1110

1211
use super::Dimension;
1312
use super::IntoDimension;
13+
use crate::itertools::zip;
1414
use crate::Ix;
1515

1616
/// Dimension description.

src/dimension/dimension_trait.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ use std::fmt::Debug;
1010
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
1111
use std::ops::{Index, IndexMut};
1212

13-
use itertools::{enumerate, izip, zip};
14-
1513
use super::axes_of;
1614
use super::conversion::Convert;
1715
use super::{stride_offset, stride_offset_checked};
16+
use crate::itertools::{enumerate, zip};
1817
use crate::Axis;
1918
use crate::IntoDimension;
2019
use crate::RemoveAxis;

src/dimension/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
use crate::error::{from_kind, ErrorKind, ShapeError};
1010
use crate::{Ix, Ixs, Slice, SliceOrIndex};
11-
use itertools::izip;
1211
use num_integer::div_floor;
1312

1413
pub use self::axes::{axes_of, Axes, AxisDescription};

src/dimension/ndindex.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use std::fmt::Debug;
22

3-
use itertools::zip;
4-
53
use super::{stride_offset, stride_offset_checked};
4+
use crate::itertools::zip;
65
use crate::{
76
Dim, Dimension, IntoDimension, Ix, Ix0, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn, IxDynImpl,
87
};

src/impl_methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use std::cmp;
1010
use std::ptr as std_ptr;
1111
use std::slice;
1212

13-
use itertools::{izip, zip};
1413
use rawpointer::PointerExt;
1514

1615
use crate::imp_prelude::*;
@@ -22,6 +21,7 @@ use crate::dimension::{
2221
abs_index, axes_of, do_slice, merge_axes, size_of_shape_checked, stride_offset, Axes,
2322
};
2423
use crate::error::{self, ErrorKind, ShapeError};
24+
use crate::itertools::zip;
2525
use crate::zip::Zip;
2626

2727
use crate::iter::{

src/itertools.rs

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
// Copyright 2014-2019 bluss and ndarray developers
2+
// and Michał Krasnoborski (krdln)
3+
//
4+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7+
// option. This file may not be copied, modified, or distributed
8+
// except according to those terms.
9+
10+
//! A few iterator-related utilities and tools
11+
12+
use std::iter;
13+
14+
/// Iterate `iterable` with a running index.
15+
///
16+
/// `IntoIterator` enabled version of `.enumerate()`.
17+
///
18+
/// ```
19+
/// use itertools::enumerate;
20+
///
21+
/// for (i, elt) in enumerate(&[1, 2, 3]) {
22+
/// /* loop body */
23+
/// }
24+
/// ```
25+
pub(crate) fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
26+
where
27+
I: IntoIterator,
28+
{
29+
iterable.into_iter().enumerate()
30+
}
31+
32+
/// Iterate `i` and `j` in lock step.
33+
///
34+
/// `IntoIterator` enabled version of `i.zip(j)`.
35+
///
36+
/// ```
37+
/// use itertools::zip;
38+
///
39+
/// let data = [1, 2, 3, 4, 5];
40+
/// for (a, b) in zip(&data, &data[1..]) {
41+
/// /* loop body */
42+
/// }
43+
/// ```
44+
pub(crate) fn zip<I, J>(i: I, j: J) -> iter::Zip<I::IntoIter, J::IntoIter>
45+
where
46+
I: IntoIterator,
47+
J: IntoIterator,
48+
{
49+
i.into_iter().zip(j)
50+
}
51+
52+
/// Create an iterator running multiple iterators in lockstep.
53+
///
54+
/// The `izip!` iterator yields elements until any subiterator
55+
/// returns `None`.
56+
///
57+
/// This is a version of the standard ``.zip()`` that's supporting more than
58+
/// two iterators. The iterator element type is a tuple with one element
59+
/// from each of the input iterators. Just like ``.zip()``, the iteration stops
60+
/// when the shortest of the inputs reaches its end.
61+
///
62+
/// **Note:** The result of this macro is in the general case an iterator
63+
/// composed of repeated `.zip()` and a `.map()`; it has an anonymous type.
64+
/// The special cases of one and two arguments produce the equivalent of
65+
/// `$a.into_iter()` and `$a.into_iter().zip($b)` respectively.
66+
///
67+
/// Prefer this macro `izip!()` over [`multizip`] for the performance benefits
68+
/// of using the standard library `.zip()`.
69+
///
70+
/// [`multizip`]: fn.multizip.html
71+
///
72+
/// ```
73+
/// #[macro_use] extern crate itertools;
74+
/// # fn main() {
75+
///
76+
/// // iterate over three sequences side-by-side
77+
/// let mut results = [0, 0, 0, 0];
78+
/// let inputs = [3, 7, 9, 6];
79+
///
80+
/// for (r, index, input) in izip!(&mut results, 0..10, &inputs) {
81+
/// *r = index * 10 + input;
82+
/// }
83+
///
84+
/// assert_eq!(results, [0 + 3, 10 + 7, 29, 36]);
85+
/// # }
86+
/// ```
87+
///
88+
/// **Note:** To enable the macros in this crate, use the `#[macro_use]`
89+
/// attribute when importing the crate:
90+
///
91+
/// ```
92+
/// #[macro_use] extern crate itertools;
93+
/// # fn main() { }
94+
/// ```
95+
macro_rules! izip {
96+
// @closure creates a tuple-flattening closure for .map() call. usage:
97+
// @closure partial_pattern => partial_tuple , rest , of , iterators
98+
// eg. izip!( @closure ((a, b), c) => (a, b, c) , dd , ee )
99+
( @closure $p:pat => $tup:expr ) => {
100+
|$p| $tup
101+
};
102+
103+
// The "b" identifier is a different identifier on each recursion level thanks to hygiene.
104+
( @closure $p:pat => ( $($tup:tt)* ) , $_iter:expr $( , $tail:expr )* ) => {
105+
izip!(@closure ($p, b) => ( $($tup)*, b ) $( , $tail )*)
106+
};
107+
108+
// unary
109+
($first:expr $(,)*) => {
110+
IntoIterator::into_iter($first)
111+
};
112+
113+
// binary
114+
($first:expr, $second:expr $(,)*) => {
115+
izip!($first)
116+
.zip($second)
117+
};
118+
119+
// n-ary where n > 2
120+
( $first:expr $( , $rest:expr )* $(,)* ) => {
121+
izip!($first)
122+
$(
123+
.zip($rest)
124+
)*
125+
.map(
126+
izip!(@closure a => (a) $( , $rest )*)
127+
)
128+
};
129+
}

src/layout/layoutfmt.rs

+9-14
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
use super::Layout;
1010
use super::LayoutPriv;
11-
use itertools::Itertools;
1211

1312
const LAYOUT_NAMES: &[&str] = &["C", "F"];
1413

@@ -17,20 +16,16 @@ use std::fmt;
1716
impl fmt::Debug for Layout {
1817
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1918
if self.0 == 0 {
20-
write!(f, "Custom")
19+
write!(f, "Custom")?
2120
} else {
22-
write!(
23-
f,
24-
"{}",
25-
(0..32)
26-
.filter(|&i| self.is(1 << i))
27-
.format_with(" | ", |i, f| if let Some(name) = LAYOUT_NAMES.get(i) {
28-
f(name)
29-
} else {
30-
f(&format_args!("0x{:x}", i))
31-
})
32-
)
33-
}?;
21+
(0..32).filter(|&i| self.is(1 << i)).try_fold((), |_, i| {
22+
if let Some(name) = LAYOUT_NAMES.get(i) {
23+
write!(f, "{}", name)
24+
} else {
25+
write!(f, "{:#x}", i)
26+
}
27+
})?;
28+
};
3429
write!(f, " ({:#x})", self.0)
3530
}
3631
}

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ mod macro_utils;
141141
#[macro_use]
142142
mod private;
143143
mod aliases;
144+
#[macro_use]
145+
mod itertools;
144146
#[cfg(feature = "approx")]
145147
mod array_approx;
146148
#[cfg(feature = "serde")]

src/numeric/impl_numeric.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
use itertools::free::enumerate;
109
use num_traits::{self, Float, FromPrimitive, Zero};
1110
use std::ops::{Add, Div, Mul};
1211

1312
use crate::imp_prelude::*;
13+
use crate::itertools::enumerate;
1414
use crate::numeric_util;
1515

1616
use crate::{FoldWhile, Zip};

0 commit comments

Comments
 (0)