#ifndef PYTHONIC_INCLUDE_ITERTOOLS_PRODUCT_HPP #define PYTHONIC_INCLUDE_ITERTOOLS_PRODUCT_HPP #include "pythonic/include/utils/iterator.hpp" #include "pythonic/include/utils/seq.hpp" #include "pythonic/include/utils/int_.hpp" #include "pythonic/include/itertools/common.hpp" #include "pythonic/include/utils/functor.hpp" #include #include PYTHONIC_NS_BEGIN namespace itertools { namespace details { // FIXME : should be a combined_iterator_tag template struct product_iterator : std::iterator> { std::tuple const it_begin; std::tuple const it_end; std::tuple it; bool end; product_iterator() = default; template product_iterator(std::tuple &_iters, utils::index_sequence const &); template product_iterator(npos, std::tuple &_iters, utils::index_sequence const &); types::make_tuple_t operator*() const; product_iterator &operator++(); bool operator==(product_iterator const &other) const; bool operator!=(product_iterator const &other) const; bool operator<(product_iterator const &other) const; private: template void advance(utils::int_); void advance(utils::int_<0>); template types::make_tuple_t get_value(utils::index_sequence const &) const; }; template struct product : utils::iterator_reminder, product_iterator { using value_type = types::make_tuple_t; using iterator = product_iterator; iterator end_iter; product() = default; product(Iters const &... _iters); iterator &begin(); iterator const &begin() const; iterator const &end() const; }; } template details::product::type>::type...> product(Iter &&... iters); DEFINE_FUNCTOR(pythonic::itertools, product); } PYTHONIC_NS_END /* type inference stuff {*/ #include "pythonic/include/types/combined.hpp" template struct __combined> { using type = typename __combined::value_type>>::type; }; /* } */ #endif