Chris@16
|
1 // Boost.Range library
|
Chris@16
|
2 //
|
Chris@16
|
3 // Copyright Neil Groves 2009.
|
Chris@16
|
4 // Use, modification and distribution is subject to the Boost Software
|
Chris@16
|
5 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
6 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 //
|
Chris@16
|
8 // For more information, see http://www.boost.org/libs/range/
|
Chris@16
|
9 //
|
Chris@16
|
10 #ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
|
Chris@16
|
11 #define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/config.hpp>
|
Chris@16
|
14 #include <boost/range/concepts.hpp>
|
Chris@16
|
15 #include <iterator>
|
Chris@16
|
16
|
Chris@16
|
17 namespace boost
|
Chris@16
|
18 {
|
Chris@16
|
19 namespace range_detail
|
Chris@16
|
20 {
|
Chris@16
|
21 // An implementation of equality comparison that is optimized for iterator
|
Chris@16
|
22 // traversal categories less than RandomAccessTraversal.
|
Chris@16
|
23 template< class SinglePassTraversalReadableIterator1,
|
Chris@16
|
24 class SinglePassTraversalReadableIterator2,
|
Chris@16
|
25 class IteratorCategoryTag1,
|
Chris@16
|
26 class IteratorCategoryTag2 >
|
Chris@16
|
27 inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
|
Chris@16
|
28 SinglePassTraversalReadableIterator1 last1,
|
Chris@16
|
29 SinglePassTraversalReadableIterator2 first2,
|
Chris@16
|
30 SinglePassTraversalReadableIterator2 last2,
|
Chris@16
|
31 IteratorCategoryTag1,
|
Chris@16
|
32 IteratorCategoryTag2 )
|
Chris@16
|
33 {
|
Chris@101
|
34 for (;;)
|
Chris@16
|
35 {
|
Chris@16
|
36 // If we have reached the end of the left range then this is
|
Chris@16
|
37 // the end of the loop. They are equal if and only if we have
|
Chris@16
|
38 // simultaneously reached the end of the right range.
|
Chris@16
|
39 if (first1 == last1)
|
Chris@16
|
40 return first2 == last2;
|
Chris@16
|
41
|
Chris@16
|
42 // If we have reached the end of the right range at this line
|
Chris@16
|
43 // it indicates that the right range is shorter than the left
|
Chris@16
|
44 // and hence the result is false.
|
Chris@16
|
45 if (first2 == last2)
|
Chris@16
|
46 return false;
|
Chris@16
|
47
|
Chris@16
|
48 // continue looping if and only if the values are equal
|
Chris@16
|
49 if (*first1 != *first2)
|
Chris@16
|
50 break;
|
Chris@16
|
51
|
Chris@16
|
52 ++first1;
|
Chris@16
|
53 ++first2;
|
Chris@16
|
54 }
|
Chris@16
|
55
|
Chris@16
|
56 // Reaching this line in the algorithm indicates that a value
|
Chris@16
|
57 // inequality has been detected.
|
Chris@16
|
58 return false;
|
Chris@16
|
59 }
|
Chris@16
|
60
|
Chris@16
|
61 template< class SinglePassTraversalReadableIterator1,
|
Chris@16
|
62 class SinglePassTraversalReadableIterator2,
|
Chris@16
|
63 class IteratorCategoryTag1,
|
Chris@16
|
64 class IteratorCategoryTag2,
|
Chris@16
|
65 class BinaryPredicate >
|
Chris@16
|
66 inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
|
Chris@16
|
67 SinglePassTraversalReadableIterator1 last1,
|
Chris@16
|
68 SinglePassTraversalReadableIterator2 first2,
|
Chris@16
|
69 SinglePassTraversalReadableIterator2 last2,
|
Chris@16
|
70 BinaryPredicate pred,
|
Chris@16
|
71 IteratorCategoryTag1,
|
Chris@16
|
72 IteratorCategoryTag2 )
|
Chris@16
|
73 {
|
Chris@101
|
74 for (;;)
|
Chris@16
|
75 {
|
Chris@16
|
76 // If we have reached the end of the left range then this is
|
Chris@16
|
77 // the end of the loop. They are equal if and only if we have
|
Chris@16
|
78 // simultaneously reached the end of the right range.
|
Chris@16
|
79 if (first1 == last1)
|
Chris@16
|
80 return first2 == last2;
|
Chris@16
|
81
|
Chris@16
|
82 // If we have reached the end of the right range at this line
|
Chris@16
|
83 // it indicates that the right range is shorter than the left
|
Chris@16
|
84 // and hence the result is false.
|
Chris@16
|
85 if (first2 == last2)
|
Chris@16
|
86 return false;
|
Chris@16
|
87
|
Chris@16
|
88 // continue looping if and only if the values are equal
|
Chris@16
|
89 if (!pred(*first1, *first2))
|
Chris@16
|
90 break;
|
Chris@16
|
91
|
Chris@16
|
92 ++first1;
|
Chris@16
|
93 ++first2;
|
Chris@16
|
94 }
|
Chris@16
|
95
|
Chris@16
|
96 // Reaching this line in the algorithm indicates that a value
|
Chris@16
|
97 // inequality has been detected.
|
Chris@16
|
98 return false;
|
Chris@16
|
99 }
|
Chris@16
|
100
|
Chris@16
|
101 // An implementation of equality comparison that is optimized for
|
Chris@16
|
102 // random access iterators.
|
Chris@16
|
103 template< class RandomAccessTraversalReadableIterator1,
|
Chris@16
|
104 class RandomAccessTraversalReadableIterator2 >
|
Chris@16
|
105 inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
|
Chris@16
|
106 RandomAccessTraversalReadableIterator1 last1,
|
Chris@16
|
107 RandomAccessTraversalReadableIterator2 first2,
|
Chris@16
|
108 RandomAccessTraversalReadableIterator2 last2,
|
Chris@16
|
109 std::random_access_iterator_tag,
|
Chris@16
|
110 std::random_access_iterator_tag )
|
Chris@16
|
111 {
|
Chris@16
|
112 return ((last1 - first1) == (last2 - first2))
|
Chris@16
|
113 && std::equal(first1, last1, first2);
|
Chris@16
|
114 }
|
Chris@16
|
115
|
Chris@16
|
116 template< class RandomAccessTraversalReadableIterator1,
|
Chris@16
|
117 class RandomAccessTraversalReadableIterator2,
|
Chris@16
|
118 class BinaryPredicate >
|
Chris@16
|
119 inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
|
Chris@16
|
120 RandomAccessTraversalReadableIterator1 last1,
|
Chris@16
|
121 RandomAccessTraversalReadableIterator2 first2,
|
Chris@16
|
122 RandomAccessTraversalReadableIterator2 last2,
|
Chris@101
|
123 BinaryPredicate pred,
|
Chris@101
|
124 std::random_access_iterator_tag,
|
Chris@101
|
125 std::random_access_iterator_tag )
|
Chris@16
|
126 {
|
Chris@16
|
127 return ((last1 - first1) == (last2 - first2))
|
Chris@16
|
128 && std::equal(first1, last1, first2, pred);
|
Chris@16
|
129 }
|
Chris@16
|
130
|
Chris@16
|
131 template< class SinglePassTraversalReadableIterator1,
|
Chris@16
|
132 class SinglePassTraversalReadableIterator2 >
|
Chris@16
|
133 inline bool equal( SinglePassTraversalReadableIterator1 first1,
|
Chris@16
|
134 SinglePassTraversalReadableIterator1 last1,
|
Chris@16
|
135 SinglePassTraversalReadableIterator2 first2,
|
Chris@16
|
136 SinglePassTraversalReadableIterator2 last2 )
|
Chris@16
|
137 {
|
Chris@16
|
138 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
|
Chris@16
|
139 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
|
Chris@16
|
140
|
Chris@16
|
141 return equal_impl(first1, last1, first2, last2, tag1, tag2);
|
Chris@16
|
142 }
|
Chris@16
|
143
|
Chris@16
|
144 template< class SinglePassTraversalReadableIterator1,
|
Chris@16
|
145 class SinglePassTraversalReadableIterator2,
|
Chris@16
|
146 class BinaryPredicate >
|
Chris@16
|
147 inline bool equal( SinglePassTraversalReadableIterator1 first1,
|
Chris@16
|
148 SinglePassTraversalReadableIterator1 last1,
|
Chris@16
|
149 SinglePassTraversalReadableIterator2 first2,
|
Chris@16
|
150 SinglePassTraversalReadableIterator2 last2,
|
Chris@16
|
151 BinaryPredicate pred )
|
Chris@16
|
152 {
|
Chris@16
|
153 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
|
Chris@16
|
154 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
|
Chris@16
|
155
|
Chris@16
|
156 return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 } // namespace range_detail
|
Chris@16
|
160
|
Chris@16
|
161 namespace range
|
Chris@16
|
162 {
|
Chris@16
|
163
|
Chris@16
|
164 /// \brief template function equal
|
Chris@16
|
165 ///
|
Chris@16
|
166 /// range-based version of the equal std algorithm
|
Chris@16
|
167 ///
|
Chris@16
|
168 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
|
Chris@16
|
169 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
|
Chris@16
|
170 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
|
Chris@16
|
171 template< class SinglePassRange1, class SinglePassRange2 >
|
Chris@16
|
172 inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
|
Chris@16
|
173 {
|
Chris@16
|
174 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
Chris@16
|
175 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
Chris@16
|
176
|
Chris@16
|
177 return ::boost::range_detail::equal(
|
Chris@16
|
178 ::boost::begin(rng1), ::boost::end(rng1),
|
Chris@16
|
179 ::boost::begin(rng2), ::boost::end(rng2) );
|
Chris@16
|
180 }
|
Chris@16
|
181
|
Chris@16
|
182 /// \overload
|
Chris@16
|
183 template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
|
Chris@16
|
184 inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
|
Chris@16
|
185 BinaryPredicate pred )
|
Chris@16
|
186 {
|
Chris@16
|
187 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
|
Chris@16
|
188 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
|
Chris@16
|
189
|
Chris@16
|
190 return ::boost::range_detail::equal(
|
Chris@16
|
191 ::boost::begin(rng1), ::boost::end(rng1),
|
Chris@16
|
192 ::boost::begin(rng2), ::boost::end(rng2),
|
Chris@16
|
193 pred);
|
Chris@16
|
194 }
|
Chris@16
|
195
|
Chris@16
|
196 } // namespace range
|
Chris@16
|
197 using ::boost::range::equal;
|
Chris@16
|
198 } // namespace boost
|
Chris@16
|
199
|
Chris@16
|
200 #endif // include guard
|