1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <numeric>
11
12// template <InputIterator Iter1, InputIterator Iter2, MoveConstructible T>
13//   requires HasMultiply<Iter1::reference, Iter2::reference>
14//         && HasPlus<T, HasMultiply<Iter1::reference, Iter2::reference>::result_type>
15//         && HasAssign<T,
16//                      HasPlus<T,
17//                              HasMultiply<Iter1::reference,
18//                                          Iter2::reference>::result_type>::result_type>
19//   T
20//   inner_product(Iter1 first1, Iter1 last1, Iter2 first2, T init);
21
22#include <numeric>
23#include <cassert>
24
25#include "test_iterators.h"
26
27template <class Iter1, class Iter2, class T>
28void
29test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x)
30{
31    assert(std::inner_product(first1, last1, first2, init) == x);
32}
33
34template <class Iter1, class Iter2>
35void
36test()
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    test(Iter1(a), Iter1(a), Iter2(b), 0, 0);
42    test(Iter1(a), Iter1(a), Iter2(b), 10, 10);
43    test(Iter1(a), Iter1(a+1), Iter2(b), 0, 6);
44    test(Iter1(a), Iter1(a+1), Iter2(b), 10, 16);
45    test(Iter1(a), Iter1(a+2), Iter2(b), 0, 16);
46    test(Iter1(a), Iter1(a+2), Iter2(b), 10, 26);
47    test(Iter1(a), Iter1(a+sa), Iter2(b), 0, 56);
48    test(Iter1(a), Iter1(a+sa), Iter2(b), 10, 66);
49}
50
51int main()
52{
53    test<input_iterator<const int*>, input_iterator<const int*> >();
54    test<input_iterator<const int*>, forward_iterator<const int*> >();
55    test<input_iterator<const int*>, bidirectional_iterator<const int*> >();
56    test<input_iterator<const int*>, random_access_iterator<const int*> >();
57    test<input_iterator<const int*>, const int*>();
58
59    test<forward_iterator<const int*>, input_iterator<const int*> >();
60    test<forward_iterator<const int*>, forward_iterator<const int*> >();
61    test<forward_iterator<const int*>, bidirectional_iterator<const int*> >();
62    test<forward_iterator<const int*>, random_access_iterator<const int*> >();
63    test<forward_iterator<const int*>, const int*>();
64
65    test<bidirectional_iterator<const int*>, input_iterator<const int*> >();
66    test<bidirectional_iterator<const int*>, forward_iterator<const int*> >();
67    test<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >();
68    test<bidirectional_iterator<const int*>, random_access_iterator<const int*> >();
69    test<bidirectional_iterator<const int*>, const int*>();
70
71    test<random_access_iterator<const int*>, input_iterator<const int*> >();
72    test<random_access_iterator<const int*>, forward_iterator<const int*> >();
73    test<random_access_iterator<const int*>, bidirectional_iterator<const int*> >();
74    test<random_access_iterator<const int*>, random_access_iterator<const int*> >();
75    test<random_access_iterator<const int*>, const int*>();
76
77    test<const int*, input_iterator<const int*> >();
78    test<const int*, forward_iterator<const int*> >();
79    test<const int*, bidirectional_iterator<const int*> >();
80    test<const int*, random_access_iterator<const int*> >();
81    test<const int*, const int*>();
82}
83