have RangeArgument return a Bound<&T> from each of its methods

This commit is contained in:
djzin 2016-12-23 19:15:56 +00:00
parent ef04fc82b1
commit 35f23e8211
4 changed files with 46 additions and 18 deletions

View File

@ -15,6 +15,7 @@
//! Range syntax.
use core::ops::{RangeFull, Range, RangeTo, RangeFrom};
use Bound::{self, Excluded, Included, Unbounded};
/// **RangeArgument** is implemented by Rust's built-in range types, produced
/// by range syntax like `..`, `a..`, `..b` or `c..d`.
@ -38,8 +39,8 @@ pub trait RangeArgument<T> {
/// assert_eq!((3..10).start(), Some(&3));
/// # }
/// ```
fn start(&self) -> Option<&T> {
None
fn start(&self) -> Bound<&T> {
Unbounded
}
/// End index (exclusive)
@ -61,8 +62,8 @@ fn start(&self) -> Option<&T> {
/// assert_eq!((3..10).end(), Some(&10));
/// # }
/// ```
fn end(&self) -> Option<&T> {
None
fn end(&self) -> Bound<&T> {
Unbounded
}
}
@ -71,22 +72,22 @@ fn end(&self) -> Option<&T> {
impl<T> RangeArgument<T> for RangeFull {}
impl<T> RangeArgument<T> for RangeFrom<T> {
fn start(&self) -> Option<&T> {
Some(&self.start)
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
}
impl<T> RangeArgument<T> for RangeTo<T> {
fn end(&self) -> Option<&T> {
Some(&self.end)
fn end(&self) -> Bound<&T> {
Excluded(&self.end)
}
}
impl<T> RangeArgument<T> for Range<T> {
fn start(&self) -> Option<&T> {
Some(&self.start)
fn start(&self) -> Bound<&T> {
Included(&self.start)
}
fn end(&self) -> Option<&T> {
Some(&self.end)
fn end(&self) -> Bound<&T> {
Excluded(&self.end)
}
}

View File

@ -68,6 +68,7 @@
use borrow::{Cow, ToOwned};
use range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
use str::{self, FromStr, Utf8Error, Chars};
use vec::Vec;
use boxed::Box;
@ -1350,8 +1351,16 @@ pub fn drain<R>(&mut self, range: R) -> Drain
// Because the range removal happens in Drop, if the Drain iterator is leaked,
// the removal will not happen.
let len = self.len();
let start = *range.start().unwrap_or(&0);
let end = *range.end().unwrap_or(&len);
let start = match range.start() {
Included(&n) => n,
Excluded(&n) => n + 1,
Unbounded => 0,
};
let end = match range.end() {
Included(&n) => n + 1,
Excluded(&n) => n,
Unbounded => len,
};
// Take out two simultaneous borrows. The &mut String won't be accessed
// until iteration is over, in Drop.

View File

@ -84,6 +84,7 @@
use core::slice;
use super::range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector'.
///
@ -1060,8 +1061,16 @@ pub fn drain<R>(&mut self, range: R) -> Drain<T>
// the hole, and the vector length is restored to the new length.
//
let len = self.len();
let start = *range.start().unwrap_or(&0);
let end = *range.end().unwrap_or(&len);
let start = match range.start() {
Included(&n) => n,
Excluded(&n) => n + 1,
Unbounded => 0,
};
let end = match range.end() {
Included(&n) => n + 1,
Excluded(&n) => n,
Unbounded => len,
};
assert!(start <= end);
assert!(end <= len);

View File

@ -33,6 +33,7 @@
use alloc::raw_vec::RawVec;
use super::range::RangeArgument;
use Bound::{Excluded, Included, Unbounded};
use super::vec::Vec;
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
@ -852,8 +853,16 @@ pub fn drain<R>(&mut self, range: R) -> Drain<T>
// and the head/tail values will be restored correctly.
//
let len = self.len();
let start = *range.start().unwrap_or(&0);
let end = *range.end().unwrap_or(&len);
let start = match range.start() {
Included(&n) => n,
Excluded(&n) => n + 1,
Unbounded => 0,
};
let end = match range.end() {
Included(&n) => n + 1,
Excluded(&n) => n,
Unbounded => len,
};
assert!(start <= end, "drain lower bound was too large");
assert!(end <= len, "drain upper bound was too large");