specializations.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. use itertools::Itertools;
  2. use std::fmt::Debug;
  3. use quickcheck::quickcheck;
  4. struct Unspecialized<I>(I);
  5. impl<I> Iterator for Unspecialized<I>
  6. where
  7. I: Iterator,
  8. {
  9. type Item = I::Item;
  10. #[inline(always)]
  11. fn next(&mut self) -> Option<Self::Item> {
  12. self.0.next()
  13. }
  14. }
  15. macro_rules! check_specialized {
  16. ($src:expr, |$it:pat| $closure:expr) => {
  17. let $it = $src.clone();
  18. let v1 = $closure;
  19. let $it = Unspecialized($src.clone());
  20. let v2 = $closure;
  21. assert_eq!(v1, v2);
  22. }
  23. }
  24. fn test_specializations<IterItem, Iter>(
  25. it: &Iter,
  26. ) where
  27. IterItem: Eq + Debug + Clone,
  28. Iter: Iterator<Item = IterItem> + Clone,
  29. {
  30. check_specialized!(it, |i| i.count());
  31. check_specialized!(it, |i| i.last());
  32. check_specialized!(it, |i| i.collect::<Vec<_>>());
  33. check_specialized!(it, |i| {
  34. let mut parameters_from_fold = vec![];
  35. let fold_result = i.fold(vec![], |mut acc, v: IterItem| {
  36. parameters_from_fold.push((acc.clone(), v.clone()));
  37. acc.push(v);
  38. acc
  39. });
  40. (parameters_from_fold, fold_result)
  41. });
  42. check_specialized!(it, |mut i| {
  43. let mut parameters_from_all = vec![];
  44. let first = i.next();
  45. let all_result = i.all(|x| {
  46. parameters_from_all.push(x.clone());
  47. Some(x)==first
  48. });
  49. (parameters_from_all, all_result)
  50. });
  51. let size = it.clone().count();
  52. for n in 0..size + 2 {
  53. check_specialized!(it, |mut i| i.nth(n));
  54. }
  55. // size_hint is a bit harder to check
  56. let mut it_sh = it.clone();
  57. for n in 0..size + 2 {
  58. let len = it_sh.clone().count();
  59. let (min, max) = it_sh.size_hint();
  60. assert_eq!(size - n.min(size), len);
  61. assert!(min <= len);
  62. if let Some(max) = max {
  63. assert!(len <= max);
  64. }
  65. it_sh.next();
  66. }
  67. }
  68. quickcheck! {
  69. fn intersperse(v: Vec<u8>) -> () {
  70. test_specializations(&v.into_iter().intersperse(0));
  71. }
  72. }
  73. quickcheck! {
  74. fn put_back_qc(test_vec: Vec<i32>) -> () {
  75. test_specializations(&itertools::put_back(test_vec.iter()));
  76. let mut pb = itertools::put_back(test_vec.into_iter());
  77. pb.put_back(1);
  78. test_specializations(&pb);
  79. }
  80. }
  81. quickcheck! {
  82. fn merge_join_by_qc(i1: Vec<usize>, i2: Vec<usize>) -> () {
  83. test_specializations(&i1.into_iter().merge_join_by(i2.into_iter(), std::cmp::Ord::cmp));
  84. }
  85. }
  86. quickcheck! {
  87. fn map_into(v: Vec<u8>) -> () {
  88. test_specializations(&v.into_iter().map_into::<u32>());
  89. }
  90. }
  91. quickcheck! {
  92. fn map_ok(v: Vec<Result<u8, char>>) -> () {
  93. test_specializations(&v.into_iter().map_ok(|u| u.checked_add(1)));
  94. }
  95. }
  96. quickcheck! {
  97. fn process_results(v: Vec<Result<u8, u8>>) -> () {
  98. helper(v.iter().copied());
  99. helper(v.iter().copied().filter(Result::is_ok));
  100. fn helper(it: impl Iterator<Item = Result<u8, u8>> + Clone) {
  101. macro_rules! check_results_specialized {
  102. ($src:expr, |$it:pat| $closure:expr) => {
  103. assert_eq!(
  104. itertools::process_results($src.clone(), |$it| $closure),
  105. itertools::process_results($src.clone(), |i| {
  106. let $it = Unspecialized(i);
  107. $closure
  108. }),
  109. )
  110. }
  111. }
  112. check_results_specialized!(it, |i| i.count());
  113. check_results_specialized!(it, |i| i.last());
  114. check_results_specialized!(it, |i| i.collect::<Vec<_>>());
  115. check_results_specialized!(it, |i| {
  116. let mut parameters_from_fold = vec![];
  117. let fold_result = i.fold(vec![], |mut acc, v| {
  118. parameters_from_fold.push((acc.clone(), v.clone()));
  119. acc.push(v);
  120. acc
  121. });
  122. (parameters_from_fold, fold_result)
  123. });
  124. check_results_specialized!(it, |mut i| {
  125. let mut parameters_from_all = vec![];
  126. let first = i.next();
  127. let all_result = i.all(|x| {
  128. parameters_from_all.push(x.clone());
  129. Some(x)==first
  130. });
  131. (parameters_from_all, all_result)
  132. });
  133. let size = it.clone().count();
  134. for n in 0..size + 2 {
  135. check_results_specialized!(it, |mut i| i.nth(n));
  136. }
  137. }
  138. }
  139. }