1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // <numeric> 10 11 // Became constexpr in C++20 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_macros.h" 26 #include "test_iterators.h" 27 28 template <class Iter1, class Iter2, class T> 29 TEST_CONSTEXPR_CXX20 void 30 test(Iter1 first1, Iter1 last1, Iter2 first2, T init, T x) 31 { 32 assert(std::inner_product(first1, last1, first2, init) == x); 33 } 34 35 template <class Iter1, class Iter2> 36 TEST_CONSTEXPR_CXX20 void 37 test() 38 { 39 int a[] = {1, 2, 3, 4, 5, 6}; 40 int b[] = {6, 5, 4, 3, 2, 1}; 41 unsigned sa = sizeof(a) / sizeof(a[0]); 42 test(Iter1(a), Iter1(a), Iter2(b), 0, 0); 43 test(Iter1(a), Iter1(a), Iter2(b), 10, 10); 44 test(Iter1(a), Iter1(a+1), Iter2(b), 0, 6); 45 test(Iter1(a), Iter1(a+1), Iter2(b), 10, 16); 46 test(Iter1(a), Iter1(a+2), Iter2(b), 0, 16); 47 test(Iter1(a), Iter1(a+2), Iter2(b), 10, 26); 48 test(Iter1(a), Iter1(a+sa), Iter2(b), 0, 56); 49 test(Iter1(a), Iter1(a+sa), Iter2(b), 10, 66); 50 } 51 52 TEST_CONSTEXPR_CXX20 bool 53 test() 54 { 55 test<cpp17_input_iterator<const int*>, cpp17_input_iterator<const int*> >(); 56 test<cpp17_input_iterator<const int*>, forward_iterator<const int*> >(); 57 test<cpp17_input_iterator<const int*>, bidirectional_iterator<const int*> >(); 58 test<cpp17_input_iterator<const int*>, random_access_iterator<const int*> >(); 59 test<cpp17_input_iterator<const int*>, const int*>(); 60 61 test<forward_iterator<const int*>, cpp17_input_iterator<const int*> >(); 62 test<forward_iterator<const int*>, forward_iterator<const int*> >(); 63 test<forward_iterator<const int*>, bidirectional_iterator<const int*> >(); 64 test<forward_iterator<const int*>, random_access_iterator<const int*> >(); 65 test<forward_iterator<const int*>, const int*>(); 66 67 test<bidirectional_iterator<const int*>, cpp17_input_iterator<const int*> >(); 68 test<bidirectional_iterator<const int*>, forward_iterator<const int*> >(); 69 test<bidirectional_iterator<const int*>, bidirectional_iterator<const int*> >(); 70 test<bidirectional_iterator<const int*>, random_access_iterator<const int*> >(); 71 test<bidirectional_iterator<const int*>, const int*>(); 72 73 test<random_access_iterator<const int*>, cpp17_input_iterator<const int*> >(); 74 test<random_access_iterator<const int*>, forward_iterator<const int*> >(); 75 test<random_access_iterator<const int*>, bidirectional_iterator<const int*> >(); 76 test<random_access_iterator<const int*>, random_access_iterator<const int*> >(); 77 test<random_access_iterator<const int*>, const int*>(); 78 79 test<const int*, cpp17_input_iterator<const int*> >(); 80 test<const int*, forward_iterator<const int*> >(); 81 test<const int*, bidirectional_iterator<const int*> >(); 82 test<const int*, random_access_iterator<const int*> >(); 83 test<const int*, const int*>(); 84 85 return true; 86 } 87 88 int main(int, char**) 89 { 90 test(); 91 #if TEST_STD_VER > 17 92 static_assert(test()); 93 #endif 94 return 0; 95 } 96