]> git.proxmox.com Git - rustc.git/blame - src/libcore/ops/range.rs
New upstream version 1.20.0+dfsg1
[rustc.git] / src / libcore / ops / range.rs
CommitLineData
041b39d2
XL
1// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use fmt;
12
13/// An unbounded range. Use `..` (two dots) for its shorthand.
14///
15/// Its primary use case is slicing index. It cannot serve as an iterator
16/// because it doesn't have a starting point.
17///
18/// # Examples
19///
20/// The `..` syntax is a `RangeFull`:
21///
22/// ```
23/// assert_eq!((..), std::ops::RangeFull);
24/// ```
25///
26/// It does not have an `IntoIterator` implementation, so you can't use it in a
27/// `for` loop directly. This won't compile:
28///
29/// ```compile_fail,E0277
30/// for i in .. {
31/// // ...
32/// }
33/// ```
34///
35/// Used as a slicing index, `RangeFull` produces the full array as a slice.
36///
37/// ```
38/// let arr = [0, 1, 2, 3];
39/// assert_eq!(arr[ .. ], [0,1,2,3]); // RangeFull
40/// assert_eq!(arr[ ..3], [0,1,2 ]);
41/// assert_eq!(arr[1.. ], [ 1,2,3]);
42/// assert_eq!(arr[1..3], [ 1,2 ]);
43/// ```
44#[derive(Copy, Clone, PartialEq, Eq, Hash)]
45#[stable(feature = "rust1", since = "1.0.0")]
46pub struct RangeFull;
47
48#[stable(feature = "rust1", since = "1.0.0")]
49impl fmt::Debug for RangeFull {
50 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
51 write!(fmt, "..")
52 }
53}
54
55/// A (half-open) range which is bounded at both ends: { x | start <= x < end }.
56/// Use `start..end` (two dots) for its shorthand.
57///
58/// See the [`contains`](#method.contains) method for its characterization.
59///
60/// # Examples
61///
62/// ```
63/// fn main() {
64/// assert_eq!((3..5), std::ops::Range{ start: 3, end: 5 });
65/// assert_eq!(3+4+5, (3..6).sum());
66///
67/// let arr = [0, 1, 2, 3];
68/// assert_eq!(arr[ .. ], [0,1,2,3]);
69/// assert_eq!(arr[ ..3], [0,1,2 ]);
70/// assert_eq!(arr[1.. ], [ 1,2,3]);
71/// assert_eq!(arr[1..3], [ 1,2 ]); // Range
72/// }
73/// ```
74#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
75#[stable(feature = "rust1", since = "1.0.0")]
76pub struct Range<Idx> {
77 /// The lower bound of the range (inclusive).
78 #[stable(feature = "rust1", since = "1.0.0")]
79 pub start: Idx,
80 /// The upper bound of the range (exclusive).
81 #[stable(feature = "rust1", since = "1.0.0")]
82 pub end: Idx,
83}
84
85#[stable(feature = "rust1", since = "1.0.0")]
86impl<Idx: fmt::Debug> fmt::Debug for Range<Idx> {
87 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
88 write!(fmt, "{:?}..{:?}", self.start, self.end)
89 }
90}
91
92#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
93impl<Idx: PartialOrd<Idx>> Range<Idx> {
94 /// # Examples
95 ///
96 /// ```
97 /// #![feature(range_contains)]
98 /// fn main() {
99 /// assert!( ! (3..5).contains(2));
100 /// assert!( (3..5).contains(3));
101 /// assert!( (3..5).contains(4));
102 /// assert!( ! (3..5).contains(5));
103 ///
104 /// assert!( ! (3..3).contains(3));
105 /// assert!( ! (3..2).contains(3));
106 /// }
107 /// ```
108 pub fn contains(&self, item: Idx) -> bool {
109 (self.start <= item) && (item < self.end)
110 }
111}
112
113/// A range which is only bounded below: { x | start <= x }.
114/// Use `start..` for its shorthand.
115///
116/// See the [`contains`](#method.contains) method for its characterization.
117///
118/// Note: Currently, no overflow checking is done for the iterator
119/// implementation; if you use an integer range and the integer overflows, it
120/// might panic in debug mode or create an endless loop in release mode. This
121/// overflow behavior might change in the future.
122///
123/// # Examples
124///
125/// ```
126/// fn main() {
127/// assert_eq!((2..), std::ops::RangeFrom{ start: 2 });
128/// assert_eq!(2+3+4, (2..).take(3).sum());
129///
130/// let arr = [0, 1, 2, 3];
131/// assert_eq!(arr[ .. ], [0,1,2,3]);
132/// assert_eq!(arr[ ..3], [0,1,2 ]);
133/// assert_eq!(arr[1.. ], [ 1,2,3]); // RangeFrom
134/// assert_eq!(arr[1..3], [ 1,2 ]);
135/// }
136/// ```
137#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
138#[stable(feature = "rust1", since = "1.0.0")]
139pub struct RangeFrom<Idx> {
140 /// The lower bound of the range (inclusive).
141 #[stable(feature = "rust1", since = "1.0.0")]
142 pub start: Idx,
143}
144
145#[stable(feature = "rust1", since = "1.0.0")]
146impl<Idx: fmt::Debug> fmt::Debug for RangeFrom<Idx> {
147 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
148 write!(fmt, "{:?}..", self.start)
149 }
150}
151
152#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
153impl<Idx: PartialOrd<Idx>> RangeFrom<Idx> {
154 /// # Examples
155 ///
156 /// ```
157 /// #![feature(range_contains)]
158 /// fn main() {
159 /// assert!( ! (3..).contains(2));
160 /// assert!( (3..).contains(3));
161 /// assert!( (3..).contains(1_000_000_000));
162 /// }
163 /// ```
164 pub fn contains(&self, item: Idx) -> bool {
165 (self.start <= item)
166 }
167}
168
169/// A range which is only bounded above: { x | x < end }.
170/// Use `..end` (two dots) for its shorthand.
171///
172/// See the [`contains`](#method.contains) method for its characterization.
173///
174/// It cannot serve as an iterator because it doesn't have a starting point.
175///
176/// # Examples
177///
178/// The `..{integer}` syntax is a `RangeTo`:
179///
180/// ```
181/// assert_eq!((..5), std::ops::RangeTo{ end: 5 });
182/// ```
183///
184/// It does not have an `IntoIterator` implementation, so you can't use it in a
185/// `for` loop directly. This won't compile:
186///
187/// ```compile_fail,E0277
188/// for i in ..5 {
189/// // ...
190/// }
191/// ```
192///
193/// When used as a slicing index, `RangeTo` produces a slice of all array
194/// elements before the index indicated by `end`.
195///
196/// ```
197/// let arr = [0, 1, 2, 3];
198/// assert_eq!(arr[ .. ], [0,1,2,3]);
199/// assert_eq!(arr[ ..3], [0,1,2 ]); // RangeTo
200/// assert_eq!(arr[1.. ], [ 1,2,3]);
201/// assert_eq!(arr[1..3], [ 1,2 ]);
202/// ```
203#[derive(Copy, Clone, PartialEq, Eq, Hash)]
204#[stable(feature = "rust1", since = "1.0.0")]
205pub struct RangeTo<Idx> {
206 /// The upper bound of the range (exclusive).
207 #[stable(feature = "rust1", since = "1.0.0")]
208 pub end: Idx,
209}
210
211#[stable(feature = "rust1", since = "1.0.0")]
212impl<Idx: fmt::Debug> fmt::Debug for RangeTo<Idx> {
213 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
214 write!(fmt, "..{:?}", self.end)
215 }
216}
217
218#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
219impl<Idx: PartialOrd<Idx>> RangeTo<Idx> {
220 /// # Examples
221 ///
222 /// ```
223 /// #![feature(range_contains)]
224 /// fn main() {
225 /// assert!( (..5).contains(-1_000_000_000));
226 /// assert!( (..5).contains(4));
227 /// assert!( ! (..5).contains(5));
228 /// }
229 /// ```
230 pub fn contains(&self, item: Idx) -> bool {
231 (item < self.end)
232 }
233}
234
235/// An inclusive range which is bounded at both ends: { x | start <= x <= end }.
236/// Use `start...end` (three dots) for its shorthand.
237///
238/// See the [`contains`](#method.contains) method for its characterization.
239///
240/// # Examples
241///
242/// ```
243/// #![feature(inclusive_range,inclusive_range_syntax)]
244/// fn main() {
245/// assert_eq!((3...5), std::ops::RangeInclusive{ start: 3, end: 5 });
246/// assert_eq!(3+4+5, (3...5).sum());
247///
248/// let arr = [0, 1, 2, 3];
249/// assert_eq!(arr[ ...2], [0,1,2 ]);
250/// assert_eq!(arr[1...2], [ 1,2 ]); // RangeInclusive
251/// }
252/// ```
253#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186
254#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
255pub struct RangeInclusive<Idx> {
256 /// The lower bound of the range (inclusive).
257 #[unstable(feature = "inclusive_range",
258 reason = "recently added, follows RFC",
259 issue = "28237")]
260 pub start: Idx,
261 /// The upper bound of the range (inclusive).
262 #[unstable(feature = "inclusive_range",
263 reason = "recently added, follows RFC",
264 issue = "28237")]
265 pub end: Idx,
266}
267
268#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
269impl<Idx: fmt::Debug> fmt::Debug for RangeInclusive<Idx> {
270 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
271 write!(fmt, "{:?}...{:?}", self.start, self.end)
272 }
273}
274
275#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
276impl<Idx: PartialOrd<Idx>> RangeInclusive<Idx> {
277 /// # Examples
278 ///
279 /// ```
280 /// #![feature(range_contains,inclusive_range_syntax)]
281 /// fn main() {
282 /// assert!( ! (3...5).contains(2));
283 /// assert!( (3...5).contains(3));
284 /// assert!( (3...5).contains(4));
285 /// assert!( (3...5).contains(5));
286 /// assert!( ! (3...5).contains(6));
287 ///
288 /// assert!( (3...3).contains(3));
289 /// assert!( ! (3...2).contains(3));
290 /// }
291 /// ```
292 pub fn contains(&self, item: Idx) -> bool {
293 self.start <= item && item <= self.end
294 }
295}
296
297/// An inclusive range which is only bounded above: { x | x <= end }.
298/// Use `...end` (three dots) for its shorthand.
299///
300/// See the [`contains`](#method.contains) method for its characterization.
301///
302/// It cannot serve as an iterator because it doesn't have a starting point.
303///
304/// # Examples
305///
306/// The `...{integer}` syntax is a `RangeToInclusive`:
307///
308/// ```
309/// #![feature(inclusive_range,inclusive_range_syntax)]
310/// assert_eq!((...5), std::ops::RangeToInclusive{ end: 5 });
311/// ```
312///
313/// It does not have an `IntoIterator` implementation, so you can't use it in a
314/// `for` loop directly. This won't compile:
315///
316/// ```compile_fail,E0277
317/// #![feature(inclusive_range_syntax)]
318/// for i in ...5 {
319/// // ...
320/// }
321/// ```
322///
323/// When used as a slicing index, `RangeToInclusive` produces a slice of all
324/// array elements up to and including the index indicated by `end`.
325///
326/// ```
327/// #![feature(inclusive_range_syntax)]
328/// let arr = [0, 1, 2, 3];
329/// assert_eq!(arr[ ...2], [0,1,2 ]); // RangeToInclusive
330/// assert_eq!(arr[1...2], [ 1,2 ]);
331/// ```
332#[derive(Copy, Clone, PartialEq, Eq, Hash)]
333#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
334pub struct RangeToInclusive<Idx> {
335 /// The upper bound of the range (inclusive)
336 #[unstable(feature = "inclusive_range",
337 reason = "recently added, follows RFC",
338 issue = "28237")]
339 pub end: Idx,
340}
341
342#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")]
343impl<Idx: fmt::Debug> fmt::Debug for RangeToInclusive<Idx> {
344 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
345 write!(fmt, "...{:?}", self.end)
346 }
347}
348
349#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")]
350impl<Idx: PartialOrd<Idx>> RangeToInclusive<Idx> {
351 /// # Examples
352 ///
353 /// ```
354 /// #![feature(range_contains,inclusive_range_syntax)]
355 /// fn main() {
356 /// assert!( (...5).contains(-1_000_000_000));
357 /// assert!( (...5).contains(5));
358 /// assert!( ! (...5).contains(6));
359 /// }
360 /// ```
361 pub fn contains(&self, item: Idx) -> bool {
362 (item <= self.end)
363 }
364}
365
366// RangeToInclusive<Idx> cannot impl From<RangeTo<Idx>>
367// because underflow would be possible with (..0).into()