19 #include <boost/iterator/filter_iterator.hpp>
20 #include <boost/iterator/transform_iterator.hpp>
21 #include <boost/range/iterator_range.hpp>
23 #ifndef PAAL_SUBSET_ITERATOR_HPP
24 #define PAAL_SUBSET_ITERATOR_HPP
27 namespace data_structures {
32 template <
int k,
typename Iterator>
72 if (baseBegin != end) {
73 m_begin = ++baseBegin;
121 template <
typename F,
typename... Args>
123 std::move(f), std::forward<Args>(args)..., *std::declval<Iterator>())) {
124 return base::call(std::move(f), *m_begin, std::forward<Args>(args)...);
137 return left.m_begin == right.m_begin &&
138 static_cast<base>(left) == static_cast<base>(right);
188 bool next()
const {
return false; }
200 template <
typename F,
typename... Args>
202 Args &&... args) const->decltype(f(std::forward<Args>(args)...)) {
203 return f(std::forward<Args>(args)...);
233 template <
int k,
typename Iterator>
247 template <
int k,
typename Iterator,
typename Joiner = make_tuple>
249 subsets_iterator<k, Iterator, Joiner>,
251 (subsets_iterator_engine<k, Iterator>().call(std::declval<Joiner>())))
256 typename boost::forward_traversal_tag,
258 subsets_iterator_engine<k, Iterator>().call(std::declval<Joiner>()))> {
268 : m_joiner(joiner), m_iterator_engine(begin, end) {}
280 using ref = decltype(
281 subsets_iterator_engine<k, Iterator>().call(std::declval<Joiner>()));
283 friend class boost::iterator_core_access;
288 void increment() { m_iterator_engine.next(); }
298 return this->m_iterator_engine == other.m_iterator_engine;
306 ref dereference()
const {
return m_iterator_engine.call(m_joiner); }
310 subsets_iterator_engine<k, Iterator> m_iterator_engine;
326 template <
int k,
typename Iterator,
typename Joiner = make_tuple>
327 boost::iterator_range<subsets_iterator<k, Iterator, Joiner>>
329 typedef subsets_iterator<k, Iterator, Joiner> SI;
330 return boost::make_iterator_range(SI(b, e, joiner), SI(e, e, joiner));
344 template <
int k,
typename Range,
typename Joiner = make_tuple>
346 return make_subsets_iterator_range<k>(std::begin(range), std::end(range), std::move(joiner));
352 #endif // PAAL_SUBSET_ITERATOR_HPP
bool next()
sets next configuration of iterators, pointing to next subset
subsets_iterator_engine(Iterator begin, Iterator end)
constructor
Iterator get_end()
get_end, returns end of the input collection
auto call(F f, Args &&...args) const -> decltype(f(std::forward< Args >(args)...))
actually calls f for given arguments
void set_to_end()
boundary case, does nothing
subsets_iterator_engine< k, Iterator > make_subsets_iterator_engine(Iterator b, Iterator e)
make for subsets_iterator_engine
auto call(F f, Args &&...args) const -> decltype(std::declval< base >().call(std::move(f), std::forward< Args >(args)...,*std::declval< Iterator >()))
calls arbitrary function f on (*m_curr)...
boost::iterator_range< subsets_iterator< k, Iterator, Joiner > > make_subsets_iterator_range(Iterator b, Iterator e, Joiner joiner=Joiner{})
make for subsets_iterator
Iterator to all k-subsets of given collection.
friend bool operator==(const subsets_iterator_engine &left, const subsets_iterator_engine &right)
operator==
Iterator get_begin()
current being
subsets_iterator(Iterator begin, Iterator end, Joiner joiner=Joiner{})
constructor
Iterator get_end()
end is stored in the subsets_iterator_engine<0>
void set_to_end()
sets all iterators to m_end
Iterator get_begin()
get_begin, fake returns m_end
bool next() const
boundary case, does nothing
friend bool operator==(const subsets_iterator_engine &left, const subsets_iterator_engine &right)
operator==, always true
subsets_iterator_engine(Iterator begin, Iterator end)
constructor
subsets_iterator()=default
default constructor represents end of the range