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 <boost/config.hpp>
11 #include <boost/algorithm/cxx14/equal.hpp>
12 
13 #include "iterator_test.hpp"
14 
15 #define BOOST_TEST_MAIN
16 #include <boost/test/unit_test.hpp>
17 
18 template <typename T>
eq(const T & a,const T & b)19 BOOST_CXX14_CONSTEXPR bool eq ( const T& a, const T& b ) { return a == b; }
20 
21 template <typename T>
never_eq(const T &,const T &)22 bool never_eq ( const T&, const T& ) { return false; }
23 
24 int comparison_count = 0;
25 template <typename T>
counting_equals(const T & a,const T & b)26 bool counting_equals ( const T &a, const T &b ) {
27     ++comparison_count;
28     return a == b;
29     }
30 
31 namespace ba = boost::algorithm;
32 
test_equal()33 void test_equal ()
34 {
35 //  Note: The literal values here are tested against directly, careful if you change them:
36     int num[] = { 1, 1, 2, 3, 5 };
37     const int sz = sizeof (num)/sizeof(num[0]);
38 
39 
40 //  Empty sequences are equal to each other, but not to non-empty sequences
41     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num),
42                               input_iterator<int *>(num),     input_iterator<int *>(num)));
43     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num),
44                               input_iterator<int *>(num),     input_iterator<int *>(num),
45                               never_eq<int> ));
46     BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num),     random_access_iterator<int *>(num),
47                               random_access_iterator<int *>(num),     random_access_iterator<int *>(num),
48                               never_eq<int> ));
49 
50     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num),
51                               input_iterator<int *>(num),     input_iterator<int *>(num + 1)));
52     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
53                               input_iterator<int *>(num),     input_iterator<int *>(num)));
54     BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + 2),
55                               random_access_iterator<int *>(num),     random_access_iterator<int *>(num)));
56 
57 //  Single element sequences are equal if they contain the same value
58     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + 1),
59                               input_iterator<int *>(num),     input_iterator<int *>(num + 1)));
60     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + 1),
61                               input_iterator<int *>(num),     input_iterator<int *>(num + 1),
62                               eq<int> ));
63     BOOST_CHECK ( ba::equal ( random_access_iterator<int *>(num),     random_access_iterator<int *>(num + 1),
64                               random_access_iterator<int *>(num),     random_access_iterator<int *>(num + 1),
65                               eq<int> ));
66     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + 1),
67                               input_iterator<int *>(num),     input_iterator<int *>(num + 1),
68                               never_eq<int> ));
69     BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num),     random_access_iterator<int *>(num + 1),
70                               random_access_iterator<int *>(num),     random_access_iterator<int *>(num + 1),
71                               never_eq<int> ));
72 
73     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + 1),
74                               input_iterator<int *>(num + 1), input_iterator<int *>(num + 2)));
75     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + 1),
76                               input_iterator<int *>(num + 1), input_iterator<int *>(num + 2),
77                               eq<int> ));
78 
79     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
80                               input_iterator<int *>(num),     input_iterator<int *>(num + 1)));
81     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 2), input_iterator<int *>(num + 3),
82                               input_iterator<int *>(num),     input_iterator<int *>(num + 1),
83                               eq<int> ));
84 
85 //  Identical long sequences are equal.
86     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + sz),
87                               input_iterator<int *>(num),     input_iterator<int *>(num + sz)));
88     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + sz),
89                               input_iterator<int *>(num),     input_iterator<int *>(num + sz),
90                               eq<int> ));
91     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + sz),
92                               input_iterator<int *>(num),     input_iterator<int *>(num + sz),
93                               never_eq<int> ));
94     BOOST_CHECK ( ba::equal ( input_iterator<int *>(num),             input_iterator<int *>(num + sz),
95                               random_access_iterator<int *>(num),     random_access_iterator<int *>(num + sz),
96                               eq<int> ));
97 
98 //  different sequences are different
99     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
100                               input_iterator<int *>(num),     input_iterator<int *>(num + sz)));
101     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
102                               input_iterator<int *>(num),     input_iterator<int *>(num + sz),
103                               eq<int> ));
104     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + sz),
105                               input_iterator<int *>(num),     input_iterator<int *>(num + sz - 1)));
106     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + sz),
107                               input_iterator<int *>(num),     input_iterator<int *>(num + sz - 1),
108                               eq<int> ));
109 
110 //  When there's a cheap check, bail early
111     comparison_count = 0;
112     BOOST_CHECK (!ba::equal ( random_access_iterator<int *>(num),     random_access_iterator<int *>(num + sz),
113                               random_access_iterator<int *>(num),     random_access_iterator<int *>(num + sz - 1),
114                               counting_equals<int> ));
115     BOOST_CHECK ( comparison_count == 0 );
116 //  And when there's not, we can't
117     comparison_count = 0;
118     BOOST_CHECK (!ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + sz),
119                               input_iterator<int *>(num),     input_iterator<int *>(num + sz - 1),
120                               counting_equals<int> ));
121     BOOST_CHECK ( comparison_count > 0 );
122 
123 }
124 
125 
test_constexpr_equal()126 BOOST_CXX14_CONSTEXPR bool test_constexpr_equal() {
127     int num[] = { 1, 1, 2, 3, 5};
128     const int sz = sizeof (num)/sizeof(num[0]);
129     bool res = true;
130 //  Empty sequences are equal to each other
131     res = (   ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num),
132                           input_iterator<int *>(num),     input_iterator<int *>(num))
133 //  Identical long sequences are equal
134            && ba::equal ( input_iterator<int *>(num),     input_iterator<int *>(num + sz),
135                           input_iterator<int *>(num),     input_iterator<int *>(num + sz),
136                           eq<int> )
137 //  Different sequences are different
138            && !ba::equal ( input_iterator<int *>(num + 1), input_iterator<int *>(num + sz),
139                            input_iterator<int *>(num),     input_iterator<int *>(num + sz))
140           );
141 #ifdef __cpp_lib_array_constexpr // or cpp17 compiler
142 //  Turn on tests for random_access_iterator, because std functions used in equal are marked constexpr_res
143     res = ( res
144 //  Empty sequences are equal to each other
145            && ba::equal ( random_access_iterator<int *>(num),     random_access_iterator<int *>(num),
146                           random_access_iterator<int *>(num),     random_access_iterator<int *>(num))
147 //  Identical long sequences are equal
148            && ba::equal ( random_access_iterator<int *>(num),     random_access_iterator<int *>(num + sz),
149                           random_access_iterator<int *>(num),     random_access_iterator<int *>(num + sz),
150                           eq<int> )
151 //  Different sequences are different
152            && !ba::equal ( random_access_iterator<int *>(num + 1), random_access_iterator<int *>(num + sz),
153                            random_access_iterator<int *>(num),     random_access_iterator<int *>(num + sz))
154           );
155 #endif
156     return res;
157   }
158 
159 
BOOST_AUTO_TEST_CASE(test_main)160 BOOST_AUTO_TEST_CASE( test_main )
161 {
162   test_equal ();
163   BOOST_CXX14_CONSTEXPR bool constexpr_res = test_constexpr_equal ();
164   BOOST_CHECK (constexpr_res);
165 }
166