lib.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. //! External iterators for generic mathematics
  11. extern crate num_traits as traits;
  12. extern crate num_integer as integer;
  13. use integer::Integer;
  14. use traits::{Zero, One, CheckedAdd, ToPrimitive};
  15. use std::ops::{Add, Sub};
  16. /// An iterator over the range [start, stop)
  17. #[derive(Clone)]
  18. pub struct Range<A> {
  19. state: A,
  20. stop: A,
  21. one: A
  22. }
  23. /// Returns an iterator over the given range [start, stop) (that is, starting
  24. /// at start (inclusive), and ending at stop (exclusive)).
  25. ///
  26. /// # Example
  27. ///
  28. /// ```rust
  29. /// let array = [0, 1, 2, 3, 4];
  30. ///
  31. /// for i in num_iter::range(0, 5) {
  32. /// println!("{}", i);
  33. /// assert_eq!(i, array[i]);
  34. /// }
  35. /// ```
  36. #[inline]
  37. pub fn range<A>(start: A, stop: A) -> Range<A>
  38. where A: Add<A, Output = A> + PartialOrd + Clone + One
  39. {
  40. Range{state: start, stop: stop, one: One::one()}
  41. }
  42. // FIXME: rust-lang/rust#10414: Unfortunate type bound
  43. impl<A> Iterator for Range<A>
  44. where A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive
  45. {
  46. type Item = A;
  47. #[inline]
  48. fn next(&mut self) -> Option<A> {
  49. if self.state < self.stop {
  50. let result = self.state.clone();
  51. self.state = self.state.clone() + self.one.clone();
  52. Some(result)
  53. } else {
  54. None
  55. }
  56. }
  57. #[inline]
  58. fn size_hint(&self) -> (usize, Option<usize>) {
  59. // This first checks if the elements are representable as i64. If they aren't, try u64 (to
  60. // handle cases like range(huge, huger)). We don't use usize/int because the difference of
  61. // the i64/u64 might lie within their range.
  62. let bound = match self.state.to_i64() {
  63. Some(a) => {
  64. let sz = self.stop.to_i64().map(|b| b.checked_sub(a));
  65. match sz {
  66. Some(Some(bound)) => bound.to_usize(),
  67. _ => None,
  68. }
  69. },
  70. None => match self.state.to_u64() {
  71. Some(a) => {
  72. let sz = self.stop.to_u64().map(|b| b.checked_sub(a));
  73. match sz {
  74. Some(Some(bound)) => bound.to_usize(),
  75. _ => None
  76. }
  77. },
  78. None => None
  79. }
  80. };
  81. match bound {
  82. Some(b) => (b, Some(b)),
  83. // Standard fallback for unbounded/unrepresentable bounds
  84. None => (0, None)
  85. }
  86. }
  87. }
  88. /// `Integer` is required to ensure the range will be the same regardless of
  89. /// the direction it is consumed.
  90. impl<A> DoubleEndedIterator for Range<A>
  91. where A: Integer + Clone + ToPrimitive
  92. {
  93. #[inline]
  94. fn next_back(&mut self) -> Option<A> {
  95. if self.stop > self.state {
  96. self.stop = self.stop.clone() - self.one.clone();
  97. Some(self.stop.clone())
  98. } else {
  99. None
  100. }
  101. }
  102. }
  103. /// An iterator over the range [start, stop]
  104. #[derive(Clone)]
  105. pub struct RangeInclusive<A> {
  106. range: Range<A>,
  107. done: bool,
  108. }
  109. /// Return an iterator over the range [start, stop]
  110. #[inline]
  111. pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A>
  112. where A: Add<A, Output = A> + PartialOrd + Clone + One
  113. {
  114. RangeInclusive{range: range(start, stop), done: false}
  115. }
  116. impl<A> Iterator for RangeInclusive<A>
  117. where A: Add<A, Output = A> + PartialOrd + Clone + ToPrimitive
  118. {
  119. type Item = A;
  120. #[inline]
  121. fn next(&mut self) -> Option<A> {
  122. match self.range.next() {
  123. Some(x) => Some(x),
  124. None => {
  125. if !self.done && self.range.state == self.range.stop {
  126. self.done = true;
  127. Some(self.range.stop.clone())
  128. } else {
  129. None
  130. }
  131. }
  132. }
  133. }
  134. #[inline]
  135. fn size_hint(&self) -> (usize, Option<usize>) {
  136. let (lo, hi) = self.range.size_hint();
  137. if self.done {
  138. (lo, hi)
  139. } else {
  140. let lo = lo.saturating_add(1);
  141. let hi = match hi {
  142. Some(x) => x.checked_add(1),
  143. None => None
  144. };
  145. (lo, hi)
  146. }
  147. }
  148. }
  149. impl<A> DoubleEndedIterator for RangeInclusive<A>
  150. where A: Sub<A, Output = A> + Integer + Clone + ToPrimitive
  151. {
  152. #[inline]
  153. fn next_back(&mut self) -> Option<A> {
  154. if self.range.stop > self.range.state {
  155. let result = self.range.stop.clone();
  156. self.range.stop = self.range.stop.clone() - self.range.one.clone();
  157. Some(result)
  158. } else if !self.done && self.range.state == self.range.stop {
  159. self.done = true;
  160. Some(self.range.stop.clone())
  161. } else {
  162. None
  163. }
  164. }
  165. }
  166. /// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
  167. #[derive(Clone)]
  168. pub struct RangeStep<A> {
  169. state: A,
  170. stop: A,
  171. step: A,
  172. rev: bool,
  173. }
  174. /// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping.
  175. #[inline]
  176. pub fn range_step<A>(start: A, stop: A, step: A) -> RangeStep<A>
  177. where A: CheckedAdd + PartialOrd + Clone + Zero
  178. {
  179. let rev = step < Zero::zero();
  180. RangeStep{state: start, stop: stop, step: step, rev: rev}
  181. }
  182. impl<A> Iterator for RangeStep<A>
  183. where A: CheckedAdd + PartialOrd + Clone
  184. {
  185. type Item = A;
  186. #[inline]
  187. fn next(&mut self) -> Option<A> {
  188. if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
  189. let result = self.state.clone();
  190. match self.state.checked_add(&self.step) {
  191. Some(x) => self.state = x,
  192. None => self.state = self.stop.clone()
  193. }
  194. Some(result)
  195. } else {
  196. None
  197. }
  198. }
  199. }
  200. /// An iterator over the range [start, stop] by `step`. It handles overflow by stopping.
  201. #[derive(Clone)]
  202. pub struct RangeStepInclusive<A> {
  203. state: A,
  204. stop: A,
  205. step: A,
  206. rev: bool,
  207. done: bool,
  208. }
  209. /// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping.
  210. #[inline]
  211. pub fn range_step_inclusive<A>(start: A, stop: A, step: A) -> RangeStepInclusive<A>
  212. where A: CheckedAdd + PartialOrd + Clone + Zero
  213. {
  214. let rev = step < Zero::zero();
  215. RangeStepInclusive{state: start, stop: stop, step: step, rev: rev, done: false}
  216. }
  217. impl<A> Iterator for RangeStepInclusive<A>
  218. where A: CheckedAdd + PartialOrd + Clone + PartialEq
  219. {
  220. type Item = A;
  221. #[inline]
  222. fn next(&mut self) -> Option<A> {
  223. if !self.done && ((self.rev && self.state >= self.stop) ||
  224. (!self.rev && self.state <= self.stop)) {
  225. let result = self.state.clone();
  226. match self.state.checked_add(&self.step) {
  227. Some(x) => self.state = x,
  228. None => self.done = true
  229. }
  230. Some(result)
  231. } else {
  232. None
  233. }
  234. }
  235. }
  236. #[cfg(test)]
  237. mod tests {
  238. use std::usize;
  239. use std::ops::{Add, Mul};
  240. use std::cmp::Ordering;
  241. use traits::{One, ToPrimitive};
  242. #[test]
  243. fn test_range() {
  244. /// A mock type to check Range when ToPrimitive returns None
  245. struct Foo;
  246. impl ToPrimitive for Foo {
  247. fn to_i64(&self) -> Option<i64> { None }
  248. fn to_u64(&self) -> Option<u64> { None }
  249. }
  250. impl Add<Foo> for Foo {
  251. type Output = Foo;
  252. fn add(self, _: Foo) -> Foo {
  253. Foo
  254. }
  255. }
  256. impl PartialEq for Foo {
  257. fn eq(&self, _: &Foo) -> bool {
  258. true
  259. }
  260. }
  261. impl PartialOrd for Foo {
  262. fn partial_cmp(&self, _: &Foo) -> Option<Ordering> {
  263. None
  264. }
  265. }
  266. impl Clone for Foo {
  267. fn clone(&self) -> Foo {
  268. Foo
  269. }
  270. }
  271. impl Mul<Foo> for Foo {
  272. type Output = Foo;
  273. fn mul(self, _: Foo) -> Foo {
  274. Foo
  275. }
  276. }
  277. impl One for Foo {
  278. fn one() -> Foo {
  279. Foo
  280. }
  281. }
  282. assert!(super::range(0, 5).collect::<Vec<isize>>() == vec![0, 1, 2, 3, 4]);
  283. assert!(super::range(-10, -1).collect::<Vec<isize>>() ==
  284. vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
  285. assert!(super::range(0, 5).rev().collect::<Vec<isize>>() == vec![4, 3, 2, 1, 0]);
  286. assert_eq!(super::range(200, -5).count(), 0);
  287. assert_eq!(super::range(200, -5).rev().count(), 0);
  288. assert_eq!(super::range(200, 200).count(), 0);
  289. assert_eq!(super::range(200, 200).rev().count(), 0);
  290. assert_eq!(super::range(0, 100).size_hint(), (100, Some(100)));
  291. // this test is only meaningful when sizeof usize < sizeof u64
  292. assert_eq!(super::range(usize::MAX - 1, usize::MAX).size_hint(), (1, Some(1)));
  293. assert_eq!(super::range(-10, -1).size_hint(), (9, Some(9)));
  294. }
  295. #[test]
  296. fn test_range_inclusive() {
  297. assert!(super::range_inclusive(0, 5).collect::<Vec<isize>>() ==
  298. vec![0, 1, 2, 3, 4, 5]);
  299. assert!(super::range_inclusive(0, 5).rev().collect::<Vec<isize>>() ==
  300. vec![5, 4, 3, 2, 1, 0]);
  301. assert_eq!(super::range_inclusive(200, -5).count(), 0);
  302. assert_eq!(super::range_inclusive(200, -5).rev().count(), 0);
  303. assert!(super::range_inclusive(200, 200).collect::<Vec<isize>>() == vec![200]);
  304. assert!(super::range_inclusive(200, 200).rev().collect::<Vec<isize>>() == vec![200]);
  305. }
  306. #[test]
  307. fn test_range_step() {
  308. assert!(super::range_step(0, 20, 5).collect::<Vec<isize>>() ==
  309. vec![0, 5, 10, 15]);
  310. assert!(super::range_step(20, 0, -5).collect::<Vec<isize>>() ==
  311. vec![20, 15, 10, 5]);
  312. assert!(super::range_step(20, 0, -6).collect::<Vec<isize>>() ==
  313. vec![20, 14, 8, 2]);
  314. assert!(super::range_step(200u8, 255, 50).collect::<Vec<u8>>() ==
  315. vec![200u8, 250]);
  316. assert!(super::range_step(200, -5, 1).collect::<Vec<isize>>() == vec![]);
  317. assert!(super::range_step(200, 200, 1).collect::<Vec<isize>>() == vec![]);
  318. }
  319. #[test]
  320. fn test_range_step_inclusive() {
  321. assert!(super::range_step_inclusive(0, 20, 5).collect::<Vec<isize>>() ==
  322. vec![0, 5, 10, 15, 20]);
  323. assert!(super::range_step_inclusive(20, 0, -5).collect::<Vec<isize>>() ==
  324. vec![20, 15, 10, 5, 0]);
  325. assert!(super::range_step_inclusive(20, 0, -6).collect::<Vec<isize>>() ==
  326. vec![20, 14, 8, 2]);
  327. assert!(super::range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>() ==
  328. vec![200u8, 250]);
  329. assert!(super::range_step_inclusive(200, -5, 1).collect::<Vec<isize>>() ==
  330. vec![]);
  331. assert!(super::range_step_inclusive(200, 200, 1).collect::<Vec<isize>>() ==
  332. vec![200]);
  333. }
  334. }