Skip to content

prefer ranges algorithms over iterator-pair std calls (library + tests)#243

Closed
cameroncuster wants to merge 2 commits into
devfrom
use-ranges-iota
Closed

prefer ranges algorithms over iterator-pair std calls (library + tests)#243
cameroncuster wants to merge 2 commits into
devfrom
use-ranges-iota

Conversation

@cameroncuster

@cameroncuster cameroncuster commented Jul 12, 2026

Copy link
Copy Markdown
Member

What

Prefer the ranges:: algorithms over their iterator-pair std::
counterparts for full-range calls, across both the library and the
test suite. The rule: use ranges:: even when all() would work, unless
iterators specifically make more sense.

Conversions applied:

  • iota(all(x), v)ranges::iota(x, v)
  • unique(all(x))begin(ranges::unique(x)) (erase / == end idioms)
  • partition(all(x), pred)begin(ranges::partition(x, pred))
  • remove_if(all(x), pred)begin(ranges::remove_if(x, pred)) (erase)
  • next_permutation(all(x))ranges::next_permutation(x).found

ranges::unique / ranges::partition / ranges::remove_if return a
subrange, so begin(...) yields the iterator the erase / offset logic
needs; ranges::next_permutation returns a struct whose .found drives
the do/while.

Why

  • The library and tests already use ranges:: algorithms extensively
    (e.g. ranges::sort everywhere); this makes the remaining full-range
    calls consistent with that style.
  • Drops an all(...) macro expansion (relevant when expanding KACTL
    macros on main).

Scope / what is intentionally NOT changed

  • std::partial_sum and std::accumulate — no ranges::
    numeric-reduction equivalents in C++23 (ranges::fold_left would change
    the idiom), so these stay as-is.
  • Partial-range calls (iterator sub-ranges such as
    lower_bound(begin(sa) + lo, ...), find_if(rank + begin(mat), ...),
    partition(el, er, ...), remove_if(idx + begin(upd_st), ...)) — read
    more clearly with explicit iterators.
  • Member functions named find / count — not std:: algorithms.
  • Scalar std::min / std::max.

Files

library/ (12 sites, 12 files): line_tree, mst,
offline_incremental_scc, complement_graph_ccs, calc_sieve,
calc_linear_sieve, lcs_dp, longest_palindrome_query, suffix_array (2),
suffix_array_short (iota); virtual_tree (unique); edge_cd (partition).

tests/ (10 files): bit_ordered_set, kth_smallest_pst, mode_query,
sa_sort_pairs, seg_tree_find (unique); mono_st_asserts,
offline_incremental_scc, sa_sort_pairs (iota); permutation_tree_small,
rmq_small_n (iota + next_permutation); single_matching_bs (remove_if).

Testing

Syntax-checked all affected library-checker/aizu tests locally with
clang++ -std=c++2b -fsyntax-only — all pass.

Behaviorally ran (exit 0, all asserts pass):

  • edge_cd_small_trees — exhaustive over all trees on 2–7 nodes
    (ranges::partition).
  • lca_all_methods_aizu — includes compress_tree_asserts, comparing
    compress_tree against KACTL's reference over random subsets plus the
    empty-subset edge case (ranges::unique).
  • permutation_tree_small and rmq_small_n — exhaustive over all
    permutations of size 1–8 (ranges::next_permutation(...).found,
    ranges::iota).

Convert the full-range std::iota(begin, end, v) calls to
ranges::iota(range, v). This favors the ranges algorithms already used
throughout the library and removes an all(...) macro expansion on main.

Partial-range calls (e.g. iterator sub-ranges) and std::partial_sum are
left as-is: partial_sum has no ranges equivalent, and partial ranges read
more clearly with explicit iterators.
Convert the remaining full-range std algorithm calls to their ranges::
equivalents:
- virtual_tree: unique(all(subset)) -> begin(ranges::unique(subset))
- edge_cd: partition(all(g[u]), ...) -> begin(ranges::partition(g[u], ...))

ranges::unique / ranges::partition return a subrange, so begin(...) yields
the iterator the erase / offset logic needs.

Partial-range calls (iterator sub-ranges) and std::partial_sum are still
left as-is: partial_sum has no ranges equivalent, and partial ranges read
more clearly with explicit iterators.
@cameroncuster cameroncuster changed the title use ranges::iota over std::iota for full-range calls prefer ranges algorithms for full-range std calls (iota, unique, partition) Jul 12, 2026
@cameroncuster cameroncuster changed the title prefer ranges algorithms for full-range std calls (iota, unique, partition) prefer ranges algorithms over iterator-pair std calls (library + tests) Jul 12, 2026
@cameroncuster cameroncuster deleted the use-ranges-iota branch July 12, 2026 17:56
@cameroncuster

Copy link
Copy Markdown
Member Author

Superseded by #244 (branch renamed use-ranges-iota -> use-ranges-algorithms as scope expanded to ranges::unique/partition/remove_if/next_permutation across library + tests).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant