Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Javadoc-style comments #14

Merged
merged 1 commit into from
May 25, 2023
Merged
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
121 changes: 115 additions & 6 deletions src/graaflib/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,63 +25,151 @@ namespace graaf {
using edge_id_t = std::size_t;

using vertices_t = std::unordered_set<vertex_id_t>;


/**
* Checks whether graph is directed.
*
* @return booleon - This return True for directed graph otherwise False
*/
[[nodiscard]] constexpr bool is_directed() const { return GRAPH_SPEC_V == GRAPH_SPEC::DIRECTED; }

/**
* Checks whether graph is undirected.
*
* @return booleon - This return True for undirected graph otherwise False
*/
[[nodiscard]] constexpr bool is_undirected() const { return GRAPH_SPEC_V == GRAPH_SPEC::UNDIRECTED; }


// STATISTICS


/**
* STATISTICS
*/
* Query the number of vertices
*
* @return size_t - Number of vertices
*/
[[nodiscard]] std::size_t vertex_count() const noexcept { return vertices_.size(); }
/**
* Query the number of edges
*
* @return size_t - Number of edges
*/
[[nodiscard]] std::size_t edge_count() const noexcept { return edges_.size(); }

// GETTERS

/**
* GETTERS
* Checks whether a vertex with a given ID is contained in the graph.
*
* @param vertex_id The ID of the vertex we want to check
* @return boolean - This return Ture to indicate the vertex is contained in the
* graph otherwise False
*/
[[nodiscard]] bool has_vertex(vertex_id_t vertex_id) const noexcept {
return vertices_.contains(vertex_id);
}

/**
* Checks whether two vertices are connected
*
* @param vertex_id_lhs The ID of the first vertex
* @param vertex_id_rhs The ID of the second vertex
* @return boolean - This return Ture to indicate there is an edge between the two vertices
* otherwise False
*/

[[nodiscard]] bool has_edge(vertex_id_t vertex_id_lhs, vertex_id_t vertex_id_rhs) const noexcept {
return do_has_edge(vertex_id_lhs, vertex_id_rhs);
}

/**
* Get a reference to the vertex using its vertex_id
*
* @param vertex_id The ID of the vertex
* @return vertex_t - A reference to the vertex
* @throws out_of_range exception - If vertex_id does not existing within the graph
*/
[[nodiscard]] vertex_t& get_vertex(vertex_id_t vertex_id) {
if (!has_vertex(vertex_id)) {
throw std::out_of_range{fmt::format("Vertex with ID [{}] not found in graph.", vertex_id)};
// May be more accurate to throw std::invalid_argument.
}
return vertices_.at(vertex_id);
}

/**
* Get a const reference to the vertex using its vertex_id
*
* @see graph#get_vertex()
* @param vertex_id The ID of the vertex
* @return vertex_t - A const reference to the vertex
*/

[[nodiscard]] const vertex_t& get_vertex(vertex_id_t vertex_id) const {
return get_vertex(vertex_id);
}

/**
* Get edge between two vertices with theirs ID
*
* @param vertex_id_lhs The ID of the first vertex
* @param vertex_id_rhs The ID of the second vertex
* @return edge_t - A reference to edge
* @throws out_of_range exception - If No edge exit between the two vertices
*/
[[nodiscard]] edge_t& get_edge(vertex_id_t vertex_id_lhs, vertex_id_t vertex_id_rhs) {
if (!has_edge(vertex_id_lhs, vertex_id_rhs)) {
throw std::out_of_range{fmt::format("No edge found between vertices [{}] -> [{}].", vertex_id_lhs, vertex_id_rhs)};
}
return do_get_edge(vertex_id_lhs, vertex_id_rhs);
}

/**
* Get const version of edge between two vertices with their ID by calling get_edge()
*
* @see graph#get_edge()
* @param vertex_id_lhs The ID of the first vertex
* @param vertex_id_rhs The ID of the second vertex
* @return edge_t - A const reference to the edge
*/
[[nodiscard]] const edge_t& get_edge(vertex_id_t vertex_id_lhs, vertex_id_t vertex_id_rhs) const {
return get_edge(vertex_id_lhs, vertex_id_rhs);
}

/**
* Get a list of neighbour vertices
*
* @param vertex_id The ID of the vertex
* @return vertices_t - A list of neigbounthood vertices
*/
[[nodiscard]] const vertices_t& get_neighbors(vertex_id_t vertex_id) const {
if (!adjacency_list_.contains(vertex_id)) {
throw std::out_of_range{fmt::format("Vertex with ID [{}] has no neighbors in graph.", vertex_id)};
}

return adjacency_list_.at(vertex_id);
}

/**
/*
* SETTERS
*/
/**
* Add a vertex to the graph
*
* @param vertex The vertex to be added
* @return vertices_id_t - The ID of the new vertex
*/
vertex_id_t add_vertex(VERTEX_T vertex) {
// TODO: check overflow
const auto vertex_id{vertex_id_supplier_++};
vertices_.emplace(vertex_id, std::move(vertex));
return vertex_id;
}
/**
* Remove a vertex from the graph and update all its neighbors
*
* @param vertex_id - The ID of the vertex
*/

void remove_vertex(vertex_id_t vertex_id) {

Expand All @@ -100,19 +188,40 @@ namespace graaf {
}
}

/**
* Add a new edge between two existing vertices
*
* @param vertex_id The ID of the vertex
* @throws out_of_range - If either of the vertex does not exist in graph
*/

void add_edge(vertex_id_t vertex_id_lhs, vertex_id_t vertex_id_rhs, EDGE_T edge) {
if (!has_vertex(vertex_id_lhs) || !has_vertex(vertex_id_rhs)) {
throw std::out_of_range{fmt::format("Vertices with ID [{}] and [{}] not found in graph.", vertex_id_lhs, vertex_id_rhs)};
}
do_add_edge(vertex_id_lhs, vertex_id_rhs, std::move(edge));
}
/**
* Add two connected new vertices to the graph
*
* @param vertex_id_lhs The ID of the first vertex
* @param vertex_id_rhs The ID of the second vertex
* @param edge
* @return vertex_ids_t - Vertices ID of the pair of vertices
*/

vertex_ids_t add_edge(VERTEX_T vertex_lhs, VERTEX_T vertex_rhs, EDGE_T edge) {
const auto vertex_id_lhs{add_vertex(std::move(vertex_lhs))};
const auto vertex_id_rhs{add_vertex(std::move(vertex_rhs))};
add_edge(vertex_id_lhs, vertex_id_rhs, std::move(edge));
return {vertex_id_lhs, vertex_id_rhs};
}
/**
* Remove the edge between two vertices
*
* @param vertex_id_lhs The ID of the first vertex
* @param vertex_id_rhs The ID of the second vertex
*/

void remove_edge(vertex_id_t vertex_id_lhs, vertex_id_t vertex_id_rhs) { do_remove_edge(vertex_id_lhs, vertex_id_rhs); }

Expand Down