2013-04-06 03:31:01 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2013-06-28 02:45:46 +04:00
|
|
|
use std::cmp::{max, min};
|
2013-10-22 20:16:17 +04:00
|
|
|
use std::iter;
|
2013-11-01 03:34:14 +04:00
|
|
|
use std::fmt;
|
2014-05-08 02:10:22 +04:00
|
|
|
use std::num;
|
2014-12-18 14:42:50 +03:00
|
|
|
use std::num::Int;
|
2014-05-14 00:43:27 +04:00
|
|
|
|
|
|
|
/// An index type to be used by a `Range`
|
2015-02-12 03:24:45 +03:00
|
|
|
pub trait RangeIndex: Int + fmt::Debug {
|
2015-01-31 14:27:49 +03:00
|
|
|
type Index;
|
|
|
|
fn new(x: Self::Index) -> Self;
|
|
|
|
fn get(self) -> Self::Index;
|
2014-05-14 00:43:27 +04:00
|
|
|
}
|
|
|
|
|
2015-01-31 14:27:49 +03:00
|
|
|
impl RangeIndex for int {
|
|
|
|
type Index = int;
|
2014-05-14 00:43:27 +04:00
|
|
|
#[inline]
|
|
|
|
fn new(x: int) -> int { x }
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get(self) -> int { self }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Implements a range index type with operator overloads
|
|
|
|
#[macro_export]
|
2014-05-16 02:37:37 +04:00
|
|
|
macro_rules! int_range_index {
|
2014-05-14 00:43:27 +04:00
|
|
|
($(#[$attr:meta])* struct $Self:ident($T:ty)) => (
|
2015-02-12 03:24:45 +03:00
|
|
|
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Copy)]
|
2014-05-14 00:43:27 +04:00
|
|
|
$(#[$attr])*
|
|
|
|
pub struct $Self(pub $T);
|
|
|
|
|
|
|
|
impl $Self {
|
|
|
|
#[inline]
|
|
|
|
pub fn to_uint(self) -> uint {
|
|
|
|
self.get() as uint
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-31 14:27:49 +03:00
|
|
|
impl RangeIndex for $Self {
|
|
|
|
type Index = $T;
|
2014-12-18 14:42:50 +03:00
|
|
|
#[inline]
|
|
|
|
fn new(x: $T) -> $Self {
|
|
|
|
$Self(x)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn get(self) -> $T {
|
|
|
|
match self { $Self(x) => x }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-18 04:45:49 +03:00
|
|
|
impl ::std::num::Int for $Self {
|
|
|
|
fn zero() -> $Self { $Self(0) }
|
|
|
|
fn one() -> $Self { $Self(1) }
|
|
|
|
fn min_value() -> $Self { $Self(::std::num::Int::min_value()) }
|
|
|
|
fn max_value() -> $Self { $Self(::std::num::Int::max_value()) }
|
|
|
|
fn count_ones(self) -> uint { self.get().count_ones() }
|
|
|
|
fn leading_zeros(self) -> uint { self.get().leading_zeros() }
|
|
|
|
fn trailing_zeros(self) -> uint { self.get().trailing_zeros() }
|
|
|
|
fn rotate_left(self, n: uint) -> $Self { $Self(self.get().rotate_left(n)) }
|
|
|
|
fn rotate_right(self, n: uint) -> $Self { $Self(self.get().rotate_right(n)) }
|
|
|
|
fn swap_bytes(self) -> $Self { $Self(self.get().swap_bytes()) }
|
|
|
|
fn checked_add(self, other: $Self) -> Option<$Self> {
|
|
|
|
self.get().checked_add(other.get()).map($Self)
|
|
|
|
}
|
|
|
|
fn checked_sub(self, other: $Self) -> Option<$Self> {
|
|
|
|
self.get().checked_sub(other.get()).map($Self)
|
|
|
|
}
|
|
|
|
fn checked_mul(self, other: $Self) -> Option<$Self> {
|
|
|
|
self.get().checked_mul(other.get()).map($Self)
|
|
|
|
}
|
|
|
|
fn checked_div(self, other: $Self) -> Option<$Self> {
|
|
|
|
self.get().checked_div(other.get()).map($Self)
|
|
|
|
}
|
|
|
|
}
|
2014-05-16 02:37:37 +04:00
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Add<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
|
2014-05-14 00:43:27 +04:00
|
|
|
#[inline]
|
2015-01-28 04:15:50 +03:00
|
|
|
fn add(self, other: $Self) -> $Self {
|
2014-05-14 00:43:27 +04:00
|
|
|
$Self(self.get() + other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Sub<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
|
2014-05-14 00:43:27 +04:00
|
|
|
#[inline]
|
2015-01-28 04:15:50 +03:00
|
|
|
fn sub(self, other: $Self) -> $Self {
|
2014-05-14 00:43:27 +04:00
|
|
|
$Self(self.get() - other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Mul<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
|
2014-10-14 04:36:40 +04:00
|
|
|
#[inline]
|
2015-01-28 04:15:50 +03:00
|
|
|
fn mul(self, other: $Self) -> $Self {
|
2014-10-14 04:36:40 +04:00
|
|
|
$Self(self.get() * other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Neg for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
|
2014-05-14 00:43:27 +04:00
|
|
|
#[inline]
|
2015-01-28 04:15:50 +03:00
|
|
|
fn neg(self) -> $Self {
|
2014-05-14 00:43:27 +04:00
|
|
|
$Self(-self.get())
|
|
|
|
}
|
|
|
|
}
|
2013-06-27 02:36:53 +04:00
|
|
|
|
2014-10-14 04:36:40 +04:00
|
|
|
impl ToPrimitive for $Self {
|
|
|
|
fn to_i64(&self) -> Option<i64> {
|
|
|
|
Some(self.get() as i64)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_u64(&self) -> Option<u64> {
|
|
|
|
Some(self.get() as u64)
|
|
|
|
}
|
|
|
|
}
|
2014-12-18 04:45:49 +03:00
|
|
|
|
|
|
|
impl ::std::num::NumCast for $Self {
|
|
|
|
fn from<T: ToPrimitive>(n: T) -> Option<$Self> {
|
|
|
|
n.to_int().map($Self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Div<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn div(self, other: $Self) -> $Self {
|
2014-12-18 04:45:49 +03:00
|
|
|
$Self(self.get() / other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Rem<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn rem(self, other: $Self) -> $Self {
|
2014-12-18 04:45:49 +03:00
|
|
|
$Self(self.get() % other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Not for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn not(self) -> $Self {
|
2014-12-18 04:45:49 +03:00
|
|
|
$Self(!self.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl BitAnd<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn bitand(self, other: $Self) -> $Self {
|
2014-12-18 04:45:49 +03:00
|
|
|
$Self(self.get() & other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl BitOr<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn bitor(self, other: $Self) -> $Self {
|
2014-12-18 04:45:49 +03:00
|
|
|
$Self(self.get() | other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl BitXor<$Self> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn bitxor(self, other: $Self) -> $Self {
|
2014-12-18 04:45:49 +03:00
|
|
|
$Self(self.get() ^ other.get())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Shl<uint> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn shl(self, n: uint) -> $Self {
|
|
|
|
$Self(self.get() << n)
|
2014-12-18 04:45:49 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 04:15:50 +03:00
|
|
|
impl Shr<uint> for $Self {
|
|
|
|
type Output = $Self;
|
|
|
|
fn shr(self, n: uint) -> $Self {
|
|
|
|
$Self(self.get() >> n)
|
2014-12-18 04:45:49 +03:00
|
|
|
}
|
|
|
|
}
|
2014-10-14 04:36:40 +04:00
|
|
|
)
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2014-05-14 00:43:27 +04:00
|
|
|
/// A range of indices
|
2015-01-28 04:15:50 +03:00
|
|
|
#[derive(Clone, RustcEncodable, Copy)]
|
2014-05-14 00:43:27 +04:00
|
|
|
pub struct Range<I> {
|
2014-05-16 02:37:37 +04:00
|
|
|
begin: I,
|
|
|
|
length: I,
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2015-02-12 03:24:45 +03:00
|
|
|
impl<I: RangeIndex> fmt::Debug for Range<I> {
|
2014-03-19 20:35:17 +04:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
2015-01-28 04:15:50 +03:00
|
|
|
write!(f, "[{:?} .. {:?})", self.begin(), self.end())
|
2013-11-01 03:34:14 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-14 00:43:27 +04:00
|
|
|
/// An iterator over each index in a range
|
|
|
|
pub struct EachIndex<T, I> {
|
|
|
|
it: iter::Range<T>,
|
|
|
|
}
|
|
|
|
|
2015-01-31 14:27:49 +03:00
|
|
|
pub fn each_index<T: Int, I: RangeIndex<Index=T>>(start: I, stop: I) -> EachIndex<T, I> {
|
2014-05-16 02:37:37 +04:00
|
|
|
EachIndex { it: iter::range(start.get(), stop.get()) }
|
2014-05-14 00:43:27 +04:00
|
|
|
}
|
|
|
|
|
2015-01-31 14:27:49 +03:00
|
|
|
impl<T: Int, I: RangeIndex<Index=T>> Iterator for EachIndex<T, I> {
|
2015-01-28 04:15:50 +03:00
|
|
|
type Item = I;
|
|
|
|
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-14 00:43:27 +04:00
|
|
|
fn next(&mut self) -> Option<I> {
|
2014-12-18 14:42:50 +03:00
|
|
|
self.it.next().map(|i| RangeIndex::new(i))
|
2014-05-14 00:43:27 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
fn size_hint(&self) -> (uint, Option<uint>) {
|
|
|
|
self.it.size_hint()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-31 14:27:49 +03:00
|
|
|
impl<I: RangeIndex> Range<I> {
|
2014-05-16 02:37:37 +04:00
|
|
|
/// Create a new range from beginning and length offsets. This could be
|
|
|
|
/// denoted as `[begin, begin + length)`.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// |-- begin ->|-- length ->|
|
|
|
|
/// | | |
|
|
|
|
/// <- o - - - - - +============+ - - - ->
|
|
|
|
/// ~~~
|
2014-05-14 00:43:27 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn new(begin: I, length: I) -> Range<I> {
|
|
|
|
Range { begin: begin, length: length }
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-14 00:43:27 +04:00
|
|
|
pub fn empty() -> Range<I> {
|
2014-12-18 14:42:50 +03:00
|
|
|
Range::new(Int::zero(), Int::zero())
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2014-05-16 02:37:37 +04:00
|
|
|
/// The index offset to the beginning of the range.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// |-- begin ->|
|
|
|
|
/// | |
|
|
|
|
/// <- o - - - - - +============+ - - - ->
|
|
|
|
/// ~~~
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn begin(&self) -> I { self.begin }
|
|
|
|
|
|
|
|
/// The index offset from the beginning to the end of the range.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// |-- length ->|
|
|
|
|
/// | |
|
|
|
|
/// <- o - - - - - +============+ - - - ->
|
|
|
|
/// ~~~
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn length(&self) -> I { self.length }
|
|
|
|
|
|
|
|
/// The index offset to the end of the range.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// |--------- end --------->|
|
|
|
|
/// | |
|
|
|
|
/// <- o - - - - - +============+ - - - ->
|
|
|
|
/// ~~~
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn end(&self) -> I { self.begin + self.length }
|
|
|
|
|
|
|
|
/// `true` if the index is between the beginning and the end of the range.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// false true false
|
|
|
|
/// | | |
|
|
|
|
/// <- o - - + - - +=====+======+ - + - ->
|
|
|
|
/// ~~~
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-14 00:43:27 +04:00
|
|
|
pub fn contains(&self, i: I) -> bool {
|
2012-11-19 03:29:17 +04:00
|
|
|
i >= self.begin() && i < self.end()
|
|
|
|
}
|
|
|
|
|
2014-05-16 02:37:37 +04:00
|
|
|
/// `true` if the offset from the beginning to the end of the range is zero.
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2013-06-28 02:45:46 +04:00
|
|
|
pub fn is_empty(&self) -> bool {
|
2014-12-18 14:42:50 +03:00
|
|
|
self.length() == Int::zero()
|
2013-06-28 02:45:46 +04:00
|
|
|
}
|
|
|
|
|
2014-05-16 02:37:37 +04:00
|
|
|
/// Shift the entire range by the supplied index delta.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// |-- delta ->|
|
|
|
|
/// | |
|
|
|
|
/// <- o - +============+ - - - - - | - - - ->
|
|
|
|
/// |
|
|
|
|
/// <- o - - - - - - - +============+ - - - ->
|
|
|
|
/// ~~~
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn shift_by(&mut self, delta: I) {
|
|
|
|
self.begin = self.begin + delta;
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2014-05-16 02:37:37 +04:00
|
|
|
/// Extend the end of the range by the supplied index delta.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// |-- delta ->|
|
|
|
|
/// | |
|
|
|
|
/// <- o - - - - - +====+ - - - - - | - - - ->
|
|
|
|
/// |
|
|
|
|
/// <- o - - - - - +================+ - - - ->
|
|
|
|
/// ~~~
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn extend_by(&mut self, delta: I) {
|
|
|
|
self.length = self.length + delta;
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2014-05-16 02:37:37 +04:00
|
|
|
/// Move the end of the range to the target index.
|
|
|
|
///
|
2014-09-18 04:05:29 +04:00
|
|
|
/// ~~~ignore
|
2014-05-16 02:37:37 +04:00
|
|
|
/// target
|
|
|
|
/// |
|
|
|
|
/// <- o - - - - - +====+ - - - - - | - - - ->
|
|
|
|
/// |
|
|
|
|
/// <- o - - - - - +================+ - - - ->
|
|
|
|
/// ~~~
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn extend_to(&mut self, target: I) {
|
|
|
|
self.length = target - self.begin;
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2014-05-16 02:37:37 +04:00
|
|
|
/// Adjust the beginning offset and the length by the supplied deltas.
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn adjust_by(&mut self, begin_delta: I, length_delta: I) {
|
|
|
|
self.begin = self.begin + begin_delta;
|
|
|
|
self.length = self.length + length_delta;
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
|
|
|
|
2014-05-16 02:37:37 +04:00
|
|
|
/// Set the begin and length values.
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-16 02:37:37 +04:00
|
|
|
pub fn reset(&mut self, begin: I, length: I) {
|
|
|
|
self.begin = begin;
|
|
|
|
self.length = length;
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|
2012-11-19 06:31:01 +04:00
|
|
|
|
2013-10-29 00:31:44 +04:00
|
|
|
#[inline]
|
2014-05-14 00:43:27 +04:00
|
|
|
pub fn intersect(&self, other: &Range<I>) -> Range<I> {
|
2013-06-28 02:45:46 +04:00
|
|
|
let begin = max(self.begin(), other.begin());
|
|
|
|
let end = min(self.end(), other.end());
|
|
|
|
|
|
|
|
if end < begin {
|
|
|
|
Range::empty()
|
|
|
|
} else {
|
|
|
|
Range::new(begin, end - begin)
|
|
|
|
}
|
|
|
|
}
|
2014-05-16 02:37:37 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Methods for `Range`s with indices based on integer values
|
2015-01-31 14:27:49 +03:00
|
|
|
impl<T: Int, I: RangeIndex<Index=T>> Range<I> {
|
2014-05-16 02:37:37 +04:00
|
|
|
/// Returns an iterater that increments over `[begin, end)`.
|
|
|
|
#[inline]
|
|
|
|
pub fn each_index(&self) -> EachIndex<T, I> {
|
|
|
|
each_index(self.begin(), self.end())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
pub fn is_valid_for_string(&self, s: &str) -> bool {
|
|
|
|
let s_len = s.len();
|
|
|
|
match num::cast::<uint, T>(s_len) {
|
|
|
|
Some(len) => {
|
2014-12-18 14:42:50 +03:00
|
|
|
let len = RangeIndex::new(len);
|
2014-05-16 02:37:37 +04:00
|
|
|
self.begin() < len
|
|
|
|
&& self.end() <= len
|
|
|
|
&& self.length() <= len
|
|
|
|
},
|
|
|
|
None => {
|
2015-01-28 04:15:50 +03:00
|
|
|
debug!("Range<T>::is_valid_for_string: string length \
|
|
|
|
(len={:?}) is longer than the max value for the range \
|
|
|
|
index (max={:?})", s_len,
|
2014-05-16 02:37:37 +04:00
|
|
|
{
|
2014-12-18 14:42:50 +03:00
|
|
|
let max: T = Int::max_value();
|
|
|
|
let val: I = RangeIndex::new(max);
|
2014-05-16 02:37:37 +04:00
|
|
|
val
|
|
|
|
});
|
|
|
|
false
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2012-11-13 00:08:38 +04:00
|
|
|
}
|