lib.rs 11 KB

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