#ifndef ITER_POWERSET_HPP_ #define ITER_POWERSET_HPP_ #include "combinations.hpp" #include "internal/iterbase.hpp" #include #include #include #include #include #include namespace iter { namespace impl { template class Powersetter; using PowersetFn = IterToolFn; } constexpr impl::PowersetFn powerset{}; } template class iter::impl::Powersetter { private: Container container_; template using CombinatorType = decltype(combinations(std::declval(), 0)); friend PowersetFn; Powersetter(Container&& container) : container_(std::forward(container)) {} public: Powersetter(Powersetter&&) = default; template class Iterator { private: #if 0 template friend class Iterator; #endif std::remove_reference_t* container_p_; std::size_t set_size_{}; std::shared_ptr> comb_; iterator_type> comb_iter_; iterator_type> comb_end_; public: using iterator_category = std::input_iterator_tag; using value_type = CombinatorType; using difference_type = std::ptrdiff_t; using pointer = value_type*; using reference = value_type&; Iterator(ContainerT& container, std::size_t sz) : container_p_{&container}, set_size_{sz}, comb_{std::make_shared>( combinations(container, sz))}, comb_iter_{get_begin(*comb_)}, comb_end_{get_end(*comb_)} {} Iterator& operator++() { ++comb_iter_; if (comb_iter_ == comb_end_) { ++set_size_; comb_ = std::make_shared>( combinations(*container_p_, set_size_)); comb_iter_ = get_begin(*comb_); comb_end_ = get_end(*comb_); } return *this; } Iterator operator++(int) { auto ret = *this; ++*this; return ret; } iterator_deref> operator*() { return *comb_iter_; } iterator_arrow> operator->() { apply_arrow(comb_iter_); } bool operator!=(const Iterator& other) const { return !(*this == other); } bool operator==(const Iterator& other) const { return set_size_ == other.set_size_ && comb_iter_ == other.comb_iter_; } #if 0 template bool operator!=(const Iterator& other) const { return !(*this == other); } template bool operator==(const Iterator& other) const { return set_size_ == other.set_size_ && comb_iter_ == other.comb_iter_; } #endif }; Iterator begin() { return {container_, 0}; } Iterator end() { return {container_, dumb_size(container_) + 1}; } Iterator> begin() const { return {std::as_const(container_), 0}; } Iterator> end() const { return { std::as_const(container_), dumb_size(std::as_const(container_)) + 1}; } }; #endif