Program Listing for File combination.hpp#
↰ Return to documentation for file (source/pele/combination.hpp)
#ifndef _COMBINATION_GENERATOR_H_
#define _COMBINATION_GENERATOR_H_
/*code adapted from
* http://coliru.stacked-crooked.com/view?id=c11dc445d3f7d49a415e3aa0478d7ba2-542192d2d8aca3c820c7acc656fa0c68
* and here
* https://stackoverflow.com/questions/25138049/c-variable-number-of-nested-loops
* This returns the combinations by obtaining the sorted permutations of the
* array elements
* */
#include <algorithm>
#include <stdexcept>
#include <vector>
namespace pele {
template <class iterator_type>
class combination_generator {
iterator_type first, last;
std::vector<bool> use;
size_t r;
typedef typename std::iterator_traits<iterator_type>::value_type element_type;
public:
combination_generator(iterator_type first_, iterator_type last_, size_t r_)
: first(first_), last(last_), r(r_) {
use.resize(std::distance(first, last), false);
if (r > use.size())
throw std::domain_error(
"pele::combination_generator: can't select more "
"elements than exist for combination");
std::fill(use.end() - r, use.end(), true);
}
template <class output_iterator>
bool operator()(output_iterator result) {
iterator_type c = first;
for (size_t i = 0; i < use.size(); ++i, ++c) {
if (use[i]) {
*result++ = *c;
}
}
return std::next_permutation(use.begin(), use.end());
}
};
template <class iterator_type>
combination_generator<iterator_type> make_combination_generator(
iterator_type first, iterator_type last, size_t r) {
return combination_generator<iterator_type>(first, last, r);
}
} // namespace pele
#endif