1#ifndef ENTT_GRAPH_ADJACENCY_MATRIX_HPP
2#define ENTT_GRAPH_ADJACENCY_MATRIX_HPP
10#include "../config/config.h"
11#include "../core/iterator.hpp"
21 using size_type = std::size_t;
24 using value_type = std::pair<size_type, size_type>;
25 using pointer = input_iterator_pointer<value_type>;
26 using reference = value_type;
27 using difference_type = std::ptrdiff_t;
28 using iterator_category = std::input_iterator_tag;
29 using iterator_concept = std::forward_iterator_tag;
31 constexpr edge_iterator() noexcept = default;
34 constexpr edge_iterator(It base, const size_type vertices, const size_type from, const size_type to, const size_type step) noexcept
35 : it{std::move(base)},
40 for(; pos != last && !it[pos]; pos += offset) {}
43 constexpr edge_iterator &operator++() noexcept {
44 for(pos += offset; pos != last && !it[pos]; pos += offset) {}
48 constexpr edge_iterator operator++(
int)
noexcept {
49 edge_iterator orig = *
this;
50 return ++(*this), orig;
53 [[nodiscard]]
constexpr reference operator*() const noexcept {
57 [[nodiscard]]
constexpr pointer operator->() const noexcept {
58 return std::make_pair<size_type>(pos / vert, pos % vert);
61 template<
typename Type>
62 friend constexpr bool operator==(
const edge_iterator<Type> &,
const edge_iterator<Type> &)
noexcept;
72template<
typename Container>
73[[nodiscard]]
inline constexpr bool operator==(
const edge_iterator<Container> &lhs,
const edge_iterator<Container> &rhs)
noexcept {
74 return lhs.pos == rhs.pos;
77template<
typename Container>
78[[nodiscard]]
inline constexpr bool operator!=(
const edge_iterator<Container> &lhs,
const edge_iterator<Container> &rhs)
noexcept {
90template<
typename Category,
typename Allocator>
92 using alloc_traits = std::allocator_traits<Allocator>;
93 static_assert(std::is_base_of_v<directed_tag, Category>,
"Invalid graph category");
94 static_assert(std::is_same_v<typename alloc_traits::value_type, std::size_t>,
"Invalid value type");
95 using container_type = std::vector<std::size_t, typename alloc_traits::template rebind_alloc<std::size_t>>;
109 using edge_iterator = internal::edge_iterator<typename container_type::const_iterator>;
183 return matrix.get_allocator();
211 const auto iterable =
edges();
212 return (iterable.begin() == iterable.end());
236 const auto it = matrix.cbegin();
237 const auto sz = matrix.size();
238 return {{
it, vert, 0
u,
sz, 1u}, {
it, vert,
sz,
sz, 1u}};
247 const auto it = matrix.cbegin();
248 const auto from = vertex * vert;
249 const auto to =
from + vert;
259 const auto it = matrix.cbegin();
260 const auto from = vertex;
261 const auto to = vert * vert +
from;
290 if constexpr(std::is_same_v<graph_category, undirected_tag>) {
292 ENTT_ASSERT(matrix[
pos] == matrix[
rev],
"Something went really wrong");
296 const auto inserted = !std::exchange(matrix[
pos], 1u);
309 if constexpr(std::is_same_v<graph_category, undirected_tag>) {
311 ENTT_ASSERT(matrix[
pos] == matrix[
rev],
"Something went really wrong");
315 return std::exchange(matrix[
pos], 0
u);
326 return pos < matrix.size() && matrix[
pos];
330 container_type matrix;
Basic implementation of a directed adjacency matrix.
std::pair< edge_iterator, bool > insert(const vertex_type lhs, const vertex_type rhs)
Inserts an edge into the adjacency matrix, if it does not exist.
adjacency_matrix(const adjacency_matrix &)=default
Default copy constructor.
adjacency_matrix() noexcept(noexcept(allocator_type{}))
Default constructor.
Category graph_category
Graph category tag.
bool empty() const noexcept
Returns true if an adjacency matrix is empty, false otherwise.
iterable_adaptor< out_edge_iterator > out_edges(const vertex_type vertex) const noexcept
Returns an iterable object to visit all out-edges of a vertex.
internal::edge_iterator< typename container_type::const_iterator > edge_iterator
Edge iterator type.
void swap(adjacency_matrix &other) noexcept
Exchanges the contents with those of a given adjacency matrix.
size_type size() const noexcept
Returns the number of vertices.
std::size_t size_type
Unsigned integer type.
Allocator allocator_type
Allocator type.
adjacency_matrix & operator=(adjacency_matrix &&) noexcept=default
Default move assignment operator.
bool contains(const vertex_type lhs, const vertex_type rhs) const
Checks if an adjacency matrix contains a given edge.
void clear() noexcept
Clears the adjacency matrix.
adjacency_matrix(const size_type vertices, const allocator_type &allocator=allocator_type{})
Constructs an empty container with a given allocator and user supplied number of vertices.
edge_iterator out_edge_iterator
Out-edge iterator type.
iterable_adaptor< in_edge_iterator > in_edges(const vertex_type vertex) const noexcept
Returns an iterable object to visit all in-edges of a vertex.
std::pair< vertex_type, vertex_type > edge_type
Edge type.
~adjacency_matrix()=default
Default destructor.
iterable_adaptor< vertex_iterator > vertices() const noexcept
Returns an iterable object to visit all vertices of a matrix.
adjacency_matrix & operator=(const adjacency_matrix &)=default
Default copy assignment operator.
iterable_adaptor< edge_iterator > edges() const noexcept
Returns an iterable object to visit all edges of a matrix.
edge_iterator in_edge_iterator
In-edge iterator type.
void resize(const size_type vertices)
Resizes an adjacency matrix.
size_type vertex_type
Vertex type.
adjacency_matrix(const adjacency_matrix &other, const allocator_type &allocator)
Allocator-extended copy constructor.
adjacency_matrix(adjacency_matrix &&) noexcept=default
Default move constructor.
size_type erase(const vertex_type lhs, const vertex_type rhs)
Removes the edge associated with a pair of given vertices.
adjacency_matrix(const allocator_type &allocator) noexcept
Constructs an empty container with a given allocator.
constexpr allocator_type get_allocator() const noexcept
Returns the associated allocator.
Plain iota iterator (waiting for C++20).
constexpr Type make_obj_using_allocator(const Allocator &allocator, Args &&...args)
Uses-allocator construction utility (waiting for C++20).
constexpr bool operator!=(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
constexpr bool operator==(const basic_hashed_string< Char > &lhs, const basic_hashed_string< Char > &rhs) noexcept
Compares two hashed strings.
Utility class to create an iterable object from a pair of iterators.