#ifndef ITER_POWERSET_HPP_ #define ITER_POWERSET_HPP_ #include "internal/iterbase.hpp" #include "combinations.hpp" #include #include #include #include #include #include namespace iter { namespace impl { template class Powersetter; } template impl::Powersetter powerset(Container&&); template impl::Powersetter> powerset( std::initializer_list); } template class iter::impl::Powersetter { private: Container container; using CombinatorType = decltype(combinations(std::declval(), 0)); friend Powersetter iter::powerset(Container&&); template friend Powersetter> iter::powerset( std::initializer_list); Powersetter(Container&& in_container) : container(std::forward(in_container)) {} public: Powersetter(Powersetter&&) = default; class Iterator : public std::iterator { private: std::remove_reference_t* container_p; std::size_t set_size; std::shared_ptr comb; iterator_type comb_iter; iterator_type comb_end; public: Iterator(Container& in_container, std::size_t sz) : container_p{&in_container}, set_size{sz}, comb{ std::make_shared(combinations(in_container, sz))}, comb_iter{std::begin(*comb)}, comb_end{std::end(*comb)} {} Iterator& operator++() { ++this->comb_iter; if (this->comb_iter == this->comb_end) { ++this->set_size; this->comb = std::make_shared( combinations(*this->container_p, this->set_size)); this->comb_iter = std::begin(*this->comb); this->comb_end = std::end(*this->comb); } return *this; } Iterator operator++(int) { auto ret = *this; ++*this; return ret; } iterator_deref operator*() { return *this->comb_iter; } iterator_arrow operator->() { apply_arrow(this->comb_iter); } bool operator!=(const Iterator& other) const { return !(*this == other); } bool operator==(const Iterator& other) const { return this->set_size == other.set_size && this->comb_iter == other.comb_iter; } }; Iterator begin() { return {this->container, 0}; } Iterator end() { return {this->container, dumb_size(this->container) + 1}; } }; template iter::impl::Powersetter iter::powerset(Container&& container) { return {std::forward(container)}; } template iter::impl::Powersetter> iter::powerset( std::initializer_list il) { return {std::move(il)}; } #endif