Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
f5f5e0c
invalid_argument instead of out_of_range for invalid vertices and hyp…
SpectraL519 Apr 28, 2026
940eaa3
aligned the naming of callback parameters
SpectraL519 Apr 28, 2026
444ca03
init hgl doc pages
SpectraL519 Apr 28, 2026
592880e
init hgl groups + first hgl doc comments
SpectraL519 Apr 28, 2026
46be8f9
hypergraph elements and dir tags docs
SpectraL519 Apr 28, 2026
b6b2ec5
structural tags + hypergraph traits docs
SpectraL519 Apr 28, 2026
e28158d
hypergraph doc
SpectraL519 Apr 28, 2026
b3982aa
hypergraph docs refinement
SpectraL519 Apr 28, 2026
af9ec04
impl tags docs refinement
SpectraL519 Apr 28, 2026
f90082d
conversion docs
SpectraL519 Apr 28, 2026
65b7311
io docs
SpectraL519 Apr 28, 2026
1490421
alg core doc
SpectraL519 Apr 28, 2026
7f355d9
init_range -> init_node_range + bfs tmpl doc
SpectraL519 Apr 28, 2026
7a5d129
dfs docs
SpectraL519 Apr 28, 2026
1f89fe6
alg utils docs
SpectraL519 Apr 28, 2026
e508ac8
concrete bfs docs + @see fix
SpectraL519 Apr 28, 2026
af48dda
concrete dfs docs
SpectraL519 Apr 28, 2026
007d302
bsearch and fsearch docs
SpectraL519 Apr 29, 2026
805d242
algo umbrella header docs
SpectraL519 Apr 29, 2026
5afec4f
hgl quick start page
SpectraL519 Apr 29, 2026
12ef265
architecture page
SpectraL519 Apr 29, 2026
8336400
architecture page refinement
SpectraL519 Apr 29, 2026
f422335
conversion page + self-loops in clique exp
SpectraL519 Apr 29, 2026
cefc1ff
io page
SpectraL519 Apr 29, 2026
0c3410f
alg overview page
SpectraL519 Apr 29, 2026
9de28ca
alg templates page
SpectraL519 Apr 29, 2026
0c08429
alg traversal doc
SpectraL519 Apr 29, 2026
6c4ce5e
alg properties doc + moved property functions to algorithm/properties…
SpectraL519 Apr 29, 2026
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
83 changes: 79 additions & 4 deletions docs/config/groups.dox
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@

/// @defgroup GL-IO I/O Utility
/// @ingroup GL
/// @brief Comprehensive I/O stream support, parsing algorithms, and range-based formatting.
/// @brief I/O stream operations, formatting, and serialization of graph data.
///
/// This group provides the necessary infrastructure to seamlessly serialize, deserialize, and
/// visualize complex graph structures. By offering a robust set of stream manipulators, formatting
/// traits, and configuration options, it allows users to easily translate in-memory graphs to
/// and from standard streams, files, or custom string representations.
/// visualize complex graph structures. By offering a robust set of stream manipulators, range
/// formatting utilities, and configuration options, it allows users to easily translate
/// in-memory graphs to and from standard streams, files, or custom string representations.

/// @defgroup GL-Traits Traits & Concepts
/// @ingroup GL
Expand Down Expand Up @@ -83,3 +83,78 @@
/// operations, these utilities are completely independent of graph theory semantics. They provide
/// a curated set of highly reusable, general-purpose tools that can smoothly integrate into any
/// modern C++ codebase.

/// @defgroup HGL Hypergraph Library (HGL)
/// @brief The top-level module defining the general-purpose C++ template hypergraph library.
///
/// This module provides a comprehensive suite of memory-efficient hypergraph representations,
/// highly customizable algorithms, and robust I/O facilities. Designed strictly around modern
/// C++ paradigms, the library leverages templates and concepts to deliver an API that is fast,
/// generic, and type-safe. It supports both undirected hypergraphs and backward-forward (bf)
/// directed hypergraphs.

/// @defgroup HGL-Core Core Hypergraph Components
/// @ingroup HGL
/// @brief Fundamental hypergraph data structures, element descriptors, and configuration tags.
///
/// This group establishes the primary user interface for the HGL module, centered around the highly
/// configurable @ref hgl::hypergraph "hypergraph" class. It provides the core data types, such as vertex
/// and hyperedge descriptors, required to safely navigate and manipulate graph elements.
///
/// Furthermore, this module defines the declarative tags (e.g., directedness and backend
/// implementation types) that dictate both the behavioral semantics and the underlying memory
/// layout of the instantiated hypergraphs.

/// @defgroup HGL-Algorithm Hypergraph Algorithms
/// @ingroup HGL
/// @brief Generic hypergraph algorithms, search templates, and related utilities.
///
/// This module provides hypergraph-specific algorithmic templates and implementations
/// (such as forward and backward searches) designed to natively navigate the complex,
/// high-order structure of hyperedges.

/// @defgroup HGL-IO I/O Utility
/// @ingroup HGL
/// @brief I/O stream operations, formatting, and serialization of hypergraph data.
///
/// Provides the necessary infrastructure to seamlessly serialize, deserialize, and visualize
/// complex hypergraph structures. It utilizes shared stream manipulation options and range
/// formatting utilities to easily translate in-memory hypergraphs to and from standard
/// streams and files.

/// @defgroup HGL-Traits Traits & Concepts
/// @ingroup HGL
/// @brief Type traits, template constraints, and compile-time metaprogramming utilities.
///
/// These components form the strict conceptual backbone of the HGL module, used extensively
/// to ensure internal type safety and correctness, while also constraining user-defined types
/// to required structural contracts.
///
/// @section concepts_link Detailed Concept Specifications
/// For a detailed list of all HGL module's concepts and their formal requirements, please refer to
/// the [HGL Concepts Documentation](hgl_concepts.md#hgl-concepts-documentation) page.
///
/// > [!NOTE]
/// >
/// > Because hypergraphs share the same underlying implementation design and mechanisms as standard
/// > graphs, they seamlessly reuse the same fundamental C++20 concepts. Therefore the HGL module
/// > pulls in all standard graph traits, concept checkers, and metaprogramming utilities from the
/// > GL module. To get an overview of these traits and concepts, please refer to the GL module's
/// > @ref GL-Traits documentation page.

/// @defgroup HGL-Types Generic Types
/// @ingroup HGL
/// @brief Independent, high-performance data structures and utility types.
///
/// This module houses a variety of general-purpose data structures and types. Though they are
/// utilized natively by hypergraph implementations, these components are carefully decoupled
/// from specific hypergraph logic, they can be seamlessly extracted and utilized in broader
/// contexts.

/// @defgroup HGL-Util General Utilities
/// @ingroup HGL
/// @brief Practical, domain-agnostic C++ helpers, mathematical functions, and polyfills.
///
/// These utilities provide a curated set of general-purpose tools that support the
/// library's internal algorithms and hypergraph modeling operations, completely
/// independent of strict hypergraph theory semantics.
10 changes: 8 additions & 2 deletions docs/gl/algorithms/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ The CPP-GL algorithms module is designed with a strict architectural separation

This separation ensures maximum code reuse, provides strict zero-cost abstractions, and allows power users to inject highly customized logic directly into the traversal control flow.

---

## The Architectural Separation

### 1. The Generic Templates (Engines)
Expand All @@ -19,13 +21,15 @@ The core generic templates include:

### 2. The Concrete Algorithms

Concrete algorithms (like `dijkstra_shortest_paths`, `topological_sort`, or `breadth_first_search`) are essentially lightweight wrappers around the generic engines. They are responsible for:
Concrete algorithms (like `dijkstra_shortest_paths`, `topological_sort`, or `breadth_first_search`) are essentially simple wrappers around the generic engines. They are responsible for:
- Allocating and managing memory for algorithm state tracking (e.g., `std::vector<bool> visited` arrays, distance maps).
- Defining the specific logic inside the lambda callbacks and predicates.
- Managing the final return types and structures.

By separating these layers, CPP-GL guarantees that all algorithms inherently benefit from the exact same optimized design and element management.

---

## Core Algorithm Elements

To interact with the generic templates or understand the concrete algorithms, you must be familiar with a few foundational types and tags used uniformly across the library.
Expand Down Expand Up @@ -63,7 +67,9 @@ CPP-GL manages this via the [**gl::algorithm::result_discriminator**](../../cpp-
- `ret`: The algorithm will allocate memory and return a stateful object (e.g., `predecessors_map<G>`).
- `noret`: The algorithm will execute purely for side-effects and return `void` (or a simple success boolean).

## Available Concrete Algorithms
---

## Available Algorithms
Comment thread
SpectraL519 marked this conversation as resolved.

Explore the specific layers of the algorithm module below:

Expand Down
4 changes: 2 additions & 2 deletions docs/gl/algorithms/pathfinding.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ std::cout << "Path: "
> [!INFO] Algorithmic Complexity
>
> The time complexity depends heavily on the underlying representation of GraphType and the priority queue overhead:
> - **Adjacency List Representations:** $\mathcal{O}((|V| + |E|) \log |V|)$. The queue operations scale with the number of edges, making this optimal for sparse graphs.
> - **Adjacency Matrix Representations:** $\mathcal{O}(|V|^2 + |E| \log |V|)$. Iterating over adjacent vertices requires scanning the entire $|V|$-length matrix row, shifting the bottleneck to row traversal.
> - **Adjacency List Representations:** $O((|V| + |E|) \log |V|)$. The queue operations scale with the number of edges, making this optimal for sparse graphs.
> - **Adjacency Matrix Representations:** $O(|V|^2 + |E| \log |V|)$. Iterating over adjacent vertices requires scanning the entire $|V|$-length matrix row, shifting the bottleneck to row traversal.

---

Expand Down
2 changes: 1 addition & 1 deletion docs/gl/algorithms/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The library provides four primary traversal engines.

## The Callback Sequence

The true power of the generic templates lies in their callback/predicate hooks. Every iteration of the engine loop rigidly follows a defined sequence. By injecting custom lambdas (or omitting them via the [**empty_callback**](../../cpp-gl/structgl_1_1algorithm_1_1empty__callback.md)), you dictate the algorithm's behavior.
The true power of the generic templates lies in their callback/predicate hooks. Every iteration of the engine loop rigidly follows a defined sequence. By injecting custom callbacks (or omitting them via the [**empty_callback**](../../cpp-gl/structgl_1_1algorithm_1_1empty__callback.md)), you dictate the algorithm's behavior.

### Execution Flowchart

Expand Down
8 changes: 4 additions & 4 deletions docs/gl/algorithms/topological_algs.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ else {
> [!INFO] Algorithmic Complexity
>
> The time complexity depends on the underlying representation of `GraphType`:
> - **Adjacency List Representations:** $\mathcal{O}(|V| + |E|)$.
> - **Adjacency Matrix Representations:** $\mathcal{O}(|V|^2)$. Iterating over adjacent vertices requires scanning the entire $|V|$-length matrix row.
> - **Adjacency List Representations:** $O(|V| + |E|)$.
> - **Adjacency Matrix Representations:** $O(|V|^2)$. Iterating over adjacent vertices requires scanning the entire $|V|$-length matrix row.

---

Expand Down Expand Up @@ -87,5 +87,5 @@ else {
> [!INFO] Algorithmic Complexity
>
> The time complexity depends on the underlying representation of `GraphType`:
> - **Adjacency List Representations:** $\mathcal{O}(|V| + |E|)$.
> - **Adjacency Matrix Representations:** $\mathcal{O}(|V|^2)$. Iterating over adjacent vertices requires scanning the entire $|V|$-length matrix row.
> - **Adjacency List Representations:** $O(|V| + |E|)$.
> - **Adjacency Matrix Representations:** $O(|V|^2)$. Iterating over adjacent vertices requires scanning the entire $|V|$-length matrix row.
6 changes: 2 additions & 4 deletions docs/gl/algorithms/traversal.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ gl::algorithm::breadth_first_search<gl::algorithm::noret>( // (2)!
3. Traverses all vertices in the graph, automatically jumping to new roots if disconnected components are found.
4. A custom PreVisitCallback executed exactly when a vertex is marked as visited.

<!-- TODO: Diagram -->

---

## Depth-First Search (DFS)
Expand Down Expand Up @@ -110,6 +108,6 @@ The following diagram illustrates the fundamental difference in exploration orde

The time complexity for all three traversals (BFS, Iterative DFS, and Recursive DFS) depends entirely on the underlying representation of `GraphType`:

- **Adjacency List Representations:** $\mathcal{O}(|V| + |E|)$. The algorithm strictly evaluates existing edges, making this optimal for sparse graphs.
- **Adjacency List Representations:** $O(|V| + |E|)$. The algorithm strictly evaluates existing edges, making this optimal for sparse graphs.

- **Adjacency Matrix Representations:** $\mathcal{O}(|V|^2)$. To find adjacent unvisited vertices, the algorithm must scan the entire $|V|$-length matrix row for every visited vertex, shifting the bottleneck from edge evaluation to row traversal.
- **Adjacency Matrix Representations:** $O(|V|^2)$. To find adjacent unvisited vertices, the algorithm must scan the entire $|V|$-length matrix row for every visited vertex, shifting the bottleneck from edge evaluation to row traversal.
6 changes: 3 additions & 3 deletions docs/gl/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The **GL (Graph Library)** module is engineered around a singular philosophy: pr

This section explores the core architectural decisions of the GL module:

- [Core Concepts](#core-concepts): Learn how the gl::graph template operates, the difference between IDs and descriptors, and how to navigate topologies.
- [Core Concepts](#core-concepts): Learn how the `gl::graph` template operates, the difference between IDs and descriptors, and how to navigate topologies.
- [Graph Representation Models](#graph-representation-models): Understand the diverse memory models available and their performance characteristics.
- [Properties & Custom Data](#properties-custom-data): Discover how to inject arbitrary data directly into your graph elements with strict type safety.

Expand Down Expand Up @@ -82,7 +82,7 @@ When you add new vertices or edges to the graph, the library guarantees that exi
>
> Because a property-less vertex descriptor is essentially just a wrapper around an ID, there is zero overhead to using it instead of a raw ID, and it will never invalidate when new elements are added.
>
> This means that performing operations like the following is completely safe:
> This means that performing operations like the following are completely safe:
> ```cpp
> const auto v1 = graph.add_vertex();
> const auto v2 = graph.add_vertex();
Expand Down Expand Up @@ -232,7 +232,7 @@ By keeping all vertex and edge data in adjacent memory blocks, these models prov
>
> While the flat adjacency list model is highly efficient for graph storage and traversal, it is highly inefficient to construct element-by-element. The most efficient approach for utilizing flat list graphs is to construct your graph using the standard list model first, and then convert it into the flat list model using the generic [**gl::to**](../cpp-gl/group__GL-Core.md#function-to) conversion function. This exact methodology is utilized internally by the [**graph topology generators**](topologies.md) defined within the library.

### Operation Complexity
### Operation Complexities

Depending on the chosen representation model, the computational complexity of standard graph operations will differ. The table below outlines these complexities.

Expand Down
10 changes: 4 additions & 6 deletions docs/gl/io.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ int main() {
auto e = g.add_edge(v0, v1);

std::cout << "Vertex: " << v0 << '\n'; // (1)!
std::cout << "Edge: " << e << '\n'; // (2)!
std::cout << "Graph:\n" << g << '\n'; // (3)!
std::cout << "Edge: " << e << '\n'; // (2)!
std::cout << "Graph:\n" << g << '\n'; // (3)!
}
```

Expand Down Expand Up @@ -87,12 +87,11 @@ int main() {
using graph_type = gl::directed_graph<gl::name_property, gl::name_property>;
auto graph = gl::topology::biclique<graph_type>(2uz, 3uz); // (1)!

std::size_t v_idx = 0uz, e_idx = 0uz;
for (const auto& vertex : graph.vertices()) { // (2)!
vertex->name = std::format("vertex_{}", ++v_idx);
vertex->name = std::format("vertex_{}", vertex.id() + 1);
for (const auto& edge : graph.out_edges(vertex))
if (edge->name.empty())
edge->name = std::format("edge_{}", ++e_idx);
edge->name = std::format("edge_{}", edge.id() + 1);
}

std::cout << graph << std::endl; // (3)!
Expand Down Expand Up @@ -170,7 +169,6 @@ For disk storage and network transmission, CPP-GL defines the **Graph Specificat
<edge-list>
```

<!-- TODO: ensure element col wide enough -->
| **Element** | **Description** |
| :----------------- | :-------------- |
| `dir-spec` | `1` if the graph is directed<br/>`0` if the graph is undirected |
Expand Down
9 changes: 7 additions & 2 deletions docs/gl/quick_start.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ int main() {
return 1;
}

auto path_to_target = gl::algorithm::reconstruct_path(paths.predecessors, target_id); // (7)!
auto path_to_target
= gl::algorithm::reconstruct_path(paths.predecessors, target_id); // (7)!
std::cout << "Shortest path distance to vertex " << target_id << ": "
<< paths.distances[target_id] << "\nPath: "
<< gl::io::range_formatter(path_to_target, " -> ", "", "") << '\n'; // (8)!
<< gl::io::range_formatter(path_to_target, " -> ", "", "") // (8)!
<< '\n';

return 0;
}
Expand All @@ -69,6 +71,9 @@ Path: 0 -> 2 -> 3 -> 1 -> 4
### Understanding the Code

- **Traits (`gl::list_graph_traits`):** CPP-GL relies heavily on template abstraction. Instead of passing multiple arguments to the `gl::graph` constructor, you pass a single *Traits* struct as its template parameter. This strictly dictates whether the graph uses an adjacency list or matrix, if it is directed, what custom properties (like `gl::weight_property`) exist on its elements and what id type is used for its elements.

- **Property Access (`->weight`):** Adding an edge returns a descriptor handle. You access the specific payload fields associated with that edge by using the overloaded `->` operator, ensuring highly performant and type-safe data manipulation.

- **Algorithm Separation:** Search engines and algorithms (like `dijkstra_shortest_paths`) exist entirely outside the graph class. They accept the graph as a `const` reference, mathematically guaranteeing that algorithms will never accidentally mutate your topology.

- **Formatting (`gl::io::range_formatter`):** The library includes lightweight utility formatters so you can easily stream sequences, paths, and standard ranges directly to the console with complete control over delimiters and brackets.
Loading
Loading