1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
// 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
|