1#ifndef GRAPHLIB_INTERNAL_ADJACENCY_LIST_H
2#define GRAPHLIB_INTERNAL_ADJACENCY_LIST_H
9#include <unordered_map>
10#include <unordered_set>
23namespace GraphLib::Internal {
25template <val
id_
id_type I, val
id_edge_type<I> E>
28template <
typename I,
typename E>
38template <val
id_
id_type I, val
id_edge_type<I> E>
62 auto keys = std::unordered_set<id_type> {};
63 std::transform(
adj_map_.begin(),
adj_map_.end(), std::inserter(keys, keys.end()),
64 [](
const auto& pair) { return pair.first; });
80 auto neighbor_ids = std::set<id_type> {};
81 std::transform(edges.begin(), edges.end(), std::inserter(neighbor_ids, neighbor_ids.end()),
82 [](
const edge_type edge) { return edge.node_id; });
97 adj_map_.insert({node_id, std::set<edge_type> {}});
111 for (
auto& [_, edge_set] :
adj_map_) {
112 for (
auto it = edge_set.begin(); it != edge_set.end();) {
113 if (it->node_id == node_id)
114 it = edge_set.erase(it);
134 auto it = std::find_if(
adj_map_.at(from_id).begin(),
adj_map_.at(from_id).end(),
135 [to_id](
const edge_type& edge) { return edge.node_id == to_id; });
136 return it !=
adj_map_.at(from_id).end();
151 auto it = std::find_if(
adj_map_.at(from_id).begin(),
adj_map_.at(from_id).end(),
152 [to_id](
const edge_type& edge) { return edge.node_id == to_id; });
215 std::size_t count {0};
216 for (
const auto& [_, edge_set] :
adj_map_)
217 count += edge_set.size();
248 template <
typename D>
252 for (
const auto& [node, edges] :
adj_map_) {
253 D node_value = data_map.at(node);
254 os << node_value <<
": [";
256 for (
const auto& edge : edges) {
259 edge.print_with_data(os, data_map.at(edge.node_id));
267 std::unordered_map<id_type, std::set<edge_type>>
adj_map_ {};
289template <
typename I,
typename E>
292 for (
const auto& [node, edges] : adj_list.
adj_map_) {
295 for (
const auto& edge : edges) {
std::ostream & operator<<(std::ostream &os, const Graph< D, I, E > &graph)
Stream insertion operator for any valid graph type.
Represents a directed (by nature) Adjacency List Graph Structure.
void print_with_data_map(std::ostream &os, const std::unordered_map< I, D > data_map) const
Outputs the adjacency map to the given output stream, but with data instead of IDs.
std::unordered_set< id_type > get_node_ids() const
Retrieves all node IDs present in the graph.
I id_type
Alias for the node ID type.
void add_node_id(const id_type node_id)
Adds a node with the specified ID to the graph.
bool has_node_id(const id_type node_id) const
Checks if a node with given ID exists in the graph.
std::set< edge_type > get_edges(const id_type from_id) const
Retrieves all edges outgoing from the specified node.
constexpr bool operator==(const AdjacencyList &other) const
Equality comparison operator.
edge_type get_edge(const id_type from_id, const id_type to_id) const
Retrieves the edge from from_id to to_id.
bool has_edge(const id_type from_id, const id_type to_id) const
Checks if an edge from from_id to to_id exists.
void add_edge(const id_type from_id, edge_type edge)
Adds an edge from from_id to the edge's target node.
void remove_node_id(const id_type node_id)
Removes the node with the specified ID and all edges pointing to it.
void remove_edge(const id_type from_id, const id_type to_id)
Removes the edge from from_id to to_id.
std::unordered_map< id_type, std::set< edge_type > > adj_map_
Maps node IDs to their outgoing edges.
std::set< id_type > get_neighboring_node_ids(const id_type node_id) const
Gets the neighboring node IDs of a given node.
friend std::ostream & operator(std::ostream &os, const AdjacencyList< id_type, edge_type > &adj_list)
friend for outputting to a std::ostream.
E edge_type
Alias for the edge type.
std::size_t edge_count() const
Returns the total number of edges in the graph.
std::size_t node_id_count() const
Returns the number of nodes in the graph.
Checks whether a type supports streaming to std::ostream.
Placeholder for user-defined data types used in vertices or edges.
Defines C++20 concepts used for type constraints in the GraphLib library.