diff options
Diffstat (limited to 'toolsrc/include')
| -rw-r--r-- | toolsrc/include/PackageSpec.h | 1 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Dependencies.h | 46 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Graphs.h | 127 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_Util.h | 6 | ||||
| -rw-r--r-- | toolsrc/include/vcpkg_optional.h | 2 |
5 files changed, 67 insertions, 115 deletions
diff --git a/toolsrc/include/PackageSpec.h b/toolsrc/include/PackageSpec.h index 4c3b47365..0d69ac89c 100644 --- a/toolsrc/include/PackageSpec.h +++ b/toolsrc/include/PackageSpec.h @@ -25,6 +25,7 @@ namespace vcpkg }; bool operator==(const PackageSpec& left, const PackageSpec& right); + bool operator!=(const PackageSpec& left, const PackageSpec& right); } //namespace vcpkg namespace std diff --git a/toolsrc/include/vcpkg_Dependencies.h b/toolsrc/include/vcpkg_Dependencies.h index 0e629ffef..f35250447 100644 --- a/toolsrc/include/vcpkg_Dependencies.h +++ b/toolsrc/include/vcpkg_Dependencies.h @@ -16,6 +16,15 @@ namespace vcpkg::Dependencies std::string to_output_string(RequestType request_type, const CStringView s); + struct AnyParagraph + { + std::vector<PackageSpec> dependencies(const Triplet& triplet) const; + + Optional<StatusParagraph> status_paragraph; + Optional<BinaryParagraph> binary_paragraph; + Optional<SourceParagraph> source_paragraph; + }; + enum class InstallPlanType { UNKNOWN, @@ -26,27 +35,19 @@ namespace vcpkg::Dependencies struct InstallPlanAction { + static bool compare_by_name(const InstallPlanAction* left, const InstallPlanAction* right); + InstallPlanAction(); - InstallPlanAction(const InstallPlanType& plan_type, const RequestType& request_type, Optional<BinaryParagraph> binary_pgh, Optional<SourceParagraph> source_pgh); + explicit InstallPlanAction(const PackageSpec& spec, const AnyParagraph& any_paragraph, const RequestType& request_type); InstallPlanAction(const InstallPlanAction&) = delete; InstallPlanAction(InstallPlanAction&&) = default; InstallPlanAction& operator=(const InstallPlanAction&) = delete; InstallPlanAction& operator=(InstallPlanAction&&) = default; + PackageSpec spec; + AnyParagraph any_paragraph; InstallPlanType plan_type; RequestType request_type; - Optional<BinaryParagraph> binary_pgh; - Optional<SourceParagraph> source_pgh; - }; - - struct PackageSpecWithInstallPlan - { - static bool compare_by_name(const PackageSpecWithInstallPlan* left, const PackageSpecWithInstallPlan* right); - - PackageSpecWithInstallPlan(const PackageSpec& spec, InstallPlanAction&& plan); - - PackageSpec spec; - InstallPlanAction plan; }; enum class RemovePlanType @@ -58,28 +59,21 @@ namespace vcpkg::Dependencies struct RemovePlanAction { + static bool compare_by_name(const RemovePlanAction* left, const RemovePlanAction* right); + RemovePlanAction(); - RemovePlanAction(const RemovePlanType& plan_type, const RequestType& request_type); + RemovePlanAction(const PackageSpec& spec, const RemovePlanType& plan_type, const RequestType& request_type); RemovePlanAction(const RemovePlanAction&) = delete; RemovePlanAction(RemovePlanAction&&) = default; RemovePlanAction& operator=(const RemovePlanAction&) = delete; RemovePlanAction& operator=(RemovePlanAction&&) = default; + PackageSpec spec; RemovePlanType plan_type; RequestType request_type; }; - struct PackageSpecWithRemovePlan - { - static bool compare_by_name(const PackageSpecWithRemovePlan* left, const PackageSpecWithRemovePlan* right); - - PackageSpecWithRemovePlan(const PackageSpec& spec, RemovePlanAction&& plan); - - PackageSpec spec; - RemovePlanAction plan; - }; - - std::vector<PackageSpecWithInstallPlan> create_install_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db); + std::vector<InstallPlanAction> create_install_plan(const VcpkgPaths& paths, const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db); - std::vector<PackageSpecWithRemovePlan> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db); + std::vector<RemovePlanAction> create_remove_plan(const std::vector<PackageSpec>& specs, const StatusParagraphs& status_db); } diff --git a/toolsrc/include/vcpkg_Graphs.h b/toolsrc/include/vcpkg_Graphs.h index 933d9ac67..97cd29236 100644 --- a/toolsrc/include/vcpkg_Graphs.h +++ b/toolsrc/include/vcpkg_Graphs.h @@ -1,7 +1,6 @@ #pragma once #include <unordered_map> -#include <unordered_set> namespace vcpkg::Graphs { @@ -17,104 +16,54 @@ namespace vcpkg::Graphs FULLY_EXPLORED }; - template <class V> - class Graph + template <class V, class U> + __interface AdjacencyProvider { - static void find_topological_sort_internal(V vertex, - ExplorationStatus& status, - const std::unordered_map<V, std::unordered_set<V>>& adjacency_list, - std::unordered_map<V, ExplorationStatus>& exploration_status, - std::vector<V>& sorted) - { - status = ExplorationStatus::PARTIALLY_EXPLORED; - - for (V neighbour : adjacency_list.at(vertex)) - { - ExplorationStatus& neighbour_status = exploration_status[neighbour]; - if (neighbour_status == ExplorationStatus::NOT_EXPLORED) - { - find_topological_sort_internal(neighbour, neighbour_status, adjacency_list, exploration_status, sorted); - } - else if (neighbour_status == ExplorationStatus::PARTIALLY_EXPLORED) - { - throw std::runtime_error("cycle in graph"); - } - } - - status = ExplorationStatus::FULLY_EXPLORED; - sorted.push_back(vertex); - } + std::vector<V> adjacency_list(const U& vertex) const; - public: - - void add_vertex(V v) - { - this->vertices[v]; - } - - // TODO: Change with iterators - void add_vertices(const std::vector<V>& vs) - { - for (const V& v : vs) - { - this->vertices[v]; - } - } - - void add_edge(V u, V v) - { - this->vertices[v]; - this->vertices[u].insert(v); - } + U load_vertex_data(const V& vertex) const; + }; - std::vector<V> find_topological_sort() const + template <class V, class U> + static void topological_sort_internal(const V& vertex, + const AdjacencyProvider<V, U>& f, + std::unordered_map<V, ExplorationStatus>& exploration_status, + std::vector<U>& sorted) + { + ExplorationStatus& status = exploration_status[vertex]; + switch (status) { - std::unordered_map<V, int> indegrees = count_indegrees(); - - std::vector<V> sorted; - sorted.reserve(indegrees.size()); - - std::unordered_map<V, ExplorationStatus> exploration_status; - exploration_status.reserve(indegrees.size()); - - for (auto& pair : indegrees) - { - if (pair.second == 0) // Starting from vertices with indegree == 0. Not required. + case ExplorationStatus::FULLY_EXPLORED: + return; + case ExplorationStatus::PARTIALLY_EXPLORED: + Checks::exit_with_message(VCPKG_LINE_INFO, "cycle in graph"); + case ExplorationStatus::NOT_EXPLORED: { - V vertex = pair.first; - ExplorationStatus& status = exploration_status[vertex]; - if (status == ExplorationStatus::NOT_EXPLORED) - { - find_topological_sort_internal(vertex, status, this->vertices, exploration_status, sorted); - } + status = ExplorationStatus::PARTIALLY_EXPLORED; + U vertex_data = f.load_vertex_data(vertex); + for (const V& neighbour : f.adjacency_list(vertex_data)) + topological_sort_internal(neighbour, f, exploration_status, sorted); + + sorted.push_back(std::move(vertex_data)); + status = ExplorationStatus::FULLY_EXPLORED; + return; } - } - - return sorted; + default: + Checks::unreachable(VCPKG_LINE_INFO); } + } - std::unordered_map<V, int> count_indegrees() const - { - std::unordered_map<V, int> indegrees; - - for (auto& pair : this->vertices) - { - indegrees[pair.first]; - for (V neighbour : pair.second) - { - ++indegrees[neighbour]; - } - } - - return indegrees; - } + template <class V, class U> + std::vector<U> topological_sort(const std::vector<V>& starting_vertices, const AdjacencyProvider<V, U>& f) + { + std::vector<U> sorted; + std::unordered_map<V, ExplorationStatus> exploration_status; - const std::unordered_map<V, std::unordered_set<V>>& adjacency_list() const + for (auto& vertex : starting_vertices) { - return this->vertices; + topological_sort_internal(vertex, f, exploration_status, sorted); } - private: - std::unordered_map<V, std::unordered_set<V>> vertices; - }; + return sorted; + } } diff --git a/toolsrc/include/vcpkg_Util.h b/toolsrc/include/vcpkg_Util.h index cd8dab437..c717830f0 100644 --- a/toolsrc/include/vcpkg_Util.h +++ b/toolsrc/include/vcpkg_Util.h @@ -27,4 +27,10 @@ namespace vcpkg::Util { cont.erase(std::partition(cont.begin(), cont.end(), pred), cont.end()); } + + template<class Container, class Pred> + void keep_if(Container& cont, Pred pred) + { + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); + } }
\ No newline at end of file diff --git a/toolsrc/include/vcpkg_optional.h b/toolsrc/include/vcpkg_optional.h index 4a2ceec30..28bdc81fa 100644 --- a/toolsrc/include/vcpkg_optional.h +++ b/toolsrc/include/vcpkg_optional.h @@ -15,6 +15,8 @@ namespace vcpkg class Optional { public: + constexpr Optional() : m_is_present(false), m_t() { } + // Constructors are intentionally implicit constexpr Optional(NullOpt) : m_is_present(false), m_t() { } |
