Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"CMAKE_CXX_STANDARD": "20",
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
"CMAKE_CXX_EXTENSIONS": "OFF",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"WARNINGS_AS_ERRORS": "ON"
}
},
{
Expand Down
3 changes: 2 additions & 1 deletion benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ target_link_libraries(graph_benchmarks

# Register benchmarks with CTest
add_test(NAME graph_benchmarks
COMMAND graph_benchmarks --benchmark_min_time=0.1)
COMMAND graph_benchmarks --benchmark_min_time=0.1s)

# Add algorithm benchmarks subdirectory
add_subdirectory(algorithms)

2 changes: 1 addition & 1 deletion benchmark/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,4 @@ endif()
# Register with CTest using a short minimum time so CI stays fast.
# For proper baseline capture use: ./benchmark_dijkstra --benchmark_min_time=1.0
add_test(NAME benchmark_dijkstra
COMMAND benchmark_dijkstra --benchmark_min_time=0.1)
COMMAND benchmark_dijkstra --benchmark_min_time=0.1s)
9 changes: 4 additions & 5 deletions benchmark/algorithms/dijkstra_fixtures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

#include <graph/generators.hpp>
#include <graph/container/compressed_graph.hpp>
#include <graph/container/dynamic_graph.hpp>
#include <graph/container/traits/vov_graph_traits.hpp>

namespace graph::benchmark {
Expand Down Expand Up @@ -83,16 +82,16 @@ inline edge_list path_graph(vertex_id_t n, uint64_t seed = 42,
// ---------------------------------------------------------------------------

/// Build a compressed_graph (CSR) from a pre-sorted edge list.
inline csr_graph_t make_csr(const edge_list& edges, vertex_id_t num_vertices) {
inline csr_graph_t make_csr(const edge_list& edge_list_data, vertex_id_t vertex_count) {
csr_graph_t g;
g.load_edges(edges, std::identity{}, num_vertices);
g.load_edges(edge_list_data, std::identity{}, vertex_count);
return g;
}

/// Build a vov dynamic_graph from an edge list (order does not matter).
inline vov_graph_t make_vov(const edge_list& edges, vertex_id_t num_vertices) {
inline vov_graph_t make_vov(const edge_list& edge_list_data, vertex_id_t vertex_count) {
vov_graph_t g;
g.load_edges(edges, std::identity{}, num_vertices);
g.load_edges(edge_list_data, std::identity{}, vertex_count);
return g;
}

Expand Down
38 changes: 20 additions & 18 deletions benchmark/benchmark_views.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@ using namespace graph::views::adaptors;
using TestGraph = std::vector<std::vector<int>>;

// Create a random directed graph
TestGraph create_random_graph(size_t num_vertices, size_t avg_degree) {
TestGraph g(num_vertices);
TestGraph create_random_graph(size_t vertex_count, size_t mean_degree) {
TestGraph g(vertex_count);
std::mt19937 rng(42); // Fixed seed for reproducibility

std::uniform_int_distribution<size_t> dist(0, num_vertices - 1);
std::uniform_int_distribution<size_t> dist(0, vertex_count - 1);

for (size_t u = 0; u < num_vertices; ++u) {
size_t degree = std::poisson_distribution<size_t>(avg_degree)(rng);
for (size_t i = 0; i < degree; ++i) {
std::poisson_distribution<int> degree_dist(static_cast<int>(mean_degree));

for (size_t u = 0; u < vertex_count; ++u) {
auto sampled_degree = static_cast<size_t>(degree_dist(rng));
for (size_t i = 0; i < sampled_degree; ++i) {
size_t v = dist(rng);
if (v != u) { // Avoid self-loops
g[u].push_back(static_cast<int>(v));
Expand All @@ -41,19 +43,19 @@ TestGraph create_random_graph(size_t num_vertices, size_t avg_degree) {
}

// Create a path graph (0 -> 1 -> 2 -> ... -> n-1)
TestGraph create_path_graph(size_t num_vertices) {
TestGraph g(num_vertices);
for (size_t i = 0; i + 1 < num_vertices; ++i) {
TestGraph create_path_graph(size_t vertex_count) {
TestGraph g(vertex_count);
for (size_t i = 0; i + 1 < vertex_count; ++i) {
g[i].push_back(static_cast<int>(i + 1));
}
return g;
}

// Create a complete graph (all vertices connected)
TestGraph create_complete_graph(size_t num_vertices) {
TestGraph g(num_vertices);
for (size_t u = 0; u < num_vertices; ++u) {
for (size_t v = 0; v < num_vertices; ++v) {
TestGraph create_complete_graph(size_t vertex_count) {
TestGraph g(vertex_count);
for (size_t u = 0; u < vertex_count; ++u) {
for (size_t v = 0; v < vertex_count; ++v) {
if (u != v) {
g[u].push_back(static_cast<int>(v));
}
Expand All @@ -63,11 +65,11 @@ TestGraph create_complete_graph(size_t num_vertices) {
}

// Create a DAG (directed acyclic graph) for topological sort
TestGraph create_dag(size_t num_vertices) {
TestGraph g(num_vertices);
for (size_t u = 0; u < num_vertices; ++u) {
TestGraph create_dag(size_t vertex_count) {
TestGraph g(vertex_count);
for (size_t u = 0; u < vertex_count; ++u) {
// Connect to next few vertices only (maintains DAG property)
for (size_t v = u + 1; v < std::min(u + 5, num_vertices); ++v) {
for (size_t v = u + 1; v < std::min(u + 5, vertex_count); ++v) {
g[u].push_back(static_cast<int>(v));
}
}
Expand Down Expand Up @@ -98,7 +100,7 @@ BENCHMARK(BM_Vertexlist_Iteration)->RangeMultiplier(2)->Range(100, 10000)->Compl
// Benchmark: vertexlist with value function
static void BM_Vertexlist_WithValueFunction(benchmark::State& state) {
auto g = create_random_graph(state.range(0), 5);
auto vvf = [](const auto& g, auto v) { return vertex_id(g, v); };
auto vvf = [](const auto& gr, auto v) { return vertex_id(gr, v); };

for (auto _ : state) {
size_t sum = 0;
Expand Down
68 changes: 62 additions & 6 deletions cmake/CompilerWarnings.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Comprehensive compiler warning configuration
function(set_project_warnings target_name)
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" ON)

set(MSVC_WARNINGS
/W4 # High warning level
Expand All @@ -26,31 +26,72 @@ function(set_project_warnings target_name)
/permissive- # standards conformance mode
)

# The -Wno-* options are used to suppress specific warnings that are either not relevant or too noisy for this project.
# Further adjustments may be necessary based on the specific codebase and compiler versions used.
set(CLANG_WARNINGS
-Wall
-Wextra
-Wpedantic
-Wshadow
-Wnon-virtual-dtor
-Wold-style-cast
-Wcast-align
-Wunused
-Woverloaded-virtual
-Wconversion
-Wsign-conversion
-Wnull-dereference
-Wdouble-promotion
-Wformat=2
-Wimplicit-fallthrough
-Wshadow
#-Wconversion
#-Wsign-conversion
-Wno-unused-parameter
-Wno-unused-variable
-Wno-mismatched-tags
-Wno-ignored-qualifiers
-Wno-deprecated-declarations
-Wno-unqualified-std-cast-call
-Wno-unused-lambda-capture
-Wno-unused-local-typedef
-Wno-self-assign-overloaded
-Wno-unneeded-internal-declaration
-Wno-unused-but-set-variable
-Wno-sign-compare
-Wno-old-style-cast
-Wno-double-promotion
-Wno-conversion
-Wno-sign-conversion
)

set(GCC_WARNINGS
${CLANG_WARNINGS}
-Wall
-Wextra
-Wpedantic
-Wnon-virtual-dtor
-Wold-style-cast
-Wcast-align
-Wunused
-Woverloaded-virtual
-Wnull-dereference
-Wdouble-promotion
-Wformat=2
-Wimplicit-fallthrough
-Wshadow
#-Wconversion
#-Wsign-conversion
-Wmisleading-indentation
-Wduplicated-cond
-Wduplicated-branches
-Wlogical-op
-Wuseless-cast
-Wno-useless-cast
-Wno-old-style-cast
-Wno-unused-local-typedefs
-Wno-unused-but-set-variable
-Wno-sign-compare
-Wno-comment
-Wno-null-dereference
-Wno-deprecated-declarations
-Wno-conversion
-Wno-sign-conversion
)

if(WARNINGS_AS_ERRORS)
Expand All @@ -69,5 +110,20 @@ function(set_project_warnings target_name)
message(WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.")
endif()

# clang-cl (MSVC ABI): MSVC_WARNINGS are already applied above via if(MSVC),
# but /W4 in clang-cl maps to Clang warning groups which fire on things the
# project intentionally suppresses. Apply all -Wno-* from CLANG_WARNINGS plus
# clang-cl-specific suppressions.
if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
foreach(w ${CLANG_WARNINGS})
if(w MATCHES "^-Wno-")
list(APPEND PROJECT_WARNINGS ${w})
endif()
endforeach()
list(APPEND PROJECT_WARNINGS
-Wno-unknown-attributes # [[no_unique_address]] unsupported in MSVC ABI mode
)
endif()

target_compile_options(${target_name} INTERFACE ${PROJECT_WARNINGS})
endfunction()
4 changes: 2 additions & 2 deletions cmake/StandardProjectSettings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Enable folder organization in IDEs
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Enable parallel compilation for MSVC
if(MSVC)
# Enable parallel compilation for MSVC (cl.exe only; clang-cl doesn't support /MP)
if(MSVC AND NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Use /MP to enable parallel compilation with all available cores
add_compile_options(/MP)
message(STATUS "MSVC parallel compilation enabled with /MP")
Expand Down
38 changes: 24 additions & 14 deletions docs/user-guide/containers.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@ template <class EV = void, // edge value type
class VV = void, // vertex value type
class GV = void, // graph value type
class VId = uint32_t, // vertex id type
bool Sourced = false, // store source_id on edges?
bool Bidirectional = false, // maintain incoming-edge lists?
class Traits = vofl_graph_traits<EV, VV, GV, VId, Sourced>>
class Traits = vofl_graph_traits<EV, VV, GV, VId, Bidirectional>>
class dynamic_graph;
}
```
Expand All @@ -64,7 +63,7 @@ incoming-edge list, enabling the `in_edges`, `in_degree`, `find_in_edge`, and
|----------|-------|
| Vertex ID assignment | Contiguous (0 .. N-1) for `v`/`d` traits; sparse user-defined keys for `m`/`u` traits |
| Vertex range | Random access (`v`/`d`), bidirectional (`m`), forward (`u`) |
| Edge range per vertex | Random access (`v`/`d`), forward (`fl`/`us`), bidirectional (`l`/`s`/`em`) |
| Edge range per vertex | Random access (`v`/`d`), forward (`fl`/`us`), bidirectional (`l`/`s`/`m`) |
| Partitions | No |
| Append vertices/edges | Yes |

Expand Down Expand Up @@ -105,7 +104,6 @@ Complexity depends on the vertex container, the edge container, or neither.
| `VV` | `void` | Vertex value type (`void` → no vertex values) |
| `GV` | `void` | Graph value type (`void` → no graph value) |
| `VId` | `uint32_t` | Vertex ID type (integral for indexed traits, any ordered/hashable type for map-based traits) |
| `Sourced` | `false` | When `true`, each edge stores a source vertex ID. This does not affect the ability to use `source_id(g,uv)`. |
| `Bidirectional` | `false` | When `true`, each vertex maintains an incoming-edge list, enabling `in_edges(g,u)`, `in_degree(g,u)`, `find_in_edge(g,...)`, and `contains_in_edge(g,...)`. Satisfies `bidirectional_adjacency_list<G>`. |
| `Traits` | `vofl_graph_traits<…>` | Trait struct that defines the vertex and edge container types |

Expand All @@ -127,7 +125,19 @@ G g;
```

The `dynamic_adjacency_graph<Traits>` alias extracts `EV`, `VV`, `GV`, `VId`,
and `Sourced` from the traits struct, so you only need one template argument.
and `Bidirectional` from the traits struct, so you only need one template argument.

Each traits header also provides a convenience graph alias that matches how tests
are written (for example, `dod_graph` in `test_dynamic_graph_dod.cpp`):

```cpp
#include <graph/container/traits/dod_graph_traits.hpp>

using namespace graph::container;

using G0 = dod_graph<>; // EV=VV=GV=void
using G1 = dod_graph<int, std::string, void, uint32_t, true>; // bidirectional
```

### Trait combinations

Expand Down Expand Up @@ -197,13 +207,13 @@ All trait structs share the same template parameters:

```cpp
template <class EV = void, class VV = void, class GV = void,
class VId = uint32_t, bool Sourced = false>
class VId = uint32_t, bool Bidirectional = false>
struct vov_graph_traits { ... };
```

Each defines:
- `edge_value_type`, `vertex_value_type`, `graph_value_type`, `vertex_id_type`
- `static constexpr bool sourced`
- `static constexpr bool bidirectional`
- `edge_type`, `vertex_type`, `graph_type`
- `vertices_type` (e.g., `std::vector<vertex_type>`)
- `edges_type` (e.g., `std::vector<edge_type>`)
Expand Down Expand Up @@ -240,25 +250,25 @@ the type aliases and constant shown below:

namespace myapp {

// Forward declarations required by dynamic_edge / dynamic_vertex / dynamic_graph
// Forward declarations required by dynamic_out_edge / dynamic_vertex / dynamic_graph
using namespace graph::container;

template <class EV = void, class VV = void, class GV = void,
class VId = uint32_t, bool Sourced = false>
class VId = uint32_t, bool Bidirectional = false>
struct flat_map_small_vec_traits {
// --- Required type aliases ---
using edge_value_type = EV;
using vertex_value_type = VV;
using graph_value_type = GV;
using vertex_id_type = VId;
static constexpr bool sourced = Sourced;
static constexpr bool bidirectional = Bidirectional;

// --- Edge, vertex, and graph types (always use dynamic_*) ---
using edge_type = dynamic_edge<EV, VV, GV, VId, Sourced,
flat_map_small_vec_traits>;
using vertex_type = dynamic_vertex<EV, VV, GV, VId, Sourced,
using edge_type = dynamic_out_edge<EV, VV, GV, VId, Bidirectional,
flat_map_small_vec_traits>;
using vertex_type = dynamic_vertex<EV, VV, GV, VId, Bidirectional,
flat_map_small_vec_traits>;
using graph_type = dynamic_graph<EV, VV, GV, VId, Sourced,
using graph_type = dynamic_graph<EV, VV, GV, VId, Bidirectional,
flat_map_small_vec_traits>;

// --- Storage types (your custom containers) ---
Expand Down
6 changes: 4 additions & 2 deletions examples/BGLWorkshop2026/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,16 @@ if(_bglws_bgl_inc)
message(STATUS "BGLWorkshop2026: BGL headers at ${_bglws_bgl_inc}")
add_executable(bglws_bacon_bgl bacon_bgl.cpp)
target_link_libraries(bglws_bacon_bgl PRIVATE graph3)
target_include_directories(bglws_bacon_bgl PRIVATE ${BGLWS_INCLUDE_DIRS} ${_bglws_bgl_inc})
target_include_directories(bglws_bacon_bgl PRIVATE ${BGLWS_INCLUDE_DIRS})
target_include_directories(bglws_bacon_bgl SYSTEM PRIVATE ${_bglws_bgl_inc})
target_compile_features(bglws_bacon_bgl PRIVATE cxx_std_20)
target_compile_definitions(bglws_bacon_bgl PRIVATE
BGLWS_OUTPUT_DIR="${CMAKE_CURRENT_SOURCE_DIR}/output")

add_executable(bglws_france_routes_bgl france_routes_bgl.cpp)
target_link_libraries(bglws_france_routes_bgl PRIVATE graph3)
target_include_directories(bglws_france_routes_bgl PRIVATE ${BGLWS_INCLUDE_DIRS} ${_bglws_bgl_inc})
target_include_directories(bglws_france_routes_bgl PRIVATE ${BGLWS_INCLUDE_DIRS})
target_include_directories(bglws_france_routes_bgl SYSTEM PRIVATE ${_bglws_bgl_inc})
target_compile_features(bglws_france_routes_bgl PRIVATE cxx_std_20)
target_compile_definitions(bglws_france_routes_bgl PRIVATE
BGLWS_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/graphs"
Expand Down
1 change: 0 additions & 1 deletion examples/BGLWorkshop2026/bacon_gv3.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "graph/graph.hpp"
#include "graph/algorithm/breadth_first_search.hpp"
#include "graph/views/bfs.hpp"
#include "graph/container/dynamic_graph.hpp"
#include "graph/container/traits/uol_graph_traits.hpp"
#include "graph/container/traits/mol_graph_traits.hpp"
#include "imdb-graph.hpp"
Expand Down
Loading
Loading