Skip to content

Commit 64b4aa1

Browse files
committed
aligned edge_descriptor
1 parent b016c24 commit 64b4aa1

4 files changed

Lines changed: 124 additions & 150 deletions

File tree

include/gl/edge_descriptor.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class edge_descriptor final {
4141
const vertex_type first, const vertex_type second, properties_type properties
4242
)
4343
requires(not type_traits::is_default_properties_type_v<properties_type>)
44-
: _vertices(std::move(first), std::move(second)), _properties(std::move(properties)) {}
44+
: _vertices(std::move(first), std::move(second)), _properties(properties) {}
4545

4646
edge_descriptor(edge_descriptor&&) = default;
4747
edge_descriptor& operator=(edge_descriptor&&) = default;
@@ -80,7 +80,7 @@ class edge_descriptor final {
8080
return this->_vertices.second;
8181

8282
if (vertex_id == this->_vertices.second.id())
83-
return this->_vertice.first;
83+
return this->_vertices.first;
8484

8585
throw std::invalid_argument(std::format("Got invalid vertex id: {}", vertex_id));
8686
}
@@ -107,7 +107,7 @@ class edge_descriptor final {
107107
return this->_vertices.first == this->_vertices.second;
108108
}
109109

110-
[[nodiscard]] gl_attr_force_inline properties_ref_type properties() const {
110+
[[nodiscard]] gl_attr_force_inline properties_type& properties() const {
111111
return this->_properties;
112112
}
113113

@@ -169,7 +169,7 @@ class edge_descriptor final {
169169
}
170170

171171
types::homogeneous_pair<const vertex_type> _vertices;
172-
[[no_unique_address]] properties_ref_type _properties;
172+
[[no_unique_address]] mutable properties_type _properties{};
173173
};
174174

175175
template <

include/gl/vertex_descriptor.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ class vertex_descriptor final {
2929
friend class graph;
3030

3131
vertex_descriptor() = delete;
32-
vertex_descriptor(const vertex_descriptor&) = delete;
33-
vertex_descriptor& operator=(const vertex_descriptor&) = delete;
3432

3533
// TODO: private
3634
explicit vertex_descriptor(const types::id_type id)
@@ -42,6 +40,9 @@ class vertex_descriptor final {
4240
requires(not type_traits::is_default_properties_type_v<properties_type>)
4341
: _id(id), _properties(properties) {}
4442

43+
vertex_descriptor(const vertex_descriptor&) = default;
44+
vertex_descriptor& operator=(const vertex_descriptor&) = default;
45+
4546
vertex_descriptor(vertex_descriptor&&) = default;
4647
vertex_descriptor& operator=(vertex_descriptor&&) = default;
4748

tests/include/testing/gl/constants.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <gl/types/types.hpp>
66

7+
#include <limits>
78
#include <ranges>
89

910
#define IC inline constexpr
@@ -33,6 +34,7 @@ IC gl::types::size_type out_of_range_elemenet_idx = n_elements;
3334
IC gl::types::id_type vertex_id_1 = first_element_idx;
3435
IC gl::types::id_type vertex_id_2 = vertex_id_1 + one_element;
3536
IC gl::types::id_type vertex_id_3 = vertex_id_2 + one_element;
37+
IC gl::types::id_type invalid_id = std::numeric_limits<gl::types::id_type>::max();
3638

3739
IC auto vertex_id_view = std::views::iota(first_element_idx, n_elements);
3840

Lines changed: 115 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,116 @@
1-
// #include "testing/gl/constants.hpp"
2-
// #include "testing/gl/functional.hpp"
3-
// #include "testing/gl/types.hpp"
4-
5-
// #include <gl/edge_descriptor.hpp>
1+
#include "testing/gl/constants.hpp"
2+
#include "testing/gl/functional.hpp"
3+
#include "testing/gl/types.hpp"
64

7-
// #include <doctest.h>
8-
9-
// namespace gl_testing {
10-
11-
// TEST_SUITE_BEGIN("test_edge_descriptor");
12-
13-
// struct test_edge_descriptor {
14-
// using vertex_type = gl::vertex_descriptor<>;
15-
16-
// vertex_type vd_1{constants::vertex_id_1};
17-
// vertex_type vd_2{constants::vertex_id_2};
18-
// vertex_type vd_3{constants::vertex_id_3};
19-
20-
// vertex_type invalid_vd{constants::vertex_id_1};
21-
// };
22-
23-
// TEST_CASE_FIXTURE(
24-
// test_edge_descriptor, "is_directed() should return true only for edges with directed edge tag"
25-
// ) {
26-
// gl::directed_edge<gl::vertex<>> directed_edge{vd_1, vd_2};
27-
// CHECK(directed_edge.is_directed());
28-
29-
// gl::undirected_edge<gl::vertex<>> undirected_edge{vd_1, vd_2};
30-
// CHECK_FALSE(undirected_edge.is_directed());
31-
// }
32-
33-
// TEST_CASE_FIXTURE(
34-
// test_edge_descriptor,
35-
// "is_undirected() should return true only for edges with bidirectional edge tag"
36-
// ) {
37-
// gl::undirected_edge<gl::vertex<>> undirected_edge{vd_1, vd_2};
38-
// CHECK(undirected_edge.is_undirected());
39-
40-
// gl::directed_edge<gl::vertex<>> directed_edge{vd_1, vd_2};
41-
// CHECK_FALSE(directed_edge.is_undirected());
42-
// }
43-
44-
// TEST_CASE_TEMPLATE_DEFINE(
45-
// "properties should be properly initialized", EdgeType, properties_edge_directional_tag_template
46-
// ) {
47-
// test_edge_descriptor fixture;
48-
49-
// const types::used_property used{true};
50-
// const EdgeType sut{fixture.vd_1, fixture.vd_2, used};
51-
52-
// CHECK_EQ(sut.properties, used);
53-
// }
54-
55-
// // TODO: fix .clang-format to split such lines
56-
// TEST_CASE_TEMPLATE_INSTANTIATE(properties_edge_directional_tag_template, gl::directed_edge<gl::vertex<>, types::used_property>, gl::undirected_edge<gl::vertex<>, types::used_property>);
57-
58-
// TEST_CASE_TEMPLATE_DEFINE(
59-
// "directional_tag-independent tests", EdgeType, edge_directional_tag_template
60-
// ) {
61-
// test_edge_descriptor fixture{};
62-
63-
// EdgeType sut{fixture.vd_1, fixture.vd_2};
64-
65-
// SUBCASE("incident_vertices should return the pair of vertices the edge was initialized with") {
66-
// const auto& vertices = sut.incident_vertices();
67-
// CHECK_EQ(vertices.first, fixture.vd_1);
68-
// CHECK_EQ(vertices.second, fixture.vd_2);
69-
// }
70-
71-
// SUBCASE("first should return the first vertex descriptor the edge was initialized with") {
72-
// CHECK_EQ(sut.first(), fixture.vd_1);
73-
// }
74-
75-
// SUBCASE("second should return the second vertex descriptor the edge was initialized with") {
76-
// CHECK_EQ(sut.second(), fixture.vd_2);
77-
// }
78-
79-
// SUBCASE("incident_vertex_ids should return the pair of ids of the vertices the edge was "
80-
// "initialized with") {
81-
// const auto& vertex_ids = sut.incident_vertex_ids();
82-
// CHECK_EQ(vertex_ids.first, fixture.vd_1.id());
83-
// CHECK_EQ(vertex_ids.second, fixture.vd_2.id());
84-
// }
85-
86-
// SUBCASE("first_id should return the id of the first vertex descriptor the edge was initialized "
87-
// "with") {
88-
// CHECK_EQ(sut.first_id(), fixture.vd_1.id());
89-
// }
90-
91-
// SUBCASE("second should return the id of the second vertex descriptor the edge was initialized "
92-
// "with") {
93-
// CHECK_EQ(sut.second_id(), fixture.vd_2.id());
94-
// }
95-
96-
// SUBCASE("incident_vertex should throw if input vertex is not incident with the edge") {
97-
// CHECK_THROWS_AS(
98-
// func::discard_result(sut.incident_vertex(fixture.vd_3)), std::invalid_argument
99-
// );
100-
// }
101-
102-
// SUBCASE("incident_vertex should return the vertex incident with the input vertex") {
103-
// CHECK_EQ(sut.incident_vertex(fixture.vd_1), fixture.vd_2);
104-
// CHECK_EQ(sut.incident_vertex(fixture.vd_2), fixture.vd_1);
105-
// }
106-
107-
// SUBCASE("incident_vertex_id should throw if input vertex id is not valid") {
108-
// CHECK_THROWS_AS(
109-
// func::discard_result(sut.incident_vertex_id(fixture.vd_3.id())), std::invalid_argument
110-
// );
111-
// }
112-
113-
// SUBCASE("incident_vertex_id should return the id of the vertex incident with the input vertex"
114-
// ) {
115-
// CHECK_EQ(sut.incident_vertex_id(fixture.vd_1.id()), fixture.vd_2.id());
116-
// CHECK_EQ(sut.incident_vertex_id(fixture.vd_2.id()), fixture.vd_1.id());
117-
// }
118-
119-
// SUBCASE("is_incident_with should return true when the given vertex is one of the connected "
120-
// "vertices") {
121-
// CHECK(sut.is_incident_with(fixture.vd_1));
122-
// CHECK(sut.is_incident_with(fixture.vd_2));
123-
124-
// CHECK_FALSE(sut.is_incident_with(fixture.invalid_vd));
125-
// CHECK_FALSE(sut.is_incident_with(fixture.invalid_vd));
126-
// }
127-
128-
// SUBCASE("is_loop should return true onlyu for edges where both vertices are the same") {
129-
// CHECK_FALSE(sut.is_loop());
130-
131-
// const EdgeType loop{fixture.vd_1, fixture.vd_1};
132-
// CHECK(loop.is_loop());
133-
// }
134-
// }
135-
136-
// // TODO: fix .clang-format to split such lines
137-
// TEST_CASE_TEMPLATE_INSTANTIATE(
138-
// edge_directional_tag_template,
139-
// gl::directed_edge<gl::vertex<>>, // default directed edge
140-
// gl::undirected_edge<gl::vertex<>> // default undirected edge
141-
// );
142-
143-
// TEST_SUITE_END(); // test_edge_descriptor
144-
145-
// } // namespace gl_testing
5+
#include <gl/edge_descriptor.hpp>
6+
7+
#include <doctest.h>
8+
9+
namespace gl_testing {
10+
11+
TEST_SUITE_BEGIN("test_edge_descriptor");
12+
13+
struct test_edge_descriptor {
14+
using vertex_type = gl::vertex_descriptor<>;
15+
16+
vertex_type vd_1{constants::vertex_id_1};
17+
vertex_type vd_2{constants::vertex_id_2};
18+
vertex_type vd_3{constants::vertex_id_3};
19+
20+
vertex_type invalid_vd{constants::invalid_id};
21+
};
22+
23+
TEST_CASE_FIXTURE(
24+
test_edge_descriptor, "is_directed() should return true only for edges with directed edge tag"
25+
) {
26+
gl::directed_edge<gl::vertex<>> directed_edge{vd_1, vd_2};
27+
CHECK(directed_edge.is_directed());
28+
29+
gl::undirected_edge<gl::vertex<>> undirected_edge{vd_1, vd_2};
30+
CHECK_FALSE(undirected_edge.is_directed());
31+
}
32+
33+
TEST_CASE_FIXTURE(
34+
test_edge_descriptor,
35+
"is_undirected() should return true only for edges with bidirectional edge tag"
36+
) {
37+
gl::undirected_edge<gl::vertex<>> undirected_edge{vd_1, vd_2};
38+
CHECK(undirected_edge.is_undirected());
39+
40+
gl::directed_edge<gl::vertex<>> directed_edge{vd_1, vd_2};
41+
CHECK_FALSE(directed_edge.is_undirected());
42+
}
43+
44+
TEST_CASE_TEMPLATE_DEFINE(
45+
"properties should be properly initialized", EdgeType, properties_edge_directional_tag_template
46+
) {
47+
test_edge_descriptor fixture;
48+
49+
const types::used_property used{true};
50+
const EdgeType sut{fixture.vd_1, fixture.vd_2, used};
51+
52+
CHECK_EQ(sut.properties(), used);
53+
}
54+
55+
// TODO: fix .clang-format to split such lines
56+
TEST_CASE_TEMPLATE_INSTANTIATE(properties_edge_directional_tag_template, gl::directed_edge<gl::vertex<>, types::used_property>, gl::undirected_edge<gl::vertex<>, types::used_property>);
57+
58+
TEST_CASE_TEMPLATE_DEFINE(
59+
"directional_tag-independent tests", EdgeType, edge_directional_tag_template
60+
) {
61+
test_edge_descriptor fixture{};
62+
63+
EdgeType sut{fixture.vd_1, fixture.vd_2};
64+
65+
SUBCASE("incident_vertices should return the pair of vertices the edge was initialized with") {
66+
const auto& vertices = sut.incident_vertices();
67+
CHECK_EQ(vertices.first, fixture.vd_1);
68+
CHECK_EQ(vertices.second, fixture.vd_2);
69+
}
70+
71+
SUBCASE("first should return the first vertex descriptor the edge was initialized with") {
72+
CHECK_EQ(sut.first(), fixture.vd_1);
73+
}
74+
75+
SUBCASE("second should return the second vertex descriptor the edge was initialized with") {
76+
CHECK_EQ(sut.second(), fixture.vd_2);
77+
}
78+
79+
SUBCASE("incident_vertex should throw if input vertex is not incident with the edge") {
80+
CHECK_THROWS_AS(
81+
func::discard_result(sut.incident_vertex(fixture.vd_3)), std::invalid_argument
82+
);
83+
}
84+
85+
SUBCASE("incident_vertex should return the vertex incident with the input vertex") {
86+
CHECK_EQ(sut.incident_vertex(fixture.vd_1), fixture.vd_2);
87+
CHECK_EQ(sut.incident_vertex(fixture.vd_2), fixture.vd_1);
88+
}
89+
90+
SUBCASE("is_incident_with should return true when the given vertex is one of the connected "
91+
"vertices") {
92+
CHECK(sut.is_incident_with(fixture.vd_1));
93+
CHECK(sut.is_incident_with(fixture.vd_2));
94+
95+
CHECK_FALSE(sut.is_incident_with(fixture.invalid_vd));
96+
CHECK_FALSE(sut.is_incident_with(fixture.invalid_vd));
97+
}
98+
99+
SUBCASE("is_loop should return true onlyu for edges where both vertices are the same") {
100+
CHECK_FALSE(sut.is_loop());
101+
102+
const EdgeType loop{fixture.vd_1, fixture.vd_1};
103+
CHECK(loop.is_loop());
104+
}
105+
}
106+
107+
// TODO: fix .clang-format to split such lines
108+
TEST_CASE_TEMPLATE_INSTANTIATE(
109+
edge_directional_tag_template,
110+
gl::directed_edge<gl::vertex<>>, // default directed edge
111+
gl::undirected_edge<gl::vertex<>> // default undirected edge
112+
);
113+
114+
TEST_SUITE_END(); // test_edge_descriptor
115+
116+
} // namespace gl_testing

0 commit comments

Comments
 (0)