// Copyright 2015 Joe Neeman. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms.
use num_traits::PrimInt; use std::cmp::{max, min, Ordering}; use std::fmt::{Debug, Formatter}; use std::iter::FromIterator; use std::{mem, usize};
const DISPLAY_LIMIT: usize = 10;
/// A range of elements, including the endpoints. #[derive(Copy, Clone, Hash, PartialEq, PartialOrd, Eq, Ord)] pubstruct Range<T> { pub start: T, pub end: T,
}
impl<T: PrimInt> Range<T> { /// Creates a new range with the given start and endpoints (inclusive). /// /// # Panics /// - if `start` is strictly larger than `end` pubfn new(start: T, end: T) -> Range<T> { if start > end {
panic!("Ranges must be ordered");
}
Range {
start: start,
end: end,
}
}
/// Creates a new range containing everything. pubfn full() -> Range<T> {
Range {
start: T::min_value(),
end: T::max_value(),
}
}
/// Creates a new range containing a single thing. pubfn single(x: T) -> Range<T> {
Range::new(x, x)
}
/// Tests whether a given element belongs to this range. pubfn contains(&self, x: T) -> bool { self.start <= x && x <= self.end
}
/// When creating a [`RangeMap`] from a list of ranges and values, there's a possiblity that two /// ranges will overlap. In this case, it's a problem if they want to be associated to different /// values (because we don't know which value should be assigned to the intersection of the /// ranges). An `OverlapError` is the result of such a situation. It contains two members. The /// first is a [`RangeMap`] obtained by simply ignoring all the ranges that would cause a bad /// overlap. The second is the collection of ranges that were ignored. // TODO: an example #[derive(Clone, Debug, Eq, Hash, PartialEq)] pubstruct OverlapError<T, V> { pub non_overlapping: RangeMap<T, V>, pub discarded: Vec<(Range<T>, V)>,
}
/// A set of characters. Optionally, each character in the set may be associated with some data. #[derive(Clone, Eq, Hash, PartialEq)] pubstruct RangeMap<T, V> {
elts: Vec<(Range<T>, V)>,
}
impl<T: Debug, V: Debug> Debug for RangeMap<T, V> { // When alternate formatting is specified, only prints out the first bunch of mappings. fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { try!(f.write_fmt(format_args!("RangeMap (")));
impl<T: Debug + PrimInt, V: Clone + Debug + Eq> FromIterator<(Range<T>, V)> for RangeMap<T, V> { /// Builds a `RangeMap` from an iterator over pairs. If any ranges overlap, they must map to /// the same value. /// /// # Panics /// Panics if there are ranges that overlap and do not map to the same value. If you are not /// sure whether this could happen, use [`RangeMap::try_from_iter`] instead. fn from_iter<I: IntoIterator<Item = (Range<T>, V)>>(iter: I) -> Self {
RangeMap::try_from_iter(iter).ok().unwrap()
}
}
/// Builds a `RangeMap` from an iterator over pairs. If any ranges overlap, they should map to /// the same value. If not, returns an [`OverlapError`]. pubfn try_from_iter<I: IntoIterator<Item = (Range<T>, V)>>(
iter: I,
) -> Result<RangeMap<T, V>, OverlapError<T, V>> { letmut vec: Vec<_> = iter.into_iter().collect();
vec.sort_by(|x, y| x.0.cmp(&y.0)); letmut ret = RangeMap { elts: vec }; let discarded = ret.normalize();
// Creates a `RangeMap` from a `Vec`, which must contain ranges in ascending order. If any // ranges overlap, they must map to the same value. // // Panics if the ranges are not sorted, or if they overlap without mapping to the same value. fn from_sorted_vec(vec: Vec<(Range<T>, V)>) -> RangeMap<T, V> { letmut ret = RangeMap { elts: vec };
ret.normalize();
ret
}
// Creates a RangeMap from a Vec, which must be sorted and normalized. // // Panics unless `vec` is sorted and normalized. fn from_norm_vec(vec: Vec<(Range<T>, V)>) -> RangeMap<T, V> { for i in1..vec.len() { if vec[i].0.start <= vec[i - 1].0.end {
panic!( "vector {:?} has overlapping ranges {:?} and {:?}",
vec,
vec[i - 1],
vec[i]
);
} // If vec[i-1].0.end is T::max_value() then we've already panicked, so the unwrap is // safe. if vec[i].0.start == vec[i - 1].0.end.checked_add(&T::one()).unwrap()
&& vec[i].1 == vec[i - 1].1
{
panic!( "vector {:?} has adjacent ranges with same value {:?} and {:?}",
vec,
vec[i - 1],
vec[i]
);
}
}
RangeMap { elts: vec }
}
/// Returns the number of mapped ranges. /// /// Note that this is not usually the same as the number of mapped values. pubfn num_ranges(&self) -> usize { self.elts.len()
}
/// Tests whether this map is empty. pubfn is_empty(&self) -> bool { self.elts.is_empty()
}
/// Tests whether this `CharMap` maps every value. pubfn is_full(&self) -> bool { letmut last_end = T::min_value(); for &(range, _) in &self.elts { if range.start > last_end { returnfalse;
}
last_end = range.end;
}
last_end == T::max_value()
}
/// Iterates over all the mapped ranges and values. pubfn ranges_values<'a>(&'a self) -> std::slice::Iter<'a, (Range<T>, V)> { self.elts.iter()
}
/// Finds the value that `x` maps to, if it exists. /// /// Runs in `O(log n)` time, where `n` is the number of mapped ranges. pubfn get(&self, x: T) -> Option<&V> { self.elts // The unwrap is ok because Range<T>::partial_cmp(&T) never returns None.
.binary_search_by(|r| r.0.partial_cmp(&x).unwrap())
.ok()
.map(|idx| &self.elts[idx].1)
}
// Minimizes the number of ranges in this map. // // If there are any overlapping ranges that map to the same data, merges them. Assumes that the // ranges are sorted according to their start. // // If there are overlapping ranges that map to different values, we delete them. The return // value is the collection of all ranges that were deleted. // // TODO: because the output is always smaller than the input, this could be done in-place. fn normalize(&mutself) -> Vec<(Range<T>, V)> { letmut vec = Vec::with_capacity(self.elts.len()); letmut discarded = Vec::new();
mem::swap(&mut vec, &mutself.elts);
for (range, val) in vec.into_iter() { iflet Some(&mut (refmut last_range, ref last_val)) = self.elts.last_mut() { if range.start <= last_range.end && &val != last_val {
discarded.push((range, val)); continue;
}
/// Counts the number of mapped keys. /// /// This saturates at `usize::MAX`. pubfn num_keys(&self) -> usize { self.ranges_values().fold(0, |acc, range| {
acc.saturating_add(
(range.0.end - range.0.start)
.to_usize()
.unwrap_or(usize::MAX),
)
.saturating_add(1)
})
}
/// Returns the set of mapped chars, forgetting what they are mapped to. pubfn to_range_set(&self) -> RangeSet<T> {
RangeSet::from_sorted_vec(self.elts.iter().map(|x| (x.0, ())).collect())
}
/// Modifies the values in place. pubfn map_values<F>(&mutself, mut f: F) where
F: FnMut(&V) -> V,
{ for &mut (_, refmut data) in &mutself.elts {
*data = f(data);
}
// We need to re-normalize, because we might have mapped two adjacent ranges to the same // value. self.normalize();
}
/// Modifies this map to contain only those mappings with values `v` satisfying `f(v)`. pubfn retain_values<F>(&mutself, mut f: F) where
F: FnMut(&V) -> bool,
{ self.elts.retain(|x| f(&x.1));
}
/// Returns a mutable view into this map. /// /// The ranges should not be modified, since that might violate our invariants. /// /// This method will eventually be removed, probably once anonymous return values allow is to /// write a values_mut() iterator more easily. pubfn as_mut_slice(&mutself) -> &mut [(Range<T>, V)] {
&mutself.elts
}
}
/// A set of integers, implemented as a sorted list of (inclusive) ranges. #[derive(Clone, Eq, Hash, PartialEq)] pubstruct RangeSet<T> {
map: RangeMap<T, ()>,
}
impl<T: Debug + PrimInt> Debug for RangeSet<T> { // When alternate formatting is specified, only prints out the first buch of mappings. fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { try!(f.write_fmt(format_args!("RangeSet (")));
impl<T: Debug + PrimInt> FromIterator<Range<T>> for RangeSet<T> { /// Builds a `RangeSet` from an iterator over `Range`s. fn from_iter<I: IntoIterator<Item = Range<T>>>(iter: I) -> Self {
RangeSet { // The unwrap here is ok because RangeMap::try_from_iter only fails when two // overlapping ranges map to different values. Since every range here maps to the same // value, (i.e. ()), this will never happen.
map: RangeMap::try_from_iter(iter.into_iter().map(|x| (x, ())))
.ok()
.unwrap(),
}
}
}
/// Tests if this set is empty. pubfn is_empty(&self) -> bool { self.map.is_empty()
}
/// Tests whether this set contains every valid value of `T`. pubfn is_full(&self) -> bool { // We are assuming normalization here. self.num_ranges() == 1 && self.map.elts[0].0 == Range::full()
}
/// Returns the number of ranges used to represent this set. pubfn num_ranges(&self) -> usize { self.map.num_ranges()
}
/// Returns the number of elements in the set. /// /// This saturates at `usize::MAX`. pubfn num_elements(&self) -> usize { self.map.num_keys()
}
/// Returns an iterator over all ranges in this set. pubfn ranges<'a>(&'a self) -> RangeIter<'a, T> {
RangeIter {
set: self,
next_idx: 0,
}
}
/// Returns an iterator over all elements in this set. pubfn elements<'a>(&'a self) -> EltIter<'a, T> { ifself.map.elts.is_empty() {
EltIter {
set: self,
next_range_idx: None,
next_elt: T::min_value(),
}
} else {
EltIter {
set: self,
next_range_idx: Some(0),
next_elt: self.map.elts[0].0.start,
}
}
}
/// Checks if this set contains a value. pubfn contains(&self, val: T) -> bool { self.map.get(val).is_some()
}
// Creates a RangeSet from a vector. The vector must be sorted, but it does not need to be // normalized. fn from_sorted_vec(vec: Vec<(Range<T>, ())>) -> RangeSet<T> {
RangeSet {
map: RangeMap::from_sorted_vec(vec),
}
}
// Creates a RangeSet from a vector. The vector must be normalized, in the sense that it should // contain no adjacent ranges. fn from_norm_vec(vec: Vec<(Range<T>, ())>) -> RangeSet<T> {
RangeSet {
map: RangeMap::from_norm_vec(vec),
}
}
/// Returns the union between `self` and `other`. pubfn union(&self, other: &RangeSet<T>) -> RangeSet<T> { ifself.is_empty() { return other.clone();
} elseif other.is_empty() { returnself.clone();
}
if cur_range.is_some() {
ret.push((cur_range.unwrap(), ()));
}
RangeSet::from_norm_vec(ret)
}
/// Creates a set that contains every value of `T`. pubfn full() -> RangeSet<T> {
RangeSet::from_norm_vec(vec![(Range::full(), ())])
}
/// Creates a set containing a single element. pubfn single(x: T) -> RangeSet<T> {
RangeSet::from_norm_vec(vec![(Range::single(x), ())])
}
/// Creates a set containing all elements except the given ones. The input iterator must be /// sorted. If it is not, this will return `None`. pubfn except<I: Iterator<Item = T>>(it: I) -> Option<RangeSet<T>> { letmut ret = Vec::new(); letmut next_allowed = T::min_value(); letmut last_forbidden = T::max_value();
for i in it { if i > next_allowed {
ret.push((Range::new(next_allowed, i - T::one()), ()));
} elseif i < next_allowed.saturating_sub(T::one()) { return None;
}
/// Finds the intersection between this set and `other`. pubfn intersection(&self, other: &RangeSet<T>) -> RangeSet<T> {
RangeSet {
map: self.map.intersection(other),
}
}
/// Returns the set of all characters that are not in this set. pubfn negated(&self) -> RangeSet<T> { letmut ret = Vec::with_capacity(self.num_ranges() + 1); letmut last_end = T::min_value();
for range inself.ranges() { if range.start > last_end {
ret.push((Range::new(last_end, range.start - T::one()), ()));
}
last_end = range.end.saturating_add(T::one());
} if last_end < T::max_value() {
ret.push((Range::new(last_end, T::max_value()), ()));
}
RangeSet::from_norm_vec(ret)
}
}
/// A multi-valued mapping from primitive integers to other data. #[derive(Clone, Eq, Hash, PartialEq)] pubstruct RangeMultiMap<T, V> {
elts: Vec<(Range<T>, V)>,
}
impl<T: Debug + PrimInt, V: Clone + Debug + PartialEq> FromIterator<(Range<T>, V)> for RangeMultiMap<T, V>
{ /// Builds a `RangeMultiMap` from an iterator over `Range` and values.. fn from_iter<I: IntoIterator<Item = (Range<T>, V)>>(iter: I) -> Self {
RangeMultiMap::from_vec(iter.into_iter().collect())
}
}
/// Returns the number of mapped ranges. pubfn num_ranges(&self) -> usize { self.elts.len()
}
/// Checks if the map is empty. pubfn is_empty(&self) -> bool { self.elts.is_empty()
}
/// Adds a new mapping from a range of characters to `value`. pubfn insert(&mutself, range: Range<T>, value: V) { self.elts.push((range, value));
}
/// Creates a map from a vector of pairs. pubfn from_vec(vec: Vec<(Range<T>, V)>) -> RangeMultiMap<T, V> {
RangeMultiMap { elts: vec }
}
/// Returns a new `RangeMultiMap` containing only the mappings for keys that belong to the /// given set. pubfn intersection(&self, other: &RangeSet<T>) -> RangeMultiMap<T, V> { letmut ret = Vec::new(); for &(ref my_range, ref data) in &self.elts { let start_idx = other
.map
.elts
.binary_search_by(|r| r.0.end.cmp(&my_range.start))
.unwrap_or_else(|x| x); for &(ref other_range, _) in &other.map.elts[start_idx..] { if my_range.start > other_range.end { break;
} elseiflet Some(r) = my_range.intersection(other_range) {
ret.push((r, data.clone()));
}
}
}
RangeMultiMap::from_vec(ret)
}
pubfn map_values<F>(&mutself, mut f: F) where
F: FnMut(&V) -> V,
{ for i in0..self.elts.len() { self.elts[i].1 = f(&self.elts[i].1);
}
}
/// Modifies this map in place to only contain mappings whose values `v` satisfy `f(v)`. pubfn retain_values<F>(&mutself, mut f: F) where
F: FnMut(&V) -> bool,
{ self.elts.retain(|x| f(&x.1));
}
/// Iterates over all the mapped ranges and values. pubfn ranges_values<'a>(&'a self) -> std::slice::Iter<'a, (Range<T>, V)> { self.elts.iter()
}
}
impl<T: Debug + PrimInt, V: Clone + Debug + Ord> RangeMultiMap<T, V> { /// Makes the ranges sorted and non-overlapping. The data associated with each range will /// be a `Vec<T>` instead of a single `T`. pubfn group(&self) -> RangeMap<T, Vec<V>> { ifself.elts.is_empty() { return RangeMap::new();
}
for &(ref range, _) inself.elts.iter() {
start_chars.push(range.start); if range.end < T::max_value() {
start_chars.push(range.end + T::one());
}
}
start_chars.sort();
start_chars.dedup();
letmut ret: Vec<(Range<T>, Vec<V>)> = Vec::with_capacity(start_chars.len()); for pair in start_chars.windows(2) {
ret.push((Range::new(pair[0], pair[1] - T::one()), Vec::new()));
}
ret.push((
Range::new(*start_chars.last().unwrap(), T::max_value()),
Vec::new(),
)); for &(range, ref val) inself.elts.iter() { // The unwrap is OK because start_chars contains range.start for every range in elts. letmut idx = start_chars.binary_search(&range.start).unwrap(); while idx < start_chars.len() && start_chars[idx] <= range.end {
ret[idx].1.push(val.clone());
idx += 1;
}
}
ret.retain(|x| !x.1.is_empty());
RangeMap::from_sorted_vec(ret)
}
}
#[cfg(test)] mod tests { usesuper::*; use num_iter::range_inclusive; use num_traits::PrimInt; use quickcheck::{quickcheck, Arbitrary, Gen, TestResult}; use std::cmp::{max, min}; use std::fmt::Debug; use std::i32; use std::ops::Add;
impl<T: Arbitrary + Debug + PrimInt> Arbitrary for Range<T> { fn arbitrary<G: Gen>(g: &mut G) -> Self { let a = T::arbitrary(g); let b = T::arbitrary(g);
Range::new(min(a, b), max(a, b))
}
}
// Check that things don't panic when we have MIN and MAX in the ranges (quickcheck doesn't // check this properly). #[test] fn rangemultimap_boundaries() {
assert_eq!(
RangeMultiMap::from_vec(vec![
(Range::new(i32::MIN, 200), 5),
(Range::new(100, i32::MAX), 10),
])
.group(),
RangeMap::from_sorted_vec(vec![
(Range::new(i32::MIN, 99), vec![5]),
(Range::new(100, 200), vec![5, 10]),
(Range::new(201, i32::MAX), vec![10]),
])
);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.