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,
124 std::random_access_iterator_tag,
125 std::random_access_iterator_tag )
127 return ((last1 - first1) == (last2 - first2))
128 && std::equal(first1, last1, first2, pred);
131 template< class SinglePassTraversalReadableIterator1,
132 class SinglePassTraversalReadableIterator2 >
133 inline bool equal( SinglePassTraversalReadableIterator1 first1,
134 SinglePassTraversalReadableIterator1 last1,
135 SinglePassTraversalReadableIterator2 first2,
136 SinglePassTraversalReadableIterator2 last2 )
138 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
139 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
141 return equal_impl(first1, last1, first2, last2, tag1, tag2);
144 template< class SinglePassTraversalReadableIterator1,
145 class SinglePassTraversalReadableIterator2,
146 class BinaryPredicate >
147 inline bool equal( SinglePassTraversalReadableIterator1 first1,
148 SinglePassTraversalReadableIterator1 last1,
149 SinglePassTraversalReadableIterator2 first2,
150 SinglePassTraversalReadableIterator2 last2,
151 BinaryPredicate pred )
153 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
154 BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
156 return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
159 } // namespace range_detail
164 /// \brief template function equal
166 /// range-based version of the equal std algorithm
168 /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
169 /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
170 /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
171 template< class SinglePassRange1, class SinglePassRange2 >
172 inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
174 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
175 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
177 return ::boost::range_detail::equal(
178 ::boost::begin(rng1), ::boost::end(rng1),
179 ::boost::begin(rng2), ::boost::end(rng2) );
183 template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
184 inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
185 BinaryPredicate pred )
187 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
188 BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
190 return ::boost::range_detail::equal(
191 ::boost::begin(rng1), ::boost::end(rng1),
192 ::boost::begin(rng2), ::boost::end(rng2),
197 using ::boost::range::equal;
200 #endif // include guard