1 | // Copyright Neil Groves 2009. Use, modification and |
2 | // distribution is subject to the Boost Software License, Version |
3 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
4 | // http://www.boost.org/LICENSE_1_0.txt) |
5 | // |
6 | // |
7 | // For more information, see http://www.boost.org/libs/range/ |
8 | // |
9 | #ifndef BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED |
10 | #define BOOST_RANGE_ALGORITHM_MISMATCH_HPP_INCLUDED |
11 | |
12 | #include <boost/concept_check.hpp> |
13 | #include <boost/range/begin.hpp> |
14 | #include <boost/range/end.hpp> |
15 | #include <boost/range/concepts.hpp> |
16 | #include <boost/range/difference_type.hpp> |
17 | #include <algorithm> |
18 | |
19 | namespace boost |
20 | { |
21 | namespace range_detail |
22 | { |
23 | template< class SinglePassTraversalReadableIterator1, |
24 | class SinglePassTraversalReadableIterator2 > |
25 | inline std::pair<SinglePassTraversalReadableIterator1, |
26 | SinglePassTraversalReadableIterator2> |
27 | mismatch_impl(SinglePassTraversalReadableIterator1 first1, |
28 | SinglePassTraversalReadableIterator1 last1, |
29 | SinglePassTraversalReadableIterator2 first2, |
30 | SinglePassTraversalReadableIterator2 last2) |
31 | { |
32 | while (first1 != last1 && first2 != last2 && *first1 == *first2) |
33 | { |
34 | ++first1; |
35 | ++first2; |
36 | } |
37 | return std::pair<SinglePassTraversalReadableIterator1, |
38 | SinglePassTraversalReadableIterator2>(first1, first2); |
39 | } |
40 | |
41 | template< class SinglePassTraversalReadableIterator1, |
42 | class SinglePassTraversalReadableIterator2, |
43 | class BinaryPredicate > |
44 | inline std::pair<SinglePassTraversalReadableIterator1, |
45 | SinglePassTraversalReadableIterator2> |
46 | mismatch_impl(SinglePassTraversalReadableIterator1 first1, |
47 | SinglePassTraversalReadableIterator1 last1, |
48 | SinglePassTraversalReadableIterator2 first2, |
49 | SinglePassTraversalReadableIterator2 last2, |
50 | BinaryPredicate pred) |
51 | { |
52 | while (first1 != last1 && first2 != last2 && pred(*first1, *first2)) |
53 | { |
54 | ++first1; |
55 | ++first2; |
56 | } |
57 | return std::pair<SinglePassTraversalReadableIterator1, |
58 | SinglePassTraversalReadableIterator2>(first1, first2); |
59 | } |
60 | } // namespace range_detail |
61 | |
62 | namespace range |
63 | { |
64 | /// \brief template function mismatch |
65 | /// |
66 | /// range-based version of the mismatch std algorithm |
67 | /// |
68 | /// \pre SinglePassRange1 is a model of the SinglePassRangeConcept |
69 | /// \pre SinglePassRange2 is a model of the SinglePassRangeConcept |
70 | /// \pre BinaryPredicate is a model of the BinaryPredicateConcept |
71 | template< class SinglePassRange1, class SinglePassRange2 > |
72 | inline std::pair< |
73 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type, |
74 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type > |
75 | mismatch(SinglePassRange1& rng1, const SinglePassRange2 & rng2) |
76 | { |
77 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> )); |
78 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> )); |
79 | |
80 | return ::boost::range_detail::mismatch_impl( |
81 | ::boost::begin(rng1), ::boost::end(rng1), |
82 | ::boost::begin(rng2), ::boost::end(rng2)); |
83 | } |
84 | |
85 | /// \overload |
86 | template< class SinglePassRange1, class SinglePassRange2 > |
87 | inline std::pair< |
88 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type, |
89 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type > |
90 | mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2) |
91 | { |
92 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> )); |
93 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> )); |
94 | |
95 | return ::boost::range_detail::mismatch_impl( |
96 | ::boost::begin(rng1), ::boost::end(rng1), |
97 | ::boost::begin(rng2), ::boost::end(rng2)); |
98 | } |
99 | |
100 | /// \overload |
101 | template< class SinglePassRange1, class SinglePassRange2 > |
102 | inline std::pair< |
103 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type, |
104 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type > |
105 | mismatch(SinglePassRange1& rng1, SinglePassRange2 & rng2) |
106 | { |
107 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> )); |
108 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> )); |
109 | |
110 | return ::boost::range_detail::mismatch_impl( |
111 | ::boost::begin(rng1), ::boost::end(rng1), |
112 | ::boost::begin(rng2), ::boost::end(rng2)); |
113 | } |
114 | |
115 | /// \overload |
116 | template< class SinglePassRange1, class SinglePassRange2 > |
117 | inline std::pair< |
118 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type, |
119 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type > |
120 | mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2) |
121 | { |
122 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> )); |
123 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> )); |
124 | |
125 | return ::boost::range_detail::mismatch_impl( |
126 | ::boost::begin(rng1), ::boost::end(rng1), |
127 | ::boost::begin(rng2), ::boost::end(rng2)); |
128 | } |
129 | |
130 | |
131 | /// \overload |
132 | template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate > |
133 | inline std::pair< |
134 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type, |
135 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type > |
136 | mismatch(SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred) |
137 | { |
138 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> )); |
139 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> )); |
140 | |
141 | return ::boost::range_detail::mismatch_impl( |
142 | ::boost::begin(rng1), ::boost::end(rng1), |
143 | ::boost::begin(rng2), ::boost::end(rng2), pred); |
144 | } |
145 | |
146 | /// \overload |
147 | template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate > |
148 | inline std::pair< |
149 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type, |
150 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange2>::type > |
151 | mismatch(const SinglePassRange1& rng1, const SinglePassRange2& rng2, BinaryPredicate pred) |
152 | { |
153 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> )); |
154 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange2> )); |
155 | |
156 | return ::boost::range_detail::mismatch_impl( |
157 | ::boost::begin(rng1), ::boost::end(rng1), |
158 | ::boost::begin(rng2), ::boost::end(rng2), pred); |
159 | } |
160 | |
161 | /// \overload |
162 | template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate > |
163 | inline std::pair< |
164 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange1>::type, |
165 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type > |
166 | mismatch(SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred) |
167 | { |
168 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange1> )); |
169 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> )); |
170 | |
171 | return ::boost::range_detail::mismatch_impl( |
172 | ::boost::begin(rng1), ::boost::end(rng1), |
173 | ::boost::begin(rng2), ::boost::end(rng2), pred); |
174 | } |
175 | |
176 | /// \overload |
177 | template< class SinglePassRange1, class SinglePassRange2, class BinaryPredicate > |
178 | inline std::pair< |
179 | BOOST_DEDUCED_TYPENAME range_iterator<const SinglePassRange1>::type, |
180 | BOOST_DEDUCED_TYPENAME range_iterator<SinglePassRange2>::type > |
181 | mismatch(const SinglePassRange1& rng1, SinglePassRange2& rng2, BinaryPredicate pred) |
182 | { |
183 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<const SinglePassRange1> )); |
184 | BOOST_RANGE_CONCEPT_ASSERT(( SinglePassRangeConcept<SinglePassRange2> )); |
185 | |
186 | return ::boost::range_detail::mismatch_impl( |
187 | ::boost::begin(rng1), ::boost::end(rng1), |
188 | ::boost::begin(rng2), ::boost::end(rng2), pred); |
189 | } |
190 | |
191 | } // namespace range |
192 | using range::mismatch; |
193 | } // namespace boost |
194 | |
195 | #endif // include guard |
196 | |