types::ndarray<typename U::type, U::value> select(types::list<T> const &condlist, types::list<U> const &choicelist, typename U::dtype _default) { constexpr size_t N = U::value; auto &&choicelist0_shape = choicelist[0].shape(); types::ndarray<T, N> out(choicelist0_shape, _default); types::ndarray<T, N> selected(choicelist0_shape(), false); long size = selected.flat_size(); for (long i = 0; i < condlist.size() && size != 0; i++) size = _select(choicelist[i].begin(), choicelist[i].end(), out.begin(), selected.begin(), condlist.begin(), size, utils::int_<N>()); return out; }
/* 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++() { if(_size!=pool.size()) { // Slow path, the iterator is a "view" of a prefix smaller // than the the pool size // FIXME a better implementation would be to avoid // std::next_permutation, but only in the slow path types::list<int> prev_permut(curr_permut.begin(), curr_permut.begin()+_size); types::list<int> new_permut; while((end = std::next_permutation(curr_permut.begin(), curr_permut.end()))) { // Check if the prefix of the new permutation is // different of the previous one types::list<int> new_permut(curr_permut.begin(), curr_permut.begin()+_size); if(!(prev_permut==new_permut)) break; } } else { end = std::next_permutation(curr_permut.begin(), curr_permut.end()); } return *this; }
types::none_type sort(types::list<T> &seq) { std::sort(seq.begin(),seq.end()); return __builtin__::None; }
types::none_type reverse(types::list<T> &seq) { std::reverse(seq.begin(),seq.end()); return __builtin__::None; }
bool operator==(permutations_iterator const& other) const { if(other.end != end) return false; return std::equal(curr_permut.begin(), curr_permut.end(), other.curr_permut.begin()); }