2 // (C) Copyright Ben Bear, Herve Bronnimann 2007.
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 Nov 13, 2007: Incorporation of boost-devel comments (Jens Seidel, Ben Bear and myself)
10 Nov 11, 2007: Rewrite of Ben Bear's Gacap
13 #ifndef BOOST_ALGORITHM_COMBINATION_HPP
14 #define BOOST_ALGORITHM_COMBINATION_HPP
22 template<class BidirectionalIterator
>
23 bool next_combination(BidirectionalIterator first1
,
24 BidirectionalIterator last1
,
25 BidirectionalIterator first2
,
26 BidirectionalIterator last2
)
28 if ((first1
== last1
) || (first2
== last2
)) {
32 BidirectionalIterator m1
= last1
;
33 BidirectionalIterator m2
= last2
; --m2
;
35 // Find first m1 not less than *m2 (i.e., lower_bound(first1, last1, *m2)).
36 // Actually, this loop stops at one position before that, except perhaps
37 // if m1 == first1 (in which case one must compare *first1 with *m2).
38 while (--m1
!= first1
&& !(*m1
< *m2
)) {
41 // Test if all elements in [first1, last1) not less than *m2.
42 bool result
= (m1
== first1
) && !(*first1
< *m2
);
46 // Find first first2 greater than *m1 (since *m1 < *m2, we know it
47 // can't pass m2 and there's no need to test m2).
48 while (first2
!= m2
&& !(*m1
< *first2
)) {
53 std::iter_swap (first1
, first2
);
58 // Merge [first1, last1) with [first2, last2), given that the rest of the
59 // original ranges are sorted and compare appropriately.
60 if ((first1
!= last1
) && (first2
!= last2
)) {
61 for (m1
= last1
, m2
= first2
; (m1
!= first1
) && (m2
!= last2
); ++m2
) {
62 // changed decrement at m1 to postfix - rieger, fhi, jan 2010
63 std::iter_swap (--m1
, m2
);
66 std::reverse (first1
, m1
);
67 std::reverse (first1
, last1
);
69 std::reverse (m2
, last2
);
70 std::reverse (first2
, last2
);
76 template<class BidirectionalIterator
, class Compare
>
77 bool next_combination(BidirectionalIterator first1
,
78 BidirectionalIterator last1
,
79 BidirectionalIterator first2
,
80 BidirectionalIterator last2
, Compare comp
)
82 if ((first1
== last1
) || (first2
== last2
)) {
86 BidirectionalIterator m1
= last1
;
87 BidirectionalIterator m2
= last2
; --m2
;
89 while (--m1
!= first1
&& !comp(*m1
, *m2
)) {
92 bool result
= (m1
== first1
) && !comp(*first1
, *m2
);
96 while (first2
!= m2
&& !comp(*m1
, *first2
)) {
101 std::iter_swap (first1
, first2
);
106 if ((first1
!= last1
) && (first2
!= last2
)) {
107 for (m1
= last1
, m2
= first2
; (m1
!= first1
) && (m2
!= last2
); ++m2
) {
108 std::iter_swap (--m1
, m2
);
111 std::reverse (first1
, m1
);
112 std::reverse (first1
, last1
);
114 std::reverse (m2
, last2
);
115 std::reverse (first2
, last2
);
121 } // namespace detail
123 /* PROPOSED STANDARD EXTENSIONS:
125 * template<class BidirectionalIterator>
126 * bool next_partial_permutation(BidirectionalIterator first,
127 * BidirectionalIterator middle,
128 * BidirectionalIterator last);
130 * template<class BidirectionalIterator, class Compare>
131 * bool next_partial_permutation(BidirectionalIterator first,
132 * BidirectionalIterator middle,
133 * BidirectionalIterator last, Compare comp);
136 template <class BidirectionalIterator
>
137 bool next_partial_permutation(BidirectionalIterator first
,
138 BidirectionalIterator middle
,
139 BidirectionalIterator last
)
141 reverse (middle
, last
);
142 return next_permutation(first
, last
);
145 template<class BidirectionalIterator
, class Compare
>
146 bool next_partial_permutation(BidirectionalIterator first
,
147 BidirectionalIterator middle
,
148 BidirectionalIterator last
, Compare comp
)
150 reverse (middle
, last
);
151 return next_permutation(first
, last
, comp
);
154 /* PROPOSED STANDARD EXTENSIONS:
156 * template<class BidirectionalIterator>
157 * bool prev_partial_permutation(BidirectionalIterator first,
158 * BidirectionalIterator middle,
159 * BidirectionalIterator last);
161 * template<class BidirectionalIterator, class Compare>
162 * bool prev_partial_permutation(BidirectionalIterator first,
163 * BidirectionalIterator middle,
164 * BidirectionalIterator last, Compare comp);
167 template<class BidirectionalIterator
>
168 bool prev_partial_permutation(BidirectionalIterator first
,
169 BidirectionalIterator middle
,
170 BidirectionalIterator last
)
172 bool result
= prev_permutation(first
, last
);
173 reverse (middle
, last
);
178 template<class BidirectionalIterator
, class Compare
>
179 bool prev_partial_permutation(BidirectionalIterator first
,
180 BidirectionalIterator middle
,
181 BidirectionalIterator last
, Compare comp
)
183 bool result
= prev_permutation(first
, last
);
184 reverse (middle
, last
);
188 /* PROPOSED STANDARD EXTENSIONS:
190 * template<class BidirectionalIterator>
191 * bool next_combination(BidirectionalIterator first,
192 * BidirectionalIterator middle,
193 * BidirectionalIterator last);
195 * template<class BidirectionalIterator, class Compare>
196 * bool next_combination(BidirectionalIterator first,
197 * BidirectionalIterator middle,
198 * BidirectionalIterator last, Compare comp);
201 template<class BidirectionalIterator
>
202 bool next_combination(BidirectionalIterator first
,
203 BidirectionalIterator middle
,
204 BidirectionalIterator last
)
206 return detail::next_combination(first
, middle
, middle
, last
);
209 template<class BidirectionalIterator
, class Compare
>
210 bool next_combination(BidirectionalIterator first
,
211 BidirectionalIterator middle
,
212 BidirectionalIterator last
, Compare comp
)
214 return detail::next_combination(first
, middle
, middle
, last
, comp
);
217 /* PROPOSED STANDARD EXTENSIONS:
219 * template<class BidirectionalIterator>
220 * bool prev_combination(BidirectionalIterator first,
221 * BidirectionalIterator middle,
222 * BidirectionalIterator last);
224 * template<class BidirectionalIterator, class Compare>
225 * bool prev_combination(BidirectionalIterator first,
226 * BidirectionalIterator middle,
227 * BidirectionalIterator last, Compare comp);
230 template<class BidirectionalIterator
>
232 bool prev_combination(BidirectionalIterator first
,
233 BidirectionalIterator middle
,
234 BidirectionalIterator last
)
236 return detail::next_combination(middle
, last
, first
, middle
);
239 template<class BidirectionalIterator
, class Compare
>
241 bool prev_combination(BidirectionalIterator first
,
242 BidirectionalIterator middle
,
243 BidirectionalIterator last
, Compare comp
)
245 return detail::next_combination(middle
, last
, first
, middle
, comp
);
248 /* PROPOSED STANDARD EXTENSION:
250 * template<class BidirectionalIterator, class T>
251 * bool next_mapping(BidirectionalIterator first,
252 * BidirectionalIterator last,
253 * T first_value, T last_value);
255 * template<class BidirectionalIterator, class T, class Incrementor>
256 * bool next_mapping(BidirectionalIterator first,
257 * BidirectionalIterator last,
258 * T first_value, T last_value, Incrementor increment);
261 template <class BidirectionalIterator
, class T
>
263 next_mapping(BidirectionalIterator first
,
264 BidirectionalIterator last
,
265 T first_value
, T last_value
)
267 if (last
== first
) {
271 if (++(*(--last
)) != last_value
) {
275 } while (last
!= first
);
279 template <class BidirectionalIterator
, class T
, class Incrementer
>
281 next_mapping(BidirectionalIterator first
,
282 BidirectionalIterator last
,
283 T first_value
, T last_value
, Incrementer increment
)
285 if (last
== first
) {
289 if (incrementer(*(--last
)) != last_value
) {
293 } while (last
!= first
);
297 /* PROPOSED STANDARD EXTENSION:
299 * template<class BidirectionalIterator, class T>
300 * bool prev_mapping(BidirectionalIterator first,
301 * BidirectionalIterator last,
302 * T first_value, T last_value);
304 * template<class BidirectionalIterator, class T, class Decrementor>
305 * bool prev_mapping(BidirectionalIterator first,
306 * BidirectionalIterator last,
307 * T first_value, T last_value, Decrementor decrement);
310 template <class BidirectionalIterator
, class T
>
312 prev_mapping(BidirectionalIterator first
,
313 BidirectionalIterator last
,
314 T first_value
, T last_value
)
321 if (*(--last
) != first_value
) {
326 } while (last
!= first
);
330 template <class BidirectionalIterator
, class T
, class Decrementer
>
332 prev_mapping(BidirectionalIterator first
,
333 BidirectionalIterator last
,
334 T first_value
, T last_value
, Decrementer decrement
)
339 decrement(last_value
);
341 if (*(--last
) != first_value
) {
346 } while (last
!= first
);
350 /* PROPOSED STANDARD EXTENSION:
352 * template<class BidirectionalIterator, class T>
353 * bool next_combination_counts(BidirectionalIterator first,
354 * BidirectionalIterator last);
357 template <class BidirectionalIterator
>
359 next_combination_counts(BidirectionalIterator first
,
360 BidirectionalIterator last
)
362 BidirectionalIterator current
= last
;
363 while (current
!= first
&& *(--current
) == 0) {
365 if (current
== first
) {
366 if (first
!= last
&& *first
!= 0)
367 std::iter_swap(--last
, first
);
371 std::iter_swap(--last
, current
);
376 /* PROPOSED STANDARD EXTENSION:
378 * template<class BidirectionalIterator>
379 * bool prev_combination_counts(BidirectionalIterator first,
380 * BidirectionalIterator last);
383 template <class BidirectionalIterator
>
385 prev_combination_counts(BidirectionalIterator first
,
386 BidirectionalIterator last
)
390 BidirectionalIterator current
= --last
;
391 while (current
!= first
&& *(--current
) == 0) {
393 if (current
== last
|| current
== first
&& *current
== 0) {
395 std::iter_swap(first
, last
);
401 std::iter_swap(current
, last
);
409 #endif // BOOST_ALGORITHM_COMBINATION_HPP