lib.rs 11 KB

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