Skip to content

Commit 66d29db

Browse files
committed
hyperedge property accessors + generic hypergraph aliases
1 parent fcc6630 commit 66d29db

5 files changed

Lines changed: 118 additions & 22 deletions

File tree

include/gl/edge_descriptor.hpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@ class edge_descriptor final {
2626
using id_type = IdType;
2727
using directional_tag = DirectionalTag;
2828
using properties_type = Properties;
29-
using properties_ref_type = std::conditional_t<
30-
traits::c_empty_properties<properties_type>,
31-
empty_properties,
32-
properties_type&>;
3329

3430
friend directional_tag;
3531

@@ -156,7 +152,7 @@ class edge_descriptor final {
156152
return this->_vertices.first == this->_vertices.second;
157153
}
158154

159-
[[nodiscard]] gl_attr_force_inline properties_ref_type properties() const
155+
[[nodiscard]] gl_attr_force_inline properties_type& properties() const
160156
requires(traits::c_non_empty_properties<properties_type>)
161157
{
162158
this->_validate();

include/gl/vertex_descriptor.hpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ class vertex_descriptor final {
2525
using type = std::type_identity_t<vertex_descriptor<Properties, IdType>>;
2626
using id_type = IdType;
2727
using properties_type = Properties;
28-
using properties_ref_type = std::conditional_t<
29-
traits::c_empty_properties<properties_type>,
30-
empty_properties,
31-
properties_type&>;
3228

3329
vertex_descriptor() {
3430
*this = vertex_descriptor::invalid();
@@ -86,7 +82,7 @@ class vertex_descriptor final {
8682
return this->_id;
8783
}
8884

89-
[[nodiscard]] gl_attr_force_inline properties_ref_type properties() const
85+
[[nodiscard]] gl_attr_force_inline properties_type& properties() const
9086
requires(traits::c_non_empty_properties<properties_type>)
9187
{
9288
this->_validate();

include/hgl/hypergraph.hpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,64 @@ template <traits::c_hypergraph Hypergraph>
15671567
return Hypergraph(source);
15681568
}
15691569

1570+
template <
1571+
traits::c_properties VertexProperties = empty_properties,
1572+
traits::c_properties HyperedgeProperties = empty_properties,
1573+
traits::c_hypergraph_impl_tag ImplTag = impl::list_t<>>
1574+
using undirected_hypergraph =
1575+
hypergraph<undirected_hypergraph_traits<VertexProperties, HyperedgeProperties, ImplTag>>;
1576+
1577+
template <
1578+
traits::c_properties VertexProperties = empty_properties,
1579+
traits::c_properties HyperedgeProperties = empty_properties,
1580+
traits::c_hypergraph_impl_tag ImplTag = impl::list_t<>>
1581+
using bf_directed_hypergraph =
1582+
hypergraph<bf_directed_hypergraph_traits<VertexProperties, HyperedgeProperties, ImplTag>>;
1583+
1584+
template <
1585+
traits::c_hypergraph_layout_tag LayoutTag = impl::bidirectional_t,
1586+
traits::c_hypergraph_directional_tag DirectionalTag = undirected_t,
1587+
traits::c_properties VertexProperties = empty_properties,
1588+
traits::c_properties HyperedgeProperties = empty_properties,
1589+
traits::c_id_type IdType = default_id_type>
1590+
using list_hypergraph = hypergraph<
1591+
list_hypergraph_traits<LayoutTag, DirectionalTag, VertexProperties, HyperedgeProperties, IdType>>;
1592+
1593+
template <
1594+
traits::c_hypergraph_layout_tag LayoutTag = impl::bidirectional_t,
1595+
traits::c_hypergraph_directional_tag DirectionalTag = undirected_t,
1596+
traits::c_properties VertexProperties = empty_properties,
1597+
traits::c_properties HyperedgeProperties = empty_properties,
1598+
traits::c_id_type IdType = default_id_type>
1599+
using flat_list_hypergraph = hypergraph<flat_list_hypergraph_traits<
1600+
LayoutTag,
1601+
DirectionalTag,
1602+
VertexProperties,
1603+
HyperedgeProperties,
1604+
IdType>>;
1605+
1606+
template <
1607+
traits::c_hypergraph_layout_tag LayoutTag = impl::bidirectional_t,
1608+
traits::c_hypergraph_directional_tag DirectionalTag = undirected_t,
1609+
traits::c_properties VertexProperties = empty_properties,
1610+
traits::c_properties HyperedgeProperties = empty_properties,
1611+
traits::c_id_type IdType = default_id_type>
1612+
using matrix_hypergraph = hypergraph<
1613+
matrix_hypergraph_traits<LayoutTag, DirectionalTag, VertexProperties, HyperedgeProperties, IdType>>;
1614+
1615+
template <
1616+
traits::c_hypergraph_layout_tag LayoutTag = impl::bidirectional_t,
1617+
traits::c_hypergraph_directional_tag DirectionalTag = undirected_t,
1618+
traits::c_properties VertexProperties = empty_properties,
1619+
traits::c_properties HyperedgeProperties = empty_properties,
1620+
traits::c_id_type IdType = default_id_type>
1621+
using flat_matrix_hypergraph = hypergraph<flat_matrix_hypergraph_traits<
1622+
LayoutTag,
1623+
DirectionalTag,
1624+
VertexProperties,
1625+
HyperedgeProperties,
1626+
IdType>>;
1627+
15701628
// --- degree bounds ---
15711629

15721630
[[nodiscard]] size_type max_degree(const traits::c_hypergraph auto& hypergraph) noexcept {

include/hgl/hypergraph_elements.hpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ class hyperedge_descriptor final {
2727
using type = hyperedge_descriptor<Properties>;
2828
using id_type = IdType;
2929
using properties_type = Properties;
30-
using properties_ref_type = std::conditional_t<
31-
traits::c_empty_properties<properties_type>,
32-
empty_properties,
33-
properties_type&>;
3430

3531
hyperedge_descriptor() {
3632
*this = hyperedge_descriptor::invalid();
@@ -87,10 +83,24 @@ class hyperedge_descriptor final {
8783
return this->_id;
8884
}
8985

90-
[[nodiscard]] properties_ref_type properties() const {
91-
if (not this->is_valid())
92-
throw std::logic_error("Cannot access properties of an invalid hyperedge");
86+
[[nodiscard]] gl_attr_force_inline properties_type& properties() const
87+
requires(traits::c_non_empty_properties<properties_type>)
88+
{
89+
this->_validate();
90+
return this->_properties.get();
91+
}
92+
93+
[[nodiscard]] gl_attr_force_inline properties_type* operator->() const
94+
requires(traits::c_non_empty_properties<properties_type>)
95+
{
96+
this->_validate();
97+
return &this->_properties.get();
98+
}
9399

100+
[[nodiscard]] gl_attr_force_inline properties_type& operator*() const
101+
requires(traits::c_non_empty_properties<properties_type>)
102+
{
103+
this->_validate();
94104
return this->_properties.get();
95105
}
96106

@@ -104,6 +114,15 @@ class hyperedge_descriptor final {
104114
}
105115

106116
private:
117+
[[noreturn]] void _throw_invalid_access() const {
118+
throw std::logic_error("Cannot access properties of an invalid hyperedge");
119+
}
120+
121+
gl_attr_force_inline void _validate() const {
122+
if (not this->is_valid())
123+
this->_throw_invalid_access();
124+
}
125+
107126
std::ostream& _verbose_write(std::ostream& os) const {
108127
using enum io::detail::option_bit;
109128

tests/source/hgl/test_hypergraph_elements.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "doctest.h"
2+
#include "testing/common/functional.hpp"
23
#include "testing/hgl/constants.hpp"
34
#include "testing/hgl/types.hpp"
45

@@ -49,14 +50,40 @@ TEST_CASE_FIXTURE(test_hyperedge_descriptor, "properties should be properly init
4950
CHECK_EQ(&sut.properties(), &property);
5051
}
5152

52-
TEST_CASE("accessing properties should throw for an invalid hyperedge") {
53+
TEST_CASE_FIXTURE(
54+
test_hyperedge_descriptor, "operator* should return a reference to the properties"
55+
) {
56+
boolean_property property{constants::p_true};
57+
const hgl::hyperedge_descriptor<boolean_property> sut{id1, property};
58+
CHECK_EQ(&(*sut), &property);
59+
}
60+
61+
TEST_CASE_FIXTURE(
62+
test_hyperedge_descriptor, "operator-> should return a pointer to the properties"
63+
) {
64+
boolean_property property{constants::p_true};
65+
const hgl::hyperedge_descriptor<boolean_property> sut{id1, property};
66+
CHECK_EQ(sut.operator->(), &property);
67+
CHECK_EQ(sut->value, property.value);
68+
}
69+
70+
TEST_CASE_FIXTURE(
71+
test_hyperedge_descriptor, "accessing properties should throw for an invalid hyperedge"
72+
) {
5373
using sut_type = hgl::hyperedge_descriptor<boolean_property>;
5474
boolean_property property{constants::p_true};
5575

56-
CHECK_THROWS_AS(static_cast<void>(sut_type::invalid().properties()), std::logic_error);
57-
CHECK_THROWS_AS(
58-
static_cast<void>(sut_type{hgl::invalid_id, property}.properties()), std::logic_error
59-
);
76+
// .properties()
77+
CHECK_THROWS_AS(discard(sut_type::invalid().properties()), std::logic_error);
78+
CHECK_THROWS_AS(discard(sut_type{hgl::invalid_id, property}.properties()), std::logic_error);
79+
80+
// operator*
81+
CHECK_THROWS_AS(discard(*sut_type::invalid()), std::logic_error);
82+
CHECK_THROWS_AS(discard(*sut_type{hgl::invalid_id, property}), std::logic_error);
83+
84+
// operator->
85+
CHECK_THROWS_AS(discard(sut_type::invalid().operator->()), std::logic_error);
86+
CHECK_THROWS_AS(discard(sut_type{hgl::invalid_id, property}.operator->()), std::logic_error);
6087
}
6188

6289
TEST_SUITE_END(); // test_hypergraph_elements

0 commit comments

Comments
 (0)