Created
January 26, 2022 18:13
-
-
Save hexorer/bef4a5f5d15d02a8f4c56f48edc18c0a to your computer and use it in GitHub Desktop.
A Draft showing how libgvizard's graph class' public is gonna be...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GVIZARD_GRAPH_GRAPH_HPP_ | |
#define GVIZARD_GRAPH_GRAPH_HPP_ | |
#include <cstddef> | |
#include <optional> | |
#include <type_traits> | |
#include <variant> | |
#include "gvizard/registry/attrset.hpp" | |
#include "gvizard/registry/attrset_registry.hpp" | |
#include "gvizard/views.hpp" | |
#include "gvizard/utils.hpp" | |
#include "gvizard/graph/dynamic_square_matrix.hpp" | |
#include "gvizard/graph/dynamic_half_square_matrix.hpp" | |
/** an adjancency-matrix implementation of graph with internal registry. | |
*/ | |
namespace gvizard::graph { | |
struct no_view_t {}; | |
enum class GraphDir { directed, undirected }; | |
enum class EdgeDir { in = 1, out = 2, inout = 3 }; | |
template <GraphDir DirV = GraphDir::undirected, | |
typename NodeT = std::monostate, | |
typename EdgeT = std::monostate, | |
typename ClusterT = std::monostate> | |
class Graph { | |
public: | |
using NodeId = std::size_t; | |
using EdgeId = std::size_t; | |
using ClusterId = std::size_t; | |
private: | |
constexpr static bool is_undirected = DirV == GraphDir::undirected; | |
enum class EntityTypeEnum { node, edge, cluster }; | |
struct NodeItem { | |
NodeT value; | |
std::optional<ClusterId> cluster_id = std::nullopt; | |
}; | |
// TODO how to store clusters and nodes' relation to cluster? | |
// | |
using value_variant_type = std::variant<NodeT, EdgeT, ClusterT>; | |
using id_variant_type = std::variant<NodeId, ...>; | |
using attrset_type = registry::AttrSet<value_variant_type, ClusterId>; | |
using registry_type = registry::AttrSetRegistry<attrset_type>; | |
using optional_entity_type = | |
std::optional<typename registry_type::entity_type>; | |
using matrix_type = | |
std::conditional_t< | |
is_undirected, | |
detail::DynamicSquareMatrix<optional_entity_type>, | |
detail::DynamicHalfSquareMatrix<optional_entity_type> | |
>; | |
matrix_type matrix_{}; | |
registry_type registry_{}; | |
public: | |
auto create_cluster(ClusterT cluster) -> std::optional<ClusterId> { | |
auto cluster_id = registry_.create(); | |
if (!registry_.template set<attr_type>(cluster_id, std::move(cluster))) | |
return std::nullopt; | |
return cluster_id; | |
} | |
auto add_to_cluster(ClusterId cluster_id, NodeId node_id) -> bool | |
{ | |
// | |
} | |
auto create_node(NodeT node) -> NodeId; | |
auto create_node(NodeT node, ClusterId cluster_id) -> NodeId; | |
auto create_edge(NodeId node_a_id, NodeId node_b_id, EdgeT edge) -> EdgeId; | |
auto get_cluster(ClusterId cluster_id) -> utils::OptionalRef<ClusterT>; | |
auto get_cluster(ClusterId cluster_id) const | |
-> utils::OptionalRef<const ClusterT>; | |
auto get_cluster_nodes(ClusterId cluster_id) const | |
-> IteratorView<NodeId>; | |
auto get_node(NodeId node_id) -> utils::OptionalRef<NodeT>; | |
auto get_node(NodeId node_id) const -> utils::OptionalRef<const NodeT>; | |
auto has_edge(NodeId node_a_id, NodeId node_b_id) const -> bool; | |
auto get_edge(NodeId node_a_id, NodeId node_b_id) | |
-> utils::OptionalRef<EdgeT>; | |
auto get_edge(NodeId node_a_id, NodeId node_b_id) const | |
-> utils::OptionalRef<const EdgeT>; | |
auto get_edge(EdgeId edge_id) -> utils::OptionalRef<EdgeT>; | |
auto get_edge(EdgeId edge_id) const -> utils::OptionalRef<const EdgeT>; | |
auto get_edge_nodes(EdgeId edge_id) | |
-> std::optional<std::pair<NodeId, NodeId>>; | |
auto remove_cluster(ClusterId cluster_id) -> bool; | |
auto remove_node(NodeId node_id) -> bool; | |
auto remove_edge(NodeId node_a_id, NodeId node_b_id) -> bool; | |
auto remove_edge(EdgeId edge_id) -> bool; | |
auto get_degree(NodeId node_id, EdgeDir dir = EdgeDir::inout) | |
-> std::size_t; | |
auto get_edges(NodeId node_id) | |
-> IteratorView<std::tuple<NodeId, NodeId, EdgeT&>>; | |
auto get_edges(NodeId node_id) const | |
-> IteratorView<std::tuple<NodeId, NodeId, const EdgeT&>>; | |
auto get_neighbors(NodeId node_id, EdgeDir dir = EdgeDir::inout) const | |
-> IteratorView<NodeId>; | |
template <typename ...IdTs> | |
auto subgraph(IdTs... ids) -> Graph; | |
template <typename Iter, typename Sentinel> | |
auto subgraph(Iter begin, Sentinel end) -> Graph; | |
auto nodes_view() const -> IteratorView<NodeId>; | |
auto edges_view() const -> IteratorView<EdgeId>; | |
auto clusters_view() const -> IteratorView<ClusterId>; | |
auto node_count() const -> std::size_t; | |
auto edge_count() const -> std::size_t; | |
auto cluster_count() const -> std::size_t; | |
template <typename Callable> | |
auto traversal(Callable&& func, NodeId node_id) | |
-> CallbackView<NodeId, Callable>; | |
template <typename Callable> | |
void traversal(no_view_t, Callable&& func, NodeId node_id); | |
}; | |
} // namespace gvizard::graph | |
#endif // GVIZARD_GRAPH_GRAPH_HPP_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment