Just as std::partition partitions a container according to a unary predicate, multi_partition is to partition a container according to UnaryPredicates... pred in the same order as listed in UnaryPredicates..., and the false elements in the order of UnaryPredicates... as well at the end of the container, and return a list of all the partition points too. But I'm not getting the correct results with this helper function:
template <typename ForwardIterator, typename UnaryPredicate, typename... UnaryPredicates>
std::list<ForwardIterator> multi_partition_helper (std::list<ForwardIterator>& partition_points,
ForwardIterator first, ForwardIterator last, UnaryPredicate pred, UnaryPredicates... rest) {
while (true) {
while ((first != last) && pred(*first))
++first;
if (first == last--) break;
while ((first != last) && !pred(*last))
--last;
if (first == last) break;
std::iter_swap (first++, last);
}
partition_points.push_back (first);
multi_partition_helper (partition_points, first, last, rest...);
}
template <typename ForwardIterator, typename UnaryPredicate, typename... UnaryPredicates>
std::list<ForwardIterator> multi_partition_helper (std::list<ForwardIterator>&, ForwardIterator, ForwardIterator) {
// End of recursion.
}
Am I going about it the wrong way?
A trivial implementation is
And can be used as a reference algorithm.
The real algorithm can be implemented recursively in terms of
std::partition
itself. The idea is to callstd::partition
with the nth predicate, get the iterator to the beginning of the n+1th range and do the next call with this iterator as the first iterator and the n+1th predicate as the predicate.As the actual algorithm, which can be used as follows:
Demo.