3 // Copyright Neil Groves 2009.
4 // Use, modification and distribution is subject to the Boost Software
5 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // For more information, see http://www.boost.org/libs/range/
10 #ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
11 #define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
13 #include <boost/config.hpp>
14 #include <boost/range/concepts.hpp>
19 namespace range_detail
21 // An implementation of equality comparison that is optimized for iterator
22 // traversal categories less than RandomAccessTraversal.
23 template< class SinglePassTraversalReadableIterator1,
24 class SinglePassTraversalReadableIterator2,
25 class IteratorCategoryTag1,
26 class IteratorCategoryTag2 >
27 inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
28 SinglePassTraversalReadableIterator1 last1,
29 SinglePassTraversalReadableIterator2 first2,
30 SinglePassTraversalReadableIterator2 last2,
32 IteratorCategoryTag2 )
36 // If we have reached the end of the left range then this is
37 // the end of the loop. They are equal if and only if we have
38 // simultaneously reached the end of the right range.
40 return first2 == last2;
42 // If we have reached the end of the right range at this line
43 // it indicates that the right range is shorter than the left
44 // and hence the result is false.
48 // continue looping if and only if the values are equal
49 if (*first1 != *first2)
56 // Reaching this line in the algorithm indicates that a value
57 // inequality has been detected.
61 template< class SinglePassTraversalReadableIterator1,
62 class SinglePassTraversalReadableIterator2,
63 class IteratorCategoryTag1,
64 class IteratorCategoryTag2,
65 class BinaryPredicate >
66 inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
67 SinglePassTraversalReadableIterator1 last1,
68 SinglePassTraversalReadableIterator2 first2,
69 SinglePassTraversalReadableIterator2 last2,
72 IteratorCategoryTag2 )
76 // If we have reached the end of the left range then this is
77 // the end of the loop. They are equal if and only if we have
78 // simultaneously reached the end of the right range.
80 return first2 == last2;
82 // If we have reached the end of the right range at this line
83 // it indicates that the right range is shorter than the left
84 // and hence the result is false.
88 // continue looping if and only if the values are equal
89 if (!pred(*first1, *first2))
96 // Reaching this line in the algorithm indicates that a value
97 // inequality has been detected.
101 // An implementation of equality comparison that is optimized for
102 // random access iterators.
103 template< class RandomAccessTraversalReadableIterator1,
104 class RandomAccessTraversalReadableIterator2 >
105 inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
106 RandomAccessTraversalReadableIterator1 last1,
107 RandomAccessTraversalReadableIterator2 first2,
108 RandomAccessTraversalReadableIterator2 last2,
109 std::random_access_iterator_tag,
110 std::random_access_iterator_tag )
112 return ((last1 - first1) == (last2 - first2))
113 && std::equal(first1, last1, first2);
116 template< class RandomAccessTraversalReadableIterator1,
117 class RandomAccessTraversalReadableIterator2,
118 class BinaryPredicate >
119 inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
120 RandomAccessTraversalReadableIterator1 last1,
121 RandomAccessTraversalReadableIterator2 first2,
122 RandomAccessTraversalReadableIterator2 last2,
123 BinaryPredicate pred )
125 return ((last1 - first1) == (last2 - first2))
126 && std::equal(first1, last1, first2, pred);
129 template< class SinglePassTraversalReadableIterator1,
130 class SinglePassTraversalReadableIterator2 >
131 inline bool equal( SinglePassTraversalReadableIterator1 first1,
132 SinglePassTraversalReadableIterator1 last1,
133 SinglePassTraversalReadableIterator2 first2,
134 SinglePassTraversalReadableIterator2 last2 )
136 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
137 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
139 return equal_impl(first1, last1, first2, last2, tag1, tag2);
142 template< class SinglePassTraversalReadableIterator1,
143 class SinglePassTraversalReadableIterator2,
144 class BinaryPredicate >
145 inline bool equal( SinglePassTraversalReadableIterator1 first1,
146 SinglePassTraversalReadableIterator1 last1,
147 SinglePassTraversalReadableIterator2 first2,
148 SinglePassTraversalReadableIterator2 last2,
149 BinaryPredicate pred )
151 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
152 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
154 return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
157 } // namespace range_detail
162 /// \brief template function equal
164 /// range-based version of the equal std algorithm
166 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
167 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
168 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
169 template< class SinglePassRange1, class SinglePassRange2 >
170 inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
172 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
173 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
175 return ::boost::range_detail::equal(
176 ::boost::begin(rng1), ::boost::end(rng1),
177 ::boost::begin(rng2), ::boost::end(rng2) );
181 template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
182 inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
183 BinaryPredicate pred )
185 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
186 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
188 return ::boost::range_detail::equal(
189 ::boost::begin(rng1), ::boost::end(rng1),
190 ::boost::begin(rng2), ::boost::end(rng2),
195 using ::boost::range::equal;
198 #endif // include guard