partial_sum.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Range v3 library
  2. //
  3. // Copyright Eric Niebler 2014-present
  4. // Copyright Gonzalo Brito Gadeschi 2014
  5. //
  6. // Use, modification and distribution is subject to the
  7. // Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. //
  11. // Project home: https://github.com/ericniebler/range-v3
  12. //
  13. // Implementation based on the code in libc++
  14. // http://http://libcxx.llvm.org/
  15. //===----------------------------------------------------------------------===//
  16. //
  17. // The LLVM Compiler Infrastructure
  18. //
  19. // This file is dual licensed under the MIT and the University of Illinois Open
  20. // Source Licenses. See LICENSE.TXT for details.
  21. //
  22. //===----------------------------------------------------------------------===//
  23. #include <range/v3/core.hpp>
  24. #include <range/v3/numeric/partial_sum.hpp>
  25. #include <range/v3/view/zip.hpp>
  26. #include "../simple_test.hpp"
  27. #include "../test_iterators.hpp"
  28. struct S
  29. {
  30. int i;
  31. };
  32. template<class InIter, class OutIter, class InSent = InIter> void test()
  33. {
  34. using ranges::partial_sum;
  35. using ranges::make_subrange;
  36. { // iterator
  37. int ir[] = {1, 3, 6, 10, 15};
  38. const unsigned s = sizeof(ir) / sizeof(ir[0]);
  39. int ia[] = {1, 2, 3, 4, 5};
  40. int ib[s] = {0};
  41. auto r = partial_sum(InIter(ia), InSent(ia + s), OutIter(ib));
  42. CHECK(base(r.in) == ia + s);
  43. CHECK(base(r.out) == ib + s);
  44. for(unsigned i = 0; i < s; ++i)
  45. {
  46. CHECK(ib[i] == ir[i]);
  47. }
  48. }
  49. { // range + output iterator
  50. int ir[] = {1, 3, 6, 10, 15};
  51. const unsigned s = sizeof(ir) / sizeof(ir[0]);
  52. int ia[] = {1, 2, 3, 4, 5};
  53. int ib[s] = {0};
  54. auto rng = make_subrange(InIter(ia), InSent(ia + s));
  55. auto r = partial_sum(rng, OutIter(ib));
  56. CHECK(base(r.in) == ia + s);
  57. CHECK(base(r.out) == ib + s);
  58. for(unsigned i = 0; i < s; ++i)
  59. {
  60. CHECK(ib[i] == ir[i]);
  61. }
  62. }
  63. { // range + output range
  64. int ir[] = {1, 3, 6, 10, 15};
  65. const unsigned s = sizeof(ir) / sizeof(ir[0]);
  66. int ia[] = {1, 2, 3, 4, 5};
  67. int ib[s] = {0};
  68. auto rng = make_subrange(InIter(ia), InSent(ia + s));
  69. auto orng = make_subrange(OutIter(ib), OutIter(ib + s));
  70. auto r = partial_sum(rng, orng);
  71. CHECK(base(r.in) == ia + s);
  72. CHECK(base(r.out) == ib + s);
  73. for(unsigned i = 0; i < s; ++i)
  74. {
  75. CHECK(ib[i] == ir[i]);
  76. }
  77. }
  78. {
  79. int ia[] = {1, 2, 3, 4, 5};
  80. int ir[] = {1, -1, -4, -8, -13};
  81. const unsigned s = sizeof(ia) / sizeof(ia[0]);
  82. int ib[s] = {0};
  83. auto rng = make_subrange(InIter(ia), InSent(ia + s));
  84. auto orng = make_subrange(OutIter(ib), OutIter(ib + s));
  85. auto r = partial_sum(rng, orng, std::minus<int>());
  86. CHECK(base(r.in) == ia + s);
  87. CHECK(base(r.out) == ib + s);
  88. for(unsigned i = 0; i < s; ++i)
  89. {
  90. CHECK(ib[i] == ir[i]);
  91. }
  92. }
  93. }
  94. int main()
  95. {
  96. test<InputIterator<const int *>, InputIterator<int *>>();
  97. test<InputIterator<const int *>, ForwardIterator<int *>>();
  98. test<InputIterator<const int *>, BidirectionalIterator<int *>>();
  99. test<InputIterator<const int *>, RandomAccessIterator<int *>>();
  100. test<InputIterator<const int *>, int *>();
  101. test<ForwardIterator<const int *>, InputIterator<int *>>();
  102. test<ForwardIterator<const int *>, ForwardIterator<int *>>();
  103. test<ForwardIterator<const int *>, BidirectionalIterator<int *>>();
  104. test<ForwardIterator<const int *>, RandomAccessIterator<int *>>();
  105. test<ForwardIterator<const int *>, int *>();
  106. test<BidirectionalIterator<const int *>, InputIterator<int *>>();
  107. test<BidirectionalIterator<const int *>, ForwardIterator<int *>>();
  108. test<BidirectionalIterator<const int *>, BidirectionalIterator<int *>>();
  109. test<BidirectionalIterator<const int *>, RandomAccessIterator<int *>>();
  110. test<BidirectionalIterator<const int *>, int *>();
  111. test<RandomAccessIterator<const int *>, InputIterator<int *>>();
  112. test<RandomAccessIterator<const int *>, ForwardIterator<int *>>();
  113. test<RandomAccessIterator<const int *>, BidirectionalIterator<int *>>();
  114. test<RandomAccessIterator<const int *>, RandomAccessIterator<int *>>();
  115. test<RandomAccessIterator<const int *>, int *>();
  116. test<const int *, InputIterator<int *>>();
  117. test<const int *, ForwardIterator<int *>>();
  118. test<const int *, BidirectionalIterator<int *>>();
  119. test<const int *, RandomAccessIterator<int *>>();
  120. test<const int *, int *>();
  121. using ranges::partial_sum;
  122. { // Test projections
  123. S ia[] = {{1}, {2}, {3}, {4}, {5}};
  124. int ir[] = {1, 3, 6, 10, 15};
  125. const unsigned s = sizeof(ir) / sizeof(ir[0]);
  126. int ib[s] = {0};
  127. auto r = partial_sum(ranges::begin(ia), ranges::begin(ia) + s, ranges::begin(ib),
  128. std::plus<int>(), &S::i);
  129. CHECK(base(r.in) == ia + s);
  130. CHECK(base(r.out) == ib + s);
  131. for(unsigned i = 0; i < s; ++i)
  132. {
  133. CHECK(ib[i] == ir[i]);
  134. }
  135. }
  136. { // Test BinaryOp
  137. int ia[] = {1, 2, 3, 4, 5};
  138. int ir[] = {1, 2, 6, 24, 120};
  139. const unsigned s = sizeof(ir) / sizeof(ir[0]);
  140. int ib[s] = {0};
  141. auto r = partial_sum(ia, ranges::begin(ib), std::multiplies<int>());
  142. CHECK(base(r.in) == ia + s);
  143. CHECK(base(r.out) == ib + s);
  144. for(unsigned i = 0; i < s; ++i)
  145. {
  146. CHECK(ib[i] == ir[i]);
  147. }
  148. }
  149. { // Test calling it with an array
  150. int ia[] = {1, 2, 3, 4, 5};
  151. int ir[] = {1, 2, 6, 24, 120};
  152. const unsigned s = sizeof(ir) / sizeof(ir[0]);
  153. int ib[s] = {0};
  154. auto r = partial_sum(ia, ib, std::multiplies<int>());
  155. CHECK(base(r.in) == ia + s);
  156. CHECK(base(r.out) == ib + s);
  157. for(unsigned i = 0; i < s; ++i)
  158. {
  159. CHECK(ib[i] == ir[i]);
  160. }
  161. }
  162. { // Test calling it with proxy iterators
  163. using namespace ranges;
  164. int ia[] = {1, 2, 3, 4, 5};
  165. int ib[] = {99, 99, 99, 99, 99};
  166. int ir[] = {1, 2, 6, 24, 120};
  167. const unsigned s = sizeof(ir) / sizeof(ir[0]);
  168. int ic[s] = {0};
  169. auto rng = views::zip(ia, ib);
  170. using CR = iter_common_reference_t<iterator_t<decltype(rng)>>;
  171. auto r = partial_sum(rng, ic, std::multiplies<int>(), [](CR p) {return p.first;});
  172. CHECK(base(r.in) == ranges::begin(rng) + s);
  173. CHECK(base(r.out) == ic + s);
  174. for(unsigned i = 0; i < s; ++i)
  175. {
  176. CHECK(ic[i] == ir[i]);
  177. }
  178. }
  179. return ::test_result();
  180. }