iterator.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "simple/support/iterator.hpp"
  2. #include <vector>
  3. #include <algorithm>
  4. #include <cassert>
  5. using namespace simple::support;
  6. void Offset()
  7. {
  8. std::vector x{10};
  9. offset_iterator ofi {x};
  10. while(*ofi != 0) x.push_back(*ofi++ - 1);
  11. assert(( x == std::vector{10,9,8,7,6,5,4,3,2,1,0} ));
  12. }
  13. void OffsetExpander()
  14. {
  15. std::vector x{10};
  16. offset_expander ofe {x};
  17. offset_expander prev = ofe++;
  18. while(*prev != 0) *ofe++ = *prev++ - 1;
  19. assert(( x == std::vector{10,9,8,7,6,5,4,3,2,1,0} ));
  20. }
  21. void OutAccumulate()
  22. {
  23. std::vector x{1,2,3,4,5,6,7,8,9,10};
  24. assert(( std::copy_if(x.begin(), x.end(), out_accumulate(0), [](auto x){ return x%2 == 0;} ).accumulator == 30 ));
  25. assert(( std::copy_if(x.begin(), x.end(), out_accumulate(0), [](auto x){ return x%2 == 1;} ).accumulator == 25 ));
  26. }
  27. void OutTransform()
  28. {
  29. std::vector x{1,2,3,4,5,6,7,8,9,10};
  30. auto end = std::copy_if(x.begin(), x.end(),
  31. out_transform([](auto x){ return x + 2; }, x.begin()),
  32. [](auto x) { return x%3 == 0; }
  33. ).out;
  34. std::vector y{5,8,11};
  35. assert(( std::equal(x.begin(), end, y.begin(), y.end()) ));
  36. }
  37. void OutFilter()
  38. {
  39. // omg omg, is transform going to be applied twice, once for filter condition and once again for assignment??
  40. // do I need to cache the valueeeee omgggg?!
  41. // no... nothing of sorts... who hurt you so?
  42. {
  43. std::vector x{1,2,3,4,5,6,7,8,9,10};
  44. auto end = std::transform(x.begin(), x.end(),
  45. out_filter([](auto x){ return x%3 == 0; }, x.begin()),
  46. [](auto x){ return x + 2; }
  47. ).out;
  48. std::vector y{3,6,9,12};
  49. assert(( std::equal(x.begin(), end, y.begin(), y.end()) ));
  50. }
  51. {
  52. std::vector x{1,2,3,4,5,6,7,8,9,10};
  53. auto end = std::copy(x.begin(), x.end(),
  54. out_transform([](auto x){ return x + 2; },
  55. out_filter([](auto x){ return x%3 == 0; }, x.begin()
  56. ))).out.out;
  57. std::vector y{3,6,9,12};
  58. assert(( std::equal(x.begin(), end, y.begin(), y.end()) ));
  59. }
  60. {
  61. std::vector x{1,2,3,4,5,6,7,8,9,10};
  62. std::vector y{21,22};
  63. std::copy(x.begin(), x.end(),
  64. out_transform([](auto x){ return x + 2; },
  65. out_filter([](auto x){ return x%3 == 0; },
  66. offset_expander(y)
  67. )));
  68. assert(( y == std::vector{3,6,9,12} ));
  69. }
  70. }
  71. void OutFlattenRange()
  72. {
  73. std::vector x {
  74. std::vector{0},
  75. std::vector{1,2},
  76. std::vector{3,4,5,6},
  77. std::vector{0},
  78. std::vector{0},
  79. std::vector{7},
  80. std::vector{8,9,10},
  81. std::vector{0}
  82. };
  83. std::vector y(10,0);
  84. std::copy_if(x.begin(), x.end(), out_flatten_range(y.begin()),
  85. [](auto& x) { return x != std::vector{0}; });
  86. assert(( y == std::vector{1,2,3,4,5,6,7,8,9,10} ));
  87. }
  88. void OutFlattenTuple()
  89. {
  90. std::vector x {
  91. std::tuple{0,0,0},
  92. std::tuple{1,2,3},
  93. std::tuple{4,5,6},
  94. std::tuple{0,0,0},
  95. std::tuple{0,0,0},
  96. std::tuple{7,8,9},
  97. std::tuple{0,0,0},
  98. };
  99. std::vector y(9,0);
  100. std::copy_if(x.begin(), x.end(), out_flatten_tuple(y.begin()),
  101. [](auto& x) { return x != std::tuple{0,0,0}; });
  102. assert(( y == std::vector{1,2,3,4,5,6,7,8,9} ));
  103. }
  104. void OutInvoke()
  105. {
  106. std::vector x {
  107. std::vector{1,2,3},
  108. std::vector{1,3,2},
  109. std::vector{1,2,3},
  110. std::vector{1,2,3},
  111. std::vector{3,1,2},
  112. std::vector{2,3,1},
  113. std::vector{1,2,3},
  114. std::vector{3,2,1}
  115. };
  116. std::copy_if(x.begin(), x.end(),
  117. out_invoke([](auto& x) { std::sort(x.begin(), x.end()); }),
  118. [](auto& x) { return not std::is_sorted(x.begin(), x.end()); }
  119. );
  120. assert(( x == std::vector{
  121. std::vector{1,2,3},
  122. std::vector{1,2,3},
  123. std::vector{1,2,3},
  124. std::vector{1,2,3},
  125. std::vector{1,2,3},
  126. std::vector{1,2,3},
  127. std::vector{1,2,3},
  128. std::vector{1,2,3}
  129. } ));
  130. }
  131. void OutOptional()
  132. {
  133. const int a = 1, b = 2, c = 3, d = 4;
  134. std::vector<const int*> x{&a, nullptr, &b, &c, nullptr, nullptr, nullptr, &d};
  135. std::vector y(4,0);
  136. std::copy(x.begin(), x.end(), out_optional(y.begin()));
  137. assert(( y == std::vector{1,2,3,4} ));
  138. }
  139. void OutPartition()
  140. {
  141. {
  142. std::vector x{1,2,3,4,5,6,7,8,9,10};
  143. auto part = std::copy_if(x.begin(), x.end(),
  144. out_partition([](auto x) { return x%2 == 0; }, x.begin(), x.begin()),
  145. [](auto x) { return x > 3; }
  146. );
  147. std::vector y{4,6,8,10};
  148. assert(( std::equal(x.begin(), part.partition_point, y.begin(), y.end()) ));
  149. std::vector z{4,6,8,10, 5,9,7};
  150. assert(( std::equal(x.begin(), part.out, z.begin(), z.end()) ));
  151. assert(( x == std::vector{4,6,8,10, 5,9,7, 8,9,10} ));
  152. }
  153. {
  154. std::vector x{1,2,3,4,5,6,7,8,9,10};
  155. std::vector y{99,88};
  156. auto part = std::copy(x.begin(), x.end(),
  157. out_filter([](auto x) { return x > 3; },
  158. out_partition([](auto x) { return x%2 == 0; }, offset_iterator(y),
  159. out_transform([](auto x) { return x + x; },
  160. offset_expander(y)
  161. )))).out.partition_point.base();
  162. std::vector z{8,12,16,20};
  163. assert(( std::equal(y.begin(), part, z.begin(), z.end()) ));
  164. std::vector w{10,18,14};
  165. assert(( std::equal(part, y.end(), w.begin(), w.end()) ));
  166. assert(( y == std::vector{8,12,16,20, 10,18,14} ));
  167. }
  168. }
  169. int main()
  170. {
  171. Offset();
  172. OffsetExpander();
  173. OutAccumulate();
  174. OutTransform();
  175. OutFilter();
  176. OutFlattenRange();
  177. OutFlattenTuple();
  178. OutInvoke();
  179. OutOptional();
  180. OutPartition();
  181. return 0;
  182. }