Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
184 changes: 137 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,7 @@ 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::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 +41,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 +68,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 +93,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 +108,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 +118,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 +136,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 +148,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 +197,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 +222,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 +239,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 +249,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 +268,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 +280,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 +329,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 +414,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 +431,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
Loading