diff options
Diffstat (limited to 'src/components/util')
-rw-r--r-- | src/components/util/range.rs | 78 |
1 files changed, 44 insertions, 34 deletions
diff --git a/src/components/util/range.rs b/src/components/util/range.rs index e7cbb52117b..3f9eb33914f 100644 --- a/src/components/util/range.rs +++ b/src/components/util/range.rs @@ -5,10 +5,12 @@ use std::cmp::{max, min}; use std::iter; use std::fmt; +use std::num; +use std::num::Bounded; -pub enum RangeRelation { - OverlapsBegin(/* overlap */ uint), - OverlapsEnd(/* overlap */ uint), +pub enum RangeRelation<T> { + OverlapsBegin(/* overlap */ T), + OverlapsEnd(/* overlap */ T), ContainedBy, Contains, Coincides, @@ -17,20 +19,20 @@ pub enum RangeRelation { } #[deriving(Clone)] -pub struct Range { - off: uint, - len: uint +pub struct Range<T> { + off: T, + len: T, } -impl fmt::Show for Range { +impl<T: Int + TotalOrd> fmt::Show for Range<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "[{} .. {})", self.begin(), self.end()) } } -impl Range { +impl<T: Int + TotalOrd> Range<T> { #[inline] - pub fn new(off: uint, len: uint) -> Range { + pub fn new(off: T, len: T) -> Range<T> { Range { off: off, len: len, @@ -38,68 +40,76 @@ impl Range { } #[inline] - pub fn empty() -> Range { - Range::new(0, 0) + pub fn empty() -> Range<T> { + Range::new(num::zero(), num::zero()) } -} -impl Range { #[inline] - pub fn begin(&self) -> uint { self.off } + pub fn begin(&self) -> T { self.off } #[inline] - pub fn length(&self) -> uint { self.len } + pub fn length(&self) -> T { self.len } #[inline] - pub fn end(&self) -> uint { self.off + self.len } + pub fn end(&self) -> T { self.off + self.len } #[inline] - pub fn eachi(&self) -> iter::Range<uint> { + pub fn eachi(&self) -> iter::Range<T> { range(self.off, self.off + self.len) } #[inline] - pub fn contains(&self, i: uint) -> bool { + pub fn contains(&self, i: T) -> bool { i >= self.begin() && i < self.end() } #[inline] pub fn is_valid_for_string(&self, s: &str) -> bool { - self.begin() < s.len() && self.end() <= s.len() && self.length() <= s.len() + let s_len = s.len(); + match num::cast(s_len) { + Some(len) => { + self.begin() < len && self.end() <= len && self.length() <= len + }, + None => { + debug!("Range<T>::is_valid_for_string: string length ({}) is longer than the max \ + value for T ({})", s_len, { let val: T = Bounded::max_value(); val }); + false + }, + } } #[inline] pub fn is_empty(&self) -> bool { - self.len == 0 + self.len.is_zero() } #[inline] pub fn shift_by(&mut self, i: int) { - self.off = ((self.off as int) + i) as uint; + self.off = num::cast(self.off.to_int().unwrap() + i).unwrap(); } #[inline] pub fn extend_by(&mut self, i: int) { - self.len = ((self.len as int) + i) as uint; + self.len = num::cast(self.len.to_int().unwrap() + i).unwrap(); } #[inline] - pub fn extend_to(&mut self, i: uint) { + pub fn extend_to(&mut self, i: T) { self.len = i - self.off; } #[inline] pub fn adjust_by(&mut self, off_i: int, len_i: int) { - self.off = ((self.off as int) + off_i) as uint; - self.len = ((self.len as int) + len_i) as uint; + self.off = num::cast(self.off.to_int().unwrap() + off_i).unwrap(); + self.len = num::cast(self.len.to_int().unwrap() + len_i).unwrap(); } #[inline] - pub fn reset(&mut self, off_i: uint, len_i: uint) { + pub fn reset(&mut self, off_i: T, len_i: T) { self.off = off_i; self.len = len_i; } #[inline] - pub fn intersect(&self, other: &Range) -> Range { + pub fn intersect(&self, other: &Range<T>) -> Range<T> { let begin = max(self.begin(), other.begin()); let end = min(self.end(), other.end()); @@ -114,7 +124,7 @@ impl Range { /// from the point of view of `self`. So, 'EntirelyBefore' means /// that the `self` range is entirely before `other` range. #[inline] - pub fn relation_to_range(&self, other: &Range) -> RangeRelation { + pub fn relation_to_range(&self, other: &Range<T>) -> RangeRelation<T> { if other.begin() > self.end() { return EntirelyBefore; } @@ -143,19 +153,19 @@ impl Range { } #[inline] - pub fn repair_after_coalesced_range(&mut self, other: &Range) { + pub fn repair_after_coalesced_range(&mut self, other: &Range<T>) { let relation = self.relation_to_range(other); debug!("repair_after_coalesced_range: possibly repairing range {:?}", self); debug!("repair_after_coalesced_range: relation of original range and coalesced range({:?}): {:?}", other, relation); match relation { EntirelyBefore => { }, - EntirelyAfter => { self.shift_by(-(other.length() as int)); }, - Coincides | ContainedBy => { self.reset(other.begin(), 1); }, - Contains => { self.extend_by(-(other.length() as int)); }, - OverlapsBegin(overlap) => { self.extend_by(1 - (overlap as int)); }, + EntirelyAfter => { self.shift_by(-other.length().to_int().unwrap()); }, + Coincides | ContainedBy => { self.reset(other.begin(), num::one()); }, + Contains => { self.extend_by(-other.length().to_int().unwrap()); }, + OverlapsBegin(overlap) => { self.extend_by(1 - overlap.to_int().unwrap()); }, OverlapsEnd(overlap) => { - let len = self.length() - overlap + 1; + let len = self.length() - overlap + num::one(); self.reset(other.begin(), len); } }; |