mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Add structs for ranges to core::ops.
This commit is contained in:
parent
658529467d
commit
21ea66f47a
@ -59,7 +59,7 @@
|
||||
#![allow(unknown_features, raw_pointer_deriving)]
|
||||
#![feature(globs, intrinsics, lang_items, macro_rules, phase)]
|
||||
#![feature(simd, unsafe_destructor, slicing_syntax)]
|
||||
#![feature(default_type_params, unboxed_closures)]
|
||||
#![feature(default_type_params, unboxed_closures, associated_types)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
mod macros;
|
||||
|
@ -51,7 +51,12 @@
|
||||
//! See the documentation for each trait for a minimum implementation that prints
|
||||
//! something to the screen.
|
||||
|
||||
use clone::Clone;
|
||||
use cmp::Ord;
|
||||
use iter::{Iterator,DoubleEndedIterator};
|
||||
use kinds::Sized;
|
||||
use kinds::Copy;
|
||||
use option::Option::{mod, Some, None};
|
||||
|
||||
/// The `Drop` trait is used to run some code when a value goes out of scope. This
|
||||
/// is sometimes called a 'destructor'.
|
||||
@ -833,6 +838,114 @@ pub trait SliceMut<Sized? Idx, Sized? Result> for Sized? {
|
||||
fn slice_or_fail_mut<'a>(&'a mut self, from: &Idx, to: &Idx) -> &'a mut Result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// REVIEW could be in a better module
|
||||
/// The `Countable` trait identifies objects which are countable, i.e., are
|
||||
/// analogous to the natural numbers. A countable object can be incremented and
|
||||
/// and decremented and ordered. The `difference` function provides a way to
|
||||
/// compare two Countable objects (it could be provided using increment and Ord,
|
||||
/// but the implementation would be so inefficient as to be useless).
|
||||
#[unstable = "Trait is unstable."]
|
||||
pub trait Countable: Ord {
|
||||
// FIXME(#19391) needs a snapshot
|
||||
//type T;
|
||||
|
||||
/// Change self to the next object.
|
||||
fn increment(&mut self);
|
||||
/// Change self to the previous object.
|
||||
fn decrement(&mut self);
|
||||
/// The difference between two countable objects.
|
||||
/// Temporarily a uint, should be an associated type, but
|
||||
// FIXME(#19391) needs a snapshot
|
||||
fn difference(a: &Self, b: &Self) -> uint;
|
||||
//fn difference(a: &Self, b: &Self) -> <Self as Countable>::T;
|
||||
}
|
||||
|
||||
macro_rules! countable_impl(
|
||||
($($t:ty)*) => ($(
|
||||
#[unstable = "Trait is unstable."]
|
||||
impl Countable for $t {
|
||||
// FIXME(#19391) needs a snapshot
|
||||
//type T = uint;
|
||||
|
||||
#[inline]
|
||||
fn increment(&mut self) { *self += 1; }
|
||||
#[inline]
|
||||
fn decrement(&mut self) { *self -= 1; }
|
||||
#[inline]
|
||||
fn difference(a: &$t, b: &$t) -> uint { (*a - *b) as uint }
|
||||
}
|
||||
)*)
|
||||
)
|
||||
|
||||
countable_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
|
||||
|
||||
/// An unbounded range.
|
||||
pub struct FullRange;
|
||||
|
||||
/// A range which i bounded at both ends.
|
||||
pub struct Range<Idx> {
|
||||
/// The lower bound of the range (inclusive).
|
||||
pub start: Idx,
|
||||
/// The upper bound of the range (exclusive).
|
||||
pub end: Idx,
|
||||
}
|
||||
|
||||
// FIXME(#19391) needs a snapshot
|
||||
//impl<Idx: Clone + Countable<T=uint>> Iterator<Idx> for Range<Idx> {
|
||||
impl<Idx: Clone + Countable> Iterator<Idx> for Range<Idx> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Idx> {
|
||||
if self.start < self.end {
|
||||
let result = self.start.clone();
|
||||
self.start.increment();
|
||||
return Some(result);
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
let hint = Countable::difference(&self.end, &self.start);
|
||||
(hint, Some(hint))
|
||||
}
|
||||
}
|
||||
|
||||
impl<Idx: Clone + Countable> DoubleEndedIterator<Idx> for Range<Idx> {
|
||||
#[inline]
|
||||
fn next_back(&mut self) -> Option<Idx> {
|
||||
if self.start < self.end {
|
||||
self.end.decrement();
|
||||
return Some(self.end.clone());
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
/// A range which is only bounded below.
|
||||
pub struct RangeFrom<Idx> {
|
||||
/// The lower bound of the range (inclusive).
|
||||
pub start: Idx,
|
||||
}
|
||||
|
||||
impl<Idx: Clone + Countable> Iterator<Idx> for RangeFrom<Idx> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Idx> {
|
||||
// Deliberately overflow so we loop forever.
|
||||
let result = self.start.clone();
|
||||
self.start.increment();
|
||||
return Some(result);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Idx: Copy> Copy for Range<Idx> {}
|
||||
impl<Idx: Copy> Copy for RangeFrom<Idx> {}
|
||||
impl Copy for FullRange {}
|
||||
|
||||
|
||||
/// The `Deref` trait is used to specify the functionality of dereferencing
|
||||
/// operations like `*v`.
|
||||
///
|
||||
|
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use test::Bencher;
|
||||
use core::ops::{Range, FullRange, RangeFrom};
|
||||
|
||||
// Overhead of dtors
|
||||
|
||||
@ -27,3 +28,29 @@ fn alloc_obj_with_dtor(b: &mut Bencher) {
|
||||
HasDtor { _x : 10 };
|
||||
})
|
||||
}
|
||||
|
||||
// Test the Range structs without the syntactic sugar.
|
||||
|
||||
#[test]
|
||||
fn test_range() {
|
||||
let r = Range { start: 2u, end: 10 };
|
||||
for (i, ri) in r.enumerate() {
|
||||
assert!(ri == i + 2);
|
||||
assert!(ri >= 2u && ri < 10u);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_from() {
|
||||
let r = RangeFrom { start: 2u };
|
||||
for (i, ri) in r.take(10).enumerate() {
|
||||
assert!(ri == i + 2);
|
||||
assert!(ri >= 2u && ri < 12u);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_full_range() {
|
||||
// Not much to test.
|
||||
let _ = FullRange;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user