diff options
author | Manish Goregaokar <manishsmail@gmail.com> | 2017-01-06 15:25:04 -0800 |
---|---|---|
committer | Manish Goregaokar <manishsmail@gmail.com> | 2017-01-06 20:17:10 -0800 |
commit | 800b65622cd8881f30d4d02e87c1ba4e4c9d27d2 (patch) | |
tree | d5532beac05b59e5bb454beb287e314d1b917093 /src | |
parent | 085800c330e7f496ecd2298de4762a7cafcbc13a (diff) |
Remove need for step_by feature
Diffstat (limited to 'src')
-rw-r--r-- | src/grid.rs | 10 | ||||
-rw-r--r-- | src/index.rs | 69 | ||||
-rw-r--r-- | src/lib.rs | 1 | ||||
-rw-r--r-- | src/term/mod.rs | 8 |
4 files changed, 50 insertions, 38 deletions
diff --git a/src/grid.rs b/src/grid.rs index 77fe92b9..c5a7f70e 100644 --- a/src/grid.rs +++ b/src/grid.rs @@ -27,7 +27,7 @@ use std::ops::{Deref, DerefMut, Range, RangeTo, RangeFrom, RangeFull, Index, Ind use std::ops::RangeInclusive; use std::slice::{self, Iter, IterMut}; -use index::{self, Point}; +use index::{self, Point, IndexRange}; /// Convert a type to a linear index range. pub trait ToRange { @@ -53,7 +53,7 @@ pub struct Grid<T> { impl<T: Clone> Grid<T> { pub fn new(lines: index::Line, cols: index::Column, template: &T) -> Grid<T> { let mut raw = Vec::with_capacity(*lines); - for _ in index::Line(0)..lines { + for _ in IndexRange(index::Line(0)..lines) { raw.push(Row::new(cols, template)); } @@ -84,7 +84,7 @@ impl<T: Clone> Grid<T> { } fn grow_lines(&mut self, lines: index::Line, template: &T) { - for _ in self.num_lines()..lines { + for _ in IndexRange(self.num_lines()..lines) { self.raw.push(Row::new(self.cols, template)); } @@ -124,7 +124,7 @@ impl<T> Grid<T> { #[inline] pub fn scroll_down(&mut self, region: Range<index::Line>, positions: index::Line) { - for line in region.rev() { + for line in IndexRange(region).rev() { let src = line; let dst = line - positions; self.swap_lines(src, dst); @@ -133,7 +133,7 @@ impl<T> Grid<T> { #[inline] pub fn scroll_up(&mut self, region: Range<index::Line>, positions: index::Line) { - for line in region { + for line in IndexRange(region) { let src = line; let dst = line + positions; self.swap_lines(src, dst); diff --git a/src/index.rs b/src/index.rs index c80589da..b1f6f452 100644 --- a/src/index.rs +++ b/src/index.rs @@ -17,9 +17,7 @@ /// Indexing types and implementations for Grid and Line use std::cmp::{Ord, Ordering}; use std::fmt; -use std::iter::Step; -use std::mem; -use std::ops::{self, Deref, Add}; +use std::ops::{self, Deref, Add, Range}; /// The side of a cell #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -200,6 +198,18 @@ macro_rules! sub { } } +/// This exists because we can't implement Iterator on Range +/// and the existing impl needs the unstable Step trait +/// This should be removed and replaced with a Step impl +/// in the ops macro when `step_by` is stabilized +pub struct IndexRange<T>(pub Range<T>); + +impl<T> From<Range<T>> for IndexRange<T> { + fn from(from: Range<T>) -> Self { + IndexRange(from) + } +} + macro_rules! ops { ($ty:ty, $construct:expr) => { add!($ty, $construct); @@ -207,12 +217,7 @@ macro_rules! ops { deref!($ty, usize); forward_ref_binop!(impl Add, add for $ty, $ty); - impl Step for $ty { - #[inline] - fn step(&self, by: &$ty) -> Option<$ty> { - Some(*self + *by) - } - + impl $ty { #[inline] #[allow(trivial_numeric_casts)] fn steps_between(start: &$ty, end: &$ty, by: &$ty) -> Option<usize> { @@ -233,33 +238,41 @@ macro_rules! ops { #[inline] fn steps_between_by_one(start: &$ty, end: &$ty) -> Option<usize> { - Step::steps_between(start, end, &$construct(1)) - } - - #[inline] - #[allow(unused_comparisons)] - fn is_negative(&self) -> bool { - self.0 < 0 - } - - #[inline] - fn replace_one(&mut self) -> Self { - mem::replace(self, $construct(0)) + Self::steps_between(start, end, &$construct(1)) } + } + impl Iterator for IndexRange<$ty> { + type Item = $ty; #[inline] - fn replace_zero(&mut self) -> Self { - mem::replace(self, $construct(1)) + fn next(&mut self) -> Option<$ty> { + if self.0.start < self.0.end { + let old = self.0.start; + self.0.start = old + 1; + Some(old) + } else { + None + } } - #[inline] - fn add_one(&self) -> Self { - *self + 1 + fn size_hint(&self) -> (usize, Option<usize>) { + match Self::Item::steps_between_by_one(&self.0.start, &self.0.end) { + Some(hint) => (hint, Some(hint)), + None => (0, None) + } } + } + impl DoubleEndedIterator for IndexRange<$ty> { #[inline] - fn sub_one(&self) -> Self { - *self - 1 + fn next_back(&mut self) -> Option<$ty> { + if self.0.start < self.0.end { + let new = self.0.end - 1; + self.0.end = new; + Some(new) + } else { + None + } } } @@ -17,7 +17,6 @@ #![feature(inclusive_range_syntax)] #![feature(inclusive_range)] #![feature(drop_types_in_const)] -#![feature(step_trait)] #![cfg_attr(feature = "clippy", feature(plugin))] #![cfg_attr(feature = "clippy", plugin(clippy))] #![cfg_attr(feature = "clippy", deny(clippy))] diff --git a/src/term/mod.rs b/src/term/mod.rs index 690c2f10..4c2afc35 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -20,7 +20,7 @@ use std::io; use ansi::{self, Color, NamedColor, Attr, Handler}; use grid::{Grid, ClearRegion, ToRange}; -use index::{self, Point, Column, Line, Linear}; +use index::{self, Point, Column, Line, Linear, IndexRange}; use selection::{Span, Selection}; pub mod cell; @@ -286,7 +286,7 @@ impl Term { let grid = Grid::new(num_lines, num_cols, &template); - let mut tabs = (Column(0)..grid.num_cols()) + let mut tabs = IndexRange::from(Column(0)..grid.num_cols()) .map(|i| (*i as usize) % TAB_SPACES == 0) .collect::<Vec<bool>>(); @@ -424,7 +424,7 @@ impl Term { // Starting line res.append(&self.grid, start.line, start.col..); - let middle_range = (start.line + 1)..(end.line); + let middle_range = IndexRange::from((start.line + 1)..(end.line)); for line in middle_range { res.append(&self.grid, line, ..); } @@ -507,7 +507,7 @@ impl Term { self.cursor.col = limit(self.cursor.col, Column(0), num_cols); // Recreate tabs list - self.tabs = (Column(0)..self.grid.num_cols()) + self.tabs = IndexRange::from(Column(0)..self.grid.num_cols()) .map(|i| (*i as usize) % TAB_SPACES == 0) .collect::<Vec<bool>>(); |