inner_product.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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/inner_product.hpp>
  25. #include <range/v3/algorithm/equal.hpp>
  26. #include "../simple_test.hpp"
  27. #include "../test_iterators.hpp"
  28. RANGES_DIAGNOSTIC_IGNORE_SIGN_CONVERSION
  29. namespace
  30. {
  31. struct S
  32. {
  33. int i;
  34. };
  35. template<class Iter1, class Iter2, class Sent1 = Iter1>
  36. void test()
  37. {
  38. int a[] = {1, 2, 3, 4, 5, 6};
  39. int b[] = {6, 5, 4, 3, 2, 1};
  40. unsigned sa = sizeof(a) / sizeof(a[0]);
  41. // iterator test:
  42. auto it3 = [](int* b1, int l1, int* b2, int i)
  43. {
  44. return ranges::inner_product(Iter1(b1), Sent1(b1+l1), Iter2(b2), i);
  45. };
  46. CHECK(it3(a, 0, b, 0) == 0);
  47. CHECK(it3(a, 0, b, 10) == 10);
  48. CHECK(it3(a, 1, b, 0) == 6);
  49. CHECK(it3(a, 1, b, 10) == 16);
  50. CHECK(it3(a, 2, b, 0) == 16);
  51. CHECK(it3(a, 2, b, 10) == 26);
  52. CHECK(it3(a, sa, b, 0) == 56);
  53. CHECK(it3(a, sa, b, 10) == 66);
  54. auto it4 = [](int* b1, int l1, int* b2, int i)
  55. {
  56. return ranges::inner_product(Iter1(b1), Sent1(b1+l1), Iter2(b2), Iter2(b2+l1), i);
  57. };
  58. CHECK(it4(a, 0, b, 0) == 0);
  59. CHECK(it4(a, 0, b, 10) == 10);
  60. CHECK(it4(a, 1, b, 0) == 6);
  61. CHECK(it4(a, 1, b, 10) == 16);
  62. CHECK(it4(a, 2, b, 0) == 16);
  63. CHECK(it4(a, 2, b, 10) == 26);
  64. CHECK(it4(a, sa, b, 0) == 56);
  65. CHECK(it4(a, sa, b, 10) == 66);
  66. // rng test:
  67. auto rng3 = [](int* b1, int l1, int* b2, int i)
  68. {
  69. return ranges::inner_product(ranges::make_subrange(Iter1(b1), Sent1(b1+l1)), Iter2(b2), i);
  70. };
  71. CHECK(rng3(a, 0, b, 0) == 0);
  72. CHECK(rng3(a, 0, b, 10) == 10);
  73. CHECK(rng3(a, 1, b, 0) == 6);
  74. CHECK(rng3(a, 1, b, 10) == 16);
  75. CHECK(rng3(a, 2, b, 0) == 16);
  76. CHECK(rng3(a, 2, b, 10) == 26);
  77. CHECK(rng3(a, sa, b, 0) == 56);
  78. CHECK(rng3(a, sa, b, 10) == 66);
  79. auto rng4 = [](int* b1, int l1, int* b2, int i)
  80. {
  81. return ranges::inner_product(ranges::make_subrange(Iter1(b1), Sent1(b1+l1)),
  82. ranges::make_subrange(Iter2(b2), Iter2(b2+l1)), i);
  83. };
  84. CHECK(rng4(a, 0, b, 0) == 0);
  85. CHECK(rng4(a, 0, b, 10) == 10);
  86. CHECK(rng4(a, 1, b, 0) == 6);
  87. CHECK(rng4(a, 1, b, 10) == 16);
  88. CHECK(rng4(a, 2, b, 0) == 16);
  89. CHECK(rng4(a, 2, b, 10) == 26);
  90. CHECK(rng4(a, sa, b, 0) == 56);
  91. CHECK(rng4(a, sa, b, 10) == 66);
  92. // rng + bops:
  93. auto bops = [](int* b1, int l1, int* b2, int i)
  94. {
  95. return ranges::inner_product(ranges::make_subrange(Iter1(b1), Sent1(b1+l1)),
  96. ranges::make_subrange(Iter2(b2), Iter2(b2+l1)), i,
  97. std::multiplies<int>(), std::plus<int>());
  98. };
  99. CHECK(bops(a, 0, b, 1) == 1);
  100. CHECK(bops(a, 0, b, 10) == 10);
  101. CHECK(bops(a, 1, b, 1) == 7);
  102. CHECK(bops(a, 1, b, 10) == 70);
  103. CHECK(bops(a, 2, b, 1) == 49);
  104. CHECK(bops(a, 2, b, 10) == 490);
  105. CHECK(bops(a, sa, b, 1) == 117649);
  106. CHECK(bops(a, sa, b, 10) == 1176490);
  107. }
  108. }
  109. int main()
  110. {
  111. test<InputIterator<const int*>, InputIterator<const int*> >();
  112. test<InputIterator<const int*>, ForwardIterator<const int*> >();
  113. test<InputIterator<const int*>, BidirectionalIterator<const int*> >();
  114. test<InputIterator<const int*>, RandomAccessIterator<const int*> >();
  115. test<InputIterator<const int*>, const int*>();
  116. test<ForwardIterator<const int*>, InputIterator<const int*> >();
  117. test<ForwardIterator<const int*>, ForwardIterator<const int*> >();
  118. test<ForwardIterator<const int*>, BidirectionalIterator<const int*> >();
  119. test<ForwardIterator<const int*>, RandomAccessIterator<const int*> >();
  120. test<ForwardIterator<const int*>, const int*>();
  121. test<BidirectionalIterator<const int*>, InputIterator<const int*> >();
  122. test<BidirectionalIterator<const int*>, ForwardIterator<const int*> >();
  123. test<BidirectionalIterator<const int*>, BidirectionalIterator<const int*> >();
  124. test<BidirectionalIterator<const int*>, RandomAccessIterator<const int*> >();
  125. test<BidirectionalIterator<const int*>, const int*>();
  126. test<RandomAccessIterator<const int*>, InputIterator<const int*> >();
  127. test<RandomAccessIterator<const int*>, ForwardIterator<const int*> >();
  128. test<RandomAccessIterator<const int*>, BidirectionalIterator<const int*> >();
  129. test<RandomAccessIterator<const int*>, RandomAccessIterator<const int*> >();
  130. test<RandomAccessIterator<const int*>, const int*>();
  131. test<const int*, InputIterator<const int*> >();
  132. test<const int*, ForwardIterator<const int*> >();
  133. test<const int*, BidirectionalIterator<const int*> >();
  134. test<const int*, RandomAccessIterator<const int*> >();
  135. test<const int*, const int*>();
  136. // test projections:
  137. {
  138. S a[] = {{1}, {2}, {3}, {4}, {5}, {6}};
  139. S b[] = {{6}, {5}, {4}, {3}, {2}, {1}};
  140. unsigned sa = sizeof(a) / sizeof(a[0]);
  141. using Iter1 = InputIterator<const S*>;
  142. using Sent1 = InputIterator<const S*>;
  143. using Iter2 = Iter1;
  144. // rng + bops:
  145. auto bops = [&](S* b1, int l1, S* b2, int i)
  146. {
  147. return ranges::inner_product(ranges::make_subrange(Iter1(b1), Sent1(b1+l1)),
  148. ranges::make_subrange(Iter2(b2), Iter2(b2+l1)), i,
  149. std::multiplies<int>(), std::plus<int>(),
  150. &S::i, &S::i);
  151. };
  152. CHECK(bops(a, 0, b, 1) == 1);
  153. CHECK(bops(a, 0, b, 10) == 10);
  154. CHECK(bops(a, 1, b, 1) == 7);
  155. CHECK(bops(a, 1, b, 10) == 70);
  156. CHECK(bops(a, 2, b, 1) == 49);
  157. CHECK(bops(a, 2, b, 10) == 490);
  158. CHECK(bops(a, sa, b, 1) == 117649);
  159. CHECK(bops(a, sa, b, 10) == 1176490);
  160. }
  161. {
  162. int a[] = {1, 2, 3, 4, 5, 6};
  163. int b[] = {6, 5, 4, 3, 2, 1};
  164. // raw array test:
  165. CHECK(ranges::inner_product(a, b, 0) == 56);
  166. CHECK(ranges::inner_product(a, b, 10) == 66);
  167. }
  168. return ::test_result();
  169. }