Squashed 'external/entt/entt/' content from commit fef92113
git-subtree-dir: external/entt/entt git-subtree-split: fef921132cae7588213d0f9bcd2fb9c8ffd8b7fc
This commit is contained in:
432
test/entt/graph/adjacency_matrix.cpp
Normal file
432
test/entt/graph/adjacency_matrix.cpp
Normal file
@ -0,0 +1,432 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/graph/adjacency_matrix.hpp>
|
||||
#include "../common/throwing_allocator.hpp"
|
||||
|
||||
TEST(AdjacencyMatrix, Resize) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{2};
|
||||
adjacency_matrix.insert(1u, 0u);
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 2u);
|
||||
ASSERT_TRUE(adjacency_matrix.contains(1u, 0u));
|
||||
|
||||
adjacency_matrix.resize(3u);
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 3u);
|
||||
ASSERT_TRUE(adjacency_matrix.contains(1u, 0u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, Constructors) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{};
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 0u);
|
||||
|
||||
adjacency_matrix = entt::adjacency_matrix<entt::directed_tag>{std::allocator<bool>{}};
|
||||
adjacency_matrix = entt::adjacency_matrix<entt::directed_tag>{3u, std::allocator<bool>{}};
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 3u);
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
entt::adjacency_matrix<entt::directed_tag> temp{adjacency_matrix, adjacency_matrix.get_allocator()};
|
||||
entt::adjacency_matrix<entt::directed_tag> other{std::move(adjacency_matrix), adjacency_matrix.get_allocator()};
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 0u);
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
|
||||
ASSERT_FALSE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_TRUE(other.contains(0u, 1u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, Copy) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
entt::adjacency_matrix<entt::directed_tag> other{adjacency_matrix};
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 3u);
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_TRUE(other.contains(0u, 1u));
|
||||
|
||||
adjacency_matrix.resize(4u);
|
||||
adjacency_matrix.insert(0u, 2u);
|
||||
other.insert(1u, 2u);
|
||||
|
||||
other = adjacency_matrix;
|
||||
|
||||
ASSERT_EQ(other.size(), 4u);
|
||||
ASSERT_EQ(adjacency_matrix.size(), 4u);
|
||||
|
||||
ASSERT_TRUE(other.contains(0u, 1u));
|
||||
ASSERT_FALSE(other.contains(1u, 2u));
|
||||
ASSERT_TRUE(other.contains(0u, 2u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, Move) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
entt::adjacency_matrix<entt::directed_tag> other{std::move(adjacency_matrix)};
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 0u);
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
|
||||
ASSERT_FALSE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_TRUE(other.contains(0u, 1u));
|
||||
|
||||
adjacency_matrix = {};
|
||||
adjacency_matrix.resize(4u);
|
||||
adjacency_matrix.insert(0u, 2u);
|
||||
other.insert(1u, 2u);
|
||||
|
||||
other = std::move(adjacency_matrix);
|
||||
|
||||
ASSERT_EQ(other.size(), 4u);
|
||||
ASSERT_EQ(adjacency_matrix.size(), 0u);
|
||||
|
||||
ASSERT_FALSE(other.contains(0u, 1u));
|
||||
ASSERT_FALSE(other.contains(1u, 2u));
|
||||
ASSERT_TRUE(other.contains(0u, 2u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, Swap) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
entt::adjacency_matrix<entt::directed_tag> other{};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
ASSERT_EQ(other.size(), 0u);
|
||||
ASSERT_EQ(adjacency_matrix.size(), 3u);
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_FALSE(other.contains(0u, 1u));
|
||||
|
||||
adjacency_matrix.swap(other);
|
||||
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
ASSERT_EQ(adjacency_matrix.size(), 0u);
|
||||
ASSERT_FALSE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_TRUE(other.contains(0u, 1u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, InsertDirected) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
|
||||
auto first = adjacency_matrix.insert(0u, 1u);
|
||||
auto second = adjacency_matrix.insert(0u, 2u);
|
||||
auto other = adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
ASSERT_TRUE(first.second);
|
||||
ASSERT_TRUE(second.second);
|
||||
ASSERT_FALSE(other.second);
|
||||
|
||||
ASSERT_NE(first.first, second.first);
|
||||
ASSERT_EQ(first.first, other.first);
|
||||
|
||||
ASSERT_EQ(*first.first, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(*second.first, std::make_pair(std::size_t{0u}, std::size_t{2u}));
|
||||
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_FALSE(adjacency_matrix.contains(2u, 0u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, InsertUndirected) {
|
||||
entt::adjacency_matrix<entt::undirected_tag> adjacency_matrix{3u};
|
||||
|
||||
auto first = adjacency_matrix.insert(0u, 1u);
|
||||
auto second = adjacency_matrix.insert(0u, 2u);
|
||||
auto other = adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
ASSERT_TRUE(first.second);
|
||||
ASSERT_TRUE(second.second);
|
||||
ASSERT_FALSE(other.second);
|
||||
|
||||
ASSERT_NE(first.first, second.first);
|
||||
ASSERT_EQ(first.first, other.first);
|
||||
|
||||
ASSERT_EQ(*first.first, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(*second.first, std::make_pair(std::size_t{0u}, std::size_t{2u}));
|
||||
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_TRUE(adjacency_matrix.contains(2u, 0u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, EraseDirected) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_FALSE(adjacency_matrix.contains(1u, 0u));
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.erase(0u, 1u), 1u);
|
||||
ASSERT_EQ(adjacency_matrix.erase(0u, 1u), 0u);
|
||||
|
||||
ASSERT_FALSE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_FALSE(adjacency_matrix.contains(1u, 0u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, EraseUndirected) {
|
||||
entt::adjacency_matrix<entt::undirected_tag> adjacency_matrix{3u};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_TRUE(adjacency_matrix.contains(1u, 0u));
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.erase(0u, 1u), 1u);
|
||||
ASSERT_EQ(adjacency_matrix.erase(0u, 1u), 0u);
|
||||
|
||||
ASSERT_FALSE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_FALSE(adjacency_matrix.contains(1u, 0u));
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, Clear) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(0u, 2u);
|
||||
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 2u));
|
||||
ASSERT_EQ(adjacency_matrix.size(), 3u);
|
||||
|
||||
adjacency_matrix.clear();
|
||||
|
||||
ASSERT_FALSE(adjacency_matrix.contains(0u, 1u));
|
||||
ASSERT_FALSE(adjacency_matrix.contains(0u, 2u));
|
||||
ASSERT_EQ(adjacency_matrix.size(), 0u);
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, VertexIterator) {
|
||||
using iterator = typename entt::adjacency_matrix<entt::directed_tag>::vertex_iterator;
|
||||
|
||||
static_assert(std::is_same_v<iterator::value_type, std::size_t>);
|
||||
static_assert(std::is_same_v<iterator::pointer, void>);
|
||||
static_assert(std::is_same_v<iterator::reference, std::size_t>);
|
||||
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{2u};
|
||||
const auto iterable = adjacency_matrix.vertices();
|
||||
|
||||
iterator end{iterable.begin()};
|
||||
iterator begin{};
|
||||
|
||||
begin = iterable.end();
|
||||
std::swap(begin, end);
|
||||
|
||||
ASSERT_EQ(begin, iterable.begin());
|
||||
ASSERT_EQ(end, iterable.end());
|
||||
ASSERT_NE(begin, end);
|
||||
|
||||
ASSERT_EQ(*begin, 0u);
|
||||
ASSERT_EQ(begin++, iterable.begin());
|
||||
ASSERT_EQ(*begin, 1u);
|
||||
ASSERT_EQ(++begin, iterable.end());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, EdgeIterator) {
|
||||
using iterator = typename entt::adjacency_matrix<entt::directed_tag>::edge_iterator;
|
||||
|
||||
static_assert(std::is_same_v<iterator::value_type, std::pair<std::size_t, std::size_t>>);
|
||||
static_assert(std::is_same_v<iterator::pointer, entt::input_iterator_pointer<std::pair<std::size_t, std::size_t>>>);
|
||||
static_assert(std::is_same_v<iterator::reference, std::pair<std::size_t, std::size_t>>);
|
||||
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(0u, 2u);
|
||||
|
||||
const auto iterable = adjacency_matrix.edges();
|
||||
|
||||
iterator end{iterable.begin()};
|
||||
iterator begin{};
|
||||
|
||||
begin = iterable.end();
|
||||
std::swap(begin, end);
|
||||
|
||||
ASSERT_EQ(begin, iterable.begin());
|
||||
ASSERT_EQ(end, iterable.end());
|
||||
ASSERT_NE(begin, end);
|
||||
|
||||
ASSERT_EQ(*begin, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(begin++, iterable.begin());
|
||||
ASSERT_EQ(*begin.operator->(), std::make_pair(std::size_t{0u}, std::size_t{2u}));
|
||||
ASSERT_EQ(++begin, iterable.end());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, Vertices) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{};
|
||||
auto iterable = adjacency_matrix.vertices();
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 0u);
|
||||
ASSERT_EQ(iterable.begin(), iterable.end());
|
||||
|
||||
adjacency_matrix.resize(2u);
|
||||
iterable = adjacency_matrix.vertices();
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 2u);
|
||||
ASSERT_NE(iterable.begin(), iterable.end());
|
||||
|
||||
auto it = iterable.begin();
|
||||
|
||||
ASSERT_EQ(*it++, 0u);
|
||||
ASSERT_EQ(*it, 1u);
|
||||
ASSERT_EQ(++it, iterable.end());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, EdgesDirected) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
auto iterable = adjacency_matrix.edges();
|
||||
|
||||
ASSERT_EQ(iterable.begin(), iterable.end());
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
iterable = adjacency_matrix.edges();
|
||||
|
||||
ASSERT_NE(iterable.begin(), iterable.end());
|
||||
|
||||
auto it = iterable.begin();
|
||||
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(*it.operator->(), std::make_pair(std::size_t{1u}, std::size_t{2u}));
|
||||
ASSERT_EQ(++it, iterable.end());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, EdgesUndirected) {
|
||||
entt::adjacency_matrix<entt::undirected_tag> adjacency_matrix{3u};
|
||||
auto iterable = adjacency_matrix.edges();
|
||||
|
||||
ASSERT_EQ(iterable.begin(), iterable.end());
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
iterable = adjacency_matrix.edges();
|
||||
|
||||
ASSERT_NE(iterable.begin(), iterable.end());
|
||||
|
||||
auto it = iterable.begin();
|
||||
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(*it.operator->(), std::make_pair(std::size_t{1u}, std::size_t{0u}));
|
||||
ASSERT_EQ(*(++it).operator->(), std::make_pair(std::size_t{1u}, std::size_t{2u}));
|
||||
ASSERT_EQ(*++it, std::make_pair(std::size_t{2u}, std::size_t{1u}));
|
||||
|
||||
ASSERT_EQ(++it, iterable.end());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, OutEdgesDirected) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
auto iterable = adjacency_matrix.out_edges(0u);
|
||||
|
||||
ASSERT_EQ(iterable.begin(), iterable.end());
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
iterable = adjacency_matrix.out_edges(0u);
|
||||
|
||||
ASSERT_NE(iterable.begin(), iterable.end());
|
||||
|
||||
auto it = iterable.begin();
|
||||
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(it, iterable.end());
|
||||
|
||||
iterable = adjacency_matrix.out_edges(2u);
|
||||
it = iterable.cbegin();
|
||||
|
||||
ASSERT_EQ(it, iterable.cend());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, OutEdgesUndirected) {
|
||||
entt::adjacency_matrix<entt::undirected_tag> adjacency_matrix{3u};
|
||||
auto iterable = adjacency_matrix.out_edges(0u);
|
||||
|
||||
ASSERT_EQ(iterable.begin(), iterable.end());
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
iterable = adjacency_matrix.out_edges(0u);
|
||||
|
||||
ASSERT_NE(iterable.begin(), iterable.end());
|
||||
|
||||
auto it = iterable.begin();
|
||||
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(it, iterable.end());
|
||||
|
||||
iterable = adjacency_matrix.out_edges(2u);
|
||||
it = iterable.cbegin();
|
||||
|
||||
ASSERT_NE(it, iterable.cend());
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{2u}, std::size_t{1u}));
|
||||
ASSERT_EQ(it, iterable.cend());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, InEdgesDirected) {
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
auto iterable = adjacency_matrix.in_edges(1u);
|
||||
|
||||
ASSERT_EQ(iterable.begin(), iterable.end());
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
iterable = adjacency_matrix.in_edges(1u);
|
||||
|
||||
ASSERT_NE(iterable.begin(), iterable.end());
|
||||
|
||||
auto it = iterable.begin();
|
||||
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(it, iterable.end());
|
||||
|
||||
iterable = adjacency_matrix.in_edges(0u);
|
||||
it = iterable.cbegin();
|
||||
|
||||
ASSERT_EQ(it, iterable.cend());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, InEdgesUndirected) {
|
||||
entt::adjacency_matrix<entt::undirected_tag> adjacency_matrix{3u};
|
||||
auto iterable = adjacency_matrix.in_edges(1u);
|
||||
|
||||
ASSERT_EQ(iterable.begin(), iterable.end());
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
iterable = adjacency_matrix.in_edges(1u);
|
||||
|
||||
ASSERT_NE(iterable.begin(), iterable.end());
|
||||
|
||||
auto it = iterable.begin();
|
||||
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{1u}));
|
||||
ASSERT_EQ(it, iterable.end());
|
||||
|
||||
iterable = adjacency_matrix.in_edges(0u);
|
||||
it = iterable.cbegin();
|
||||
|
||||
ASSERT_NE(it, iterable.cend());
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{1u}, std::size_t{0u}));
|
||||
ASSERT_EQ(it, iterable.cend());
|
||||
}
|
||||
|
||||
TEST(AdjacencyMatrix, ThrowingAllocator) {
|
||||
using allocator = test::throwing_allocator<std::size_t>;
|
||||
using exception = typename allocator::exception_type;
|
||||
|
||||
entt::adjacency_matrix<entt::directed_tag, allocator> adjacency_matrix{2u};
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
|
||||
allocator::trigger_on_allocate = true;
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 2u);
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
|
||||
ASSERT_THROW(adjacency_matrix.resize(4u), exception);
|
||||
|
||||
ASSERT_EQ(adjacency_matrix.size(), 2u);
|
||||
ASSERT_TRUE(adjacency_matrix.contains(0u, 1u));
|
||||
}
|
62
test/entt/graph/dot.cpp
Normal file
62
test/entt/graph/dot.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/graph/adjacency_matrix.hpp>
|
||||
#include <entt/graph/dot.hpp>
|
||||
|
||||
TEST(Dot, DirectedGraph) {
|
||||
std::ostringstream output{};
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
adjacency_matrix.insert(0u, 2u);
|
||||
|
||||
entt::dot(output, adjacency_matrix);
|
||||
|
||||
const std::string expected = "digraph{0[];1[];2[];0->1;0->2;1->2;}";
|
||||
const auto str = output.str();
|
||||
|
||||
ASSERT_FALSE(str.empty());
|
||||
ASSERT_EQ(str, expected);
|
||||
}
|
||||
|
||||
TEST(Dot, UndirectedGraph) {
|
||||
std::ostringstream output{};
|
||||
entt::adjacency_matrix<entt::undirected_tag> adjacency_matrix{3u};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
adjacency_matrix.insert(0u, 2u);
|
||||
|
||||
entt::dot(output, adjacency_matrix);
|
||||
|
||||
const std::string expected = "graph{0[];1[];2[];0--1;0--2;1--0;1--2;2--0;2--1;}";
|
||||
const auto str = output.str();
|
||||
|
||||
ASSERT_FALSE(str.empty());
|
||||
ASSERT_EQ(str, expected);
|
||||
}
|
||||
|
||||
TEST(Dot, CustomWriter) {
|
||||
std::ostringstream output{};
|
||||
entt::adjacency_matrix<entt::directed_tag> adjacency_matrix{3u};
|
||||
|
||||
adjacency_matrix.insert(0u, 1u);
|
||||
adjacency_matrix.insert(1u, 2u);
|
||||
adjacency_matrix.insert(0u, 2u);
|
||||
|
||||
entt::dot(output, adjacency_matrix, [&adjacency_matrix](std::ostream &out, std::size_t vertex) {
|
||||
out << "label=\"v" << vertex << "\"";
|
||||
|
||||
if(auto in_edges = adjacency_matrix.in_edges(vertex); in_edges.cbegin() == in_edges.cend()) {
|
||||
out << ",shape=\"box\"";
|
||||
}
|
||||
});
|
||||
|
||||
const std::string expected = "digraph{0[label=\"v0\",shape=\"box\"];1[label=\"v1\"];2[label=\"v2\"];0->1;0->2;1->2;}";
|
||||
const auto str = output.str();
|
||||
|
||||
ASSERT_FALSE(str.empty());
|
||||
ASSERT_EQ(str, expected);
|
||||
}
|
289
test/entt/graph/flow.cpp
Normal file
289
test/entt/graph/flow.cpp
Normal file
@ -0,0 +1,289 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/core/hashed_string.hpp>
|
||||
#include <entt/graph/flow.hpp>
|
||||
#include "../common/throwing_allocator.hpp"
|
||||
|
||||
TEST(Flow, Constructors) {
|
||||
entt::flow flow{};
|
||||
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
|
||||
flow = entt::flow{std::allocator<entt::id_type>{}};
|
||||
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
|
||||
flow.bind(0);
|
||||
flow.bind(3);
|
||||
flow.bind(99);
|
||||
|
||||
ASSERT_EQ(flow.size(), 3u);
|
||||
|
||||
entt::flow temp{flow, flow.get_allocator()};
|
||||
entt::flow other{std::move(flow), flow.get_allocator()};
|
||||
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
|
||||
ASSERT_EQ(other[0u], 0);
|
||||
ASSERT_EQ(other[1u], 3);
|
||||
ASSERT_EQ(other[2u], 99);
|
||||
}
|
||||
|
||||
TEST(Flow, Copy) {
|
||||
entt::flow flow{};
|
||||
|
||||
flow.bind(0);
|
||||
flow.bind(3);
|
||||
flow.bind(99);
|
||||
|
||||
entt::flow other{flow};
|
||||
|
||||
ASSERT_EQ(flow.size(), 3u);
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
|
||||
ASSERT_EQ(other[0u], 0);
|
||||
ASSERT_EQ(other[1u], 3);
|
||||
ASSERT_EQ(other[2u], 99);
|
||||
|
||||
flow.bind(1);
|
||||
other.bind(2);
|
||||
|
||||
other = flow;
|
||||
|
||||
ASSERT_EQ(other.size(), 4u);
|
||||
ASSERT_EQ(flow.size(), 4u);
|
||||
|
||||
ASSERT_EQ(other[0u], 0);
|
||||
ASSERT_EQ(other[1u], 3);
|
||||
ASSERT_EQ(other[2u], 99);
|
||||
ASSERT_EQ(other[3u], 1);
|
||||
}
|
||||
|
||||
TEST(Flow, Move) {
|
||||
entt::flow flow{};
|
||||
|
||||
flow.bind(0);
|
||||
flow.bind(3);
|
||||
flow.bind(99);
|
||||
|
||||
entt::flow other{std::move(flow)};
|
||||
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
|
||||
ASSERT_EQ(other[0u], 0);
|
||||
ASSERT_EQ(other[1u], 3);
|
||||
ASSERT_EQ(other[2u], 99);
|
||||
|
||||
flow = {};
|
||||
flow.bind(1);
|
||||
other.bind(2);
|
||||
|
||||
other = std::move(flow);
|
||||
|
||||
ASSERT_EQ(other.size(), 1u);
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
|
||||
ASSERT_EQ(other[0u], 1);
|
||||
}
|
||||
|
||||
TEST(Flow, Swap) {
|
||||
entt::flow flow{};
|
||||
entt::flow other{};
|
||||
|
||||
flow.bind(7);
|
||||
|
||||
ASSERT_EQ(other.size(), 0u);
|
||||
ASSERT_EQ(flow.size(), 1u);
|
||||
ASSERT_EQ(flow[0u], 7);
|
||||
|
||||
flow.swap(other);
|
||||
|
||||
ASSERT_EQ(other.size(), 1u);
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
ASSERT_EQ(other[0u], 7);
|
||||
}
|
||||
|
||||
TEST(Flow, Clear) {
|
||||
entt::flow flow{};
|
||||
|
||||
flow.bind(0);
|
||||
flow.bind(99);
|
||||
|
||||
ASSERT_EQ(flow.size(), 2u);
|
||||
ASSERT_EQ(flow[0u], 0);
|
||||
ASSERT_EQ(flow[1u], 99);
|
||||
|
||||
flow.clear();
|
||||
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
}
|
||||
|
||||
TEST(Flow, Set) {
|
||||
entt::flow flow{};
|
||||
flow.bind(0).set(10, true).bind(1).set(10, true).set(11, false);
|
||||
auto graph = flow.graph();
|
||||
|
||||
ASSERT_EQ(flow.size(), 2u);
|
||||
ASSERT_EQ(flow.size(), graph.size());
|
||||
ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
|
||||
|
||||
ASSERT_TRUE(graph.contains(0u, 1u));
|
||||
ASSERT_FALSE(graph.contains(1u, 0u));
|
||||
}
|
||||
|
||||
TEST(Flow, RO) {
|
||||
entt::flow flow{};
|
||||
flow.bind(0).ro(10).bind(1).ro(10).ro(11);
|
||||
auto graph = flow.graph();
|
||||
|
||||
ASSERT_EQ(flow.size(), 2u);
|
||||
ASSERT_EQ(flow.size(), graph.size());
|
||||
ASSERT_EQ(graph.edges().cbegin(), graph.edges().cend());
|
||||
}
|
||||
|
||||
TEST(Flow, RangeRO) {
|
||||
entt::flow flow{};
|
||||
const entt::id_type res[2u]{10, 11};
|
||||
flow.bind(0).ro(res, res + 1).bind(1).ro(res, res + 2);
|
||||
auto graph = flow.graph();
|
||||
|
||||
ASSERT_EQ(flow.size(), 2u);
|
||||
ASSERT_EQ(flow.size(), graph.size());
|
||||
ASSERT_EQ(graph.edges().cbegin(), graph.edges().cend());
|
||||
}
|
||||
|
||||
TEST(Flow, RW) {
|
||||
entt::flow flow{};
|
||||
flow.bind(0).rw(10).bind(1).rw(10).rw(11);
|
||||
auto graph = flow.graph();
|
||||
|
||||
ASSERT_EQ(flow.size(), 2u);
|
||||
ASSERT_EQ(flow.size(), graph.size());
|
||||
ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
|
||||
|
||||
ASSERT_TRUE(graph.contains(0u, 1u));
|
||||
ASSERT_FALSE(graph.contains(1u, 0u));
|
||||
}
|
||||
|
||||
TEST(Flow, RangeRW) {
|
||||
entt::flow flow{};
|
||||
const entt::id_type res[2u]{10, 11};
|
||||
flow.bind(0).rw(res, res + 1).bind(1).rw(res, res + 2);
|
||||
auto graph = flow.graph();
|
||||
|
||||
ASSERT_EQ(flow.size(), 2u);
|
||||
ASSERT_EQ(flow.size(), graph.size());
|
||||
ASSERT_NE(graph.edges().cbegin(), graph.edges().cend());
|
||||
|
||||
ASSERT_TRUE(graph.contains(0u, 1u));
|
||||
ASSERT_FALSE(graph.contains(1u, 0u));
|
||||
}
|
||||
|
||||
TEST(Flow, Graph) {
|
||||
using namespace entt::literals;
|
||||
|
||||
entt::flow flow{};
|
||||
|
||||
flow.bind("task_0"_hs)
|
||||
.ro("resource_0"_hs)
|
||||
.rw("resource_1"_hs);
|
||||
|
||||
flow.bind("task_1"_hs)
|
||||
.ro("resource_0"_hs)
|
||||
.rw("resource_2"_hs);
|
||||
|
||||
flow.bind("task_2"_hs)
|
||||
.ro("resource_1"_hs)
|
||||
.rw("resource_3"_hs);
|
||||
|
||||
flow.bind("task_3"_hs)
|
||||
.rw("resource_1"_hs)
|
||||
.ro("resource_2"_hs);
|
||||
|
||||
flow.bind("task_4"_hs)
|
||||
.rw("resource_0"_hs);
|
||||
|
||||
auto graph = flow.graph();
|
||||
|
||||
ASSERT_EQ(flow.size(), 5u);
|
||||
ASSERT_EQ(flow.size(), graph.size());
|
||||
|
||||
ASSERT_EQ(flow[0u], "task_0"_hs);
|
||||
ASSERT_EQ(flow[1u], "task_1"_hs);
|
||||
ASSERT_EQ(flow[2u], "task_2"_hs);
|
||||
ASSERT_EQ(flow[3u], "task_3"_hs);
|
||||
ASSERT_EQ(flow[4u], "task_4"_hs);
|
||||
|
||||
auto it = graph.edges().cbegin();
|
||||
const auto last = graph.edges().cend();
|
||||
|
||||
ASSERT_NE(it, last);
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{2u}));
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{4u}));
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{1u}, std::size_t{3u}));
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{1u}, std::size_t{4u}));
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{2u}, std::size_t{3u}));
|
||||
ASSERT_EQ(it, last);
|
||||
}
|
||||
|
||||
TEST(Flow, Sync) {
|
||||
using namespace entt::literals;
|
||||
|
||||
entt::flow flow{};
|
||||
|
||||
flow.bind("task_0"_hs)
|
||||
.ro("resource_0"_hs);
|
||||
|
||||
flow.bind("task_1"_hs)
|
||||
.rw("resource_1"_hs);
|
||||
|
||||
flow.bind("task_2"_hs)
|
||||
.sync();
|
||||
|
||||
flow.bind("task_3"_hs)
|
||||
.ro("resource_0"_hs)
|
||||
.rw("resource_2"_hs);
|
||||
|
||||
flow.bind("task_4"_hs)
|
||||
.ro("resource_2"_hs);
|
||||
|
||||
auto graph = flow.graph();
|
||||
|
||||
ASSERT_EQ(flow.size(), 5u);
|
||||
ASSERT_EQ(flow.size(), graph.size());
|
||||
|
||||
ASSERT_EQ(flow[0u], "task_0"_hs);
|
||||
ASSERT_EQ(flow[1u], "task_1"_hs);
|
||||
ASSERT_EQ(flow[2u], "task_2"_hs);
|
||||
ASSERT_EQ(flow[3u], "task_3"_hs);
|
||||
ASSERT_EQ(flow[4u], "task_4"_hs);
|
||||
|
||||
auto it = graph.edges().cbegin();
|
||||
const auto last = graph.edges().cend();
|
||||
|
||||
ASSERT_NE(it, last);
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{0u}, std::size_t{2u}));
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{1u}, std::size_t{2u}));
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{2u}, std::size_t{3u}));
|
||||
ASSERT_EQ(*it++, std::make_pair(std::size_t{3u}, std::size_t{4u}));
|
||||
ASSERT_EQ(it, last);
|
||||
}
|
||||
|
||||
TEST(Flow, ThrowingAllocator) {
|
||||
using allocator = test::throwing_allocator<entt::id_type>;
|
||||
using task_allocator = test::throwing_allocator<std::pair<std::size_t, entt::id_type>>;
|
||||
using task_exception = typename task_allocator::exception_type;
|
||||
|
||||
entt::basic_flow<allocator> flow{};
|
||||
|
||||
task_allocator::trigger_on_allocate = true;
|
||||
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
ASSERT_THROW(flow.bind(1), task_exception);
|
||||
ASSERT_EQ(flow.size(), 0u);
|
||||
|
||||
flow.bind(1);
|
||||
|
||||
ASSERT_EQ(flow.size(), 1u);
|
||||
}
|
Reference in New Issue
Block a user