201 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| // Boost.Range library
 | |
| //
 | |
| //  Copyright Neil Groves 2009.
 | |
| //  Use, modification and distribution is subject to the Boost Software
 | |
| //  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
 | |
| //  http://www.boost.org/LICENSE_1_0.txt)
 | |
| //
 | |
| // For more information, see http://www.boost.org/libs/range/
 | |
| //
 | |
| #ifndef BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
 | |
| #define BOOST_RANGE_ALGORITHM_EQUAL_HPP_INCLUDED
 | |
| 
 | |
| #include <boost/config.hpp>
 | |
| #include <boost/range/concepts.hpp>
 | |
| #include <iterator>
 | |
| 
 | |
| namespace boost
 | |
| {
 | |
|     namespace range_detail
 | |
|     {
 | |
|         // An implementation of equality comparison that is optimized for iterator
 | |
|         // traversal categories less than RandomAccessTraversal.
 | |
|         template< class SinglePassTraversalReadableIterator1,
 | |
|                   class SinglePassTraversalReadableIterator2,
 | |
|                   class IteratorCategoryTag1,
 | |
|                   class IteratorCategoryTag2 >
 | |
|         inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
 | |
|                                 SinglePassTraversalReadableIterator1 last1,
 | |
|                                 SinglePassTraversalReadableIterator2 first2,
 | |
|                                 SinglePassTraversalReadableIterator2 last2,
 | |
|                                 IteratorCategoryTag1,
 | |
|                                 IteratorCategoryTag2 )
 | |
|         {
 | |
|             for (;;)
 | |
|             {
 | |
|                 // If we have reached the end of the left range then this is
 | |
|                 // the end of the loop. They are equal if and only if we have
 | |
|                 // simultaneously reached the end of the right range.
 | |
|                 if (first1 == last1)
 | |
|                     return first2 == last2;
 | |
| 
 | |
|                 // If we have reached the end of the right range at this line
 | |
|                 // it indicates that the right range is shorter than the left
 | |
|                 // and hence the result is false.
 | |
|                 if (first2 == last2)
 | |
|                     return false;
 | |
| 
 | |
|                 // continue looping if and only if the values are equal
 | |
|                 if (*first1 != *first2)
 | |
|                     break;
 | |
| 
 | |
|                 ++first1;
 | |
|                 ++first2;
 | |
|             }
 | |
| 
 | |
|             // Reaching this line in the algorithm indicates that a value
 | |
|             // inequality has been detected.
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         template< class SinglePassTraversalReadableIterator1,
 | |
|                   class SinglePassTraversalReadableIterator2,
 | |
|                   class IteratorCategoryTag1,
 | |
|                   class IteratorCategoryTag2,
 | |
|                   class BinaryPredicate >
 | |
|         inline bool equal_impl( SinglePassTraversalReadableIterator1 first1,
 | |
|                                 SinglePassTraversalReadableIterator1 last1,
 | |
|                                 SinglePassTraversalReadableIterator2 first2,
 | |
|                                 SinglePassTraversalReadableIterator2 last2,
 | |
|                                 BinaryPredicate                      pred,
 | |
|                                 IteratorCategoryTag1,
 | |
|                                 IteratorCategoryTag2 )
 | |
|         {
 | |
|             for (;;)
 | |
|             {
 | |
|                 // If we have reached the end of the left range then this is
 | |
|                 // the end of the loop. They are equal if and only if we have
 | |
|                 // simultaneously reached the end of the right range.
 | |
|                 if (first1 == last1)
 | |
|                     return first2 == last2;
 | |
| 
 | |
|                 // If we have reached the end of the right range at this line
 | |
|                 // it indicates that the right range is shorter than the left
 | |
|                 // and hence the result is false.
 | |
|                 if (first2 == last2)
 | |
|                     return false;
 | |
| 
 | |
|                 // continue looping if and only if the values are equal
 | |
|                 if (!pred(*first1, *first2))
 | |
|                     break;
 | |
| 
 | |
|                 ++first1;
 | |
|                 ++first2;
 | |
|             }
 | |
| 
 | |
|             // Reaching this line in the algorithm indicates that a value
 | |
|             // inequality has been detected.
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         // An implementation of equality comparison that is optimized for
 | |
|         // random access iterators.
 | |
|         template< class RandomAccessTraversalReadableIterator1,
 | |
|                   class RandomAccessTraversalReadableIterator2 >
 | |
|         inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
 | |
|                                 RandomAccessTraversalReadableIterator1 last1,
 | |
|                                 RandomAccessTraversalReadableIterator2 first2,
 | |
|                                 RandomAccessTraversalReadableIterator2 last2,
 | |
|                                 std::random_access_iterator_tag,
 | |
|                                 std::random_access_iterator_tag )
 | |
|         {
 | |
|             return ((last1 - first1) == (last2 - first2))
 | |
|                 && std::equal(first1, last1, first2);
 | |
|         }
 | |
| 
 | |
|         template< class RandomAccessTraversalReadableIterator1,
 | |
|                   class RandomAccessTraversalReadableIterator2,
 | |
|                   class BinaryPredicate >
 | |
|         inline bool equal_impl( RandomAccessTraversalReadableIterator1 first1,
 | |
|                                 RandomAccessTraversalReadableIterator1 last1,
 | |
|                                 RandomAccessTraversalReadableIterator2 first2,
 | |
|                                 RandomAccessTraversalReadableIterator2 last2,
 | |
|                                 BinaryPredicate                        pred,
 | |
|                                 std::random_access_iterator_tag,
 | |
|                                 std::random_access_iterator_tag )
 | |
|         {
 | |
|             return ((last1 - first1) == (last2 - first2))
 | |
|                 && std::equal(first1, last1, first2, pred);
 | |
|         }
 | |
| 
 | |
|         template< class SinglePassTraversalReadableIterator1,
 | |
|                   class SinglePassTraversalReadableIterator2 >
 | |
|         inline bool equal( SinglePassTraversalReadableIterator1 first1,
 | |
|                            SinglePassTraversalReadableIterator1 last1,
 | |
|                            SinglePassTraversalReadableIterator2 first2,
 | |
|                            SinglePassTraversalReadableIterator2 last2 )
 | |
|         {
 | |
|             BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
 | |
|             BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
 | |
| 
 | |
|             return equal_impl(first1, last1, first2, last2, tag1, tag2);
 | |
|         }
 | |
| 
 | |
|         template< class SinglePassTraversalReadableIterator1,
 | |
|                   class SinglePassTraversalReadableIterator2,
 | |
|                   class BinaryPredicate >
 | |
|         inline bool equal( SinglePassTraversalReadableIterator1 first1,
 | |
|                            SinglePassTraversalReadableIterator1 last1,
 | |
|                            SinglePassTraversalReadableIterator2 first2,
 | |
|                            SinglePassTraversalReadableIterator2 last2,
 | |
|                            BinaryPredicate                      pred )
 | |
|         {
 | |
|             BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator1 >::iterator_category tag1;
 | |
|             BOOST_DEDUCED_TYPENAME std::iterator_traits< SinglePassTraversalReadableIterator2 >::iterator_category tag2;
 | |
| 
 | |
|             return equal_impl(first1, last1, first2, last2, pred, tag1, tag2);
 | |
|         }
 | |
| 
 | |
|     } // namespace range_detail
 | |
| 
 | |
|     namespace range
 | |
|     {
 | |
| 
 | |
|         /// \brief template function equal
 | |
|         ///
 | |
|         /// range-based version of the equal std algorithm
 | |
|         ///
 | |
|         /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept
 | |
|         /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept
 | |
|         /// \pre BinaryPredicate is a model of the BinaryPredicateConcept
 | |
|         template< class SinglePassRange1, class SinglePassRange2 >
 | |
|         inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2 )
 | |
|         {
 | |
|             BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
 | |
|             BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
 | |
| 
 | |
|             return ::boost::range_detail::equal(
 | |
|                 ::boost::begin(rng1), ::boost::end(rng1),
 | |
|                 ::boost::begin(rng2), ::boost::end(rng2) );
 | |
|         }
 | |
| 
 | |
|         /// \overload
 | |
|         template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate >
 | |
|         inline bool equal( const SinglePassRange1& rng1, const SinglePassRange2& rng2,
 | |
|                            BinaryPredicate pred )
 | |
|         {
 | |
|             BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> ));
 | |
|             BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> ));
 | |
| 
 | |
|             return ::boost::range_detail::equal(
 | |
|                 ::boost::begin(rng1), ::boost::end(rng1),
 | |
|                 ::boost::begin(rng2), ::boost::end(rng2),
 | |
|                 pred);
 | |
|         }
 | |
| 
 | |
|     } // namespace range
 | |
|     using ::boost::range::equal;
 | |
| } // namespace boost
 | |
| 
 | |
| #endif // include guard
 | 
