`String::push(&mut self, ch: char)` currently has a single code path
that calls `Char::encode_utf8`.
Perhaps it could be faster for ASCII `char`s, which are represented as
a single byte in UTF-8.
This commit leaves the method unchanged,
adds a copy of it with the fast path,
and adds benchmarks to compare them.
Results show that the fast path very significantly improves the performance
of repeatedly pushing an ASCII `char`,
but does not significantly affect the performance for a non-ASCII `char`
(where the fast path is not taken).
Output of `make check-stage1-collections NO_REBUILD=1 PLEASE_BENCH=1 TESTNAME=string::tests::bench_push`
```
test string::tests::bench_push_char_one_byte ... bench: 59552 ns/iter (+/- 2132) = 167 MB/s
test string::tests::bench_push_char_one_byte_with_fast_path ... bench: 6563 ns/iter (+/- 658) = 1523 MB/s
test string::tests::bench_push_char_two_bytes ... bench: 71520 ns/iter (+/- 3541) = 279 MB/s
test string::tests::bench_push_char_two_bytes_with_slow_path ... bench: 71452 ns/iter (+/- 4202) = 279 MB/s
test string::tests::bench_push_str ... bench: 24 ns/iter (+/- 2)
test string::tests::bench_push_str_one_byte ... bench: 38910 ns/iter (+/- 2477) = 257 MB/s
```
A benchmark of pushing a one-byte-long `&str` is added for comparison,
but its performance [has varied a lot lately](
https://github.com/rust-lang/rust/pull/19640#issuecomment-67741561).
(When the input is fixed, `s.push_str("x")` could be used
instead of `s.push('x')`.)
The old logic would be ok with *either* 0 or all 1s in the last word,
because it didn't compute a proper mask for the case where nbits is an
exact multiple of u32::BITS.
Add mask_for_bits() to compute this properly, and use it in all(). Add
all/none assertions to most of the tests. Note in particular, the all-zero
bitv in test_32_elements() was incorrectly all()==true before this patch.
- Fix typos on Blocks and MutBlocks.
- Use slice_to_mut() for creating blocks_mut().
- Deref the block parameter in get().
- Access nbits separately from mutating set in pop().
Part of #18424
This commit changes the semantics of `reserve` and `capacity` for Bitv and BitvSet to match conventions. It also introduces the notion of `reserve_index` and `reserve_index_exact` for collections with maximum-index-based capacity semantics.
Deprecates free function constructors in favour of functions on Bitv itself.
Changes `Bitv::pop` to return an Option rather than panicking.
Deprecates and renames several methods in favour of conventions.
Marks several blessed methods as unstable.
This commit also substantially refactors Bitv and BitvSet's implementations. The new implementation is simpler, cleaner, better documented, and more robust against overflows. It also reduces coupling between Bitv and BitvSet. Tests have been seperated into seperate submodules.
Fixes#16958
[breaking-change]
This commit shuffles around some CLI flags of the compiler to some more stable
locations with some renamings. The changes made were:
* The `-v` flag has been repurposes as the "verbose" flag. The version flag has
been renamed to `-V`.
* The `-h` screen has been split into two parts. Most top-level options (not
all) show with `-h`, and the remaining options (generally obscure) can be
shown with `--help -v` which is a "verbose help screen"
* The `-V` flag (version flag now) has lost its argument as it is now requested
with `rustc -vV` "verbose version".
* The `--emit` option has had its `ir` and `bc` variants renamed to `llvm-ir`
and `llvm-bc` to emphasize that they are LLVM's IR/bytecode.
* The `--emit` option has grown a new variant, `dep-info`, which subsumes the
`--dep-info` CLI argument. The `--dep-info` flag is now deprecated.
* The `--parse-only`, `--no-trans`, `--no-analysis`, and `--pretty` flags have
moved behind the `-Z` family of flags.
* The `--debuginfo` and `--opt-level` flags were moved behind the top-level `-C`
flag.
* The `--print-file-name` and `--print-crate-name` flags were moved behind one
global `--print` flag which now accepts one of `crate-name`, `file-names`, or
`sysroot`. This global `--print` flag is intended to serve as a mechanism for
learning various metadata about the compiler itself.
* The top-level `--pretty` flag was moved to a number of `-Z` options.
No warnings are currently enabled to allow tools like Cargo to have time to
migrate to the new flags before spraying warnings to all users.
cc https://github.com/rust-lang/rust/issues/19051
This patch marks `clone` stable, as well as the `Clone` trait, but
leaves `clone_from` unstable. The latter will be decided by the beta.
The patch also marks most manual implementations of `Clone` as stable,
except where the APIs are otherwise deprecated or where there is
uncertainty about providing `Clone`.
This patch finalizes stabilization for the `cell` module, settling on
the current names `Cell`, `RefCell`, `UnsafeCell`, `Ref` and `RefMut`.
While we had considered improving these names, no one was able to
produce a truly compelling alternative.
There is one substantive change here: the `get` method of `UnsafeSell`
is now marked `unsafe`. Merely getting a raw pointer to the contents is
not, by itself, an unsafe operation. (Consider that you can always
safely turn a reference into a raw pointer, and that raw pointer may
then be aliased by subsequent references.)
This small patch stabilizes the names of all integer modules (including
`int` and `uint`) and the `MIN` and `MAX` constants. The `BITS` and
`BYTES` constants are left unstable for now.
The `is_power_of_two()` method of the `UnsignedInt` trait currently returns `true` for `self == 0`. Zero is not a power of two, assuming an integral exponent `k >= 0`. I've therefore moved this functionality to the new method `is_power_of_two_or_zero()` and reformed `is_power_of_two()` to return false for `self == 0`.
To illustrate the usefulness of the existence of both functions, consider `HashMap`. Its capacity must be zero or a power of two; conversely, it also requires a (non-zero) power of two for key and val alignment.
Also, added a small amount of documentation regarding #18604.
This commit, like the second pass of `Option`, largely just stablizes the
existing functionality after renaming a few iterators.
The specific actions taken were:
* The `Ok` and `Err` variants were marked `#[stable]` as the stability
inheritance was since removed.
* The `as_mut` method is now stable.
* The `map` method is now stable
* The `map_err` method is now stable
* The `iter`, `iter_mut`, and `into_iter` methods now returned structures named
after the method of iteration. The methods are also now all stable.
* The `and_then` method is now stable.
* The `or_else` method is now stable.
* The `unwrap` family of functions are now all stable: `unwrap_or`,
`unwrap_or_else`, `unwrap`, and `unwrap_err`.
There is a possible open extension to `Result::{and, and_then}` to make the
return type further generic over `FromError` (as proposed in #19078), but this
is a backwards compatible change due to the usage of default type parameters,
which makes the two functions safe to stabilize now regardless of the outcome of
that issue.