#ifndef PYTHONIC_INCLUDE_ITERTOOLS_PERMUTATIONS_HPP #define PYTHONIC_INCLUDE_ITERTOOLS_PERMUTATIONS_HPP #include "pythonic/include/utils/functor.hpp" #include "pythonic/include/types/dynamic_tuple.hpp" #include #include PYTHONIC_NS_BEGIN namespace itertools { /** Permutation iterator * * It wraps a vector && provide an iteration over every possible * permutation of the vector. The permutations are represented as *dynamic_tuple * of elements. * * The following iterator: * * permutations_iterator([0, 1, 2]) * * yields the following suite: * * [(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)] * */ template struct permutations_iterator : std::iterator, ptrdiff_t, types::dynamic_tuple *, types::dynamic_tuple /* no ref*/ > { // Vector of inputs, contains elements to permute std::vector pool; // The current permutation as a dynamic_tuple of index in the pool // Internally it always has the same size as the pool, even if the // external view is limited std::vector curr_permut; // Size of the "visible" permutation size_t _size; bool end; // sentinel marker permutations_iterator(); permutations_iterator(std::vector const &iter, size_t num_elts, bool end); /** Build the permutation visible from the "outside" */ types::dynamic_tuple operator*() const; /* Generate next permutation * * If the size of the permutation is smaller than the size of the * pool, we may have to iterate multiple times */ permutations_iterator &operator++(); bool operator!=(permutations_iterator const &other) const; bool operator==(permutations_iterator const &other) const; bool operator<(permutations_iterator const &other) const; }; template // FIXME document why this inheritance??? struct _permutations : permutations_iterator { using iterator = permutations_iterator; using value_type = typename iterator::value_type; _permutations(); _permutations(T iter, long elts); iterator const &begin() const; iterator begin(); iterator end() const; }; template _permutations permutations(T0 iter, long num_elts); template _permutations permutations(T0 iter); DEFINE_FUNCTOR(pythonic::itertools, permutations); } PYTHONIC_NS_END /* type inference stuff {*/ #include "pythonic/include/types/combined.hpp" template struct __combined> { using type = typename __combined< E, container< typename pythonic::itertools::_permutations::value_type>>::type; }; /* } */ #endif