8#ifndef ADOBE_ALGORITHM_SELECTION_HPP
9#define ADOBE_ALGORITHM_SELECTION_HPP
17#include <boost/range/begin.hpp>
18#include <boost/range/end.hpp>
19#include <boost/range/size.hpp>
20#include <boost/range/size_type.hpp>
21#include <boost/range/value_type.hpp>
59 bool other_inside, P pred) {
60 bool prev_op_result(pred(this_inside, other_inside));
62 while (first != last) {
63 this_inside = !this_inside;
65 bool cur_op_result(pred(this_inside, other_inside));
67 if (prev_op_result != cur_op_result)
70 prev_op_result = cur_op_result;
89 return static_cast<bool>(x) !=
static_cast<bool>(y);
106 bool s2_inside, P pred, C comp) {
107 if (s1_first == s1_last)
109 else if (s2_first == s2_last)
112 bool prev_op_result(pred(s1_inside, s2_inside));
115 typename std::iterator_traits<S1>::value_type next(comp(*s1_first, *s2_first) ? *s1_first
118 if (*s1_first == next) {
119 s1_inside = !s1_inside;
124 if (*s2_first == next) {
125 s2_inside = !s2_inside;
130 bool cur_op_result(pred(s1_inside, s2_inside));
132 if (prev_op_result != cur_op_result)
135 prev_op_result = cur_op_result;
137 if (s1_first == s1_last)
140 else if (s2_first == s2_last)
154template <
typename S1,
159inline O
selection_union(S1 s1_first, S1 s1_last, S2 s2_first, S2 s2_last, O output, C comp,
160 bool s1_inside =
false,
bool s2_inside =
false) {
161 return selection_operation(s1_first, s1_last, s2_first, s2_last, output, s1_inside, s2_inside,
162 std::logical_or<bool>(), comp);
171template <
typename S1,
177 bool s1_inside =
false,
bool s2_inside =
false) {
178 return selection_operation(s1_first, s1_last, s2_first, s2_last, output, s1_inside, s2_inside,
179 std::logical_and<bool>(), comp);
188template <
typename S1,
194 bool s1_inside =
false,
bool s2_inside =
false) {
205template <
typename S1,
211 C comp,
bool s1_inside =
false,
bool s2_inside =
false) {
212 return selection_operation(s1_first, s1_last, s2_first, s2_last, output, s1_inside, s2_inside,
222template <
typename S1,
227 bool s1_inside =
false,
bool s2_inside =
false) {
228 if (s1_inside == s2_inside) {
229 typedef typename std::iterator_traits<S1>::value_type value_type;
231 std::vector<value_type> result;
234 comp, s1_inside, s2_inside);
236 return std::equal(s2_first, s2_last, result.begin());
237 }
else if (s1_inside) {
239 !s1_inside, s2_inside);
243 return selection_includes(s1_first, s1_last, boost::next(s2_first), s2_last, comp, s1_inside,
253template <
typename Selection1,
typename Selection2>
261 std::back_inserter(result),
262 std::less<
typename boost::range_value<Selection1>::type>(),
274template <
typename Selection1,
typename Selection2>
282 std::less<
typename boost::range_value<Selection1>::type>(),
294template <
typename Selection1,
typename Selection2>
302 std::less<
typename boost::range_value<Selection1>::type>(),
314template <
typename Selection1,
typename Selection2>
322 x.begin(), x.end(), y.begin(), y.end(), std::back_inserter(result),
323 std::less<
typename boost::range_value<Selection1>::type>(),
start_selected(x),
335template <
typename Selection1,
typename Selection2>
341 std::less<
typename boost::range_value<Selection1>::type>(),
351template <
typename Selection>
362template <
typename Selection>
364 return x.start_selected();
373template <
typename Selection>
374inline typename boost::range_size<Selection>::type
size(
const Selection& x) {
384template <
typename Selection,
typename ForwardRange>
385typename boost::range_size<Selection>::type
size(
const Selection& x,
const ForwardRange& range) {
386 typedef typename boost::range_const_iterator<Selection>::type selection_const_iterator;
387 typedef typename boost::range_size<Selection>::type selection_size_type;
388 typedef typename boost::range_const_iterator<ForwardRange>::type range_const_iterator;
396 return boost::size(range);
398 selection_const_iterator s_iter(boost::begin(x));
399 selection_const_iterator s_last(boost::end(x));
401 range_const_iterator prev(boost::begin(range));
402 range_const_iterator iter(boost::next(prev, *s_iter));
403 range_const_iterator last(boost::end(range));
405 selection_size_type result(0);
410 result +=
static_cast<selection_size_type
>(std::distance(prev, iter));
417 iter = ++s_iter == s_last ? last : boost::next(boost::begin(range), *s_iter);
431template <
typename Selection>
432bool is_selected(
const Selection& x,
typename Selection::value_type index) {
433 typename boost::range_const_iterator<Selection>::type found(
434 std::upper_bound(boost::begin(x), boost::end(x), index));
435 typename boost::range_size<Selection>::type
count(std::distance(boost::begin(x), found));
447template <
typename Selection,
typename ForwardRange,
typename OutputIterator>
449 OutputIterator output) {
450 typedef typename boost::range_const_iterator<Selection>::type selection_const_iterator;
451 typedef typename boost::range_const_iterator<ForwardRange>::type range_const_iterator;
453 if (boost::size(range) == 0)
458 selection_const_iterator s_iter(boost::begin(x));
459 selection_const_iterator s_last(boost::end(x));
461 range_const_iterator iter(boost::begin(range));
462 range_const_iterator last(boost::end(range));
464 while (iter != last) {
465 if (s_iter != s_last && iter == boost::next(boost::begin(range), *s_iter)) {
486template <
typename Selection,
typename ForwardRange,
typename O1,
490 O1 false_output, O2 true_output) {
491 typedef typename boost::range_const_iterator<Selection>::type selection_const_iterator;
492 typedef typename boost::range_iterator<ForwardRange>::type range_iterator;
494 if (boost::size(range) == 0)
495 return std::make_pair(false_output, true_output);
497 selection_const_iterator selection_first(boost::begin(selection));
498 selection_const_iterator selection_last(boost::end(selection));
500 range_iterator first(boost::begin(range));
501 range_iterator last(boost::end(range));
506 range_iterator copy_last(selection_first == selection_last
508 : boost::next(boost::begin(range), *selection_first));
515 std::copy(first, copy_last, true_output);
517 std::copy(first, copy_last, false_output);
519 if (copy_last == last)
527 return std::make_pair(false_output, true_output);
536template <
typename Selection,
typename ForwardRange,
typename UnaryFunction>
537UnaryFunction
selection_foreach(
const Selection& x,
const ForwardRange& range, UnaryFunction proc) {
538 typedef typename boost::range_const_iterator<Selection>::type selection_const_iterator;
539 typedef typename boost::range_const_iterator<ForwardRange>::type range_const_iterator;
543 selection_const_iterator s_iter(boost::begin(x));
544 selection_const_iterator s_last(boost::end(x));
546 range_const_iterator iter(boost::begin(range));
547 range_const_iterator last(boost::end(range));
549 while (iter != last) {
550 if (s_iter != s_last && iter == boost::next(boost::begin(range), *s_iter)) {
571template <
typename Selection>
572inline std::pair<typename boost::range_const_iterator<Selection>::type,
573 typename boost::range_size<Selection>::type>
575 std::random_access_iterator_tag) {
576 typedef typename boost::range_const_iterator<Selection>::type const_iterator;
577 typedef typename boost::range_size<Selection>::type size_type;
578 typedef std::pair<const_iterator, size_type> result_type;
580 const_iterator bound(std::lower_bound(boost::begin(selection), boost::end(selection), p));
582 return result_type(bound,
583 static_cast<size_type
>(std::distance(boost::begin(selection), bound)));
592template <
typename Selection>
593std::pair<typename boost::range_const_iterator<Selection>::type,
594 typename boost::range_size<Selection>::type>
596 std::forward_iterator_tag) {
597 typedef typename boost::range_const_iterator<Selection>::type const_iterator;
598 typedef typename boost::range_size<Selection>::type size_type;
599 typedef std::pair<const_iterator, size_type> result_type;
601 const_iterator iter(boost::begin(selection));
602 const_iterator last(boost::end(selection));
603 size_type boundary_count(0);
605 while (iter != last && *iter < p) {
610 return result_type(iter, boundary_count);
632template <
typename Selection>
633inline std::pair<typename boost::range_const_iterator<Selection>::type,
634 typename boost::range_size<Selection>::type>
636 typedef typename boost::range_const_iterator<Selection>::type const_iterator;
637 typedef typename boost::range_size<Selection>::type size_type;
638 typedef std::pair<const_iterator, size_type> result_type;
639 typedef typename iterator_category<const_iterator>::type iterator_category;
641 if (boost::size(selection) == 0)
642 return result_type(boost::end(selection), 0);
679template <
typename SelectionIterator,
typename RangeIterator>
681 SelectionIterator selection_last, RangeIterator first,
682 RangeIterator range_first, RangeIterator range_last,
683 std::size_t boundary_count = 0) {
684 std::size_t n(
static_cast<std::size_t
>(std::distance(selection_first, selection_last)));
687 return boundary_count % 2 ? range_first : range_last;
689 std::size_t half(n / 2);
690 SelectionIterator selection_middle(boost::next(selection_first, half));
691 RangeIterator range_middle(boost::next(first, *selection_middle));
694 range_first, range_middle, boundary_count));
697 range_middle, range_last,
698 boundary_count + half + 1));
709template <
typename Selection,
typename ForwardRange>
710inline typename boost::range_iterator<ForwardRange>::type
713 boost::begin(range), boost::begin(range), boost::end(range),
753template <
typename Selection,
typename ForwardRange>
754std::pair<typename boost::range_iterator<ForwardRange>::type,
755 typename boost::range_iterator<ForwardRange>::type>
757 const Selection& selection, ForwardRange& range, std::size_t p,
758 typename boost::range_size<Selection>::type prior_boundary_count = 0) {
759 typedef typename boost::range_size<Selection>::type size_type;
760 typedef typename boost::range_const_iterator<Selection>::type selection_const_iterator;
761 typedef typename boost::range_iterator<ForwardRange>::type range_iterator;
763 std::pair<selection_const_iterator, size_type> selection_split =
766 range_iterator first(boost::begin(range));
767 range_iterator range_p(boost::next(first, p));
768 range_iterator last(boost::end(range));
771 first, first, range_p, prior_boundary_count));
774 range_p, last, selection_split.second + 1));
776 return std::pair<range_iterator, range_iterator>(i, j);
797template <
typename I,
typename N>
799 while (f != l && n == *f) {
864template <
typename Selection,
typename ForwardRange>
889template <
typename Selection,
typename OutputIterator>
891 typename boost::range_size<Selection>::type max_index,
892 OutputIterator output) {
893 typedef typename boost::range_size<Selection>::type size_type;
894 typedef typename boost::range_const_iterator<Selection>::type selection_const_iterator;
898 selection_const_iterator iter(boost::begin(selection));
899 selection_const_iterator last(boost::end(selection));
901 while (iter != last) {
902 while (index != *iter && index != max_index) {
909 selected = !selected;
914 while (index != max_index)
boost::range_difference< InputRange >::type count(InputRange &range, T &value)
count implementation
const T & other_of(const P &pair, const T &x, BinaryPredicate pred)
other_of implementation
std::pair< I, I > rotate(I f, I m, I l, std::bidirectional_iterator_tag)
std::pair< typename boost::range_iterator< ForwardRange >::type, typename boost::range_iterator< ForwardRange >::type > selection_stable_partition_about(const Selection &selection, ForwardRange &range, std::size_t p, typename boost::range_size< Selection >::type prior_boundary_count=0)
RangeIterator selection_stable_partition(SelectionIterator selection_first, SelectionIterator selection_last, RangeIterator first, RangeIterator range_first, RangeIterator range_last, std::size_t boundary_count=0)
O selection_difference(S1 s1_first, S1 s1_last, S2 s2_first, S2 s2_last, O output, C comp, bool s1_inside=false, bool s2_inside=false)
selection_difference implementation
void index_set_to_selection(I f, I l, O output)
std::pair< O1, O2 > selection_partition_copy(const Selection &selection, ForwardRange &range, O1 false_output, O2 true_output)
selection_partition_copy implementation
O selection_operation(S1 s1_first, S1 s1_last, S2 s2_first, S2 s2_last, O output, bool s1_inside, bool s2_inside, P pred, C comp)
selection_operation implementation
O selection_union(S1 s1_first, S1 s1_last, S2 s2_first, S2 s2_last, O output, C comp, bool s1_inside=false, bool s2_inside=false)
selection_union implementation
O selection_symmetric_difference(S1 s1_first, S1 s1_last, S2 s2_first, S2 s2_last, O output, C comp, bool s1_inside=false, bool s2_inside=false)
selection_symmetric_difference implementation
std::pair< typename boost::range_const_iterator< Selection >::type, typename boost::range_size< Selection >::type > selection_find_boundary(const Selection &selection, typename Selection::size_type p, std::random_access_iterator_tag)
OutputIterator selection_copy(const Selection &x, const ForwardRange &range, OutputIterator output)
O selection_intersection(S1 s1_first, S1 s1_last, S2 s2_first, S2 s2_last, O output, C comp, bool s1_inside=false, bool s2_inside=false)
selection_intersection implementation
bool is_selected(const Selection &x, typename Selection::value_type index)
O selection_operation_remainder(S first, S last, O output, bool this_inside, bool other_inside, P pred)
void invert(Selection &x)
invert implementation
std::pair< I, N > find_sequence_end(I f, I l, N n)
UnaryFunction selection_foreach(const Selection &x, const ForwardRange &range, UnaryFunction proc)
selection_foreach implementation
bool start_selected(const Selection &x)
start_selected implementation
boost::range_size< Selection >::type size(const Selection &x)
bool selection_includes(S1 s1_first, S1 s1_last, S2 s2_first, S2 s2_last, C comp, bool s1_inside=false, bool s2_inside=false)
selection_includes implementation
OutputIterator selection_to_index_set(const Selection &selection, typename boost::range_size< Selection >::type max_index, OutputIterator output)
bool operator()(const C1 &x, const C2 &y) const