Skip to content

Commit 38c99d2

Browse files
committedApr 24, 2017
Auto merge of #41503 - frewsxcv:rollup, r=frewsxcv
Rollup of 3 pull requests - Successful merges: #40434, #41370, #41500 - Failed merges:
2 parents 63c7721 + 71dfeb1 commit 38c99d2

File tree

9 files changed

+452
-15
lines changed

9 files changed

+452
-15
lines changed
 

‎src/bootstrap/bootstrap.py

+16-6
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,11 @@ def build_triple(self):
407407
# The goal here is to come up with the same triple as LLVM would,
408408
# at least for the subset of platforms we're willing to target.
409409
if ostype == 'Linux':
410-
ostype = 'unknown-linux-gnu'
410+
os = subprocess.check_output(['uname', '-o']).strip().decode(default_encoding)
411+
if os == 'Android':
412+
ostype = 'linux-android'
413+
else:
414+
ostype = 'unknown-linux-gnu'
411415
elif ostype == 'FreeBSD':
412416
ostype = 'unknown-freebsd'
413417
elif ostype == 'DragonFly':
@@ -464,15 +468,21 @@ def build_triple(self):
464468
cputype = 'i686'
465469
elif cputype in {'xscale', 'arm'}:
466470
cputype = 'arm'
471+
if ostype == 'linux-android':
472+
ostype = 'linux-androideabi'
467473
elif cputype == 'armv6l':
468474
cputype = 'arm'
469-
ostype += 'eabihf'
475+
if ostype == 'linux-android':
476+
ostype = 'linux-androideabi'
477+
else:
478+
ostype += 'eabihf'
470479
elif cputype in {'armv7l', 'armv8l'}:
471480
cputype = 'armv7'
472-
ostype += 'eabihf'
473-
elif cputype == 'aarch64':
474-
cputype = 'aarch64'
475-
elif cputype == 'arm64':
481+
if ostype == 'linux-android':
482+
ostype = 'linux-androideabi'
483+
else:
484+
ostype += 'eabihf'
485+
elif cputype in {'aarch64', 'arm64'}:
476486
cputype = 'aarch64'
477487
elif cputype == 'mips':
478488
if sys.byteorder == 'big':

‎src/doc/unstable-book/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@
195195
- [slice_rsplit](library-features/slice-rsplit.md)
196196
- [sort_internals](library-features/sort-internals.md)
197197
- [sort_unstable](library-features/sort-unstable.md)
198+
- [splice](library-features/splice.md)
198199
- [step_by](library-features/step-by.md)
199200
- [step_trait](library-features/step-trait.md)
200201
- [str_checked_slicing](library-features/str-checked-slicing.md)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# `splice`
2+
3+
The tracking issue for this feature is: [#32310]
4+
5+
[#32310]: https://github.com/rust-lang/rust/issues/32310
6+
7+
------------------------
8+
9+
The `splice()` method on `Vec` and `String` allows you to replace a range
10+
of values in a vector or string with another range of values, and returns
11+
the replaced values.
12+
13+
A simple example:
14+
15+
```rust
16+
#![feature(splice)]
17+
let mut s = String::from("α is alpha, β is beta");
18+
let beta_offset = s.find('β').unwrap_or(s.len());
19+
20+
// Replace the range up until the β from the string
21+
let t: String = s.splice(..beta_offset, "Α is capital alpha; ").collect();
22+
assert_eq!(t, "α is alpha, ");
23+
assert_eq!(s, "Α is capital alpha; β is beta");
24+
```

‎src/libcollections/slice.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -1519,13 +1519,9 @@ impl<T: Clone> ToOwned for [T] {
15191519
self.to_vec()
15201520
}
15211521

1522-
// HACK(japaric): with cfg(test) the inherent `[T]::to_vec`, which is required for this method
1523-
// definition, is not available. Since we don't require this method for testing purposes, I'll
1524-
// just stub it
1525-
// NB see the slice::hack module in slice.rs for more information
15261522
#[cfg(test)]
15271523
fn to_owned(&self) -> Vec<T> {
1528-
panic!("not available with cfg(test)")
1524+
hack::to_vec(self)
15291525
}
15301526

15311527
fn clone_into(&self, target: &mut Vec<T>) {

‎src/libcollections/string.rs

+124-1
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ impl String {
13161316
self.vec.clear()
13171317
}
13181318

1319-
/// Create a draining iterator that removes the specified range in the string
1319+
/// Creates a draining iterator that removes the specified range in the string
13201320
/// and yields the removed chars.
13211321
///
13221322
/// Note: The element range is removed even if the iterator is not
@@ -1382,6 +1382,71 @@ impl String {
13821382
}
13831383
}
13841384

1385+
/// Creates a splicing iterator that removes the specified range in the string,
1386+
/// replaces with the given string, and yields the removed chars.
1387+
/// The given string doesn’t need to be the same length as the range.
1388+
///
1389+
/// Note: The element range is removed when the `Splice` is dropped,
1390+
/// even if the iterator is not consumed until the end.
1391+
///
1392+
/// # Panics
1393+
///
1394+
/// Panics if the starting point or end point do not lie on a [`char`]
1395+
/// boundary, or if they're out of bounds.
1396+
///
1397+
/// [`char`]: ../../std/primitive.char.html
1398+
///
1399+
/// # Examples
1400+
///
1401+
/// Basic usage:
1402+
///
1403+
/// ```
1404+
/// #![feature(splice)]
1405+
/// let mut s = String::from("α is alpha, β is beta");
1406+
/// let beta_offset = s.find('β').unwrap_or(s.len());
1407+
///
1408+
/// // Replace the range up until the β from the string
1409+
/// let t: String = s.splice(..beta_offset, "Α is capital alpha; ").collect();
1410+
/// assert_eq!(t, "α is alpha, ");
1411+
/// assert_eq!(s, "Α is capital alpha; β is beta");
1412+
/// ```
1413+
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
1414+
pub fn splice<'a, 'b, R>(&'a mut self, range: R, replace_with: &'b str) -> Splice<'a, 'b>
1415+
where R: RangeArgument<usize>
1416+
{
1417+
// Memory safety
1418+
//
1419+
// The String version of Splice does not have the memory safety issues
1420+
// of the vector version. The data is just plain bytes.
1421+
// Because the range removal happens in Drop, if the Splice iterator is leaked,
1422+
// the removal will not happen.
1423+
let len = self.len();
1424+
let start = match range.start() {
1425+
Included(&n) => n,
1426+
Excluded(&n) => n + 1,
1427+
Unbounded => 0,
1428+
};
1429+
let end = match range.end() {
1430+
Included(&n) => n + 1,
1431+
Excluded(&n) => n,
1432+
Unbounded => len,
1433+
};
1434+
1435+
// Take out two simultaneous borrows. The &mut String won't be accessed
1436+
// until iteration is over, in Drop.
1437+
let self_ptr = self as *mut _;
1438+
// slicing does the appropriate bounds checks
1439+
let chars_iter = self[start..end].chars();
1440+
1441+
Splice {
1442+
start: start,
1443+
end: end,
1444+
iter: chars_iter,
1445+
string: self_ptr,
1446+
replace_with: replace_with
1447+
}
1448+
}
1449+
13851450
/// Converts this `String` into a `Box<str>`.
13861451
///
13871452
/// This will drop any excess capacity.
@@ -2145,3 +2210,61 @@ impl<'a> DoubleEndedIterator for Drain<'a> {
21452210

21462211
#[unstable(feature = "fused", issue = "35602")]
21472212
impl<'a> FusedIterator for Drain<'a> {}
2213+
2214+
/// A splicing iterator for `String`.
2215+
///
2216+
/// This struct is created by the [`splice()`] method on [`String`]. See its
2217+
/// documentation for more.
2218+
///
2219+
/// [`splice()`]: struct.String.html#method.splice
2220+
/// [`String`]: struct.String.html
2221+
#[derive(Debug)]
2222+
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
2223+
pub struct Splice<'a, 'b> {
2224+
/// Will be used as &'a mut String in the destructor
2225+
string: *mut String,
2226+
/// Start of part to remove
2227+
start: usize,
2228+
/// End of part to remove
2229+
end: usize,
2230+
/// Current remaining range to remove
2231+
iter: Chars<'a>,
2232+
replace_with: &'b str,
2233+
}
2234+
2235+
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
2236+
unsafe impl<'a, 'b> Sync for Splice<'a, 'b> {}
2237+
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
2238+
unsafe impl<'a, 'b> Send for Splice<'a, 'b> {}
2239+
2240+
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
2241+
impl<'a, 'b> Drop for Splice<'a, 'b> {
2242+
fn drop(&mut self) {
2243+
unsafe {
2244+
let vec = (*self.string).as_mut_vec();
2245+
vec.splice(self.start..self.end, self.replace_with.bytes());
2246+
}
2247+
}
2248+
}
2249+
2250+
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
2251+
impl<'a, 'b> Iterator for Splice<'a, 'b> {
2252+
type Item = char;
2253+
2254+
#[inline]
2255+
fn next(&mut self) -> Option<char> {
2256+
self.iter.next()
2257+
}
2258+
2259+
fn size_hint(&self) -> (usize, Option<usize>) {
2260+
self.iter.size_hint()
2261+
}
2262+
}
2263+
2264+
#[unstable(feature = "splice", reason = "recently added", issue = "32310")]
2265+
impl<'a, 'b> DoubleEndedIterator for Splice<'a, 'b> {
2266+
#[inline]
2267+
fn next_back(&mut self) -> Option<char> {
2268+
self.iter.next_back()
2269+
}
2270+
}

‎src/libcollections/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#![feature(pattern)]
2121
#![feature(placement_in_syntax)]
2222
#![feature(rand)]
23+
#![feature(splice)]
2324
#![feature(step_by)]
2425
#![feature(str_escape)]
2526
#![feature(test)]

‎src/libcollections/tests/string.rs

+56
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,62 @@ fn test_drain() {
419419
assert_eq!(t, "");
420420
}
421421

422+
#[test]
423+
fn test_splice() {
424+
let mut s = "Hello, world!".to_owned();
425+
let t: String = s.splice(7..12, "世界").collect();
426+
assert_eq!(s, "Hello, 世界!");
427+
assert_eq!(t, "world");
428+
}
429+
430+
#[test]
431+
#[should_panic]
432+
fn test_splice_char_boundary() {
433+
let mut s = "Hello, 世界!".to_owned();
434+
s.splice(..8, "");
435+
}
436+
437+
#[test]
438+
fn test_splice_inclusive_range() {
439+
let mut v = String::from("12345");
440+
let t: String = v.splice(2...3, "789").collect();
441+
assert_eq!(v, "127895");
442+
assert_eq!(t, "34");
443+
let t2: String = v.splice(1...2, "A").collect();
444+
assert_eq!(v, "1A895");
445+
assert_eq!(t2, "27");
446+
}
447+
448+
#[test]
449+
#[should_panic]
450+
fn test_splice_out_of_bounds() {
451+
let mut s = String::from("12345");
452+
s.splice(5..6, "789");
453+
}
454+
455+
#[test]
456+
#[should_panic]
457+
fn test_splice_inclusive_out_of_bounds() {
458+
let mut s = String::from("12345");
459+
s.splice(5...5, "789");
460+
}
461+
462+
#[test]
463+
fn test_splice_empty() {
464+
let mut s = String::from("12345");
465+
let t: String = s.splice(1..2, "").collect();
466+
assert_eq!(s, "1345");
467+
assert_eq!(t, "2");
468+
}
469+
470+
#[test]
471+
fn test_splice_unbounded() {
472+
let mut s = String::from("12345");
473+
let t: String = s.splice(.., "").collect();
474+
assert_eq!(s, "");
475+
assert_eq!(t, "12345");
476+
}
477+
422478
#[test]
423479
fn test_extend_ref() {
424480
let mut a = "foo".to_string();

‎src/libcollections/tests/vec.rs

+55
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,61 @@ fn test_drain_inclusive_out_of_bounds() {
579579
v.drain(5...5);
580580
}
581581

582+
#[test]
583+
fn test_splice() {
584+
let mut v = vec![1, 2, 3, 4, 5];
585+
let a = [10, 11, 12];
586+
v.splice(2..4, a.iter().cloned());
587+
assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
588+
v.splice(1..3, Some(20));
589+
assert_eq!(v, &[1, 20, 11, 12, 5]);
590+
}
591+
592+
#[test]
593+
fn test_splice_inclusive_range() {
594+
let mut v = vec![1, 2, 3, 4, 5];
595+
let a = [10, 11, 12];
596+
let t1: Vec<_> = v.splice(2...3, a.iter().cloned()).collect();
597+
assert_eq!(v, &[1, 2, 10, 11, 12, 5]);
598+
assert_eq!(t1, &[3, 4]);
599+
let t2: Vec<_> = v.splice(1...2, Some(20)).collect();
600+
assert_eq!(v, &[1, 20, 11, 12, 5]);
601+
assert_eq!(t2, &[2, 10]);
602+
}
603+
604+
#[test]
605+
#[should_panic]
606+
fn test_splice_out_of_bounds() {
607+
let mut v = vec![1, 2, 3, 4, 5];
608+
let a = [10, 11, 12];
609+
v.splice(5..6, a.iter().cloned());
610+
}
611+
612+
#[test]
613+
#[should_panic]
614+
fn test_splice_inclusive_out_of_bounds() {
615+
let mut v = vec![1, 2, 3, 4, 5];
616+
let a = [10, 11, 12];
617+
v.splice(5...5, a.iter().cloned());
618+
}
619+
620+
#[test]
621+
fn test_splice_items_zero_sized() {
622+
let mut vec = vec![(), (), ()];
623+
let vec2 = vec![];
624+
let t: Vec<_> = vec.splice(1..2, vec2.iter().cloned()).collect();
625+
assert_eq!(vec, &[(), ()]);
626+
assert_eq!(t, &[()]);
627+
}
628+
629+
#[test]
630+
fn test_splice_unbounded() {
631+
let mut vec = vec![1, 2, 3, 4, 5];
632+
let t: Vec<_> = vec.splice(.., None).collect();
633+
assert_eq!(vec, &[]);
634+
assert_eq!(t, &[1, 2, 3, 4, 5]);
635+
}
636+
582637
#[test]
583638
fn test_into_boxed_slice() {
584639
let xs = vec![1, 2, 3];

0 commit comments

Comments
 (0)