From bc63ee541f36030b1d04e0fe40801991a45de194 Mon Sep 17 00:00:00 2001 From: huanmie Date: Thu, 21 Jul 2022 01:10:12 +0800 Subject: [PATCH] Modified: use Allocator to construct Weight with INFINITE --- Graph/Example.cpp | 3 +++ Graph/Graph.h | 65 ++++++++++++++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/Graph/Example.cpp b/Graph/Example.cpp index ac7beab..880b096 100644 --- a/Graph/Example.cpp +++ b/Graph/Example.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -20,12 +21,14 @@ int main() out_path.clear(); graph.RemoveEdge("C", "D"); bool not_exist = graph.AddEdge("C", "D") == graph.INFINITE; + assert(not_exist); graph.GetOutPath("C", [&out_path](auto&& new_path) {out_path.push_back(new_path); return true; }); auto in_path = graph.GetInPath("B"); in_path.clear(); graph.GetInPath("B", [&in_path](auto&& new_path) {in_path.push_back(new_path); return true; }); auto weight = graph.AddEdge("C", "E"); not_exist = graph.AddEdge("C", "T") == graph.INFINITE; + assert(not_exist); auto result = graph.GetBestPath("A", "E"); return 0; } \ No newline at end of file diff --git a/Graph/Graph.h b/Graph/Graph.h index b8cd0cb..de18d24 100644 --- a/Graph/Graph.h +++ b/Graph/Graph.h @@ -3,48 +3,64 @@ template class Graph { - using AdjacencyMatrix = std::unordered_map>; - using PathType = AdjacencyMatrix::mapped_type::value_type; + using PathType = std::unordered_map::value_type; + + template + struct Allocator :public std::allocator + { + void construct(std::same_as auto* p, auto&& tag, auto&& key_tuple, auto&& value_tuple) + { + assert(std::tuple_size_v> == 0); + ::new((void*)p) PathType(std::forward(tag), + std::forward(key_tuple), + std::forward_as_tuple(Graph::INFINITE)); + } + + template + void destroy(U* p) + { + p->~U(); + } + + template + struct rebind + { + using type = Allocator; + }; + }; + + using AdjacencyMatrix = std::unordered_map, std::equal_to, Allocator>>; AdjacencyMatrix matrix; using Compare = bool(*)(const Weight&, const Weight&); std::function(const Vertex&, const Vertex&, Compare)> best_path; public: - const Weight INFINITE; + static Weight INFINITE; - Graph(const Weight& Infinite) :INFINITE(Infinite) {} + Graph(const Weight& Infinite) { INFINITE = Infinite; } - Graph(const Weight& Infinite, auto&&... rests) :INFINITE(Infinite) { Construct(std::forward(rests)...); } + Graph(const Weight& Infinite, auto&&... rests) + { + INFINITE = Infinite; + Construct(std::forward(rests)...); + } - Graph(const Weight& Infinite, std::initializer_list> list) :INFINITE(Infinite) + Graph(const Weight& Infinite, std::initializer_list> list) { + INFINITE = Infinite; for (auto&& element : list) AddEdge(std::get<0>(element), std::get<2>(element)) = std::get<1>(element); } Weight& AddEdge(const Vertex& begin, const Vertex& end) { - if (matrix.contains(begin) && matrix[begin].contains(end)) - return matrix[begin][end]; - else - { - Weight& weight = matrix[begin][end]; - weight = INFINITE; - return weight; - } + return matrix[begin][end]; } Weight& AddEdge(Vertex&& begin, Vertex&& end) { - if (matrix.contains(begin) && matrix[begin].contains(end)) - return matrix[begin][end]; - else - { - Weight& weight = matrix[std::move(begin)][std::move(end)]; - weight = INFINITE; - return weight; - } + return matrix[std::move(begin)][std::move(end)]; } void RemoveEdge(const Vertex& begin, const Vertex& end) @@ -147,4 +163,7 @@ class Graph IterateGraph(results, target, current_path, { vertex, weight }, set); } } -}; \ No newline at end of file +}; + +template +inline Weight Graph::INFINITE; \ No newline at end of file