about summary refs log tree commit diff
path: root/src/libcore/slice
AgeCommit message (Collapse)AuthorLines
2020-05-02slice::fill: take T by value.Bastian Kauschke-6/+7
2020-04-25Bump bootstrap compilerMark Rousskov-2/+2
2020-04-20Stop accessing module level int consts via crate::<Ty>Linus Färnstrand-2/+1
2020-04-15big-O notation: parenthesis, multiplication and backticksRalf Jung-7/+7
2020-04-14Tighten time complexity on the docmi_sawa-1/+1
2020-04-05Rollup merge of #70752 - yoshuawuyts:slice_fill, r=dtolnayDylan DPC-0/+24
Add slice::fill Adds the `slice::fill` method to fill a slice with an item. This replaces manual for loops where items are copied one-by-one. This is a counterpart to C++20's [`std::fill`](https://en.cppreference.com/w/cpp/algorithm/fill) function. ## Usage ```rust let mut buf = vec![0; 10]; buf.fill(1); assert_eq!(buf, vec![1; 10]); ``` ## Performance When compiling in release mode, for `[u8]` and `[u16]` this method will optimize to a `memset(3)` call ([godbolt](https://godbolt.org/z/85El_c)). The initial implementation relies on LLVM's optimizer to make it as fast as possible for any given input. But as @jonas-schievink [pointed out](https://twitter.com/sheevink/status/1245756597453885442) this can later be optimized through specialization to guarantee it has a specific performance profile. ## Why now? Conversations about adding `slice::fill` are not new. In fact, https://github.com/rust-lang/rfcs/issues/2067 was opened 3 years ago about this exact topic. However discussion stranded while discussing implementation details, and it's not seen much forward motion since. In ["The Hunt for the Fastest Zero"](https://travisdowns.github.io/blog/2020/01/20/zero.html) Travis Downs provides disects C++'s `std::fill` performance profile on gcc, comparing it among others to `memset(3)`. Even though `memset(3)` outperforms `std::fill` in their tests, the author notes the following: > That the optimization fails, perhaps unexpectedly, in some cases is unfortunate but it’s nice that you can fix it yourself. [...] Do we throw out modern C++ idioms, at least where performance matters, for example by replacing std::fill with memset? I don’t think so. Much of the article focuses on how how to fix the performance of `std::fill` by providing specializations for specific input. In Rust we don't have any dedicated methods to fill slices with values, so it either needs to be optimized at the MIR layer, or more likely rely on LLVM's optimizer. By adding a dedicated method for filling slices with values it opens up the ability for us to in the future guarantee that e.g. `Vec<u8>` will always optimize to `memset` even in debug mode. Or perhaps provide stronger guarantees about memory when zeroing values when a certain flag is passed. But regardless of that, it improves general ergonomics of working with slices by providing a dedicated method with documentation and examples. ## References - [slice-fill prototype on docs.rs](https://docs.rs/slice-fill/1.0.1/slice_fill/) - [The Hunt For The Fastest Zero](https://travisdowns.github.io/blog/2020/01/20/zero.html) - [Safe memset for slices](https://github.com/rust-lang/rfcs/issues/2067) - [C++20 std::fill](https://en.cppreference.com/w/cpp/algorithm/fill) - [ASM output on Godbolt](https://godbolt.org/z/5-XU66)
2020-04-05Add slice::fillYoshua Wuyts-0/+24
2020-04-03Replace float module consts with assoc consts in documentationLinus Färnstrand-1/+1
2020-03-23#[track_caller] on core::ops::{Index, IndexMut}.Adam Perry-0/+6
2020-03-04Use subslice patterns in slice methodsJosh Stone-22/+8
For all of the methods that pick off the first or last element, we can use subslice patterns to implement them directly, rather than relying on deeper indexing function calls. At a minimum, this means the generated code will rely less on inlining for performance, but in some cases it also optimizes better.
2020-02-29Rollup merge of #69581 - RalfJung:align_to_mut, r=CentrilDylan DPC-1/+3
fix aliasing violation in align_to_mut Fixes https://github.com/rust-lang/rust/issues/68549 I decided to add the testcase here to make it all one PR, but if you prefer I can also add that test case in the Miri repo instead.
2020-02-29fix aliasing violation in align_to_mutRalf Jung-1/+3
2020-02-28use is_empty() instead of len() == x to determine if structs are empty.Matthias Krüger-2/+2
2020-02-22Auto merge of #67330 - golddranks:split_inclusive, r=kodrausbors-1/+271
Implement split_inclusive for slice and str # Overview * Implement `split_inclusive` for `slice` and `str` and `split_inclusive_mut` for `slice` * `split_inclusive` is a substring/subslice splitting iterator that includes the matched part in the iterated substrings as a terminator. * EDIT: The behaviour has now changed, as per @KodrAus 's input, to the same semantics with the `split_terminator` function. I updated the examples below. * Two examples below: ```Rust let data = "\nMäry häd ä little lämb\nLittle lämb\n"; let split: Vec<&str> = data.split_inclusive('\n').collect(); assert_eq!(split, ["\n", "Märy häd ä little lämb\n", "Little lämb\n"]); ``` ```Rust let uppercase_separated = "SheePSharKTurtlECaT"; let mut first_char = true; let split: Vec<&str> = uppercase_separated.split_inclusive(|c: char| { let split = !first_char && c.is_uppercase(); first_char = split; split }).collect(); assert_eq!(split, ["SheeP", "SharK", "TurtlE", "CaT"]); ``` # Justification for the API * I was surprised to find that stdlib currently only has splitting iterators that leave out the matched part. In my experience, wanting to leave a substring terminator as a part of the substring is a pretty common usecase. * This API is strictly more expressive than the standard `split` API: it's easy to get the behaviour of `split` by mapping a subslicing operation that drops the terminator. On the other hand it's impossible to derive this behaviour from `split` without using hacky and brittle `unsafe` code. The normal way to achieve this functionality would be implementing the iterator yourself. * Especially when dealing with mutable slices, the only way currently is to use `split_at_mut`. This API provides an ergonomic alternative that plays to the strengths of the iterating capabilities of Rust. (Using `split_at_mut` iteratively used to be a real pain before NLL, fortunately the situation is a bit better now.) # Discussion items * <s>Does it make sense to mimic `split_terminator` in that the final empty slice would be left off in case of the string/slice ending with a terminator? It might do, as this use case is naturally geared towards considering the matching part as a terminator instead of a separator.</s> * EDIT: The behaviour was changed to mimic `split_terminator`. * Does it make sense to have `split_inclusive_mut` for `&mut str`?
2020-02-09Don't return empty slice on last iteration with matched terminator. Test ↵Pyry Kontio-105/+116
reverse iteration.
2020-02-09Implement split_inclusive for slice and str, an splitting iterator that ↵Pyry Kontio-1/+260
includes the matched part in the iterated substrings as a terminator.
2020-02-01Remove some unsound specializationsMatthew Jasper-29/+51
2019-12-26Use NonNull in slice::Iter and slice::IterMut.Martin Habovstiak-22/+25
`ptr` of `slice::Iter` and `slice::IterMut` can never be null, but this fact wasn't exploited for layout optimizations. By changing `ptr` from `*<mutability> T` to `NonNull<T>`, the compiler can now optimize layout of `Option<Iter<'a, T>>`.
2019-12-22Format the worldMark Rousskov-362/+457
2019-12-21Require issue = "none" over issue = "0" in unstable attributesRoss MacArthur-8/+8
2019-12-18Propagate cfg bootstrapMark Rousskov-9/+3
2019-12-13Require stable/unstable annotations for the constness of all stable ↵Oliver Scherer-0/+9
functions with a `const` modifier
2019-11-26Format libcore with rustfmtDavid Tolnay-51/+73
This commit applies rustfmt with default settings to files in src/libcore *that are not involved in any currently open PR* to minimize merge conflicts. The list of files involved in open PRs was determined by querying GitHub's GraphQL API with this script: https://gist.github.com/dtolnay/aa9c34993dc051a4f344d1b10e4487e8 With the list of files from the script in `outstanding_files`, the relevant commands were: $ find src/libcore -name '*.rs' | xargs rustfmt --edition=2018 $ rg libcore outstanding_files | xargs git checkout -- Repeating this process several months apart should get us coverage of most of the rest of libcore.
2019-11-07Rollup merge of #63793 - oli-obk:🧹, r=dtolnayMazdak Farrokhzad-0/+5
Have tidy ensure that we document all `unsafe` blocks in libcore cc @rust-lang/libs I documented a few and added ignore flags on the other files. We can incrementally document the files, but won't regress any files this way.
2019-11-06Have tidy ensure that we document all `unsafe` blocks in libcoreOliver Scherer-0/+5
2019-11-05fix link to ptr docsRalf Jung-2/+2
2019-11-05expand slice from_raw_part docsRalf Jung-18/+42
2019-10-25Fix slice::as_ptr_range doctest.Mara Bos-7/+10
2019-10-25Explain why pointer::add in slice::as_ptr_range is safe.Mara Bos-0/+18
2019-10-25Add slice_ptr_range tracking issue number.Mara Bos-2/+2
2019-10-25Add [T]::as_ptr_range() and [T]::as_mut_ptr_range().Mara Bos-1/+60
See https://github.com/rust-lang/rfcs/pull/2791 for motivation.
2019-10-04Allow unused attributes to avoid incremental bugMark Rousskov-0/+1
2019-09-30Auto merge of #64600 - scottmcm:no-slice-tryfold-unroll, r=blussbors-68/+1
Remove manual unrolling from slice::Iter(Mut)::try_fold While this definitely helps sometimes (particularly for trivial closures), it's also a pessimization sometimes, so it's better to leave this to (hypothetical) future LLVM improvements instead of forcing this on everyone. I think it's better for the advice to be that sometimes you need to unroll manually than you sometimes need to not-unroll manually (like #64545). --- For context see https://github.com/rust-lang/rust/pull/64572#issuecomment-532961046
2019-09-25Snap cfgs to new betaMark Rousskov-3/+1
2019-09-24Stabilize `str::len`, `[T]::len`, `is_empty` and `str::as_bytes` as const fnOliver Scherer-2/+4
2019-09-23Just delete the overrides now that they match the default implementationsScott McMurray-62/+1
2019-09-21Remove manual unrolling from slice::Iter(Mut)::try_foldScott McMurray-13/+7
While this definitely helps sometimes (particularly for trivial closures), it's also a pessimization sometimes, so it's better to leave this to (hypothetical) future LLVM improvements instead of forcing this on everyone. I think it's better for the advice to be that sometimes you need to unroll manually than you sometimes need to not-unroll manually (like #64545).
2019-08-22Apply clippy::let_and_return suggestionMateusz Mikuła-2/+1
2019-08-20Rollup merge of #63265 - JohnTitor:implement-nth-back-for-chunksexactmut, ↵Mazdak Farrokhzad-0/+16
r=scottmcm Implement `nth_back` for ChunksExactMut This is a part of #54054. r? @scottmcm
2019-08-10Use Result::unwrap_or_else instead of matchingLzu Tao-4/+1
2019-08-10Add an example to show how to insert item to a sorted vecLzu Tao-0/+14
2019-08-09Auto merge of #61937 - AaronKutch:master, r=scottmcmbors-69/+152
Improve `ptr_rotate` performance, tests, and benches The corresponding issue is #61784. I am not actually sure if miri can handle the test, but I can change the commit if necessary.
2019-08-06Improve `ptr_rotate` performance, tests, and benchmarksAaron Kutch-69/+152
2019-08-05Clarify align_to's requirements and obligationsJake Goulding-6/+8
2019-08-05Implement nth_back for ChunksExactMutYuki Okushi-0/+16
2019-08-04fix linksRalf Jung-2/+2
relative links do not work because this is included in several places
2019-08-03Apply suggestions from code reviewRalf Jung-8/+12
Co-Authored-By: Mazdak Farrokhzad <twingoow@gmail.com>
2019-08-03clarify that unchecked indexing is UB even if the reference is never usedRalf Jung-4/+12
2019-07-28Rollup merge of #62074 - wizAmit:feature/mut_chunks_nth_back, r=scottmcmMazdak Farrokhzad-0/+19
squash of all commits for nth_back on ChunksMut wip nth_back for chunks_mut working chunksmut fixed nth_back for chunksmut Signed-off-by: wizAmit <amitforfriends_dns@yahoo.com> r? @timvermeulen r? @scottmcm
2019-07-25Auto merge of #60340 - mgeier:cap-vs-capacity, r=alexcrichtonbors-2/+2
Rename .cap() methods to .capacity() As mentioned in #60316, there are a few `.cap()` methods, which seem out-of-place because such methods are called `.capacity()` in the rest of the code. This PR renames them to `.capacity()` but leaves `RawVec::cap()` in there for backwards compatibility. I didn't try to mark the old version as "deprecated", because I guess this would cause too much noise.