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