1 /*
2 Copyright (c) Marshall Clow 2013.
3
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7 For more information, see http://www.boost.org
8 */
9
10 #include <vector>
11 #include <functional>
12
13 #include <boost/config.hpp>
14 #include <boost/algorithm/cxx17/reduce.hpp>
15
16 #include "iterator_test.hpp"
17
18 #define BOOST_TEST_MAIN
19 #include <boost/test/unit_test.hpp>
20
21 namespace ba = boost::algorithm;
22
23 template <class Iter, class T, class Op>
24 void
test_reduce(Iter first,Iter last,T init,Op op,T x)25 test_reduce(Iter first, Iter last, T init, Op op, T x)
26 {
27 BOOST_CHECK(ba::reduce(first, last, init, op) == x);
28 }
29
30 template <class Iter, class T, class Op>
31 void
test_reduce(Iter first,Iter last,Op op,T x)32 test_reduce(Iter first, Iter last, Op op, T x)
33 {
34 BOOST_CHECK(ba::reduce(first, last, op) == x);
35 }
36
37 template <class Iter, class T>
38 void
test_reduce(Iter first,Iter last,T x)39 test_reduce(Iter first, Iter last, T x)
40 {
41 BOOST_CHECK(ba::reduce(first, last) == x);
42 }
43
44 template <class Iter>
45 void
test_init_op()46 test_init_op()
47 {
48 int ia[] = {1, 2, 3, 4, 5, 6};
49 unsigned sa = sizeof(ia) / sizeof(ia[0]);
50 test_reduce(Iter(ia), Iter(ia), 0, std::plus<int>(), 0);
51 test_reduce(Iter(ia), Iter(ia), 1, std::multiplies<int>(), 1);
52 test_reduce(Iter(ia), Iter(ia+1), 0, std::plus<int>(), 1);
53 test_reduce(Iter(ia), Iter(ia+1), 2, std::multiplies<int>(), 2);
54 test_reduce(Iter(ia), Iter(ia+2), 0, std::plus<int>(), 3);
55 test_reduce(Iter(ia), Iter(ia+2), 3, std::multiplies<int>(), 6);
56 test_reduce(Iter(ia), Iter(ia+sa), 0, std::plus<int>(), 21);
57 test_reduce(Iter(ia), Iter(ia+sa), 4, std::multiplies<int>(), 2880);
58 }
59
test_reduce_init_op()60 void test_reduce_init_op()
61 {
62 test_init_op<input_iterator<const int*> >();
63 test_init_op<forward_iterator<const int*> >();
64 test_init_op<bidirectional_iterator<const int*> >();
65 test_init_op<random_access_iterator<const int*> >();
66 test_init_op<const int*>();
67
68 {
69 char ia[] = {1, 2, 3, 4, 5, 6, 7, 8};
70 unsigned sa = sizeof(ia) / sizeof(ia[0]);
71 unsigned res = boost::algorithm::reduce(ia, ia+sa, 1U, std::multiplies<unsigned>());
72 BOOST_CHECK(res == 40320); // 8! will not fit into a char
73 }
74 }
75
76 template <class Iter>
77 void
test_init()78 test_init()
79 {
80 int ia[] = {1, 2, 3, 4, 5, 6};
81 unsigned sa = sizeof(ia) / sizeof(ia[0]);
82 test_reduce(Iter(ia), Iter(ia), 0, 0);
83 test_reduce(Iter(ia), Iter(ia), 1, 1);
84 test_reduce(Iter(ia), Iter(ia+1), 0, 1);
85 test_reduce(Iter(ia), Iter(ia+1), 2, 3);
86 test_reduce(Iter(ia), Iter(ia+2), 0, 3);
87 test_reduce(Iter(ia), Iter(ia+2), 3, 6);
88 test_reduce(Iter(ia), Iter(ia+sa), 0, 21);
89 test_reduce(Iter(ia), Iter(ia+sa), 4, 25);
90 }
91
test_reduce_init()92 void test_reduce_init()
93 {
94 test_init<input_iterator<const int*> >();
95 test_init<forward_iterator<const int*> >();
96 test_init<bidirectional_iterator<const int*> >();
97 test_init<random_access_iterator<const int*> >();
98 test_init<const int*>();
99 }
100
101
102 template <class Iter>
103 void
test()104 test()
105 {
106 int ia[] = {1, 2, 3, 4, 5, 6};
107 unsigned sa = sizeof(ia) / sizeof(ia[0]);
108 test_reduce(Iter(ia), Iter(ia), 0);
109 test_reduce(Iter(ia), Iter(ia+1), 1);
110 test_reduce(Iter(ia), Iter(ia+2), 3);
111 test_reduce(Iter(ia), Iter(ia+sa), 21);
112 }
113
test_reduce()114 void test_reduce()
115 {
116 test<input_iterator<const int*> >();
117 test<forward_iterator<const int*> >();
118 test<bidirectional_iterator<const int*> >();
119 test<random_access_iterator<const int*> >();
120 test<const int*>();
121 }
122
BOOST_AUTO_TEST_CASE(test_main)123 BOOST_AUTO_TEST_CASE( test_main )
124 {
125 test_reduce();
126 test_reduce_init();
127 test_reduce_init_op();
128 }
129