diff --git a/crates.js b/crates.js index 70e7227e..0224dcd0 100644 --- a/crates.js +++ b/crates.js @@ -1 +1 @@ -window.ALL_CRATES = ["accum","avl_tree","bfs","bfs01","binary","bitvec","bsgs","cht","cipolla","convex_hull","dfs","dijkstra_radix_heap","dinic","dual_segtree","elim","erato","euclid","fp","fps","gco","gss","heap_slope_trick","heap_tricks","hld","hopkarp","hungarian","interval_heap","io","lagrange","lazy_segbeats","lazy_segtree","lg","lin_ineq","link_cut_tree","low_link","make_graph","manacher","mincost_flow","monotone_minima","naive_poly","newton","next_permutation","numeric_search","partially_persistent_union_find","radix_heap","randtools","rational","rb","rbtree","riff","scc","segbeats","segbeats_task3","segtree","skew_heap","snippetter","sparse_table","splay_tree","suffix_array","swag","tree_fold","trial","trie","two_sat","uf_checklist","union_find","veb","vec_lines","wavelet_matrix","z_algo","zeta"]; \ No newline at end of file +window.ALL_CRATES = ["accum","avl_tree","bfs","bfs01","binary","bitvec","bsgs","cht","cipolla","convex_hull","dfs","dijkstra_radix_heap","dinic","dual_segtree","elim","erato","euclid","fp","fps","gco","graph","gss","heap_slope_trick","heap_tricks","hld","hopkarp","hungarian","interval_heap","io","lagrange","lazy_segbeats","lazy_segtree","lg","lin_ineq","link_cut_tree","low_link","make_graph","manacher","mincost_flow","monotone_minima","naive_poly","newton","next_permutation","numeric_search","partially_persistent_union_find","radix_heap","randtools","rational","rb","rbtree","riff","segbeats","segbeats_task3","segtree","skew_heap","snippetter","sparse_table","splay_tree","suffix_array","swag","tree_fold","trial","trie","uf_checklist","union_find","veb","vec_lines","wavelet_matrix","z_algo","zeta"]; \ No newline at end of file diff --git a/dependencies.js b/dependencies.js index 12cc89ff..509ff181 100644 --- a/dependencies.js +++ b/dependencies.js @@ -1 +1 @@ -dependencies = {"zeta":{"dependencies":[],"tags":[]},"skew-heap":{"dependencies":[],"tags":[]},"dfs":{"dependencies":[],"tags":[]},"swag":{"dependencies":[],"tags":[]},"euclid":{"dependencies":[],"tags":[]},"segtree":{"dependencies":[],"tags":[]},"radix_heap":{"dependencies":[],"tags":[]},"make_graph":{"dependencies":[],"tags":[]},"hopkarp":{"dependencies":[],"tags":[]},"next_permutation":{"dependencies":[],"tags":[]},"lagrange":{"dependencies":["fp"],"tags":[]},"manacher":{"dependencies":[],"tags":[]},"wavelet_matrix":{"dependencies":[],"tags":[]},"convex_hull":{"dependencies":[],"tags":[]},"accum":{"dependencies":[],"tags":[]},"partially_persistent_union_find":{"dependencies":[],"tags":[]},"splay_tree":{"dependencies":[],"tags":[]},"hungarian":{"dependencies":[],"tags":[]},"monotone_minima":{"dependencies":[],"tags":[]},"fps":{"dependencies":["fp"],"tags":[]},"rbtree":{"dependencies":[],"tags":[]},"io":{"dependencies":[],"tags":[]},"avl_tree":{"dependencies":[],"tags":[]},"randtools":{"dependencies":[],"tags":[]},"lin_ineq":{"dependencies":[],"tags":[]},"low_link":{"dependencies":[],"tags":[]},"segbeats_task3":{"dependencies":[],"tags":[]},"bitvec":{"dependencies":[],"tags":[]},"z_algo":{"dependencies":[],"tags":[]},"numeric_search":{"dependencies":[],"tags":[]},"trial":{"dependencies":[],"tags":[]},"rational":{"dependencies":[],"tags":[]},"tree_fold":{"dependencies":[],"tags":[]},"trie":{"dependencies":[],"tags":[]},"rb":{"dependencies":[],"tags":[]},"naive_poly":{"dependencies":[],"tags":[]},"uf_checklist":{"dependencies":["union_find"],"tags":[]},"elim":{"dependencies":[],"tags":[]},"link_cut_tree":{"dependencies":[],"tags":[]},"binary":{"dependencies":[],"tags":[]},"mincost_flow":{"dependencies":[],"tags":[]},"dinic":{"dependencies":[],"tags":[]},"gss":{"dependencies":[],"tags":[]},"newton":{"dependencies":[],"tags":[]},"sparse_table":{"dependencies":[],"tags":[]},"lazy_segbeats":{"dependencies":[],"tags":[]},"veb":{"dependencies":[],"tags":[]},"dual_segtree":{"dependencies":[],"tags":[]},"lg":{"dependencies":[],"tags":[]},"interval_heap":{"dependencies":[],"tags":[]},"cipolla":{"dependencies":[],"tags":[]},"dijkstra_radix_heap":{"dependencies":["radix_heap"],"tags":[]},"erato":{"dependencies":[],"tags":[]},"hld":{"dependencies":[],"tags":[]},"bfs":{"dependencies":[],"tags":[]},"gco":{"dependencies":["dinic"],"tags":[]},"heap_slope_trick":{"dependencies":[],"tags":[]},"two_sat":{"dependencies":["scc"],"tags":[]},"riff":{"dependencies":[],"tags":[]},"vec_lines":{"dependencies":[],"tags":[]},"cht":{"dependencies":[],"tags":[]},"segbeats":{"dependencies":[],"tags":[]},"union_find":{"dependencies":[],"tags":[]},"scc":{"dependencies":[],"tags":[]},"suffix_array":{"dependencies":[],"tags":[]},"lazy_segtree":{"dependencies":[],"tags":[]},"bfs01":{"dependencies":[],"tags":[]},"bsgs":{"dependencies":[],"tags":[]},"fp":{"dependencies":[],"tags":[]},"heap_tricks":{"dependencies":[],"tags":[]}} \ No newline at end of file +dependencies = {"wavelet_matrix":{"dependencies":[],"tags":[]},"make_graph":{"dependencies":[],"tags":[]},"rb":{"dependencies":[],"tags":[]},"gco":{"dependencies":["dinic"],"tags":[]},"partially_persistent_union_find":{"dependencies":[],"tags":[]},"rbtree":{"dependencies":[],"tags":[]},"mincost_flow":{"dependencies":[],"tags":[]},"binary":{"dependencies":[],"tags":[]},"interval_heap":{"dependencies":[],"tags":[]},"trial":{"dependencies":[],"tags":[]},"riff":{"dependencies":[],"tags":[]},"fp":{"dependencies":[],"tags":[]},"monotone_minima":{"dependencies":[],"tags":[]},"segtree":{"dependencies":[],"tags":[]},"dinic":{"dependencies":[],"tags":[]},"cht":{"dependencies":[],"tags":[]},"lin_ineq":{"dependencies":[],"tags":[]},"veb":{"dependencies":[],"tags":[]},"hopkarp":{"dependencies":[],"tags":[]},"dijkstra_radix_heap":{"dependencies":["radix_heap"],"tags":[]},"trie":{"dependencies":[],"tags":[]},"link_cut_tree":{"dependencies":[],"tags":[]},"rational":{"dependencies":[],"tags":[]},"gss":{"dependencies":[],"tags":[]},"heap_slope_trick":{"dependencies":[],"tags":[]},"bsgs":{"dependencies":[],"tags":[]},"swag":{"dependencies":[],"tags":[]},"lazy_segtree":{"dependencies":[],"tags":[]},"sparse_table":{"dependencies":[],"tags":[]},"uf_checklist":{"dependencies":["union_find"],"tags":[]},"suffix_array":{"dependencies":[],"tags":[]},"bfs01":{"dependencies":[],"tags":[]},"zeta":{"dependencies":[],"tags":[]},"naive_poly":{"dependencies":[],"tags":[]},"dual_segtree":{"dependencies":[],"tags":[]},"radix_heap":{"dependencies":[],"tags":[]},"fps":{"dependencies":["fp"],"tags":[]},"lazy_segbeats":{"dependencies":[],"tags":[]},"lagrange":{"dependencies":["fp"],"tags":[]},"euclid":{"dependencies":[],"tags":[]},"lg":{"dependencies":[],"tags":[]},"avl_tree":{"dependencies":[],"tags":[]},"splay_tree":{"dependencies":[],"tags":[]},"bitvec":{"dependencies":[],"tags":[]},"elim":{"dependencies":[],"tags":[]},"next_permutation":{"dependencies":[],"tags":[]},"erato":{"dependencies":[],"tags":[]},"hungarian":{"dependencies":[],"tags":[]},"heap_tricks":{"dependencies":[],"tags":[]},"low_link":{"dependencies":[],"tags":[]},"cipolla":{"dependencies":[],"tags":[]},"union_find":{"dependencies":[],"tags":[]},"manacher":{"dependencies":[],"tags":[]},"io":{"dependencies":[],"tags":[]},"hld":{"dependencies":[],"tags":[]},"segbeats":{"dependencies":[],"tags":[]},"tree_fold":{"dependencies":[],"tags":[]},"convex_hull":{"dependencies":[],"tags":[]},"graph":{"dependencies":[],"tags":[]},"randtools":{"dependencies":[],"tags":[]},"accum":{"dependencies":[],"tags":[]},"skew-heap":{"dependencies":[],"tags":[]},"vec_lines":{"dependencies":[],"tags":[]},"z_algo":{"dependencies":[],"tags":[]},"bfs":{"dependencies":[],"tags":[]},"numeric_search":{"dependencies":[],"tags":[]},"newton":{"dependencies":[],"tags":[]},"segbeats_task3":{"dependencies":[],"tags":[]},"dfs":{"dependencies":[],"tags":[]}} \ No newline at end of file diff --git a/graph/all.html b/graph/all.html new file mode 100644 index 00000000..b57a4ef5 --- /dev/null +++ b/graph/all.html @@ -0,0 +1,35 @@ +
Redirecting to ../../graph/struct.Csr.html...
+ + + \ No newline at end of file diff --git a/graph/csr/struct.Iter.html b/graph/csr/struct.Iter.html new file mode 100644 index 00000000..43280e0f --- /dev/null +++ b/graph/csr/struct.Iter.html @@ -0,0 +1,11 @@ + + + + +Redirecting to ../../graph/struct.Iter.html...
+ + + \ No newline at end of file diff --git a/graph/csr/struct.LastMut.html b/graph/csr/struct.LastMut.html new file mode 100644 index 00000000..e8f87ee9 --- /dev/null +++ b/graph/csr/struct.LastMut.html @@ -0,0 +1,11 @@ + + + + +Redirecting to ../../graph/struct.LastMut.html...
+ + + \ No newline at end of file diff --git a/graph/fn.kosaraju.html b/graph/fn.kosaraju.html new file mode 100644 index 00000000..222687a5 --- /dev/null +++ b/graph/fn.kosaraju.html @@ -0,0 +1,46 @@ +pub fn kosaraju(n: usize, edges: &[(usize, usize)]) -> Csr<usize>
Returns the strongly connected components of a directed graph.
+use graph::kosaraju;
+let n = 6;
+let edges = [ (1, 4), (5, 2), (3, 0), (5, 5), (4, 1), (0, 3), (4, 2)];
+let scc = kosaraju(n, &edges);
+assert_eq!(scc.len(), 4);
+assert_eq!(scc[0], [5]);
+assert_eq!(scc[1], [1, 4]);
+assert_eq!(scc[2], [2]);
+assert_eq!(scc[3], [0, 3]);
Kosaraju’s algorithm for strongly connected components
+Graphs and set partitions are represented in CSR format Csr
.
use graph::kosaraju;
+let n = 6;
+let edges = [ (1, 4), (5, 2), (3, 0), (5, 5), (4, 1), (0, 3), (4, 2)];
+let scc = kosaraju(n, &edges);
+assert_eq!(scc.len(), 4);
+assert_eq!(scc[0], [5]);
+assert_eq!(scc[1], [1, 4]);
+assert_eq!(scc[2], [2]);
+assert_eq!(scc[3], [0, 3]);
pub struct Csr<T> {
+ pub data: Vec<T>,
+ pub boundary: Vec<usize>,
+}
Compressed Sparse Row format
+data
boundaries
This struct represents a list of lists $A$ of elements of type T
.
$$ +A_{i, j} = X[s_i + j] +$$
+data: Vec<T>
$X = [x_0, x_1, \dots, x_{n-1}]$
+boundary: Vec<usize>
$S = [s_0, s_1, \dots, s_{m}]$
+Create a CSR corrsponding to $A = [\ ]$.
+use graph::Csr;
+let csr: Csr<usize> = Csr::new();
+assert!(csr.is_empty());
Create a CSR corrsponding to $A = [\ ]$ with preallocated memory.
+use graph::Csr;
+let csr: Csr<usize> = Csr::with_capacity(10, 5);
+assert!(csr.is_empty());
Create a CSR from a list of sections.
+use graph::Csr;
+let csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+assert_eq!(csr.section(0), &[1, 2, 3]);
+assert_eq!(csr.section(1), &[4, 5]);
Get the $i$-th section $A_i$. Alias for &self[i]
.
use graph::Csr;
+let csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+assert_eq!(csr.section(0), &[1, 2, 3]);
Get the mutable $i$-th section $A_i$. Alias for &mut self[i]
.
use graph::Csr;
+let mut csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+csr.section_mut(0)[0] = 42;
+assert_eq!(csr.section(0), &[42, 2, 3]);
Check if the CSR is empty. (i.e. $A = [\ ]$)
+use graph::Csr;
+let csr = Csr::<()>::new();
+assert!(csr.is_empty());
Get the number of sections $m = |A|$.
+use graph::Csr;
+let csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+assert_eq!(csr.len(), 2);
Get the total number of elements in $A$. (i.e. $\sum_{i=0}^{m-1} |A_i|$)
+use graph::Csr;
+let csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+assert_eq!(csr.flat_len(), 5);
Get the mutable and extendable reference to the last section.
+use graph::Csr;
+let mut csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+csr.last_mut().push(42);
+assert_eq!(csr.section(1), &[4, 5, 42]);
Push an empty section $A_m = [\ ]$.
+use graph::Csr;
+let mut csr = Csr::<()>::new();
+csr.push_empty();
+assert_eq!(csr.section(0), &[]);
Clone and push a section.
+use graph::Csr;
+let mut csr = Csr::new();
+csr.push_section(&[1, 2, 3]);
+assert_eq!(csr.section(0), &[1, 2, 3]);
Create a CSR from a list of edges.
+use graph::Csr;
+let csr = Csr::from_edges(3, &[(0, 1), (1, 2), (2, 0)]);
+assert_eq!(csr.to_vec(), vec![vec![1], vec![2], vec![0]]);
Create CSRs of $G$ and $G^{\mathrm{op}}$ from a list of edges.
+use graph::Csr;
+let (g, rg) = Csr::from_edges_and_rev(3, &[(0, 1), (1, 2), (2, 0)]);
+assert_eq!(g.to_vec(), vec![vec![1], vec![2], vec![0]]);
+assert_eq!(rg.to_vec(), vec![vec![2], vec![0], vec![1]]);
pub struct Iter<'a, T> { /* private fields */ }
Immutable iterator over rows.
+iter_advance_by
)n
elements. Read moren
th element from the end of the iterator. Read moreIterator::try_fold()
: it takes
+elements starting from the back of the iterator. Read moreiter_next_chunk
)N
values. Read moreiter_advance_by
)n
elements. Read moren
th element of the iterator. Read moreiter_intersperse
)separator
+between adjacent items of the original iterator. Read moren
elements. Read moren
elements, or fewer
+if the underlying iterator ends sooner. Read moreiter_collect_into
)iter_partition_in_place
)true
precede all those that return false
.
+Returns the number of true
elements found. Read moreiter_is_partitioned
)true
precede all those that return false
. Read moreiterator_try_reduce
)try_find
)iter_array_chunks
)N
elements of the iterator at a time. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read morePartialOrd
elements of
+this Iterator
with those of another. The comparison works like short-circuit
+evaluation, returning a result without comparing the remaining elements.
+As soon as an order can be determined, the evaluation stops and a result is returned. Read moreiter_order_by
)Iterator
with those
+of another with respect to the specified comparison function. Read moreiter_order_by
)Iterator
are lexicographically
+less than those of another. Read moreIterator
are lexicographically
+less or equal to those of another. Read moreIterator
are lexicographically
+greater than those of another. Read moreIterator
are lexicographically
+greater than or equal to those of another. Read moreis_sorted
)is_sorted
)pub struct LastMut<'a, T> { /* private fields */ }
Mutable and extendable reference to the last section.
+Push an element to the last section.
+use graph::Csr;
+let mut csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+csr.last_mut().push(42);
+assert_eq!(csr.section(1), &[4, 5, 42]);
Extend the last section with an iterator.
+use graph::Csr;
+let mut csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+csr.last_mut().extend(vec![42, 43]);
+assert_eq!(csr.section(1), &[4, 5, 42, 43]);
Copy elements from a slice to the last section.
+use graph::Csr;
+let mut csr = Csr::from_sections(&[vec![1, 2, 3], vec![4, 5]]);
+csr.last_mut().extend_from_slice(&[42, 43]);
+assert_eq!(csr.section(1), &[4, 5, 42, 43]);
Returns the number of elements in the slice.
+let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
Returns true
if the slice has a length of 0.
let a = [1, 2, 3];
+assert!(!a.is_empty());
Returns the first element of the slice, or None
if it is empty.
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
Returns a mutable pointer to the first element of the slice, or None
if it is empty.
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+ *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+ assert_eq!(first, &0);
+ assert_eq!(elements, &[1, 2]);
+}
Returns the first and all the rest of the elements of the slice, or None
if it is empty.
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+ *first = 3;
+ elements[0] = 4;
+ elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+ assert_eq!(last, &2);
+ assert_eq!(elements, &[0, 1]);
+}
Returns the last and all the rest of the elements of the slice, or None
if it is empty.
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+ *last = 3;
+ elements[0] = 4;
+ elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
Returns the last element of the slice, or None
if it is empty.
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
Returns a mutable pointer to the last item in the slice.
+let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+ *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
Returns a reference to an element or subslice depending on the type of +index.
+None
if out of bounds.None
if out of bounds.let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
Returns a reference to an element or subslice, without doing bounds +checking.
+For a safe alternative see get
.
Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.
+let x = &[1, 2, 4];
+
+unsafe {
+ assert_eq!(x.get_unchecked(1), &2);
+}
Returns a mutable reference to an element or subslice, without doing +bounds checking.
+For a safe alternative see get_mut
.
Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.
+let x = &mut [1, 2, 4];
+
+unsafe {
+ let elem = x.get_unchecked_mut(1);
+ *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
Returns a raw pointer to the slice’s buffer.
+The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.
+The caller must also ensure that the memory the pointer (non-transitively) points to
+is never written to (except inside an UnsafeCell
) using this pointer or any pointer
+derived from it. If you need to mutate the contents of the slice, use as_mut_ptr
.
Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.
+let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+ for i in 0..x.len() {
+ assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+ }
+}
Returns an unsafe mutable pointer to the slice’s buffer.
+The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.
+Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.
+let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+ for i in 0..x.len() {
+ *x_ptr.add(i) += 2;
+ }
+}
+assert_eq!(x, &[3, 4, 6]);
Returns the two raw pointers spanning the slice.
+The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.
+See as_ptr
for warnings on using these pointers. The end pointer
+requires extra caution, as it does not point to a valid element in the
+slice.
This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.
+It can also be useful to check if a pointer to an element refers to an +element of this slice:
+ +let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
Returns the two unsafe mutable pointers spanning the slice.
+The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.
+See as_mut_ptr
for warnings on using these pointers. The end
+pointer requires extra caution, as it does not point to a valid element
+in the slice.
This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.
+slice_swap_unchecked
)Swaps two elements in the slice, without doing bounds checking.
+For a safe alternative see swap
.
Calling this method with an out-of-bounds index is undefined behavior.
+The caller has to ensure that a < self.len()
and b < self.len()
.
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
Reverses the order of elements in the slice, in place.
+let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
Returns an iterator over the slice.
+The iterator yields all items from start to end.
+let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
Returns an iterator that allows modifying each value.
+The iterator yields all items from start to end.
+let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+ *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
Returns an iterator over all contiguous windows of length
+size
. The windows overlap. If the slice is shorter than
+size
, the iterator returns no values.
Panics if size
is 0.
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
If the slice is shorter than size
:
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
There’s no windows_mut
, as that existing would let safe code violate the
+“only one &mut
at a time to the same thing” rule. However, you can sometimes
+use Cell::as_slice_of_cells
in
+conjunction with windows
to accomplish something similar:
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+ Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
+slice, then the last chunk will not have length chunk_size
.
See chunks_exact
for a variant of this iterator that returns chunks of always exactly
+chunk_size
elements, and rchunks
for the same iterator but starting at the end of the
+slice.
Panics if chunk_size
is 0.
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+beginning of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
+length of the slice, then the last chunk will not have length chunk_size
.
See chunks_exact_mut
for a variant of this iterator that returns chunks of always
+exactly chunk_size
elements, and rchunks_mut
for the same iterator but starting at
+the end of the slice.
Panics if chunk_size
is 0.
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
+ }
+ count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+beginning of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
+slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved
+from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
+resulting code better than in the case of chunks
.
See chunks
for a variant of this iterator that also returns the remainder as a smaller
+chunk, and rchunks_exact
for the same iterator but starting at the end of the slice.
Panics if chunk_size
is 0.
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+beginning of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
+length of the slice, then the last up to chunk_size-1
elements will be omitted and can be
+retrieved from the into_remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
+resulting code better than in the case of chunks_mut
.
See chunks_mut
for a variant of this iterator that also returns the remainder as a
+smaller chunk, and rchunks_exact_mut
for the same iterator but starting at the end of
+the slice.
Panics if chunk_size
is 0.
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
+ }
+ count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
+assuming that there’s no remainder.
This may only be called when
+N
-element chunks (aka self.len() % N == 0
).N != 0
.#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+ // SAFETY: 1-element chunks never have remainder
+ unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+ // SAFETY: The slice length (6) is a multiple of 3
+ unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
+starting at the beginning of the slice,
+and a remainder slice with length strictly less than N
.
Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
If you expect the slice to be an exact multiple, you can combine
+let
-else
with an empty slice pattern:
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+ panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
+starting at the end of the slice,
+and a remainder slice with length strictly less than N
.
Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
array_chunks
)Returns an iterator over N
elements of the slice at a time, starting at the
+beginning of the slice.
The chunks are array references and do not overlap. If N
does not divide the
+length of the slice, then the last up to N-1
elements will be omitted and can be
+retrieved from the remainder
function of the iterator.
This method is the const generic equivalent of chunks_exact
.
Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
+assuming that there’s no remainder.
This may only be called when
+N
-element chunks (aka self.len() % N == 0
).N != 0
.#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+ // SAFETY: 1-element chunks never have remainder
+ unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+ // SAFETY: The slice length (6) is a multiple of 3
+ unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
+starting at the beginning of the slice,
+and a remainder slice with length strictly less than N
.
Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+ *chunk = [count; 2];
+ count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
slice_as_chunks
)Splits the slice into a slice of N
-element arrays,
+starting at the end of the slice,
+and a remainder slice with length strictly less than N
.
Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+ *chunk = [count; 2];
+ count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
array_chunks
)Returns an iterator over N
elements of the slice at a time, starting at the
+beginning of the slice.
The chunks are mutable array references and do not overlap. If N
does not divide
+the length of the slice, then the last up to N-1
elements will be omitted and
+can be retrieved from the into_remainder
function of the iterator.
This method is the const generic equivalent of chunks_exact_mut
.
Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+ *chunk = [count; 2];
+ count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
array_windows
)Returns an iterator over overlapping windows of N
elements of a slice,
+starting at the beginning of the slice.
This is the const generic equivalent of windows
.
If N
is greater than the size of the slice, it will return no windows.
Panics if N
is 0. This check will most probably get changed to a compile time
+error before this method gets stabilized.
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
+of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
+slice, then the last chunk will not have length chunk_size
.
See rchunks_exact
for a variant of this iterator that returns chunks of always exactly
+chunk_size
elements, and chunks
for the same iterator but starting at the beginning
+of the slice.
Panics if chunk_size
is 0.
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
+of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
+length of the slice, then the last chunk will not have length chunk_size
.
See rchunks_exact_mut
for a variant of this iterator that returns chunks of always
+exactly chunk_size
elements, and chunks_mut
for the same iterator but starting at the
+beginning of the slice.
Panics if chunk_size
is 0.
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
+ }
+ count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
Returns an iterator over chunk_size
elements of the slice at a time, starting at the
+end of the slice.
The chunks are slices and do not overlap. If chunk_size
does not divide the length of the
+slice, then the last up to chunk_size-1
elements will be omitted and can be retrieved
+from the remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
+resulting code better than in the case of rchunks
.
See rchunks
for a variant of this iterator that also returns the remainder as a smaller
+chunk, and chunks_exact
for the same iterator but starting at the beginning of the
+slice.
Panics if chunk_size
is 0.
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
Returns an iterator over chunk_size
elements of the slice at a time, starting at the end
+of the slice.
The chunks are mutable slices, and do not overlap. If chunk_size
does not divide the
+length of the slice, then the last up to chunk_size-1
elements will be omitted and can be
+retrieved from the into_remainder
function of the iterator.
Due to each chunk having exactly chunk_size
elements, the compiler can often optimize the
+resulting code better than in the case of chunks_mut
.
See rchunks_mut
for a variant of this iterator that also returns the remainder as a
+smaller chunk, and chunks_exact_mut
for the same iterator but starting at the beginning
+of the slice.
Panics if chunk_size
is 0.
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+ for elem in chunk.iter_mut() {
+ *elem += count;
+ }
+ count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
slice_group_by
)Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.
+The predicate is called on two elements following themselves,
+it means the predicate is called on slice[0]
and slice[1]
+then on slice[1]
and slice[2]
and so on.
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
This method can be used to extract the sorted subslices:
+ +#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
slice_group_by
)Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.
+The predicate is called on two elements following themselves,
+it means the predicate is called on slice[0]
and slice[1]
+then on slice[1]
and slice[2]
and so on.
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
This method can be used to extract the sorted subslices:
+ +#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
Divides one slice into two at an index.
+The first will contain all indices from [0, mid)
(excluding
+the index mid
itself) and the second will contain all
+indices from [mid, len)
(excluding the index len
itself).
Panics if mid > len
.
let v = [1, 2, 3, 4, 5, 6];
+
+{
+ let (left, right) = v.split_at(0);
+ assert_eq!(left, []);
+ assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+ let (left, right) = v.split_at(2);
+ assert_eq!(left, [1, 2]);
+ assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+ let (left, right) = v.split_at(6);
+ assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, []);
+}
Divides one mutable slice into two at an index.
+The first will contain all indices from [0, mid)
(excluding
+the index mid
itself) and the second will contain all
+indices from [mid, len)
(excluding the index len
itself).
Panics if mid > len
.
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
slice_split_at_unchecked
)Divides one slice into two at an index, without doing bounds checking.
+The first will contain all indices from [0, mid)
(excluding
+the index mid
itself) and the second will contain all
+indices from [mid, len)
(excluding the index len
itself).
For a safe alternative see split_at
.
Calling this method with an out-of-bounds index is undefined behavior
+even if the resulting reference is not used. The caller has to ensure that
+0 <= mid <= self.len()
.
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+ let (left, right) = v.split_at_unchecked(0);
+ assert_eq!(left, []);
+ assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+ let (left, right) = v.split_at_unchecked(2);
+ assert_eq!(left, [1, 2]);
+ assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+ let (left, right) = v.split_at_unchecked(6);
+ assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, []);
+}
slice_split_at_unchecked
)Divides one mutable slice into two at an index, without doing bounds checking.
+The first will contain all indices from [0, mid)
(excluding
+the index mid
itself) and the second will contain all
+indices from [mid, len)
(excluding the index len
itself).
For a safe alternative see split_at_mut
.
Calling this method with an out-of-bounds index is undefined behavior
+even if the resulting reference is not used. The caller has to ensure that
+0 <= mid <= self.len()
.
#![feature(slice_split_at_unchecked)]
+
+let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+ let (left, right) = v.split_at_mut_unchecked(2);
+ assert_eq!(left, [1, 0]);
+ assert_eq!(right, [3, 0, 5, 6]);
+ left[1] = 2;
+ right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
split_array
)Divides one slice into an array and a remainder slice at an index.
+The array will contain all indices from [0, N)
(excluding
+the index N
itself) and the slice will contain all
+indices from [N, len)
(excluding the index len
itself).
Panics if N > len
.
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+ let (left, right) = v.split_array_ref::<0>();
+ assert_eq!(left, &[]);
+ assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+ let (left, right) = v.split_array_ref::<2>();
+ assert_eq!(left, &[1, 2]);
+ assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+ let (left, right) = v.split_array_ref::<6>();
+ assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, []);
+}
split_array
)Divides one mutable slice into an array and a remainder slice at an index.
+The array will contain all indices from [0, N)
(excluding
+the index N
itself) and the slice will contain all
+indices from [N, len)
(excluding the index len
itself).
Panics if N > len
.
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.split_array_mut::<2>();
+assert_eq!(left, &mut [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
split_array
)Divides one slice into an array and a remainder slice at an index from +the end.
+The slice will contain all indices from [0, len - N)
(excluding
+the index len - N
itself) and the array will contain all
+indices from [len - N, len)
(excluding the index len
itself).
Panics if N > len
.
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+ let (left, right) = v.rsplit_array_ref::<0>();
+ assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+ assert_eq!(right, &[]);
+}
+
+{
+ let (left, right) = v.rsplit_array_ref::<2>();
+ assert_eq!(left, [1, 2, 3, 4]);
+ assert_eq!(right, &[5, 6]);
+}
+
+{
+ let (left, right) = v.rsplit_array_ref::<6>();
+ assert_eq!(left, []);
+ assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
split_array
)Divides one mutable slice into an array and a remainder slice at an +index from the end.
+The slice will contain all indices from [0, len - N)
(excluding
+the index N
itself) and the array will contain all
+indices from [len - N, len)
(excluding the index len
itself).
Panics if N > len
.
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.rsplit_array_mut::<4>();
+assert_eq!(left, [1, 0]);
+assert_eq!(right, &mut [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
Returns an iterator over subslices separated by elements that match
+pred
. The matched element is not contained in the subslices.
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:
+ +let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
If two matched elements are directly adjacent, an empty slice will be +present between them:
+ +let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
Returns an iterator over mutable subslices separated by elements that
+match pred
. The matched element is not contained in the subslices.
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+ group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
Returns an iterator over subslices separated by elements that match
+pred
. The matched element is contained in the end of the previous
+subslice as a terminator.
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.
+ +let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
Returns an iterator over mutable subslices separated by elements that
+match pred
. The matched element is contained in the previous
+subslice as a terminator.
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+ let terminator_idx = group.len()-1;
+ group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
Returns an iterator over subslices separated by elements that match
+pred
, starting at the end of the slice and working backwards.
+The matched element is not contained in the subslices.
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
As with split()
, if the first or last element is matched, an empty
+slice will be the first (or last) item returned by the iterator.
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
Returns an iterator over mutable subslices separated by elements that
+match pred
, starting at the end of the slice and working
+backwards. The matched element is not contained in the subslices.
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+ count += 1;
+ group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
Returns an iterator over subslices separated by elements that match
+pred
, limited to returning at most n
items. The matched element is
+not contained in the subslices.
The last element returned, if any, will contain the remainder of the +slice.
+Print the slice split once by numbers divisible by 3 (i.e., [10, 40]
,
+[20, 60, 50]
):
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+ println!("{group:?}");
+}
Returns an iterator over mutable subslices separated by elements that match
+pred
, limited to returning at most n
items. The matched element is
+not contained in the subslices.
The last element returned, if any, will contain the remainder of the +slice.
+let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+ group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
Returns an iterator over subslices separated by elements that match
+pred
limited to returning at most n
items. This starts at the end of
+the slice and works backwards. The matched element is not contained in
+the subslices.
The last element returned, if any, will contain the remainder of the +slice.
+Print the slice split once, starting from the end, by numbers divisible
+by 3 (i.e., [50]
, [10, 40, 30, 20]
):
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+ println!("{group:?}");
+}
Returns an iterator over subslices separated by elements that match
+pred
limited to returning at most n
items. This starts at the end of
+the slice and works backwards. The matched element is not contained in
+the subslices.
The last element returned, if any, will contain the remainder of the +slice.
+let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+ group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
Returns true
if the slice contains an element with the given value.
This operation is O(n).
+Note that if you have a sorted slice, binary_search
may be faster.
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
If you do not have a &T
, but some other value that you can compare
+with one (for example, String
implements PartialEq<str>
), you can
+use iter().any
:
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
Returns true
if needle
is a prefix of the slice.
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
Always returns true
if needle
is an empty slice:
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
Returns true
if needle
is a suffix of the slice.
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
Always returns true
if needle
is an empty slice:
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
Returns a subslice with the prefix removed.
+If the slice starts with prefix
, returns the subslice after the prefix, wrapped in Some
.
+If prefix
is empty, simply returns the original slice.
If the slice does not start with prefix
, returns None
.
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+ Some(b"llo".as_ref()));
Returns a subslice with the suffix removed.
+If the slice ends with suffix
, returns the subslice before the suffix, wrapped in Some
.
+If suffix
is empty, simply returns the original slice.
If the slice does not end with suffix
, returns None
.
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.
+If the value is found then Result::Ok
is returned, containing the
+index of the matching element. If there are multiple matches, then any
+one of the matches could be returned. The index is chosen
+deterministically, but is subject to change in future versions of Rust.
+If the value is not found then Result::Err
is returned, containing
+the index where a matching element could be inserted while maintaining
+sorted order.
See also binary_search_by
, binary_search_by_key
, and partition_point
.
Looks up a series of four elements. The first is found, with a
+uniquely determined position; the second and third are not
+found; the fourth could match any position in [1, 4]
.
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13), Ok(9));
+assert_eq!(s.binary_search(&4), Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
If you want to find that whole range of matching items, rather than
+an arbitrary matching one, that can be done using partition_point
:
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
If you want to insert an item to a sorted vector, while maintaining
+sort order, consider using partition_point
:
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
Binary searches this slice with a comparator function.
+The comparator function should return an order code that indicates
+whether its argument is Less
, Equal
or Greater
the desired
+target.
+If the slice is not sorted or if the comparator function does not
+implement an order consistent with the sort order of the underlying
+slice, the returned result is unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the
+index of the matching element. If there are multiple matches, then any
+one of the matches could be returned. The index is chosen
+deterministically, but is subject to change in future versions of Rust.
+If the value is not found then Result::Err
is returned, containing
+the index where a matching element could be inserted while maintaining
+sorted order.
See also binary_search
, binary_search_by_key
, and partition_point
.
Looks up a series of four elements. The first is found, with a
+uniquely determined position; the second and third are not
+found; the fourth could match any position in [1, 4]
.
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
Binary searches this slice with a key extraction function.
+Assumes that the slice is sorted by the key, for instance with
+sort_by_key
using the same key extraction function.
+If the slice is not sorted by the key, the returned result is
+unspecified and meaningless.
If the value is found then Result::Ok
is returned, containing the
+index of the matching element. If there are multiple matches, then any
+one of the matches could be returned. The index is chosen
+deterministically, but is subject to change in future versions of Rust.
+If the value is not found then Result::Err
is returned, containing
+the index where a matching element could be inserted while maintaining
+sorted order.
See also binary_search
, binary_search_by
, and partition_point
.
Looks up a series of four elements in a slice of pairs sorted by
+their second elements. The first is found, with a uniquely
+determined position; the second and third are not found; the
+fourth could match any position in [1, 4]
.
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+ (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+ (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b), Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b), Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
Sorts the slice, but might not preserve the order of equal elements.
+This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.
+The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.
+It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.
+let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
Sorts the slice with a comparator function, but might not preserve the order of equal +elements.
+This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.
+The comparator function must define a total ordering for the elements in the slice. If
+the ordering is not total, the order of the elements is unspecified. An order is a
+total order if it is (for all a
, b
and c
):
a < b
, a == b
or a > b
is true, anda < b
and b < c
implies a < c
. The same must hold for both ==
and >
.For example, while f64
doesn’t implement Ord
because NaN != NaN
, we can use
+partial_cmp
as our sort function when we know the slice doesn’t contain a NaN
.
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.
+It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.
+let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.
+This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).
+The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.
+Due to its key calling strategy, sort_unstable_by_key
+is likely to be slower than sort_by_cached_key
in
+cases where the key function is expensive.
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
Reorder the slice such that the element at index
is at its final sorted position.
This reordering has the additional property that any value at position i < index
will be
+less than or equal to any value at a position j > index
. Additionally, this reordering is
+unstable (i.e. any number of equal elements may end up at position index
), in-place
+(i.e. does not allocate), and O(n) on average. The worst-case performance is O(n log n).
+This function is also known as “kth element” in other libraries.
It returns a triplet of the following from the reordered slice:
+the subslice prior to index
, the element at index
, and the subslice after index
;
+accordingly, the values in those two subslices will respectively all be less-than-or-equal-to
+and greater-than-or-equal-to the value of the element at index
.
The current algorithm is based on the quickselect portion of the same quicksort algorithm
+used for sort_unstable
.
Panics when index >= len()
, meaning it always panics on empty slices.
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median
+v.select_nth_unstable(2);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+ v == [-5, -3, 1, 2, 4] ||
+ v == [-3, -5, 1, 4, 2] ||
+ v == [-5, -3, 1, 4, 2]);
Reorder the slice with a comparator function such that the element at index
is at its
+final sorted position.
This reordering has the additional property that any value at position i < index
will be
+less than or equal to any value at a position j > index
using the comparator function.
+Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
+position index
), in-place (i.e. does not allocate), and O(n) on average.
+The worst-case performance is O(n log n). This function is also known as
+“kth element” in other libraries.
It returns a triplet of the following from
+the slice reordered according to the provided comparator function: the subslice prior to
+index
, the element at index
, and the subslice after index
; accordingly, the values in
+those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to
+the value of the element at index
.
The current algorithm is based on the quickselect portion of the same quicksort algorithm
+used for sort_unstable
.
Panics when index >= len()
, meaning it always panics on empty slices.
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median as if the slice were sorted in descending order.
+v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+ v == [2, 4, 1, -3, -5] ||
+ v == [4, 2, 1, -5, -3] ||
+ v == [4, 2, 1, -3, -5]);
Reorder the slice with a key extraction function such that the element at index
is at its
+final sorted position.
This reordering has the additional property that any value at position i < index
will be
+less than or equal to any value at a position j > index
using the key extraction function.
+Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
+position index
), in-place (i.e. does not allocate), and O(n) on average.
+The worst-case performance is O(n log n).
+This function is also known as “kth element” in other libraries.
It returns a triplet of the following from
+the slice reordered according to the provided key extraction function: the subslice prior to
+index
, the element at index
, and the subslice after index
; accordingly, the values in
+those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to
+the value of the element at index
.
The current algorithm is based on the quickselect portion of the same quicksort algorithm
+used for sort_unstable
.
Panics when index >= len()
, meaning it always panics on empty slices.
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Return the median as if the array were sorted according to absolute value.
+v.select_nth_unstable_by_key(2, |a| a.abs());
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+ v == [1, 2, -3, -5, 4] ||
+ v == [2, 1, -3, 4, -5] ||
+ v == [2, 1, -3, -5, 4]);
slice_partition_dedup
)Moves all consecutive repeated elements to the end of the slice according to the
+PartialEq
trait implementation.
Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.
+If the slice is sorted, the first returned slice contains no duplicates.
+#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
slice_partition_dedup
)Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.
+Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.
+The same_bucket
function is passed references to two elements from the slice and
+must determine if the elements compare equal. The elements are passed in opposite order
+from their order in the slice, so if same_bucket(a, b)
returns true
, a
is moved
+at the end of the slice.
If the slice is sorted, the first returned slice contains no duplicates.
+#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
slice_partition_dedup
)Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.
+Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.
+If the slice is sorted, the first returned slice contains no duplicates.
+#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
Rotates the slice in-place such that the first mid
elements of the
+slice move to the end while the last self.len() - mid
elements move to
+the front. After calling rotate_left
, the element previously at index
+mid
will become the first element in the slice.
This function will panic if mid
is greater than the length of the
+slice. Note that mid == self.len()
does not panic and is a no-op
+rotation.
Takes linear (in self.len()
) time.
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
Rotating a subslice:
+ +let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
Rotates the slice in-place such that the first self.len() - k
+elements of the slice move to the end while the last k
elements move
+to the front. After calling rotate_right
, the element previously at
+index self.len() - k
will become the first element in the slice.
This function will panic if k
is greater than the length of the
+slice. Note that k == self.len()
does not panic and is a no-op
+rotation.
Takes linear (in self.len()
) time.
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
Rotate a subslice:
+ +let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
Fills self
with elements by cloning value
.
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
Fills self
with elements returned by calling a closure repeatedly.
This method uses a closure to create new values. If you’d rather
+Clone
a given value, use fill
. If you want to use the Default
+trait to generate values, you can pass Default::default
as the
+argument.
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
Copies the elements from src
into self
.
The length of src
must be the same as self
.
This function will panic if the two slices have different lengths.
+Cloning two elements from a slice into another:
+ +let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
Rust enforces that there can only be one mutable reference with no
+immutable references to a particular piece of data in a particular
+scope. Because of this, attempting to use clone_from_slice
on a
+single slice will result in a compile failure:
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
To work around this, we can use split_at_mut
to create two distinct
+sub-slices from a slice:
let mut slice = [1, 2, 3, 4, 5];
+
+{
+ let (left, right) = slice.split_at_mut(2);
+ left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
Copies all elements from src
into self
, using a memcpy.
The length of src
must be the same as self
.
If T
does not implement Copy
, use clone_from_slice
.
This function will panic if the two slices have different lengths.
+Copying two elements from a slice into another:
+ +let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
Rust enforces that there can only be one mutable reference with no
+immutable references to a particular piece of data in a particular
+scope. Because of this, attempting to use copy_from_slice
on a
+single slice will result in a compile failure:
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
To work around this, we can use split_at_mut
to create two distinct
+sub-slices from a slice:
let mut slice = [1, 2, 3, 4, 5];
+
+{
+ let (left, right) = slice.split_at_mut(2);
+ left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
Copies elements from one part of the slice to another part of itself, +using a memmove.
+src
is the range within self
to copy from. dest
is the starting
+index of the range within self
to copy to, which will have the same
+length as src
. The two ranges may overlap. The ends of the two ranges
+must be less than or equal to self.len()
.
This function will panic if either range exceeds the end of the slice,
+or if the end of src
is before the start.
Copying four bytes within a slice:
+ +let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
Swaps all elements in self
with those in other
.
The length of other
must be the same as self
.
This function will panic if the two slices have different lengths.
+Swapping two elements across slices:
+ +let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
Rust enforces that there can only be one mutable reference to a
+particular piece of data in a particular scope. Because of this,
+attempting to use swap_with_slice
on a single slice will result in
+a compile failure:
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
To work around this, we can use split_at_mut
to create two distinct
+mutable sub-slices from a slice:
let mut slice = [1, 2, 3, 4, 5];
+
+{
+ let (left, right) = slice.split_at_mut(2);
+ left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.
+This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.
+This method has no purpose when either input element T
or output element U
are
+zero-sized and will return the original slice without splitting anything.
This method is essentially a transmute
with respect to the elements in the returned
+middle slice, so all the usual caveats pertaining to transmute::<T, U>
also apply here.
Basic usage:
+ +unsafe {
+ let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+ let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+ // less_efficient_algorithm_for_bytes(prefix);
+ // more_efficient_algorithm_for_aligned_shorts(shorts);
+ // less_efficient_algorithm_for_bytes(suffix);
+}
Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.
+This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.
+This method has no purpose when either input element T
or output element U
are
+zero-sized and will return the original slice without splitting anything.
This method is essentially a transmute
with respect to the elements in the returned
+middle slice, so all the usual caveats pertaining to transmute::<T, U>
also apply here.
Basic usage:
+ +unsafe {
+ let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+ let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+ // less_efficient_algorithm_for_bytes(prefix);
+ // more_efficient_algorithm_for_aligned_shorts(shorts);
+ // less_efficient_algorithm_for_bytes(suffix);
+}
portable_simd
)Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.
+This is a safe wrapper around slice::align_to
, so has the same weak
+postconditions as that method. You’re only assured that
+self.len() == prefix.len() + middle.len() * LANES + suffix.len()
.
Notably, all of the following are possible:
+prefix.len() >= LANES
.middle.is_empty()
despite self.len() >= 3 * LANES
.suffix.len() >= LANES
.That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.
+This will panic if the size of the SIMD type is different from
+LANES
times that of the scalar.
At the time of writing, the trait restrictions on Simd<T, LANES>
keeps
+that from ever happening, as only power-of-two numbers of lanes are
+supported. It’s possible that, in the future, those restrictions might
+be lifted in a way that would make it possible to see panics from this
+method for something like LANES == 3
.
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+ use std::ops::Add;
+ use std::simd::f32x4;
+ let (prefix, middle, suffix) = x.as_simd();
+ let sums = f32x4::from_array([
+ prefix.iter().copied().sum(),
+ 0.0,
+ 0.0,
+ suffix.iter().copied().sum(),
+ ]);
+ let sums = middle.iter().copied().fold(sums, f32x4::add);
+ sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
portable_simd
)Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.
+This is a safe wrapper around slice::align_to_mut
, so has the same weak
+postconditions as that method. You’re only assured that
+self.len() == prefix.len() + middle.len() * LANES + suffix.len()
.
Notably, all of the following are possible:
+prefix.len() >= LANES
.middle.is_empty()
despite self.len() >= 3 * LANES
.suffix.len() >= LANES
.That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.
+This is the mutable version of slice::as_simd
; see that for examples.
This will panic if the size of the SIMD type is different from
+LANES
times that of the scalar.
At the time of writing, the trait restrictions on Simd<T, LANES>
keeps
+that from ever happening, as only power-of-two numbers of lanes are
+supported. It’s possible that, in the future, those restrictions might
+be lifted in a way that would make it possible to see panics from this
+method for something like LANES == 3
.
is_sorted
)Checks if the elements of this slice are sorted.
+That is, for each element a
and its following element b
, a <= b
must hold. If the
+slice yields exactly zero or one element, true
is returned.
Note that if Self::Item
is only PartialOrd
, but not Ord
, the above definition
+implies that this function returns false
if any two consecutive items are not
+comparable.
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
is_sorted
)Checks if the elements of this slice are sorted using the given comparator function.
+Instead of using PartialOrd::partial_cmp
, this function uses the given compare
+function to determine the ordering of two elements. Apart from that, it’s equivalent to
+is_sorted
; see its documentation for more information.
is_sorted
)Checks if the elements of this slice are sorted using the given key extraction function.
+Instead of comparing the slice’s elements directly, this function compares the keys of the
+elements, as determined by f
. Apart from that, it’s equivalent to is_sorted
; see its
+documentation for more information.
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).
+The slice is assumed to be partitioned according to the given predicate.
+This means that all elements for which the predicate returns true are at the start of the slice
+and all elements for which the predicate returns false are at the end.
+For example, [7, 15, 3, 5, 4, 12, 6]
is partitioned under the predicate x % 2 != 0
+(all odd numbers are at the start, all even at the end).
If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.
+See also binary_search
, binary_search_by
, and binary_search_by_key
.
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:
+ +let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
If you want to insert an item to a sorted vector, while maintaining +sort order:
+ +let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
slice_take
)Removes the subslice corresponding to the given range +and returns a reference to it.
+Returns None
and does not modify the slice if the given
+range is out of bounds.
Note that this method only accepts one-sided ranges such as
+2..
or ..6
, but not 2..6
.
Taking the first three elements of a slice:
+ +#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
Taking the last two elements of a slice:
+ +#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
Getting None
when range
is out of bounds:
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
slice_take
)Removes the subslice corresponding to the given range +and returns a mutable reference to it.
+Returns None
and does not modify the slice if the given
+range is out of bounds.
Note that this method only accepts one-sided ranges such as
+2..
or ..6
, but not 2..6
.
Taking the first three elements of a slice:
+ +#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
Taking the last two elements of a slice:
+ +#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
Getting None
when range
is out of bounds:
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
slice_take
)Removes the first element of the slice and returns a reference +to it.
+Returns None
if the slice is empty.
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
slice_take
)Removes the first element of the slice and returns a mutable +reference to it.
+Returns None
if the slice is empty.
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
slice_take
)Removes the last element of the slice and returns a reference +to it.
+Returns None
if the slice is empty.
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
slice_take
)Removes the last element of the slice and returns a mutable +reference to it.
+Returns None
if the slice is empty.
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
get_many_mut
)Returns mutable references to many indices at once, without doing any checks.
+For a safe alternative see get_many_mut
.
Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.
+#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+ let [a, b] = x.get_many_unchecked_mut([0, 2]);
+ *a *= 10;
+ *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
get_many_mut
)Returns mutable references to many indices at once.
+Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.
+#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+ *a = 413;
+ *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
sort_floats
)Sorts the slice of floats.
+This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses
+the ordering defined by f64::total_cmp
.
This uses the same sorting algorithm as sort_unstable_by
.
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
slice_flatten
)Takes a &[[T; N]]
, and flattens it to a &[T]
.
This panics if the length of the resulting slice would overflow a usize
.
This is only possible when flattening a slice of arrays of zero-sized
+types, and thus tends to be irrelevant in practice. If
+size_of::<T>() > 0
, this will never panic.
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+ [[1, 2, 3], [4, 5, 6]].flatten(),
+ [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
slice_flatten
)Takes a &mut [[T; N]]
, and flattens it to a &mut [T]
.
This panics if the length of the resulting slice would overflow a usize
.
This is only possible when flattening a slice of arrays of zero-sized
+types, and thus tends to be irrelevant in practice. If
+size_of::<T>() > 0
, this will never panic.
#![feature(slice_flatten)]
+
+fn add_5_to_all(slice: &mut [i32]) {
+ for i in slice {
+ *i += 5;
+ }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.flatten_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
Checks if all bytes in this slice are within the ASCII range.
+Checks that two slices are an ASCII case-insensitive match.
+Same as to_ascii_lowercase(a) == to_ascii_lowercase(b)
,
+but without allocating and copying temporaries.
Converts this slice to its ASCII upper case equivalent in-place.
+ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.
+To return a new uppercased value without modifying the existing one, use
+to_ascii_uppercase
.
Converts this slice to its ASCII lower case equivalent in-place.
+ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.
+To return a new lowercased value without modifying the existing one, use
+to_ascii_lowercase
.
Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.
+
+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
byte_slice_trim_ascii
)Returns a byte slice with leading ASCII whitespace bytes removed.
+‘Whitespace’ refers to the definition used by
+u8::is_ascii_whitespace
.
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b" ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
byte_slice_trim_ascii
)Returns a byte slice with trailing ASCII whitespace bytes removed.
+‘Whitespace’ refers to the definition used by
+u8::is_ascii_whitespace
.
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b" ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
byte_slice_trim_ascii
)Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.
+‘Whitespace’ refers to the definition used by
+u8::is_ascii_whitespace
.
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b" ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
sort_floats
)Sorts the slice of floats.
+This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses
+the ordering defined by f32::total_cmp
.
This uses the same sorting algorithm as sort_unstable_by
.
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
Sorts the slice.
+This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.
+When applicable, unstable sorting is preferred because it is generally faster than stable
+sorting and it doesn’t allocate auxiliary memory.
+See sort_unstable
.
The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.
+Also, it allocates temporary storage half the size of self
, but for short slices a
+non-allocating insertion sort is used instead.
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
Sorts the slice with a comparator function.
+This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.
+The comparator function must define a total ordering for the elements in the slice. If
+the ordering is not total, the order of the elements is unspecified. An order is a
+total order if it is (for all a
, b
and c
):
a < b
, a == b
or a > b
is true, anda < b
and b < c
implies a < c
. The same must hold for both ==
and >
.For example, while f64
doesn’t implement Ord
because NaN != NaN
, we can use
+partial_cmp
as our sort function when we know the slice doesn’t contain a NaN
.
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
When applicable, unstable sorting is preferred because it is generally faster than stable
+sorting and it doesn’t allocate auxiliary memory.
+See sort_unstable_by
.
The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.
+Also, it allocates temporary storage half the size of self
, but for short slices a
+non-allocating insertion sort is used instead.
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
Sorts the slice with a key extraction function.
+This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).
+For expensive key functions (e.g. functions that are not simple property accesses or
+basic operations), sort_by_cached_key
is likely to be
+significantly faster, as it does not recompute element keys.
When applicable, unstable sorting is preferred because it is generally faster than stable
+sorting and it doesn’t allocate auxiliary memory.
+See sort_unstable_by_key
.
The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.
+Also, it allocates temporary storage half the size of self
, but for short slices a
+non-allocating insertion sort is used instead.
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
Sorts the slice with a key extraction function.
+During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.
+This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).
+For simple key functions (e.g., functions that are property accesses or
+basic operations), sort_by_key
is likely to be
+faster.
The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.
+In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)>
the
+length of the slice.
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
Copies self
into a new Vec
.
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
allocator_api
)Copies self
into a new Vec
with an allocator.
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
Flattens a slice of T
into a single value Self::Output
.
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
Flattens a slice of T
into a single value Self::Output
, placing a
+given separator between each.
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
Flattens a slice of T
into a single value Self::Output
, placing a
+given separator between each.
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.
+ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.
+To uppercase the value in-place, use make_ascii_uppercase
.
Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.
+ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.
+To lowercase the value in-place, use make_ascii_lowercase
.
pub fn i2powm1<T: Unsigned>(n: u32) -> T
Returns $2^n - 1$.
+pub fn i2powm1<T: Unsigned>(n: u32) -> T
Returns $2^n - 1$.
use crate::i2powm1;
+use riff::i2powm1;
assert_eq!(i2powm1::<u32>(0), 0);
assert_eq!(i2powm1::<u32>(1), 1);
assert_eq!(i2powm1::<u32>(2), 3);
-assert_eq!(i2powm1::<u32>(3), 7);
+assert_eq!(i2powm1::<u32>(3), 7);
+assert_eq!(i2powm1::<u32>(31), 0x7FFF_FFFF);
+assert_eq!(i2powm1::<u32>(32), 0xFFFF_FFFF);