equal.hpp 8.8 KB

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