Commit Graph

48 Commits

Author SHA1 Message Date
Ulrik Sverdrup
bc651cac8d core: Stabilize FusedIterator
FusedIterator is a marker trait that promises that the implementing
iterator continues to return `None` from `.next()` once it has returned
`None` once (and/or `.next_back()`, if implemented).

The effects of FusedIterator are already widely available through
`.fuse()`, but with stable `FusedIterator`, stable Rust users can
implement this trait for their iterators when appropriate.
2018-03-03 14:14:03 +01:00
bors
932c736479 Auto merge of #48057 - scottmcm:less-match-more-compare, r=dtolnay
Simplify RangeInclusive::next[_back]

`match`ing on an `Option<Ordering>` seems cause some confusion for LLVM; switching to just using comparison operators removes a few jumps from the simple `for` loops I was trying.

cc https://github.com/rust-lang/rust/issues/45222 https://github.com/rust-lang/rust/issues/28237#issuecomment-363706510

Example:
```rust
#[no_mangle]
pub fn coresum(x: std::ops::RangeInclusive<u64>) -> u64 {
    let mut sum = 0;
    for i in x {
        sum += i ^ (i-1);
    }
    sum
}
```
Today:
```asm
coresum:
    xor r8d, r8d
    mov r9, -1
    xor eax, eax
    jmp .LBB0_1
.LBB0_4:
    lea rcx, [rdi - 1]
    xor rcx, rdi
    add rax, rcx
    mov rsi, rdx
    mov rdi, r10
.LBB0_1:
    cmp rdi, rsi
    mov ecx, 1
    cmovb   rcx, r9
    cmove   rcx, r8
    test    rcx, rcx
    mov edx, 0
    mov r10d, 1
    je  .LBB0_4         // 1
    cmp rcx, -1
    jne .LBB0_5         // 2
    lea r10, [rdi + 1]
    mov rdx, rsi
    jmp .LBB0_4         // 3
.LBB0_5:
    ret
```
With this PR:
```asm
coresum:
	cmp	rcx, rdx
	jbe	.LBB0_2
	xor	eax, eax
	ret
.LBB0_2:
	xor	r8d, r8d
	mov	r9d, 1
	xor	eax, eax
	.p2align	4, 0x90
.LBB0_3:
	lea	r10, [rcx + 1]
	cmp	rcx, rdx
	cmovae	rdx, r8
	cmovae	r10, r9
	lea	r11, [rcx - 1]
	xor	r11, rcx
	add	rax, r11
	mov	rcx, r10
	cmp	r10, rdx
	jbe	.LBB0_3         // Just this
	ret
```

<details><summary>Though using internal iteration (`.map(|i| i ^ (i-1)).sum()`) is still shorter to type, and lets the compiler unroll it</summary>

```asm
coresum_inner:
.Lcfi0:
.seh_proc coresum_inner
	sub	rsp, 168
.Lcfi1:
	.seh_stackalloc 168
	vmovdqa	xmmword ptr [rsp + 144], xmm15
.Lcfi2:
	.seh_savexmm 15, 144
	vmovdqa	xmmword ptr [rsp + 128], xmm14
.Lcfi3:
	.seh_savexmm 14, 128
	vmovdqa	xmmword ptr [rsp + 112], xmm13
.Lcfi4:
	.seh_savexmm 13, 112
	vmovdqa	xmmword ptr [rsp + 96], xmm12
.Lcfi5:
	.seh_savexmm 12, 96
	vmovdqa	xmmword ptr [rsp + 80], xmm11
.Lcfi6:
	.seh_savexmm 11, 80
	vmovdqa	xmmword ptr [rsp + 64], xmm10
.Lcfi7:
	.seh_savexmm 10, 64
	vmovdqa	xmmword ptr [rsp + 48], xmm9
.Lcfi8:
	.seh_savexmm 9, 48
	vmovdqa	xmmword ptr [rsp + 32], xmm8
.Lcfi9:
	.seh_savexmm 8, 32
	vmovdqa	xmmword ptr [rsp + 16], xmm7
.Lcfi10:
	.seh_savexmm 7, 16
	vmovdqa	xmmword ptr [rsp], xmm6
.Lcfi11:
	.seh_savexmm 6, 0
.Lcfi12:
	.seh_endprologue
	cmp	rdx, rcx
	jae	.LBB1_2
	xor	eax, eax
	jmp	.LBB1_13
.LBB1_2:
	mov	r8, rdx
	sub	r8, rcx
	jbe	.LBB1_3
	cmp	r8, 7
	jbe	.LBB1_5
	mov	rax, r8
	and	rax, -8
	mov	r9, r8
	and	r9, -8
	je	.LBB1_5
	add	rax, rcx
	vmovq	xmm0, rcx
	vpshufd	xmm0, xmm0, 68
	mov	ecx, 1
	vmovq	xmm1, rcx
	vpslldq	xmm1, xmm1, 8
	vpaddq	xmm1, xmm0, xmm1
	vpxor	xmm0, xmm0, xmm0
	vpcmpeqd	xmm11, xmm11, xmm11
	vmovdqa	xmm12, xmmword ptr [rip + __xmm@00000000000000010000000000000001]
	vmovdqa	xmm13, xmmword ptr [rip + __xmm@00000000000000030000000000000003]
	vmovdqa	xmm14, xmmword ptr [rip + __xmm@00000000000000050000000000000005]
	vmovdqa	xmm15, xmmword ptr [rip + __xmm@00000000000000080000000000000008]
	mov	rcx, r9
	vpxor	xmm4, xmm4, xmm4
	vpxor	xmm5, xmm5, xmm5
	vpxor	xmm6, xmm6, xmm6
	.p2align	4, 0x90
.LBB1_9:
	vpaddq	xmm7, xmm1, xmmword ptr [rip + __xmm@00000000000000020000000000000002]
	vpaddq	xmm9, xmm1, xmmword ptr [rip + __xmm@00000000000000040000000000000004]
	vpaddq	xmm10, xmm1, xmmword ptr [rip + __xmm@00000000000000060000000000000006]
	vpaddq	xmm8, xmm1, xmm12
	vpxor	xmm7, xmm8, xmm7
	vpaddq	xmm2, xmm1, xmm13
	vpxor	xmm8, xmm2, xmm9
	vpaddq	xmm3, xmm1, xmm14
	vpxor	xmm3, xmm3, xmm10
	vpaddq	xmm2, xmm1, xmm11
	vpxor	xmm2, xmm2, xmm1
	vpaddq	xmm0, xmm2, xmm0
	vpaddq	xmm4, xmm7, xmm4
	vpaddq	xmm5, xmm8, xmm5
	vpaddq	xmm6, xmm3, xmm6
	vpaddq	xmm1, xmm1, xmm15
	add	rcx, -8
	jne	.LBB1_9
	vpaddq	xmm0, xmm4, xmm0
	vpaddq	xmm0, xmm5, xmm0
	vpaddq	xmm0, xmm6, xmm0
	vpshufd	xmm1, xmm0, 78
	vpaddq	xmm0, xmm0, xmm1
	vmovq	r10, xmm0
	cmp	r8, r9
	jne	.LBB1_6
	jmp	.LBB1_11
.LBB1_3:
	xor	r10d, r10d
	jmp	.LBB1_12
.LBB1_5:
	xor	r10d, r10d
	mov	rax, rcx
	.p2align	4, 0x90
.LBB1_6:
	lea	rcx, [rax - 1]
	xor	rcx, rax
	inc	rax
	add	r10, rcx
	cmp	rdx, rax
	jne	.LBB1_6
.LBB1_11:
	mov	rcx, rdx
.LBB1_12:
	lea	rax, [rcx - 1]
	xor	rax, rcx
	add	rax, r10
.LBB1_13:
	vmovaps	xmm6, xmmword ptr [rsp]
	vmovaps	xmm7, xmmword ptr [rsp + 16]
	vmovaps	xmm8, xmmword ptr [rsp + 32]
	vmovaps	xmm9, xmmword ptr [rsp + 48]
	vmovaps	xmm10, xmmword ptr [rsp + 64]
	vmovaps	xmm11, xmmword ptr [rsp + 80]
	vmovaps	xmm12, xmmword ptr [rsp + 96]
	vmovaps	xmm13, xmmword ptr [rsp + 112]
	vmovaps	xmm14, xmmword ptr [rsp + 128]
	vmovaps	xmm15, xmmword ptr [rsp + 144]
	add	rsp, 168
	ret
	.seh_handlerdata
	.section	.text,"xr",one_only,coresum_inner
.Lcfi13:
	.seh_endproc
```

</details>
2018-02-08 06:38:30 +00:00
Scott McMurray
27d4d51670 Simplify RangeInclusive::next[_back]
`match`ing on an `Option<Ordering>` seems cause some confusion for LLVM; switching to just using comparison operators removes a few jumps from the simple `for` loops I was trying.
2018-02-07 11:11:54 -08:00
Manish Goregaokar
da6dcbc21e Rollup merge of #47944 - oberien:unboundediterator-trustedlen, r=bluss
Implement TrustedLen for Take<Repeat> and Take<RangeFrom>

This will allow optimization of simple `repeat(x).take(n).collect()` iterators, which are currently not vectorized and have capacity checks.

This will only support a few aggregates on `Repeat` and `RangeFrom`, which might be enough for simple cases, but doesn't optimize more complex ones. Namely, Cycle, StepBy, Filter, FilterMap, Peekable, SkipWhile, Skip, FlatMap, Fuse and Inspect are not marked `TrustedLen` when the inner iterator is infinite.

Previous discussion can be found in #47082

r? @alexcrichton
2018-02-07 08:30:53 -08:00
Scott McMurray
1b1e887f4d Override try_[r]fold for RangeInclusive
Because the last item needs special handling, it seems that LLVM has trouble canonicalizing the loops in external iteration.  With the override, it becomes obvious that the start==end case exits the loop (as opposed to the one *after* that exiting the loop in external iteration).
2018-02-04 23:48:40 -08:00
oberien
a1809d5784 Implement TrustedLen for Take<Repeat> and Take<RangeFrom> 2018-02-04 16:09:32 +01:00
varkor
919d643b79 Add min and last specialisations for Range 2018-01-09 19:37:44 +00:00
varkor
2d8334358a Use next and next_back 2018-01-06 22:14:02 +00:00
varkor
c23d4500fd Fix behaviour after iterator exhaustion 2018-01-05 18:57:10 +00:00
varkor
439beab41f Remove min from RangeFrom 2018-01-04 15:03:50 +00:00
varkor
087bffa78c Remove RangeInclusive::sum 2018-01-04 12:36:43 +00:00
varkor
29e6b1034b Add max and sum specialisations for Range 2018-01-04 01:51:18 +00:00
varkor
3d9c36fbf5 Add min specialisation for RangeFrom and last for RangeInclusive 2018-01-04 00:58:41 +00:00
varkor
680ebf7b16 Add min and max specialisations for RangeInclusive 2018-01-04 00:17:36 +00:00
Jimmy Cuadra
80e3f8941d Add blanket TryFrom impl when From is implemented.
Adds `impl<T, U> TryFrom<T> for U where U: From<T>`.

Removes `impl<'a, T> TryFrom<&'a str> for T where T: FromStr` due to
overlapping impls caused by the new blanket impl. This removal is to
be discussed further on the tracking issue for TryFrom.

Refs #33417.
2017-08-29 22:13:21 -07:00
oyvindln
4bb9a8b4ac Add an overflow check in the Iter::next() impl for Range<_>
This helps with vectorization in some cases, such as (0..u16::MAX).collect::<Vec<u16>>(),
 as LLVM is able to change the loop condition to use equality instead of less than
2017-08-01 19:31:50 +02:00
Simon Sapin
de4afc6797 Implement O(1)-time Iterator::nth for Range* 2017-07-08 08:55:55 +02:00
Simon Sapin
8e8fd02419 Factorize some macros in iter/range.rs 2017-07-08 08:55:55 +02:00
Simon Sapin
d1ec6c22d1 Remove Step::steps_between, rename steps_between_by_one to steps_between 2017-07-08 08:55:55 +02:00
Simon Sapin
4b2f40dfdf Remove unused Step methods 2017-07-08 08:55:55 +02:00
Simon Sapin
dbed18ca20 Remove unused Add bounds in iterator for ranges impls. 2017-07-08 08:55:28 +02:00
Scott McMurray
dcd332ed94 Delete deprecated & unstable range-specific step_by
Replacement: 41439
Deprecation: 42310 for 1.19
Fixes 41477
2017-07-01 19:18:02 -07:00
Scott McMurray
1723e063c9 Deprecate iter::range::StepBy
Only exposed as DeprecatedStepBy (as of PR 41439)
2017-05-31 22:35:34 -07:00
Scott McMurray
0967e2495d Deprecate Range*::step_by
Changed all the tests except test_range_step to use Iterator::step_by.
2017-05-31 22:35:34 -07:00
Scott McMurray
265dce66b6 RangeFrom should have an infinite size_hint
This makes the size_hint from things like `take` more precise.
2017-05-30 09:15:25 -07:00
Corey Farwell
7e47327d90 Rollup merge of #42169 - scottmcm:new-step-trait-issue, r=alexcrichton
Give step_trait a distinct tracking issue from step_by

iterator_step_by has decoupled their futures, so the tracking issue should split.

Old issue: https://github.com/rust-lang/rust/issues/27741
New issue: https://github.com/rust-lang/rust/issues/42168

r? @alexcrichton (another follow-up to closed PR https://github.com/rust-lang/rust/pull/42110#issuecomment-303176049)
2017-05-26 10:20:25 -04:00
Scott McMurray
794e5724a8 Give step_trait a distinct tracking issue from step_by
iterator_step_by has decoupled their futures, so the tracking issue should split.
2017-05-23 03:08:18 -07:00
Scott McMurray
7eaca60f3b Return a correct size_hint for degenerate inclusive ranges
Fixes https://github.com/rust-lang/rust/issues/42135

Found while fixing run-pass/range_inclusive test failure.
2017-05-21 05:03:49 -07:00
Scott McMurray
f166bd9857 Make RangeInclusive just a two-field struct
Not being an enum improves ergonomics, especially since NonEmpty could be Empty.  It can still be iterable without an extra "done" bit by making the range have !(start <= end), which is even possible without changing the Step trait.

Implements RFC 1980
2017-05-21 01:48:03 -07:00
Scott McMurray
f8c6436173 Step::replace_one should put a one, not a zero (Issue #41492)
Turns out all six of these impls are incorrect.
2017-04-23 21:47:09 -07:00
Alex Crichton
626e754473 Bump version, upgrade bootstrap
This commit updates the version number to 1.17.0 as we're not on that version of
the nightly compiler, and at the same time this updates src/stage0.txt to
bootstrap from freshly minted beta compiler and beta Cargo.
2017-02-03 13:25:46 -08:00
Simonas Kazlauskas
508fef5dff impl Step for iu128
Also fix the leb128 tests
2016-12-30 15:17:26 +01:00
bors
57f971bc16 Auto merge of #36365 - matthew-piziak:silent-overflow, r=eddyb
fix silent overflows on `Step` impls

Part of https://github.com/rust-lang/rust/issues/36110

r? @eddyb
2016-11-07 11:48:16 -08:00
Ulrik Sverdrup
f0e6b90790 Link the tracking issue for TrustedLen 2016-11-04 01:00:55 +01:00
Ulrik Sverdrup
69b9400b79 Implement TrustedLen for more iterators 2016-10-20 14:40:09 +02:00
Ulrik Sverdrup
9ae9930e2f Introduce iterator trait TrustedLen 2016-10-20 14:07:06 +02:00
Matthew Piziak
db1e85d092 remove erroneous semicolons 2016-10-11 20:17:52 -04:00
Matthew Piziak
dc607deac7 use UFCS with Add::add and Sub::sub instead of unstable attributes 2016-10-09 06:35:07 -04:00
Oliver Middleton
06a7dcd355 std: Correct stability attributes for some implementations
These are displayed by rustdoc so should be correct.
2016-10-01 23:58:14 +01:00
Alex Burka
bd1ae637f8 remove ExactSizeIterator from RangeInclusive<u/isize> 2016-09-12 17:06:53 +00:00
Matthew Piziak
f6c4fcf128 fix silent overflows on Step impls
r? @eddyb
2016-09-09 12:21:01 -04:00
Matthew Piziak
50e0fbc904 accumulate vector and assert for RangeFrom and RangeInclusive examples
PR #35695 for `Range` was approved, so it seems that this side-effect-free style is preferred for Range* examples. This PR performs the same translation for `RangeFrom` and `RangeInclusive`. It also removes what looks to be an erroneously commented line for `#![feature(step_by)]`, and an unnecessary primitive-type annotation in `0u8..`.

add `fn main` wrappers to enable Rust Playground "Run" button
2016-08-26 11:54:32 -04:00
Jeffrey Seyfried
e2ad3be178 Use #[prelude_import] in libcore. 2016-08-24 22:12:23 +00:00
Steven Allen
de91872a33 Add a FusedIterator trait.
This trait can be used to avoid the overhead of a fuse wrapper when an iterator
is already well-behaved.

Conforming to: RFC 1581
Closes: #35602
2016-08-18 12:16:29 -04:00
Matthew Piziak
2c9a1d9c4a remove .take(10) from Range example 2016-08-15 18:30:25 -04:00
Matthew Piziak
c9f2055110 accumulate into vector and assert, instead of printing
I'm only making this change in one place so that people can express
their preferences for this stylistic change. If/when this change is
approved I'll go ahead and translate the rest of the `std::ops`
examples.
2016-08-15 18:03:11 -04:00
Alex Crichton
3016626c3a std: Stabilize APIs for the 1.11.0 release
Although the set of APIs being stabilized this release is relatively small, the
trains keep going! Listed below are the APIs in the standard library which have
either transitioned from unstable to stable or those from unstable to
deprecated.

Stable

* `BTreeMap::{append, split_off}`
* `BTreeSet::{append, split_off}`
* `Cell::get_mut`
* `RefCell::get_mut`
* `BinaryHeap::append`
* `{f32, f64}::{to_degrees, to_radians}` - libcore stabilizations mirroring past
  libstd stabilizations
* `Iterator::sum`
* `Iterator::product`

Deprecated

* `{f32, f64}::next_after`
* `{f32, f64}::integer_decode`
* `{f32, f64}::ldexp`
* `{f32, f64}::frexp`
* `num::One`
* `num::Zero`

Added APIs (all unstable)

* `iter::Sum`
* `iter::Product`
* `iter::Step` - a few methods were added to accomodate deprecation of One/Zero

Removed APIs

* `From<Range<T>> for RangeInclusive<T>` - everything about `RangeInclusive` is
  unstable

Closes #27739
Closes #27752
Closes #32526
Closes #33444
Closes #34152
cc #34529 (new tracking issue)
2016-07-03 10:49:01 -07:00
Ulrik Sverdrup
84654fa4bf Split core::iter module implementation into parts
split iter.rs into a directory of (implementation private) modules.

+ mod Adaptor structs
  - Private fields need to be available both for them and Iterator
+ iterator (Iterator trait)
+ traits (FromIterator, traits but Iterator itself)
+ range (range related)
+ sources (Repeat, Once, Empty)
2016-04-18 20:08:27 +02:00