boostorg / boostorg/graph

[draft] Good first issues: start contributing to Boost.Graph here

Open Beginner friendly
#593 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
392
Forks
239
Avg merge
1d 11m
Merged PRs (30d)
20

Description

Welcome! 🥳

This is the landing issue for anyone who wants to make a first contribution to Boost.Graph. Every task below is small, self-contained, and reviewable in one sitting. They are real cleanups we want done, not busywork.

Tasks are grouped into three tiers by the C++ background they actually require, so you can pick one that matches where you are.
- Tier 1 needs nothing beyond being able to read code
- Tier 3 assumes you know what the old workaround was working around.

## How to claim a task

1. Read [CONTRIBUTING.md](https://github.com/boostorg/graph/blob/develop/CONTRIBUTING.md) first: it has the superproject setup, the build and test commands, the naming conventions, and the full `BOOST_*` macro policy table that several tasks below refer to.
2. Comment on this issue saying which box you are taking, e.g. *"Taking 2.1 on `strong_components.hpp`"*. We will tick it here so nobody duplicates work.
3. Ask questions in the comments. There is no such thing as a question too basic on this issue.

## Ground rules

- **One file per PR.** Every checkbox below is exactly one file and exactly one PR. This is deliberate: small PRs get reviewed much faster, they are easy to revert if we got something wrong, and they let many people contribute in parallel without stepping on each other. Please do not batch several files together to "save time" as it costs review time. The one exception is a header and its matching test when the change genuinely spans both.
- **One task per PR.** Several files appear under more than one task. If your file needs work from two tasks, that is two PRs. Do not mix a macro cleanup with a rename or a formatting pass.
- **No behavior change.** Everything below should be a no-op at runtime. If you find a bug along the way, that is great: open a separate PR, with a regression test.
- **The test suite must stay green.** `./b2` from `libs/graph/test` runs everything (~10 min). For a single test: `./b2 cycle_canceling_test`. If you struggle with local builds, feel free to run on CI.
- **The CI matrix is gcc-14 + clang-19 over C++14/17/20/23.** C++14 is the floor: no structured bindings, no `if constexpr`, no inline variables, no single-argument `static_assert`.
- Do not run `clang-format`. We will soon make a repo-wide formatting PR and integrate `clang-format` in CI.

## Do not touch these files

The SGB (Stanford GraphBase) and LEDA adaptors are only built when `SDB` / `LEDA` roots are passed to b2, so **nothing in this list is currently verified by CI**.

```
include/boost/graph/leda_graph.hpp
include/boost/graph/stanford_graph.hpp
test/leda_graph_cc.cpp
test/stanford_graph_cc.cpp
example/girth.cpp
example/leda-concept-check.cpp
example/leda-graph-eg.cpp
example/miles_span.cpp
example/roget_components.cpp
example/topo-sort-with-leda.cpp
example/topo-sort-with-sgb.cpp
```
---

# Tier 1 (no C++ background required)

You need to be able to read code and run the build on CI. That is it. Start here if this is your first Boost PR.

## 1.1 Triage the `TODO` / `FIXME` comments

**Zero C++ required. ~24 comments in `include/`. Not a PR: a comment on this issue.**

Go through the `TODO`/`FIXME`/`XXX` comments in `include/` and work out which are stale (already done, or about a compiler nobody uses any more). Comment here with your findings. We will turn the live ones into individual issues and delete the dead ones. Good way to get a feel for the codebase before writing any code.

## 1.2 Wire up two orphaned tests

**Needs: no C++ authoring. One PR each.**

These two files exist but are not referenced from `test/Jamfile.v2`, so they are never built or run. Find out whether they still compile and pass, maybe using [Compiler Explorer](https://godbolt.org/z/9Esszr9Ga) then either add them to the Jamfile (preferred) or open a PR removing them with an explanation. Either outcome is a useful contribution.

- [ ] `test/bidir_vec_remove_edge.cpp`
- [ ] `test/undirected_dfs_visitor.cpp`

## 1.3 `BOOST_FOREACH` to range-based `for`

**Needs: range-based `for`. 19 sites, all in tests and examples: the safest possible first PR.**

Watch for the cases that iterate a `std::pair` of iterators: those need `boost::make_iterator_range(...)` (see 1.4).

- [ ] `test/incremental_components_test.cpp`
- [ ] `test/grid_graph_test.cpp`
- [ ] `example/incremental-components-eg.cpp`
- [ ] `example/incremental_components.cpp`
- [ ] `example/graph-thingie.cpp`

## 1.4 `BGL_FORALL_*` → `make_iterator_range` + range-based `for` (tests and examples)

**Needs: range-based `for`. ~55 expansions across 19 files.**

The `BGL_FORALL_*` macros predate range-based `for`. We are standardising the whole library on one iteration idiom:

```cpp
for (auto v : boost::make_iterator_range(vertices(g)))
```

with `#include `.

| Macro | Replacement range expression |
|---|---|
| `BGL_FORALL_VERTICES(_T)(v, g, G)` | `boost::make_iterator_range(vertices(g))` |
| `BGL_FORALL_EDGES(_T)(e, g, G)` | `boost::make_iterator_range(edges(g))` |
| `BGL_FORALL_OUTEDGES(_T)(u, e, g, G)` | `boost::make_iterator_range(out_edges(u, g))` |
| `BGL_FORALL_INEDGES(_T)(u, e, g, G)` | `boost::make_iterator_range(in_edges(u, g))` |
| `BGL_FORALL_ADJ(_T)` / `BGL_FORALL_ADJACENT` | `boost::make_iterator_range(adjacent_vertices(u, g))` |

**This is a migration, not a deprecation.** `iteration_macros.hpp` stays, keeps working, and is not being removed — plenty of downstream code uses it. Do not add deprecation attributes or warnings in these PRs. The goal is that BGL's own code reads one way. Leave `iteration_macros.hpp`, `iteration_macros_undef.hpp` and `example/iteration_macros.cpp` untouched; the last one demonstrates the macros on purpose.

`break` and `continue` behave identically — the macro's odd nested-loop shape exists precisely to make `break` work, and range-for gives you that for free.

- [ ] `test/mcgregor_subgraphs_test.cpp` (10)
- [ ] `test/graph_test.hpp` (4) — also drop its `iteration_macros_undef.hpp` include
- [ ] `test/csr_graph_test.cpp` (4)
- [ ] `test/subgraph_add.cpp` (3)
- [ ] `test/random_spanning_tree_test.cpp` (3)
- [ ] `test/rcsp_custom_vertex_id.cpp` (2)
- [ ] `test/rcsp_custom_vertex_id_old.cpp` (2)
- [ ] `test/named_vertices_test.cpp` (2)
- [ ] `test/mas_test_old.cpp` (2) — also drop its `iteration_macros_undef.hpp` include
- [ ] `test/cycle_ratio_tests.cpp` (2)
- [ ] `test/bundled_properties.cpp` (2)
- [ ] `test/adjacency_matrix_test.cpp` (2)
- [ ] `test/vf2_sub_graph_iso_test.cpp` (1)
- [ ] `test/subgraph_bundled.cpp` (1)
- [ ] `test/subgraph.cpp` (1)
- [ ] `test/layout_test.cpp` (1)
- [ ] `test/dijkstra_no_color_map_compare.cpp` (1)
- [ ] `example/csr-example.cpp` (2)
- [ ] `example/graphviz.cpp` (1)
## 1.5 `NULL` → `nullptr`

**Needs: knowing why `nullptr` is better. 11 sites.**

- [ ] `example/minimum_degree_ordering.cpp` (4)
- [ ] `include/boost/graph/dimacs.hpp` (3)
- [ ] `include/boost/pending/stringtok.hpp` (1)
- [ ] `include/boost/pending/relaxed_heap.hpp` (1)
- [ ] `include/boost/graph/detail/connected_components.hpp` (1)
- [ ] `example/implicit_graph.cpp` (1)
Skip `example/iohb.c` — it is C, `NULL` is correct there.

## 1.6 Documentation for undocumented headers

**Needs: AsciiDoc and patience; C++ only to write one small example. One page per PR.**

The docs are AsciiDoc under `doc/` (Antora). Several public headers have no page at all. Each needs a short page: what it is for, the synopsis, one compilable example, and a link from the relevant index. Pick **one** and follow an existing page's structure.

- [ ] `graph_as_tree.hpp`
- [ ] `labeled_graph.hpp`
- [ ] `lookup_edge.hpp`
- [ ] `matrix_as_graph.hpp`
- [ ] `named_graph.hpp`
- [ ] `tree_traits.hpp`
- [ ] `exterior_property.hpp`
- [ ] `numeric_values.hpp`
- [ ] `point_traits.hpp`
- [ ] `graph_selectors.hpp`
- [ ] A page on iterating a graph: the `make_iterator_range` idiom from 1.4 as the recommended form, plus a reference section for the `BGL_FORALL_*` macros, which are still supported, appear all over user code, and are documented nowhere
---

# Tier 2 — comfortable with templates

You should be able to read a function template with three template parameters without flinching. No metaprogramming required.

## 2.1 `BOOST_STATIC_ASSERT` → `static_assert`

**Needs: templates, and understanding what the assertion is checking. 69 sites.**

Because we compile as C++14, the message argument is mandatory — you have to write one. A good message says what the *user* did wrong, not what the condition is: prefer `"the graph type must model IncidenceGraph"` over `"is_incidence_graph::value must be true"`. Remove `#include ` if it becomes dead.

- [ ] `include/boost/graph/detail/adjacency_list.hpp` (25) — see 3.3 first
- [ ] `include/boost/graph/graph_concepts.hpp` (8)
- [ ] `include/boost/graph/vf2_sub_graph_iso.hpp` (6)
- [ ] `include/boost/graph/two_graphs_common_spanning_trees.hpp` (5)
- [ ] `include/boost/graph/isomorphism.hpp` (4)
- [ ] `include/boost/graph/compressed_sparse_row_graph.hpp` (4)
- [ ] `test/two_graphs_common_spanning_trees_test.cpp` (2)
- [ ] `include/boost/graph/strong_components.hpp` (2)
- [ ] `include/boost/graph/connected_components.hpp` (2)
- [ ] `include/boost/graph/adjacency_matrix.hpp` (2)
- [ ] `include/boost/graph/topology.hpp` (1)
- [ ] `include/boost/graph/subgraph.hpp` (1)
- [ ] `include/boost/graph/named_graph.hpp` (1)
- [ ] `include/boost/graph/maximum_weighted_matching.hpp` (1)
- [ ] `include/boost/graph/kamada_kawai_spring_layout.hpp` (1)
- [ ] `include/boost/graph/howard_cycle_ratio.hpp` (1)
- [ ] `include/boost/graph/fruchterman_reingold.hpp` (1)
- [ ] `include/boost/graph/detail/d_ary_heap.hpp` (1)
- [ ] `include/boost/graph/circle_layout.hpp` (1)
## 2.2 `BGL_FORALL_*` migration in public headers

**Needs: dependent types and ADL. ~65 expansions across 28 headers.**

Same idiom and same rules as 1.4. The difference: these are templates, so the macros used are the `_T` variants, which exist only to place a `typename` in front of the iterator type. That disappears entirely with `auto`, so `_T` and non-`_T` collapse to the same replacement.

Two things to check in your file: whether the loop body mutates the graph (a few algorithms add or remove edges while iterating — semantics are unchanged, since both the macro and `make_iterator_range` evaluate `vertices(g)` once, but it deserves a second look), and whether the file still needs its `iteration_macros.hpp` / `iteration_macros_undef.hpp` includes afterwards.

- [ ] `include/boost/graph/mcgregor_common_subgraphs.hpp` (19) — coordinate here before starting
- [ ] `include/boost/graph/isomorphism.hpp` (13) — coordinate here before starting; also drop the undef include
- [ ] `include/boost/graph/vf2_sub_graph_iso.hpp` (11) — coordinate here before starting; also drop the undef include
- [ ] `include/boost/graph/page_rank.hpp` (7)
- [ ] `include/boost/graph/edge_coloring.hpp` (6)
- [ ] `include/boost/graph/stoer_wagner_min_cut.hpp` (5) — also drop the undef include
- [ ] `include/boost/graph/graph_stats.hpp` (5)
- [ ] `include/boost/graph/successive_shortest_path_nonnegative_weights.hpp` (4)
- [ ] `include/boost/graph/graph_utility.hpp` (3)
- [ ] `include/boost/graph/fruchterman_reingold.hpp` (3)
- [ ] `include/boost/graph/adjacency_list_io.hpp` (3)
- [ ] `include/boost/graph/st_connected.hpp` (2)
- [ ] `include/boost/graph/random_spanning_tree.hpp` (2) — also drop the undef include
- [ ] `include/boost/graph/random.hpp` (2) — also drop the undef include
- [ ] `include/boost/graph/r_c_shortest_paths.hpp` (2)
- [ ] `include/boost/graph/king_ordering.hpp` (2)
- [ ] `include/boost/graph/dijkstra_shortest_paths_no_color_map.hpp` (2)
- [ ] `include/boost/graph/cycle_canceling.hpp` (2)
- [ ] `include/boost/graph/cuthill_mckee_ordering.hpp` (2)
- [ ] `include/boost/graph/adj_list_serialize.hpp` (2)
- [ ] `include/boost/graph/random_layout.hpp` (1)
- [ ] `include/boost/graph/kamada_kawai_spring_layout.hpp` (1)
- [ ] `include/boost/graph/graphviz.hpp` (1)
- [ ] `include/boost/graph/find_flow_cost.hpp` (1)
- [ ] `include/boost/graph/detail/compressed_sparse_row_struct.hpp` (1)
- [ ] `include/boost/graph/circle_layout.hpp` (1)
- [ ] `include/boost/graph/astar_search.hpp` (1)
## 2.3 Template parameter naming

**Needs: template syntax only. Pure rename, 16 sites.**

Per the naming table in CONTRIBUTING, template parameters are `PascalCase`. These files still use lowercase names, which reads as if they were concrete types. Rename consistently through declaration and definition. Nothing outside the file should need to change; if it does, the parameter name has leaked into a public alias — flag it rather than fixing it silently.

- [ ] `include/boost/graph/detail/adjacency_list.hpp` (6) — e.g. `edge_descriptor` and `incidence_iterator` as *parameter* names, actively confusing next to the real typedefs of those names; see 3.3 first
- [ ] `test/graphviz_test.cpp` (4)
- [ ] `include/boost/graph/detail/array_binary_tree.hpp` (2) — `node_type`
- [ ] `include/boost/graph/graphviz.hpp` (1)
- [ ] `include/boost/graph/graph_concepts.hpp` (1)
- [ ] `include/boost/graph/detail/shadow_iterator.hpp` (1)
- [ ] `test/subgraph.cpp` (1)
## 2.4 `BOOST_USING_STD_MIN` / `BOOST_USING_STD_MAX`

**Needs: ADL, and why Windows breaks unparenthesised `min`. ~42 sites.**

Replace the macro with parenthesized calls at the use site: `(std::min)(a, b)`. The parentheses are not optional — they stop the Windows `min`/`max` macros from expanding. Add `#include ` where missing.

- [ ] `include/boost/graph/topology.hpp` (12)
- [ ] `include/boost/graph/push_relabel_max_flow.hpp` (6)
- [ ] `include/boost/graph/eccentricity.hpp` (4)
- [ ] `include/boost/graph/tiernan_all_cycles.hpp` (2)
- [ ] `include/boost/graph/planar_detail/boyer_myrvold_impl.hpp` (2)
- [ ] `include/boost/graph/fruchterman_reingold.hpp` (2)
- [ ] `include/boost/graph/biconnected_components.hpp` (2)
- [ ] `include/boost/graph/bandwidth.hpp` (2)
- [ ] `include/boost/graph/wavefront.hpp` (1)
- [ ] `include/boost/graph/transitive_closure.hpp` (1)
- [ ] `include/boost/graph/ssca_graph_generator.hpp` (1)
- [ ] `include/boost/graph/smallest_last_ordering.hpp` (1)
- [ ] `include/boost/graph/isomorphism.hpp` (1)
- [ ] `include/boost/graph/edmonds_karp_max_flow.hpp` (1)
- [ ] `include/boost/graph/detail/geodesic.hpp` (1)
- [ ] `include/boost/graph/detail/augment.hpp` (1)
- [ ] `include/boost/graph/detail/adjacency_list.hpp` (1) — see 3.3 first
- [ ] `include/boost/graph/bron_kerbosch_all_cliques.hpp` (1)
- [ ] `include/boost/graph/boykov_kolmogorov_max_flow.hpp` (1)
- [ ] `example/boost_web_graph.cpp` (1)
## 2.5 `throw()` → `noexcept`

**Needs: exception specifications and how they changed across standards. 15 sites.**

`throw()` was deprecated in C++17 and removed in C++20, and our CI matrix includes both. Most occurrences are on exception-class destructors and `what()` overrides. Note that destructors are already implicitly `noexcept`, so in many cases the specification can simply be dropped.

- [ ] `include/boost/graph/exception.hpp` (8) — start here, it sets the pattern
- [ ] `include/boost/graph/loop_erased_random_walk.hpp` (2)
- [ ] `include/boost/graph/graphviz.hpp` (2)
- [ ] `include/boost/graph/graphml.hpp` (2)
- [ ] `include/boost/graph/bipartite.hpp` (1)
---

# Tier 3 — you need to know what the workaround was for

These require judgement about what the old code was compensating for. Say in your PR what you concluded and why; "this branch is dead on our matrix, because …" is exactly the right kind of PR description here.

## 3.1 `BOOST_STATIC_CONSTANT` → in-class `static constexpr`

**Needs: ODR-use, and why C++14 has no inline variables. 25 sites.**

The trap: in C++14 a `static constexpr` data member that is ODR-used still needs an out-of-line definition. In practice these constants are used in constant expressions only, so it rarely bites — but if you hit a link error, that is why. Say so in the PR if you had to add a definition.

- [ ] `include/boost/pending/property.hpp` (7)
- [ ] `include/boost/graph/two_bit_color_map.hpp` (4)
- [ ] `include/boost/graph/topology.hpp` (3)
- [ ] `include/boost/graph/one_bit_color_map.hpp` (3)
- [ ] `include/boost/graph/named_function_params.hpp` (2)
- [ ] `include/boost/graph/erdos_renyi_generator.hpp` (2)
- [ ] `include/boost/graph/betweenness_centrality.hpp` (2)
- [ ] `include/boost/graph/mesh_graph_generator.hpp` (1)
- [ ] `include/boost/graph/graphml.hpp` (1)
## 3.2 Delete dead `BOOST_NO_*` configuration branches

**Needs: Boost.Config, and the ability to tell a dead branch from a live one.**

These guard workarounds for compilers we no longer support. Delete the branch never taken on our toolchains and keep only the modern path. Still one file per PR — but please post your analysis of the *macro* in a comment here before opening the first PR for it, so we agree on the reasoning once rather than per file. A macro is only fully gone once every file below it is ticked; the last PR in each group is the one that also removes the macro from the CONTRIBUTING policy table.

**`BOOST_NO_STD_ITERATOR_TRAITS`** — the biggest win, 25 sites:
- [ ] `include/boost/graph/isomorphism.hpp`
- [ ] `include/boost/graph/detail/permutation.hpp`
- [ ] `include/boost/graph/detail/array_binary_tree.hpp`
- [ ] `include/boost/graph/edge_list.hpp`
- [ ] `include/boost/graph/properties.hpp`
- [ ] `include/boost/pending/mutable_queue.hpp`
- [ ] `example/put-get-helper-eg.cpp`
**`BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION`** — not in the CONTRIBUTING table yet; propose the removal in your analysis comment and we will confirm:
- [ ] `example/gerdemann.cpp`
- [ ] `example/container_gen.cpp`
- [ ] `example/transitive_closure.cpp`
- [ ] `example/vector_as_graph.cpp`
- [ ] `example/ordered_out_edges.cpp`
**`BOOST_NO_CXX11_ALLOCATOR`**:
- [ ] `include/boost/graph/r_c_shortest_paths.hpp`
- [ ] `include/boost/graph/adjacency_matrix.hpp`
- [ ] `example/container_gen.cpp`
**`BOOST_BORLANDC`**:
- [ ] `include/boost/graph/random.hpp`
- [ ] `include/boost/graph/graph_concepts.hpp`
**`BOOST_NO_STD_ALLOCATOR`**:
- [ ] `include/boost/graph/adjacency_matrix.hpp`
- [ ] `example/container_gen.cpp`
**`BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP`**:
- [ ] `include/boost/graph/graph_concepts.hpp`
- [ ] `test/bfs.cpp`
**One file each:**
- [ ] `BOOST_NO_MEMBER_TEMPLATE_FRIENDS` in `include/boost/pending/queue.hpp`
- [ ] `BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS` in `include/boost/graph/sequential_vertex_coloring.hpp`
- [ ] `BOOST_NO_SFINAE` in `include/boost/graph/overloading.hpp`
- [ ] `BOOST_DEDUCED_TYPENAME` in `include/boost/graph/copy.hpp`
- [ ] `BOOST_NO_CXX11_RVALUE_REFERENCES`, `BOOST_NO_CXX11_SMART_PTR` and `BOOST_NO_AUTO_PTR` in `include/boost/graph/detail/adjacency_list.hpp` — all three in that one file; see 3.3. For `BOOST_NO_AUTO_PTR`, drop the `std::auto_ptr` branch and keep `std::unique_ptr` unconditionally: `std::auto_ptr` was removed in C++17, so that branch is already unreachable across most of our matrix. Update the stale comment above it too.
Leave `BOOST_NO_STDC_NAMESPACE`, `BOOST_NO_EXCEPTIONS` and `BOOST_NO_CXX17_STRUCTURED_BINDINGS` alone — those are still doing real work.

## 3.3 `detail/adjacency_list.hpp`

**Needs: real template fluency.**

This one header carries 25 `BOOST_STATIC_ASSERT`s, three `BOOST_NO_*` macros, 6 misnamed template parameters and one `BOOST_USING_STD_MIN`. It is the most-instantiated header in the library and mistakes there break everything downstream. Perfectly doable, but please do not make it your first PR — and it is four separate PRs, one per task, not one big one.

---

## What a good PR looks like

- Title: `Replace BOOST_STATIC_ASSERT in graph_concepts.hpp`
- Description: what you changed, which box from this issue, anything that surprised you.
- Diff: one file, one task, no unrelated reformatting.
- CI green on the full matrix.
Maintainers aim for a first-pass review within two weeks. If your PR is sitting untouched past that, ping this issue — that is not rude, it is helpful.

Happy to help anyone get unstuck on setup, b2, or the review process. Just ask below.

Contributor guide

Open the contributing guide

Research direction

Read CONTRIBUTING.md first, then choose one unchecked task and inspect the named file or test entry, such as test/Jamfile.v2 or a listed header. Run the relevant single test or CI build command described in the issue. Done means one focused, behavior-preserving change or documented finding, with the test suite remaining green.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
developer-experience, documentation, testing
Issue type
Refactor
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.