Skip to content

Commit d118cd0

Browse files
committed
Added needle methods for slices
1 parent a10c43a commit d118cd0

File tree

4 files changed

+403
-1
lines changed

4 files changed

+403
-1
lines changed

src/liballoc/slice.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ use core::cmp::Ordering::{self, Less};
9292
use core::mem::{self, size_of};
9393
use core::ptr;
9494
use core::{u8, u16, u32};
95+
use core::needle::{ext, Needle, Searcher, Consumer};
9596

9697
use crate::borrow::ToOwned;
9798
use crate::boxed::Box;
@@ -485,6 +486,40 @@ impl<T> [T] {
485486
}
486487
buf
487488
}
489+
490+
/// Replaces all matches of a predicate with another slice.
491+
#[unstable(feature = "slice_needle_methods", issue = "56345")]
492+
#[inline]
493+
#[must_use = "this returns the replaced slice as a new allocation, \
494+
without modifying the original"]
495+
pub fn replace<'s: 'a, 'a, F>(&'s self, from: F, to: &'a [T]) -> Vec<T>
496+
where
497+
T: Clone,
498+
F: Needle<&'a [T]>,
499+
F::Searcher: Searcher<[T]>, // FIXME: RFC 2089
500+
F::Consumer: Consumer<[T]>, // FIXME: RFC 2089
501+
{
502+
let mut result = Vec::with_capacity(self.len());
503+
ext::replace_with(self, from, |_| to, |s| result.extend_from_slice(s));
504+
result
505+
}
506+
507+
/// Replaces first N matches of a predicate with another slice.
508+
#[unstable(feature = "slice_needle_methods", issue = "56345")]
509+
#[inline]
510+
#[must_use = "this returns the replaced slice as a new allocation, \
511+
without modifying the original"]
512+
pub fn replacen<'s: 'a, 'a, F>(&'s self, from: F, to: &'a [T], count: usize) -> Vec<T>
513+
where
514+
T: Clone,
515+
F: Needle<&'a [T]>,
516+
F::Searcher: Searcher<[T]>, // FIXME: RFC 2089
517+
F::Consumer: Consumer<[T]>, // FIXME: RFC 2089
518+
{
519+
let mut result = Vec::with_capacity(self.len());
520+
ext::replacen_with(self, from, |_| to, count, |s| result.extend_from_slice(s));
521+
result
522+
}
488523
}
489524

490525
#[lang = "slice_u8_alloc"]

src/liballoc/tests/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#![feature(unboxed_closures)]
1111
#![feature(vecdeque_rotate)]
1212
#![feature(mut_str_needle_methods)]
13+
#![feature(slice_needle_methods)]
1314

1415
use std::hash::{Hash, Hasher};
1516
use std::collections::hash_map::DefaultHasher;

src/liballoc/tests/slice.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::panic;
55
use std::rc::Rc;
66
use std::sync::atomic::{Ordering::Relaxed, AtomicUsize};
77
use std::thread;
8+
use std::f64::NAN;
89

910
use rand::{Rng, RngCore, thread_rng};
1011
use rand::seq::SliceRandom;
@@ -1655,3 +1656,60 @@ fn repeat_generic_slice() {
16551656
vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
16561657
);
16571658
}
1659+
1660+
#[test]
1661+
fn test_match_indices_simple() {
1662+
let haystack = &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 2.0, 3.0, 2.0, 4.0, 8.0][..];
1663+
let needle = &[2.0, 3.0][..];
1664+
1665+
assert_eq!(haystack.match_indices(needle).collect::<Vec<_>>(), vec![
1666+
(1, needle),
1667+
(8, needle),
1668+
]);
1669+
}
1670+
1671+
#[test]
1672+
fn test_match_indices_nan_haystack() {
1673+
let haystack = &[1.0, 2.0, NAN, 1.0, 2.0, NAN, 1.0, NAN, NAN, NAN, 2.0, 1.0, 2.0][..];
1674+
let needle = &[1.0, 2.0][..];
1675+
1676+
assert_eq!(haystack.match_indices(needle).collect::<Vec<_>>(), vec![
1677+
(0, needle),
1678+
(3, needle),
1679+
(11, needle),
1680+
]);
1681+
}
1682+
1683+
#[test]
1684+
fn test_match_indices_nan_needle() {
1685+
let haystack = &[1.0, 2.0, NAN, 1.0, 2.0, NAN, 1.0, NAN, NAN, NAN, 2.0, 1.0, 2.0][..];
1686+
let needle = &[1.0, 2.0][..];
1687+
1688+
assert_eq!(haystack.match_indices(needle).collect::<Vec<_>>(), vec![
1689+
(0, needle),
1690+
(3, needle),
1691+
(11, needle),
1692+
]);
1693+
}
1694+
1695+
#[test]
1696+
fn test_match_indices_negative_zero() {
1697+
let haystack = &[1.0, 2.0, NAN, 1.0, 2.0, NAN, 1.0, NAN, NAN, NAN, 2.0, 1.0, 2.0][..];
1698+
let needle = &[1.0, 2.0][..];
1699+
1700+
assert_eq!(haystack.match_indices(needle).collect::<Vec<_>>(), vec![
1701+
(0, needle),
1702+
(3, needle),
1703+
(11, needle),
1704+
]);
1705+
}
1706+
1707+
#[test]
1708+
fn test_replace() {
1709+
let haystack = &b" empowering everyone to build reliable and efficient software."[..];
1710+
1711+
assert_eq!(
1712+
haystack.replace(&b" e"[..], b" **E**"),
1713+
b" **E**mpowering **E**veryone to build reliable and **E**fficient software.".to_vec()
1714+
);
1715+
}

0 commit comments

Comments
 (0)