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