static I1 sized_impl(I1 const begin1_, S1 end1, D1 const d1_, I2 begin2, S2 end2, D2 d2, C &pred, P1 &proj1, P2 &proj2) { D1 d1 = d1_; auto begin1 = uncounted(begin1_); while(true) { // Find begin element in sequence 1 that matches *begin2, with a mininum of loop checks while(true) { if(d1 < d2) // return the end if we've run out of room return next_to(recounted(begin1_, std::move(begin1), d1_ - d1), std::move(end1)); if(pred(proj1(*begin1), proj2(*begin2))) break; ++begin1; --d1; } // *begin1 matches *begin2, now match elements after here auto m1 = begin1; I2 m2 = begin2; while(true) { if(++m2 == end2) // If pattern exhausted, begin1 is the answer (works for 1 element pattern) return recounted(begin1_, std::move(begin1), d1_ - d1); ++m1; // No need to check, we know we have room to match successfully if(!pred(proj1(*m1), proj2(*m2))) // if there is a mismatch, restart with a new begin1 { ++begin1; --d1; break; } // else there is a match, check next elements } } }
static I impl(I begin, S end_, C pred, P proj, concepts::BidirectionalIterator *bi) { using difference_type = iterator_difference_t<I>; using value_type = iterator_value_t<I>; difference_type const alloc_limit = 4; // might want to make this a function of trivial assignment // Either prove all true and return begin or point to first false while(true) { if(begin == end_) return begin; if(!pred(proj(*begin))) break; ++begin; } // begin points to first false, everything prior to begin is already set. // Either prove [begin, end) is all false and return begin, or point end to last true I end = next_to(begin, end_); do { if(begin == --end) return begin; } while(!pred(proj(*end))); // We now have a reduced range [begin, end] // *begin is known to be false // *end is known to be true // len >= 2 auto len = distance(begin, end) + 1; auto p = len >= alloc_limit ? std::get_temporary_buffer<value_type>(len) : detail::value_init{}; std::unique_ptr<value_type, detail::return_temporary_buffer> const h{p.first}; return stable_partition_fn::impl(begin, end, pred, proj, len, p, bi); }
list<string> transform_words(const string &begin, const string &end, const vector<string> &dict) { list<string> words; vector<bool> visited(dict.size(), false); queue<Item*> qu; qu.push(new Item(begin, NULL)); while (!qu.empty()) { Item* w = qu.front(); qu.pop(); // propagate neighbors for (int i = 0; i < dict.size(); ++i) { if (visited[i]) continue; if ( next_to(w->str, dict[i]) ) { if (dict[i] == end) { // back track words.push_front(end); while (w != NULL) { words.push_front(w->str); w = w->parent; } return words; } qu.push(new Item(dict[i], w)); visited[i] = true; } } // for } // while return words; }
std::pair<I, O> operator()(I begin, S end_, O out, P proj = P{}) const { auto &&iproj = invokable(proj); I i = next_to(begin, end_), end = i; while(begin != i) *--out = iproj(*--i); return {end, out}; }
std::pair<I, O> operator()(I begin, S end_, O out, P proj_ = P{}) const { auto &&proj = invokable(proj_); I i = next_to(begin, end_), end = i; while(begin != i) { // BUGBUG should the projection be applied *before* the move? auto &&x = iter_move(--i); *--out = proj((decltype(x) &&) x); } return {end, out}; }
/** * @brief A simple, but effective AI function which will attack the player or other hostile creatures - or chase them if necessary! * * @param m The monster/actor which is performing this hostility. */ void hostile_ai(actor_t *m) { int oy, ox; co c; oy = m->y; ox = m->x; if(m->attacker && next_to(m, m->attacker)) { attack(m, m->attacker); return; } if(next_to(m, player) && !is_invisible(player)) { m->attacker = player; attack(m, m->attacker); return; } if(actor_in_lineofsight(m, player)) { m->goalx = player->x; m->goaly = player->y; } else { m->attacker = NULL; do { m->goalx = ri(1, world->curlevel->xsize-1); m->goaly = ri(1, world->curlevel->ysize-1); } while(!monster_passable(world->curlevel, m->goaly, m->goalx)); } c = get_next_step(m); if(c.x == 0 && c.y == 0) { return; } else { m->y = c.y; m->x = c.x; world->cmap[oy][ox].monster = NULL; world->cmap[m->y][m->x].monster = m; } }
range_iterator_t<Rng> pos_at_(Rng && rng, Int i, concepts::BidirectionalIterable *, std::false_type) { if(0 > i) { // If it's not bounded and we know the size, faster to count from the front if(SizedIterable<Rng>() && !BoundedIterable<Rng>()) return next(ranges::begin(rng), distance(rng) + i); // Otherwise, probably faster to count from the back. return next(next_to(ranges::begin(rng), ranges::end(rng)), i); } return next(ranges::begin(rng), i); }
I operator()(I begin, S end_, Gen && gen) const { I end = next_to(begin, end_); auto d = end - begin; if(d > 1) { using param_t = std::uniform_int_distribution<std::ptrdiff_t>::param_type; std::uniform_int_distribution<std::ptrdiff_t> uid; for(--end, --d; begin < end; ++begin, --d) { auto i = uid(gen, param_t{0, d}); if(i != 0) ranges::iter_swap(begin, begin + i); } } return end; }
static I impl(I begin, S end_, C pred_, P proj_, concepts::BidirectionalIterator*) { auto && pred = invokable(pred_); auto && proj = invokable(proj_); I end = next_to(begin, end_); while(true) { while(true) { if(begin == end) return begin; if(!pred(proj(*begin))) break; ++begin; } do { if(begin == --end) return begin; } while(!pred(proj(*end))); ranges::iter_swap(begin, end); ++begin; } }
std::pair<D, I> impl_i(I begin, S end, D d, concepts::SizedIteratorRange*, Concept) const { return {(end - begin) + d, next_to(begin, end)}; }
std::pair<D, I> impl_i(I begin, S end_, D d, concepts::IteratorRange*, concepts::SizedIteratorRange*) const { I end = next_to(begin, end_); return {(end - begin) + d, end}; }
I next_to_if(I i, S s, std::true_type) { return next_to(i, s); }