Skip to content

Commit 378b435

Browse files
committed
resolved comments
1 parent 16fcaf4 commit 378b435

4 files changed

Lines changed: 55 additions & 37 deletions

File tree

docs/additional_functionality.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Additional functionality
22

33
- [Force inlining](#force-inlining)
4+
- [Ranges utility](#ranges-utility)
45

56
<br />
67

@@ -16,3 +17,44 @@ To enable the force inlining functionality you have to add the following in your
1617

1718
> [!NOTE]
1819
> Force inlining is supported only for the GNU G++ and CLang++ compilers.
20+
21+
<br />
22+
<br />
23+
24+
## Ranges utility
25+
26+
Small helpers for working with C++20 ranges.
27+
28+
> [!NOTE]
29+
> - Header: [gl/util/ranges.hpp](/include/gl/util/ranges.hpp)
30+
> - Namespace: `gl::util`
31+
32+
### View adapters
33+
34+
- **`deref_view`**
35+
- *Description*: A transform view that dereferences pointer-like elements in a range. Useful for turning a range of pointers or smart pointers into a range of references.
36+
- *Usage*: `range | gl::util::deref_view`
37+
- *Works with*: `T*`, `std::unique_ptr<T>`, `std::shared_ptr<T>`, and generally pointer-like objects supporting unary `*`.
38+
- *Return type*: A lazy transformed view whose reference type is `decltype(*p)` of the underlying elements.
39+
- *Example*:
40+
```cpp
41+
std::vector<std::unique_ptr<int>> v; /* ... */
42+
for (int& x : v | gl::util::deref_view) {
43+
// use x as an int&
44+
}
45+
```
46+
47+
### Functions
48+
49+
- **`range_size(r)`**
50+
- *Template parameters*:
51+
- `R: std::ranges::range`
52+
- *Description*: Returns the size of a range. If `R` models `std::ranges::sized_range`, it forwards to `std::ranges::size(r)` in O(1). Otherwise, it computes `std::ranges::distance(std::begin(r), std::end(r))` in O(n).
53+
- *Parameters*:
54+
- `r: R&&` – the input range.
55+
- *Return type*: Same type as produced by `std::ranges::size(r)` for sized ranges or `std::ranges::distance(...)` otherwise.
56+
- *Complexity*: O(1) for sized ranges; O(n) otherwise.
57+
- *Exceptions*: No specific exceptions; propagates iterator operations if they throw.
58+
59+
> [!CAUTION]
60+
> For non-sized, single-pass/input ranges `range_size` will consume the range when computing distance.

docs/algorithms.md

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,6 @@ This section covers the specific types and type traits used for the algorithm im
6262
- `id: types::id_type` - the ID of the vertex.
6363
- `source_id: types::id_type` - the ID of the source vertex, typically used during algorithms.
6464

65-
- `edge_info`
66-
- *Description*: Holds information about an edge, including the edge itself and its source vertex's ID.
67-
- *Template parameters*:
68-
- `EdgeType: type_traits::c_instantiation_of<edge_descriptor>` - the type of the edge.
69-
- *Constructors*:
70-
- `vertex_info(types::id_type id)` - initializes the object with the same value for `id` and `source_id` representing a starting vertex
71-
- `vertex_info(types::id_type id, types::id_type source_id)`
72-
- *Member variables*:
73-
- `edge: types::const_ref_wrap<EdgeType>` - a constant reference wrapper for the edge.
74-
- `source_id: types::id_type` - the ID of the source vertex of the held edge.
75-
7665
- `predicate_result`
7766
- *Description*: Represents the result of a predicate evaluation.
7867
- *Type definitions*:
@@ -383,7 +372,7 @@ This section covers the specific types and type traits used for the algorithm im
383372
> - *Constructors*:
384373
> - `mst_descriptor(types::size_type n_vertices)` - Initializes an empty `edges` list with the capacity of $\text{n-vertices} - 1$ and the total weight is set to $0$.
385374
> - *Member variables*:
386-
> - `edges: std::vector<types::const_ref_wrap<edge_type>>` - A list of constant edge references representing the edges of the spanning tree.
375+
> - `edges: std::vector<edge_type>` - A list of edges of the spanning tree.
387376
> - `weight: weight_type` - The total weight of all edges of the spanning tree.
388377
389378
<br />

include/gl/algorithm/mst.hpp

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,18 @@ template <type_traits::c_undirected_graph GraphType>
3434

3535
using vertex_type = typename GraphType::vertex_type;
3636
using edge_type = typename GraphType::edge_type;
37-
using edge_info_type = algorithm::edge_info<edge_type>;
3837
using distance_type = types::vertex_distance_type<GraphType>;
3938

40-
struct edge_info_comparator {
39+
struct edge_comparator {
4140
[[nodiscard]] gl_attr_force_inline bool operator()(
42-
const edge_info_type& lhs, const edge_info_type& rhs
41+
const edge_type& lhs, const edge_type& rhs
4342
) const {
44-
return get_weight<GraphType>(lhs.edge) > get_weight<GraphType>(rhs.edge);
43+
return get_weight<GraphType>(lhs) > get_weight<GraphType>(rhs);
4544
}
4645
};
4746

4847
using queue_type =
49-
std::priority_queue<edge_info_type, std::vector<edge_info_type>, edge_info_comparator>;
48+
std::priority_queue<edge_type, std::vector<edge_type>, edge_comparator>;
5049

5150
// prepare the necessary utility
5251
const auto n_vertices = graph.n_vertices();
@@ -58,35 +57,31 @@ template <type_traits::c_undirected_graph GraphType>
5857
const types::id_type root_id = root_id_opt.value_or(constants::zero);
5958

6059
for (const auto& edge : graph.adjacent_edges(root_id))
61-
edge_queue.emplace(edge, root_id);
60+
edge_queue.emplace(edge);
6261

6362
// mark the root vertex as visited
6463
visited[root_id] = true;
6564
types::size_type n_vertices_in_mst = constants::one;
6665

6766
// find the mst
6867
while (n_vertices_in_mst < n_vertices) {
69-
const auto min_edge_info = edge_queue.top();
68+
const auto min_edge = edge_queue.top();
7069
edge_queue.pop();
7170

72-
const auto& min_edge = min_edge_info.edge;
73-
const auto min_weight = get_weight<GraphType>(min_edge);
74-
75-
const auto& target_id = min_edge.incident_vertex(min_edge_info.source_id);
76-
if (visited[target_id])
71+
if (visited[min_edge.target()])
7772
continue;
7873

7974
// add the minimum weight edge to the mst
8075
mst.edges.emplace_back(min_edge);
81-
mst.weight += min_weight;
76+
mst.weight += get_weight<GraphType>(min_edge);
8277

83-
visited[target_id] = true;
78+
visited[min_edge.target()] = true;
8479
++n_vertices_in_mst;
8580

8681
// enqueue all edges adjacent to the `target` vertex if they lead to unvisited verties
87-
for (const auto& edge : graph.adjacent_edges(target_id))
88-
if (not visited[edge.incident_vertex(target_id)])
89-
edge_queue.emplace(edge, target_id);
82+
for (const auto& edge : graph.adjacent_edges(min_edge.target()))
83+
if (not visited[edge.incident_vertex(min_edge.target())])
84+
edge_queue.emplace(edge);
9085
}
9186

9287
return mst;

include/gl/algorithm/types.hpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,6 @@ struct vertex_info {
2727
types::id_type pred_id;
2828
};
2929

30-
template <type_traits::c_instantiation_of<edge_descriptor> EdgeType>
31-
struct edge_info {
32-
using edge_type = EdgeType;
33-
34-
edge_type edge;
35-
types::id_type source_id;
36-
};
37-
3830
struct predicate_result {
3931
enum class eval : std::uint8_t { ok, not_ok, unknown };
4032
using enum eval;

0 commit comments

Comments
 (0)