diff --git a/example/AdaptingThirdPartyGraph/CMakeLists.txt b/example/AdaptingThirdPartyGraph/CMakeLists.txt new file mode 100644 index 0000000..5425e38 --- /dev/null +++ b/example/AdaptingThirdPartyGraph/CMakeLists.txt @@ -0,0 +1,12 @@ +# example/AdaptingThirdPartyGraph/CMakeLists.txt + +set(EXAMPLE_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/output/") +add_compile_definitions(EXAMPLE_OUTPUT_DIR="${EXAMPLE_OUTPUT_DIR}") + +#add_library(catch_main STATIC catch_main.cpp) +#target_link_libraries(catch_main PUBLIC Catch2::Catch2) +#target_link_libraries(catch_main PRIVATE project_options) +#target_link_options(catch_main INTERFACE $<$:-pthread -fconcepts-diagnostics-depth=1>) + +add_executable(AdaptingThirdPartyGraph "adapting_a_third_party_graph.cpp") +target_link_libraries(AdaptingThirdPartyGraph PRIVATE project_warnings project_options catch_main Catch2::Catch2WithMain graph) diff --git a/example/AdaptingThirdPartyGraph/adapting_a_third_party_graph.cpp b/example/AdaptingThirdPartyGraph/adapting_a_third_party_graph.cpp new file mode 100644 index 0000000..f7dbe31 --- /dev/null +++ b/example/AdaptingThirdPartyGraph/adapting_a_third_party_graph.cpp @@ -0,0 +1,89 @@ +// Copyright (C) 2025 Andrzej Krzemienski. +// +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// This test file demonstrates how one can adapt one's own graph container for use with +// this Graph Library + +#include +#include +#include +#include +#include + + +namespace MyLibrary +{ // custom graph container, conceptually an adjacency list + +struct MyEdge +{ + std::string content; + int indexOfTarget; +}; + +struct MyVertex +{ + std::string content; + std::vector outEdges; +}; + +class MyGraph +{ + std::vector _vertices; +public: + MyVertex const* getVertexByIndex(int index) const + { return &_vertices[static_cast(index)]; } + + std::vector const& getAllVertices() const // !! one of customization points + { return _vertices; } // forced me to add this fun + + void setTopology(std::vector t) { _vertices = std::move(t); } +}; + +} + +namespace MyLibrary +{ // customization for graph, unintrusive + // although forcing me to provide `vertices()` is superfluous + +auto vertices(MyGraph const& g) +{ return std::views::all(g.getAllVertices()); } // for vertex_range_t + +auto edges(MyGraph const&, const MyLibrary::MyVertex& v) +{ return std::views::all(v.outEdges); } + +auto edges(MyGraph const& g, int i) +{ return edges(g, *g.getVertexByIndex(i)); } + +int vertex_id(MyGraph const& g, std::vector::const_iterator it) +{ return static_cast(std::distance(g.getAllVertices().begin(), it)); } + +int target_id(MyGraph const&, MyEdge const& uv) +{ return uv.indexOfTarget; } + +} + + +int main() +{ + static_assert(graph::adjacency_list); + + const MyLibrary::MyGraph g = [] { // populate the graph + MyLibrary::MyGraph r; + std::vector topo { // A | + /*0*/ {"A", {{"", 1}, {"", 2}}}, // / \ | + /*1*/ {"B", {{"", 3}}}, // B C | + /*2*/ {"C", {{"", 3}}}, // \ / | + /*3*/ {"D", {}} // D | + }; + r.setTopology(std::move(topo)); + return r; + }(); + + for (auto const& [vid, v] : graph::views::vertices_depth_first_search(g, 0)) + std::cout << v.content << " "; + + std::cout << std::endl; +} \ No newline at end of file diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 5be2cac..27ff98c 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -2,3 +2,4 @@ add_subdirectory(CppCon2021) add_subdirectory(CppCon2022) +add_subdirectory(AdaptingThirdPartyGraph)