Skip to content
Merged
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
2 changes: 1 addition & 1 deletion include/hgl/directional_tags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#pragma once

#include "types/type_traits.hpp"
#include "hgl/types/type_traits.hpp"

namespace hgl {

Expand Down
185 changes: 138 additions & 47 deletions include/hgl/hypergraph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

#pragma once

#include "constants.hpp"
#include "hypergraph_traits.hpp"
#include "util.hpp"
#include "hgl/constants.hpp"
#include "hgl/hypergraph_traits.hpp"
#include "hgl/util.hpp"

#include <memory>
#include <set>
Expand All @@ -21,6 +21,8 @@ class hypergraph final {
using traits_type = HypergraphTraits;
using directional_tag = typename traits_type::directional_tag;
using implementation_tag = typename traits_type::implementation_tag;
using implementation_type =
typename implementation_tag::template implementation_type<directional_tag>;

using vertex_type = typename traits_type::vertex_type;
using vertex_properties_type = typename traits_type::vertex_properties_type;
Expand All @@ -40,7 +42,7 @@ class hypergraph final {
hypergraph& operator=(const hypergraph&) = delete;

hypergraph(const types::size_type n_vertices = 0uz, const types::size_type n_hyperedges = 0uz)
: _n_vertices(n_vertices), _n_hyperedges(n_hyperedges) {
: _n_vertices(n_vertices), _n_hyperedges(n_hyperedges), _impl(n_vertices, n_hyperedges) {
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
this->_vertex_properties.reserve(n_vertices);
for (const auto _ : this->vertex_ids())
Expand All @@ -67,21 +69,8 @@ class hypergraph final {

// --- vertex methods ---

[[nodiscard]] gl_attr_force_inline auto vertices() const
requires(type_traits::c_empty_properties<vertex_properties_type>)
{
return this->vertex_ids()
| std::views::transform([](const types::id_type id) { return vertex_type{id}; });
}

[[nodiscard]] gl_attr_force_inline auto vertices() const
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
{
return this->_vertex_properties | std::views::enumerate
| std::views::transform([](const auto& property_item) {
const auto& [id, ptr] = property_item;
return vertex_type{static_cast<types::id_type>(id), *ptr};
});
[[nodiscard]] gl_attr_force_inline auto vertices() noexcept {
return this->vertex_ids() | std::views::transform(this->_create_vertex_descriptor());
}

[[nodiscard]] gl_attr_force_inline auto vertex_ids() const noexcept {
Expand All @@ -105,7 +94,7 @@ class hypergraph final {
}

vertex_type add_vertex() {
// this->_impl.add_vertex();
this->_impl.add_vertices(1uz);
const auto new_vertex_id = this->_n_vertices++;

if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
Expand All @@ -120,7 +109,7 @@ class hypergraph final {
vertex_type add_vertex_with(vertex_properties_type properties)
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
{
// this->_impl.add_vertex();
this->_impl.add_vertices(1uz);
return vertex_type{
this->_n_vertices++,
*this->_vertex_properties.emplace_back(
Expand All @@ -130,7 +119,7 @@ class hypergraph final {
}

void add_vertices(const types::size_type n) {
// this->_impl.add_vertices(n);
this->_impl.add_vertices(n);
this->_n_vertices += n;

if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
Expand All @@ -148,7 +137,7 @@ class hypergraph final {
{
const auto n = std::ranges::size(properties_range);

// this->_impl.add_vertices(n);
this->_impl.add_vertices(n);
this->_n_vertices += n;

if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>) {
Expand All @@ -160,8 +149,7 @@ class hypergraph final {
}
}

void remove_vertex(const types::id_type vertex_id) {
this->_verify_vertex_id(vertex_id);
gl_attr_force_inline void remove_vertex(const types::id_type vertex_id) {
this->_remove_vertex_impl(vertex_id);
}

Expand Down Expand Up @@ -210,21 +198,8 @@ class hypergraph final {

// --- hyperedge methods ---

[[nodiscard]] gl_attr_force_inline auto hyperedges() const
requires(type_traits::c_empty_properties<hyperedge_properties_type>)
{
return this->hyperedge_ids()
| std::views::transform([](const types::id_type id) { return hyperedge_type{id}; });
}

[[nodiscard]] gl_attr_force_inline auto hyperedges() const
requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
{
return this->_hyperedge_properties | std::views::enumerate
| std::views::transform([](const auto& property_item) {
const auto& [id, ptr] = property_item;
return hyperedge_type{static_cast<types::id_type>(id), *ptr};
});
[[nodiscard]] gl_attr_force_inline auto hyperedges() noexcept {
return this->hyperedge_ids() | std::views::transform(this->_create_hyperedge_descriptor());
}

[[nodiscard]] gl_attr_force_inline auto hyperedge_ids() const noexcept {
Expand All @@ -248,7 +223,7 @@ class hypergraph final {
}

hyperedge_type add_hyperedge() {
// this->_impl.add_hyperedge();
this->_impl.add_hyperedges(1uz);
const auto new_hyperedge_id = this->_n_hyperedges++;

if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>)
Expand All @@ -265,7 +240,7 @@ class hypergraph final {
hyperedge_type add_hyperedge_with(hyperedge_properties_type properties)
requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
{
// this->_impl.add_hyperedge();
this->_impl.add_hyperedges(1uz);
return hyperedge_type{
this->_n_hyperedges++,
*this->_hyperedge_properties.emplace_back(
Expand All @@ -275,7 +250,7 @@ class hypergraph final {
}

void add_hyperedges(const types::size_type n) {
// this->_impl.add_hyperedges(n);
this->_impl.add_hyperedges(n);
this->_n_hyperedges += n;

if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>) {
Expand All @@ -294,7 +269,7 @@ class hypergraph final {
{
const auto n = std::ranges::size(properties_range);

// this->_impl.add_hyperedges(n);
this->_impl.add_hyperedges(n);
this->_n_hyperedges += n;

if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>) {
Expand All @@ -306,8 +281,7 @@ class hypergraph final {
}
}

void remove_hyperedge(const types::id_type hyperedge_id) {
this->_verify_hyperedge_id(hyperedge_id);
gl_attr_force_inline void remove_hyperedge(const types::id_type hyperedge_id) {
this->_remove_hyperedge_impl(hyperedge_id);
}

Expand Down Expand Up @@ -356,6 +330,82 @@ class hypergraph final {
return *this->_hyperedge_properties[id];
}

// --- incidence methods ---

void bind(const types::id_type vertex_id, const types::id_type hyperedge_id) {
this->_verify_vertex_id(vertex_id);
this->_verify_hyperedge_id(hyperedge_id);
this->_impl.bind(vertex_id, hyperedge_id);
}

gl_attr_force_inline void bind(const vertex_type& vertex, const hyperedge_type& hyperedge) {
this->bind(vertex.id(), hyperedge.id());
}

void unbind(const types::id_type vertex_id, const types::id_type hyperedge_id) {
this->_verify_vertex_id(vertex_id);
this->_verify_hyperedge_id(hyperedge_id);
this->_impl.unbind(vertex_id, hyperedge_id);
}

gl_attr_force_inline void unbind(const vertex_type& vertex, const hyperedge_type& hyperedge) {
this->unbind(vertex.id(), hyperedge.id());
}

[[nodiscard]] bool are_incident(
const types::id_type vertex_id, const types::id_type hyperedge_id
) const {
this->_verify_vertex_id(vertex_id);
this->_verify_hyperedge_id(hyperedge_id);
return this->_impl.are_bound(vertex_id, hyperedge_id);
}

[[nodiscard]] gl_attr_force_inline bool are_incident(
const vertex_type& vertex, const hyperedge_type& hyperedge
) const {
return this->are_incident(vertex.id(), hyperedge.id());
}

[[nodiscard]] auto incident_hyperedges(const types::id_type vertex_id) {
this->_verify_vertex_id(vertex_id);
return this->_impl.incident_hyperedges(vertex_id)
| std::views::transform(this->_create_hyperedge_descriptor());
}

[[nodiscard]] gl_attr_force_inline auto incident_hyperedges(const vertex_type& vertex) {
return this->incident_hyperedges(vertex.id());
}

[[nodiscard]] types::size_type degree(const types::id_type vertex_id) const {
this->_verify_vertex_id(vertex_id);
return this->_impl.degree(vertex_id);
}

[[nodiscard]] gl_attr_force_inline types::size_type degree(const vertex_type& vertex) const {
return this->degree(vertex.id());
}

[[nodiscard]] auto incident_vertices(const types::id_type hyperedge_id) {
this->_verify_hyperedge_id(hyperedge_id);
return this->_impl.incident_vertices(hyperedge_id)
| std::views::transform(this->_create_vertex_descriptor());
}

[[nodiscard]] gl_attr_force_inline auto incident_vertices(const hyperedge_type& hyperedge) {
return this->incident_vertices(hyperedge.id());
}

[[nodiscard]] types::size_type hyperedge_size(const types::id_type hyperedge_id) const {
this->_verify_hyperedge_id(hyperedge_id);
return this->_impl.hyperedge_size(hyperedge_id);
}

[[nodiscard]] gl_attr_force_inline types::size_type hyperedge_size(
const hyperedge_type& hyperedge
) const {
return this->hyperedge_size(hyperedge.id());
}

private:
// --- vertex methods ---

Expand All @@ -365,10 +415,13 @@ class hypergraph final {
}

void _remove_vertex_impl(const types::id_type vertex_id) {
if (not this->has_vertex(vertex_id))
return;

this->_impl.remove_vertex(vertex_id);
this->_n_vertices--;
if constexpr (type_traits::c_non_empty_properties<vertex_properties_type>)
this->_vertex_properties.erase(this->_vertex_properties.begin() + vertex_id);
// TODO: impl::remove_vertex(vertex_id)
}

// --- hyperedge methods ---
Expand All @@ -379,14 +432,52 @@ class hypergraph final {
}

void _remove_hyperedge_impl(const types::id_type hyperedge_id) {
if (not this->has_hyperedge(hyperedge_id))
return;

this->_impl.remove_hyperedge(hyperedge_id);
this->_n_hyperedges--;
if constexpr (type_traits::c_non_empty_properties<hyperedge_properties_type>)
this->_hyperedge_properties.erase(this->_hyperedge_properties.begin() + hyperedge_id);
}

// --- transformations ---

gl_attr_force_inline auto _create_vertex_descriptor() noexcept
requires(type_traits::c_empty_properties<vertex_properties_type>)
{
return [](const types::id_type id) { return vertex_type{id}; };
}

gl_attr_force_inline auto _create_vertex_descriptor() noexcept
requires(type_traits::c_non_empty_properties<vertex_properties_type>)
{
return [&pmap = this->_vertex_properties](const types::id_type id) {
return vertex_type{id, *pmap[id]};
};
}

gl_attr_force_inline auto _create_hyperedge_descriptor() noexcept
requires(type_traits::c_empty_properties<hyperedge_properties_type>)
{
return [](const types::id_type id) { return hyperedge_type{id}; };
}

gl_attr_force_inline auto _create_hyperedge_descriptor() noexcept
requires(type_traits::c_non_empty_properties<hyperedge_properties_type>)
{
return [&pmap = this->_hyperedge_properties](const types::id_type id) {
return hyperedge_type{id, *pmap[id]};
};
}

// --- data members ---

types::size_type _n_vertices = 0uz;
types::size_type _n_hyperedges = 0uz;

implementation_type _impl{};

[[no_unique_address]] vertex_properties_map_type _vertex_properties{};
[[no_unique_address]] hyperedge_properties_map_type _hyperedge_properties{};
};
Expand Down
6 changes: 3 additions & 3 deletions include/hgl/hypergraph_elements.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

#pragma once

#include "constants.hpp"
#include "gl/vertex_descriptor.hpp"
#include "types/type_traits.hpp"
#include "types/types.hpp"
#include "hgl/constants.hpp"
#include "hgl/types/type_traits.hpp"
#include "hgl/types/types.hpp"

namespace hgl {

Expand Down
8 changes: 4 additions & 4 deletions include/hgl/hypergraph_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

#pragma once

#include "directional_tags.hpp"
#include "hypergraph_elements.hpp"
#include "impl/impl_tags.hpp"
#include "impl/layout_tags.hpp"
#include "hgl/directional_tags.hpp"
#include "hgl/hypergraph_elements.hpp"
#include "hgl/impl/impl_tags.hpp"
#include "hgl/impl/layout_tags.hpp"

namespace hgl {

Expand Down
11 changes: 10 additions & 1 deletion include/hgl/impl/impl_tags.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

#pragma once

#include "hgl/directional_tags.hpp"
#include "hgl/impl/incidence_list.hpp"
#include "hgl/impl/incidence_matrix.hpp"
#include "hgl/impl/layout_tags.hpp"
#include "hgl/types/type_traits.hpp"
#include "hgl/types/types.hpp"
#include "layout_tags.hpp"

namespace hgl {

Expand All @@ -15,11 +18,17 @@ namespace impl {
template <type_traits::c_hypergraph_layout_tag LayoutTag>
struct list_t {
using layout_tag = LayoutTag;

template <type_traits::c_hypergraph_directional_tag DirectionalTag>
using implementation_type = incidence_list<DirectionalTag, LayoutTag>;
};

template <type_traits::c_hypergraph_layout_tag LayoutTag>
struct matrix_t {
using layout_tag = LayoutTag;

template <type_traits::c_hypergraph_directional_tag DirectionalTag>
using implementation_type = incidence_matrix<DirectionalTag, LayoutTag>;
};

} // namespace impl
Expand Down
Loading