Skip to content

Commit 40deb27

Browse files
committed
Auto merge of #32396 - nodakai:range-contains, r=alexcrichton
Add core::ops::Range*::contains() as per #32311
2 parents d7a7168 + a21c5f2 commit 40deb27

File tree

1 file changed

+208
-6
lines changed

1 file changed

+208
-6
lines changed

src/libcore/ops.rs

+208-6
Original file line numberDiff line numberDiff line change
@@ -1446,7 +1446,24 @@ pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
14461446
fn index_mut(&mut self, index: Idx) -> &mut Self::Output;
14471447
}
14481448

1449-
/// An unbounded range.
1449+
/// An unbounded range. Use `..` (two dots) for its shorthand.
1450+
///
1451+
/// Its primary use case is slicing index. It cannot serve as an iterator
1452+
/// because it doesn't have a starting point.
1453+
///
1454+
/// # Examples
1455+
///
1456+
/// ```
1457+
/// fn main() {
1458+
/// assert_eq!((..), std::ops::RangeFull);
1459+
///
1460+
/// let arr = [0, 1, 2, 3];
1461+
/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull
1462+
/// assert_eq!(arr[ ..3], [0,1,2 ]);
1463+
/// assert_eq!(arr[1.. ], [ 1,2,3]);
1464+
/// assert_eq!(arr[1..3], [ 1,2 ]);
1465+
/// }
1466+
/// ```
14501467
#[derive(Copy, Clone, PartialEq, Eq)]
14511468
#[stable(feature = "rust1", since = "1.0.0")]
14521469
pub struct RangeFull;
@@ -1458,7 +1475,26 @@ impl fmt::Debug for RangeFull {
14581475
}
14591476
}
14601477

1461-
/// A (half-open) range which is bounded at both ends.
1478+
/// A (half-open) range which is bounded at both ends: { x | start <= x < end }.
1479+
/// Use `start..end` (two dots) for its shorthand.
1480+
///
1481+
/// See the [`contains()`](#method.contains) method for its characterization.
1482+
///
1483+
/// # Examples
1484+
///
1485+
/// ```
1486+
/// #![feature(iter_arith)]
1487+
/// fn main() {
1488+
/// assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 });
1489+
/// assert_eq!(3+4+5, (3..6).sum());
1490+
///
1491+
/// let arr = [0, 1, 2, 3];
1492+
/// assert_eq!(arr[ .. ], [0,1,2,3]);
1493+
/// assert_eq!(arr[ ..3], [0,1,2 ]);
1494+
/// assert_eq!(arr[1.. ], [ 1,2,3]);
1495+
/// assert_eq!(arr[1..3], [ 1,2 ]); // Range
1496+
/// }
1497+
/// ```
14621498
#[derive(Clone, PartialEq, Eq)]
14631499
#[stable(feature = "rust1", since = "1.0.0")]
14641500
pub struct Range<Idx> {
@@ -1477,7 +1513,47 @@ impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
14771513
}
14781514
}
14791515

1480-
/// A range which is only bounded below.
1516+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1517+
impl<Idx: PartialOrd<Idx>> Range<Idx> {
1518+
/// # Examples
1519+
///
1520+
/// ```
1521+
/// #![feature(range_contains)]
1522+
/// fn main() {
1523+
/// assert!( ! (3..5).contains(2));
1524+
/// assert!( (3..5).contains(3));
1525+
/// assert!( (3..5).contains(4));
1526+
/// assert!( ! (3..5).contains(5));
1527+
///
1528+
/// assert!( ! (3..3).contains(3));
1529+
/// assert!( ! (3..2).contains(3));
1530+
/// }
1531+
/// ```
1532+
pub fn contains(&self, item: Idx) -> bool {
1533+
(self.start <= item) && (item < self.end)
1534+
}
1535+
}
1536+
1537+
/// A range which is only bounded below: { x | start <= x }.
1538+
/// Use `start..` for its shorthand.
1539+
///
1540+
/// See the [`contains()`](#method.contains) method for its characterization.
1541+
///
1542+
/// # Examples
1543+
///
1544+
/// ```
1545+
/// #![feature(iter_arith)]
1546+
/// fn main() {
1547+
/// assert_eq!((2..), std::ops::RangeFrom{ start: 2 });
1548+
/// assert_eq!(2+3+4, (2..).take(3).sum());
1549+
///
1550+
/// let arr = [0, 1, 2, 3];
1551+
/// assert_eq!(arr[ .. ], [0,1,2,3]);
1552+
/// assert_eq!(arr[ ..3], [0,1,2 ]);
1553+
/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom
1554+
/// assert_eq!(arr[1..3], [ 1,2 ]);
1555+
/// }
1556+
/// ```
14811557
#[derive(Clone, PartialEq, Eq)]
14821558
#[stable(feature = "rust1", since = "1.0.0")]
14831559
pub struct RangeFrom<Idx> {
@@ -1493,7 +1569,40 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
14931569
}
14941570
}
14951571

1496-
/// A range which is only bounded above.
1572+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1573+
impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
1574+
/// # Examples
1575+
///
1576+
/// ```
1577+
/// #![feature(range_contains)]
1578+
/// fn main() {
1579+
/// assert!( ! (3..).contains(2));
1580+
/// assert!( (3..).contains(3));
1581+
/// assert!( (3..).contains(1_000_000_000));
1582+
/// }
1583+
/// ```
1584+
pub fn contains(&self, item: Idx) -> bool {
1585+
(self.start <= item)
1586+
}
1587+
}
1588+
1589+
/// A range which is only bounded above: { x | x < end }.
1590+
/// Use `..end` (two dots) for its shorthand.
1591+
///
1592+
/// See the [`contains()`](#method.contains) method for its characterization.
1593+
///
1594+
/// It cannot serve as an iterator because it doesn't have a starting point.
1595+
/// ```
1596+
/// fn main() {
1597+
/// assert_eq!((..5), std::ops::RangeTo{ end: 5 });
1598+
///
1599+
/// let arr = [0, 1, 2, 3];
1600+
/// assert_eq!(arr[ .. ], [0,1,2,3]);
1601+
/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo
1602+
/// assert_eq!(arr[1.. ], [ 1,2,3]);
1603+
/// assert_eq!(arr[1..3], [ 1,2 ]);
1604+
/// }
1605+
/// ```
14971606
#[derive(Copy, Clone, PartialEq, Eq)]
14981607
#[stable(feature = "rust1", since = "1.0.0")]
14991608
pub struct RangeTo<Idx> {
@@ -1509,7 +1618,41 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
15091618
}
15101619
}
15111620

1512-
/// An inclusive range which is bounded at both ends.
1621+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1622+
impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
1623+
/// # Examples
1624+
///
1625+
/// ```
1626+
/// #![feature(range_contains)]
1627+
/// fn main() {
1628+
/// assert!( (..5).contains(-1_000_000_000));
1629+
/// assert!( (..5).contains(4));
1630+
/// assert!( ! (..5).contains(5));
1631+
/// }
1632+
/// ```
1633+
pub fn contains(&self, item: Idx) -> bool {
1634+
(item < self.end)
1635+
}
1636+
}
1637+
1638+
/// An inclusive range which is bounded at both ends: { x | start <= x <= end }.
1639+
/// Use `start...end` (three dots) for its shorthand.
1640+
///
1641+
/// See the [`contains()`](#method.contains) method for its characterization.
1642+
///
1643+
/// # Examples
1644+
///
1645+
/// ```
1646+
/// #![feature(inclusive_range,inclusive_range_syntax,iter_arith)]
1647+
/// fn main() {
1648+
/// assert_eq!((3...5), std::ops::RangeInclusive::NonEmpty{ start: 3, end: 5 });
1649+
/// assert_eq!(3+4+5, (3...5).sum());
1650+
///
1651+
/// let arr = [0, 1, 2, 3];
1652+
/// assert_eq!(arr[ ...2], [0,1,2 ]);
1653+
/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive
1654+
/// }
1655+
/// ```
15131656
#[derive(Copy, Clone, PartialEq, Eq)]
15141657
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
15151658
pub enum RangeInclusive<Idx> {
@@ -1572,7 +1715,49 @@ impl<Idx: PartialOrd + One + Sub<Output=Idx>> From<Range<Idx>> for RangeInclusiv
15721715
}
15731716
}
15741717

1575-
/// An inclusive range which is only bounded above.
1718+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1719+
impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
1720+
/// # Examples
1721+
///
1722+
/// ```
1723+
/// #![feature(range_contains,inclusive_range_syntax)]
1724+
/// fn main() {
1725+
/// assert!( ! (3...5).contains(2));
1726+
/// assert!( (3...5).contains(3));
1727+
/// assert!( (3...5).contains(4));
1728+
/// assert!( (3...5).contains(5));
1729+
/// assert!( ! (3...5).contains(6));
1730+
///
1731+
/// assert!( (3...3).contains(3));
1732+
/// assert!( ! (3...2).contains(3));
1733+
/// }
1734+
/// ```
1735+
pub fn contains(&self, item: Idx) -> bool {
1736+
if let &RangeInclusive::NonEmpty{ref start, ref end} = self {
1737+
(*start <= item) && (item <= *end)
1738+
} else { false }
1739+
}
1740+
}
1741+
1742+
/// An inclusive range which is only bounded above: { x | x <= end }.
1743+
/// Use `...end` (three dots) for its shorthand.
1744+
///
1745+
/// See the [`contains()`](#method.contains) method for its characterization.
1746+
///
1747+
/// It cannot serve as an iterator because it doesn't have a starting point.
1748+
///
1749+
/// # Examples
1750+
///
1751+
/// ```
1752+
/// #![feature(inclusive_range,inclusive_range_syntax)]
1753+
/// fn main() {
1754+
/// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 });
1755+
///
1756+
/// let arr = [0, 1, 2, 3];
1757+
/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive
1758+
/// assert_eq!(arr[1...2], [ 1,2 ]);
1759+
/// }
1760+
/// ```
15761761
#[derive(Copy, Clone, PartialEq, Eq)]
15771762
#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
15781763
pub struct RangeToInclusive<Idx> {
@@ -1590,6 +1775,23 @@ impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
15901775
}
15911776
}
15921777

1778+
#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
1779+
impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
1780+
/// # Examples
1781+
///
1782+
/// ```
1783+
/// #![feature(range_contains,inclusive_range_syntax)]
1784+
/// fn main() {
1785+
/// assert!( (...5).contains(-1_000_000_000));
1786+
/// assert!( (...5).contains(5));
1787+
/// assert!( ! (...5).contains(6));
1788+
/// }
1789+
/// ```
1790+
pub fn contains(&self, item: Idx) -> bool {
1791+
(item <= self.end)
1792+
}
1793+
}
1794+
15931795
// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
15941796
// because underflow would be possible with (..0).into()
15951797

0 commit comments

Comments
 (0)