├── .clang-format ├── .clang-tidy ├── .cmake-format.yaml ├── .github └── workflows │ ├── cache-cleanup.yml │ ├── clang-format.yml │ ├── codeql-analysis.yml │ ├── coverage.yml │ ├── macos.yml │ ├── pages.yml │ ├── ubuntu.yml │ └── windows.yml ├── .gitignore ├── CMakeLists.txt ├── CMakePresets.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Notes.md ├── README.md ├── ToDo.md ├── benchmark ├── CMakeLists.txt ├── graph_bench.cpp ├── mm_bench_dijkstra.cpp ├── mm_files.cpp ├── mm_files.hpp ├── mm_load.hpp ├── mm_load_example.cpp ├── mm_simple.cpp ├── nwgraph_dijkstra.hpp ├── sort_matrix_market.cpp ├── timer.cpp └── timer.hpp ├── cmake ├── CompilerWarnings.cmake ├── Doxygen.cmake ├── FetchBoost.cmake ├── FetchCSVParser.cmake ├── FetchCatch.cmake ├── FetchDocopt.cmake ├── FetchFMT.cmake ├── FetchFastMM.cmake ├── FetchRange.cmake ├── FetchSPDLog.cmake ├── Linker.cmake ├── PreventInSourceBuilds.cmake ├── Sanitizers.cmake ├── StandardProjectSettings.cmake └── StaticAnalyzers.cmake ├── data ├── bktest1.mtx ├── bktest2.mtx ├── cc_directed.csv ├── cc_undirected.csv ├── germany_routes.csv ├── karate.mtx └── tc_test.csv ├── doc └── Identifiers.docx ├── docs └── sphinx │ ├── Makefile │ ├── _extensions │ └── nw_exhale │ │ ├── __init__.py │ │ ├── configs.py │ │ ├── data │ │ ├── treeView-bootstrap │ │ │ └── bootstrap-treeview │ │ │ │ ├── LICENSE │ │ │ │ ├── apply-bootstrap-treview.js │ │ │ │ ├── bootstrap-treeview.min.css │ │ │ │ └── bootstrap-treeview.min.js │ │ └── treeView │ │ │ └── collapsible-lists │ │ │ ├── LICENSE.md │ │ │ ├── css │ │ │ ├── button-closed.png │ │ │ ├── button-open.png │ │ │ ├── button.png │ │ │ ├── list-item-contents.png │ │ │ ├── list-item-last-open.png │ │ │ ├── list-item-last.png │ │ │ ├── list-item-open.png │ │ │ ├── list-item-root.png │ │ │ ├── list-item.png │ │ │ └── tree_view.css │ │ │ └── js │ │ │ ├── CollapsibleLists.compressed.js │ │ │ └── apply-collapsible-lists.js │ │ ├── deploy.py │ │ ├── graph.py │ │ ├── parse.py │ │ └── utils.py │ ├── _static │ └── css │ │ └── custom.css │ ├── _templates │ └── layout.html │ ├── conf.py │ ├── graph-v2-api.rst │ ├── index.rst │ ├── layout.xml │ ├── make.bat │ └── requirements.txt ├── example ├── AdaptingThirdPartyGraph │ ├── CMakeLists.txt │ └── adapting_a_third_party_graph.cpp ├── CMakeLists.txt ├── CppCon2021 │ ├── CMakeLists.txt │ ├── examples │ │ ├── CMakeLists.txt │ │ ├── bacon.cpp │ │ ├── graphs.cpp │ │ ├── imdb.cpp │ │ └── ospf.cpp │ ├── graphs │ │ ├── imdb-graph.hpp │ │ ├── karate-graph.hpp │ │ ├── ospf-graph.hpp │ │ └── spice-graph.hpp │ └── include │ │ ├── bfs.hpp │ │ ├── bfs_edge_range.hpp │ │ ├── dijkstra.hpp │ │ ├── graph_concepts.hpp │ │ └── utilities.hpp ├── CppCon2022 │ ├── C++ - Phil Ratzloff - CppCon 2022.pdf │ ├── CMakeLists.txt │ ├── germany_routes_example.cpp │ ├── graphviz_output.hpp │ └── rr_adaptor.hpp └── PageRank │ ├── pagerank.hpp │ └── pagerank_tests.cpp ├── include └── graph │ ├── algorithm │ ├── bellman_ford_shortest_paths.hpp │ ├── breadth_first_search.hpp │ ├── common_shortest_paths.hpp │ ├── connected_components.hpp │ ├── depth_first_search.hpp │ ├── dijkstra_clrs.hpp │ ├── dijkstra_shortest_paths.hpp │ ├── experimental │ │ ├── bfs_cmn.hpp │ │ ├── co_bfs.hpp │ │ ├── co_cmn.hpp │ │ ├── co_dijkstra.hpp │ │ ├── notes.txt │ │ └── visitor_dijkstra.hpp │ ├── mis.hpp │ ├── mst.hpp │ ├── tc.hpp │ ├── topological_sort.hpp │ └── transitive_closure.hpp │ ├── container │ ├── compressed_graph.hpp │ ├── container_utility.hpp │ ├── dynamic_graph.hpp │ └── utility_edgelist.hpp │ ├── detail │ ├── co_generator.hpp │ ├── descriptor.hpp │ ├── graph_cpo.hpp │ └── graph_using.hpp │ ├── edgelist.hpp │ ├── graph.hpp │ ├── graph_info.hpp │ ├── graph_utility.hpp │ └── views │ ├── breadth_first_search.hpp │ ├── depth_first_search.hpp │ ├── edgelist.hpp │ ├── incidence.hpp │ ├── neighbors.hpp │ └── vertexlist.hpp ├── scripts └── format.sh └── tests ├── CMakeLists.txt ├── bellman_shortest_paths_tests.cpp ├── bfs_tests.cpp ├── breadth_first_search_tests.cpp ├── catch_main.cpp ├── cc_tests.cpp ├── co_bfs_tests.cpp ├── co_dijkstra_tests.cpp ├── constexpr_tests.cpp ├── csv.hpp ├── csv_routes.cpp ├── csv_routes.hpp ├── csv_routes_csr_tests.cpp ├── csv_routes_dov_tests.cpp ├── csv_routes_vofl_tests.cpp ├── depth_first_search_tests.cpp ├── descriptor_tests.cpp ├── dfs_tests.cpp ├── dijkstra_shortest_paths_tests.cpp ├── edgelist_tests.cpp ├── edgelist_view_tests.cpp ├── examples.cpp ├── examples_tests.cpp ├── incidence_tests.cpp ├── mis_tests.cpp ├── mst_tests.cpp ├── neighbors_tests.cpp ├── tc_tests.cpp ├── tests.cpp ├── topological_sort_tests.cpp ├── transitive_closure_tests.cpp ├── vertexlist_tests.cpp └── visitor_dijkstra_tests.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | BasedOnStyle: LLVM 4 | DisableFormat: false 5 | 6 | AlignConsecutiveAssignments: true 7 | AlignConsecutiveDeclarations: true 8 | AlignTrailingComments: true 9 | AllowShortCaseLabelsOnASingleLine: true 10 | AllowShortFunctionsOnASingleLine: true 11 | AllowShortIfStatementsOnASingleLine: false 12 | AlwaysBreakTemplateDeclarations: Yes 13 | BinPackParameters: false 14 | BreakBeforeBraces: Custom 15 | BraceWrapping: 16 | AfterClass: false 17 | AfterControlStatement: false 18 | AfterEnum: false 19 | AfterFunction: false 20 | AfterNamespace: false 21 | AfterObjCDeclaration: false 22 | AfterStruct: false 23 | AfterUnion: false 24 | AfterExternBlock: false 25 | BeforeCatch: false 26 | BeforeElse: false 27 | IndentBraces: false 28 | SplitEmptyFunction: false 29 | SplitEmptyRecord: true 30 | SplitEmptyNamespace: false 31 | BreakConstructorInitializers: BeforeComma 32 | BreakBeforeConceptDeclarations: true 33 | BreakBeforeInheritanceComma: true 34 | BreakInheritanceList: BeforeComma 35 | ColumnLimit: 120 36 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 37 | ConstructorInitializerIndentWidth: 6 38 | ContinuationIndentWidth: 6 39 | IncludeCategories: 40 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 41 | Priority: 2 42 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 43 | Priority: 3 44 | - Regex: '.*' 45 | Priority: 1 46 | IncludeIsMainRegex: '(Test)?$' 47 | IndentPPDirectives: AfterHash 48 | IndentRequires: false 49 | IndentWidth: 2 50 | 51 | MacroBlockBegin: '' 52 | MacroBlockEnd: '' 53 | MaxEmptyLinesToKeep: 2 54 | NamespaceIndentation: Inner 55 | 56 | PointerAlignment: Left 57 | 58 | ReflowComments: false 59 | SortIncludes: false 60 | 61 | SortUsingDeclarations: false 62 | SpacesBeforeTrailingComments: 1 63 | 64 | Standard: Latest 65 | UseTab: Never 66 | ... 67 | 68 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: '*,-fuchsia-*,-google-*,-zircon-*,-abseil-*,-modernize-use-trailing-return-type,-llvm*' 3 | WarningsAsErrors: '' 4 | HeaderFilterRegex: '' 5 | FormatStyle: none 6 | 7 | 8 | -------------------------------------------------------------------------------- /.cmake-format.yaml: -------------------------------------------------------------------------------- 1 | additional_commands: 2 | foo: 3 | flags: 4 | - BAR 5 | - BAZ 6 | kwargs: 7 | DEPENDS: '*' 8 | HEADERS: '*' 9 | SOURCES: '*' 10 | bullet_char: '*' 11 | dangle_parens: false 12 | enum_char: . 13 | line_ending: unix 14 | line_width: 120 15 | max_pargs_hwrap: 3 16 | separate_ctrl_name_with_space: false 17 | separate_fn_name_with_space: false 18 | tab_size: 2 19 | 20 | -------------------------------------------------------------------------------- /.github/workflows/cache-cleanup.yml: -------------------------------------------------------------------------------- 1 | name: Cache Cleanup 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | permissions: 7 | actions: write 8 | 9 | jobs: 10 | clear-cache: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Clear cache 14 | uses: actions/github-script@v6 15 | with: 16 | script: | 17 | console.log("About to clear") 18 | const caches = await github.rest.actions.getActionsCacheList({ 19 | owner: context.repo.owner, 20 | repo: context.repo.repo, 21 | }) 22 | for (const cache of caches.data.actions_caches) { 23 | console.log(cache) 24 | github.rest.actions.deleteActionsCacheById({ 25 | owner: context.repo.owner, 26 | repo: context.repo.repo, 27 | cache_id: cache.id, 28 | }) 29 | } 30 | console.log("Clear completed") -------------------------------------------------------------------------------- /.github/workflows/clang-format.yml: -------------------------------------------------------------------------------- 1 | name: Formatting 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master and dev branch 6 | push: 7 | branches: [ master ] 8 | 9 | jobs: 10 | formatting-check: 11 | name: Format 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | with: 16 | ref: ${{ github.event.pull_request.head.ref }} 17 | 18 | - name: Install clang-format 19 | run: | 20 | pip install clang-format \ 21 | && clang-format --version 22 | shell: bash 23 | 24 | - name: Format files 25 | run: ${{github.workspace}}/scripts/format.sh ${{github.workspace}} y 26 | shell: bash 27 | 28 | - name: Commit changes 29 | uses: EndBug/add-and-commit@v9 30 | with: 31 | committer_name: GitHub Actions 32 | committer_email: 41898282+github-actions[bot]@users.noreply.github.com 33 | message: ':octocat: Applied clang-format.' 34 | add: '*.hpp *.cpp' -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | schedule: 5 | # At 00:00 on day-of-month 1. 6 | - cron: "0 0 1 * *" 7 | workflow_dispatch: 8 | 9 | jobs: 10 | analyze: 11 | name: Analyze 12 | runs-on: ubuntu-latest 13 | permissions: 14 | actions: read 15 | contents: read 16 | security-events: write 17 | 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | language: [ 'cpp' ] 22 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 23 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 24 | 25 | steps: 26 | - name: Checkout repository 27 | uses: actions/checkout@v4 28 | 29 | # Initializes the CodeQL tools for scanning. 30 | - name: Initialize CodeQL 31 | uses: github/codeql-action/init@v2 32 | with: 33 | languages: ${{ matrix.language }} 34 | 35 | - run: sudo apt update && sudo apt install gcc-11 g++-11 36 | shell: bash 37 | 38 | - name: Configure cmake 39 | run: cmake -B ${{github.workspace}}/build 40 | shell: bash 41 | env: 42 | CC: gcc-11 43 | CXX: g++-11 44 | 45 | - name: Build all applications 46 | run: cmake --build ${{github.workspace}}/build 47 | 48 | - name: Perform CodeQL Analysis 49 | uses: github/codeql-action/analyze@v3 50 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Coverage 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master and dev branch 6 | push: 7 | branches: [ master ] 8 | 9 | pull_request: 10 | branches: [ master ] 11 | 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 16 | jobs: 17 | # This workflow contains a single job called "build" 18 | build: 19 | # https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/ 20 | if: "!contains(github.event.commits[0].message, '[skip cov]')" 21 | runs-on: ubuntu-latest 22 | container: ubuntu:24.04 23 | 24 | # Steps represent a sequence of tasks that will be executed as part of the job 25 | steps: 26 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 27 | - uses: actions/checkout@v4 28 | 29 | - run: apt-get update && apt-get install -y gcc-13 g++-13 lcov cmake git 30 | shell: bash 31 | 32 | - name: Configure cmake 33 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 34 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 35 | run: cmake -B ${{github.workspace}}/build -D ENABLE_COVERAGE=ON 36 | shell: bash 37 | env: 38 | CC: gcc-13 39 | CXX: g++-13 40 | 41 | - name: Build all applications 42 | run: cmake --build ${{github.workspace}}/build 43 | 44 | - name: Run tests 45 | run: ctest --test-dir ${{github.workspace}}/build/tests 46 | 47 | - name: Coverage 48 | shell: bash 49 | run: | 50 | cd ${{github.workspace}}/build 51 | lcov --no-external --capture --directory . --output-file coverage.info 52 | lcov --ignore-errors unused --remove coverage.info '/usr/include/*' '*/tests/*' --output-file coverage.info 53 | geninfo --rc geninfo_unexecuted_blocks=1 --ignore-errors gcov --output-filename coverage.info . 54 | genhtml coverage.info --output-directory out 55 | 56 | - name: Upload coverage reports to Codecov 57 | uses: codecov/codecov-action@v5 58 | with: 59 | files: ${{github.workspace}}/build/out/index.html 60 | token: ${{ secrets.CODECOV_TOKEN }} 61 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: MacOS 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master and dev branch 6 | push: 7 | branches: [ master ] 8 | 9 | pull_request: 10 | branches: [ master ] 11 | 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 16 | jobs: 17 | # This workflow contains a single job called "build" 18 | build: 19 | # https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/ 20 | if: "!contains(github.event.commits[0].message, '[skip macos]')" 21 | runs-on: macos-latest 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v4 27 | 28 | - name: Install GCC-13 29 | run: brew install gcc@13 30 | 31 | - name: Configure cmake 32 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 33 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 34 | run: cmake -B ${{github.workspace}}/build -D CMAKE_BUILD_TYPE=Release 35 | shell: bash 36 | env: 37 | CC: gcc-13 38 | CXX: g++-13 39 | 40 | - name: Build all applications 41 | run: cmake --build ${{github.workspace}}/build 42 | 43 | - name: Run tests 44 | run: ctest --test-dir ${{github.workspace}}/build/tests 45 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | name: Documentation 2 | 3 | on: 4 | # Runs on pushes targeting the default branch 5 | push: 6 | branches: ["master"] 7 | 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 12 | permissions: 13 | contents: read 14 | pages: write 15 | id-token: write 16 | 17 | # Allow one concurrent deployment 18 | concurrency: 19 | group: "pages" 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | deploy: 24 | environment: 25 | name: github-pages 26 | url: ${{ steps.deployment.outputs.page_url }} 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | 32 | - run: sudo apt update && sudo apt install gcc-11 g++-11 33 | shell: bash 34 | 35 | - name: Configure cmake for Doxygen 36 | run: cmake -B ${{github.workspace}}/build 37 | shell: bash 38 | env: 39 | CC: gcc-11 40 | CXX: g++-11 41 | 42 | # Testing with a different python 43 | - name: Install Python 44 | uses: actions/setup-python@v4 45 | with: 46 | python-version: '3.7' 47 | 48 | # Install requirements 49 | # Note: doxygen is not visible in $PATH until the subsequent actions. 50 | - name: Install Doxygen 51 | run: | 52 | wget https://www.doxygen.nl/files/doxygen-1.9.5.linux.bin.tar.gz 53 | tar -xvf doxygen-1.9.5.linux.bin.tar.gz 54 | echo "${{github.workspace}}/doxygen-1.9.5/bin" >> $GITHUB_PATH 55 | shell: bash 56 | 57 | - name: Install/Verify Requirements 58 | run: | 59 | python --version 60 | doxygen --version 61 | cd ${{github.workspace}}/docs/sphinx 62 | pip install -r requirements.txt 63 | 64 | # Build Sphinx documentation 65 | - name: Build Documentation 66 | run: | 67 | cd ${{github.workspace}}/docs/sphinx 68 | make html 69 | 70 | - name: Setup Pages 71 | uses: actions/configure-pages@v5 72 | 73 | - name: Upload artifact 74 | uses: actions/upload-pages-artifact@v3 75 | with: 76 | # Upload html directory 77 | path: './docs/sphinx/_build/html' 78 | 79 | - name: Deploy to GitHub Pages 80 | id: deployment 81 | uses: actions/deploy-pages@v4 82 | -------------------------------------------------------------------------------- /.github/workflows/ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: Ubuntu 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master and dev branch 6 | push: 7 | branches: [ master ] 8 | 9 | pull_request: 10 | branches: [ master ] 11 | 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 16 | jobs: 17 | # This workflow contains a single job called "build" 18 | build: 19 | # https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/ 20 | if: "!contains(github.event.commits[0].message, '[skip ubuntu]')" 21 | runs-on: ubuntu-latest 22 | container: ubuntu:24.04 23 | 24 | # Steps represent a sequence of tasks that will be executed as part of the job 25 | steps: 26 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 27 | - uses: actions/checkout@v4 28 | 29 | - run: apt-get update && apt-get install -y gcc-13 g++-13 lcov cmake git 30 | shell: bash 31 | 32 | - name: Configure cmake 33 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 34 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 35 | run: cmake -B ${{github.workspace}}/build -D ENABLE_COVERAGE=ON 36 | shell: bash 37 | env: 38 | CC: gcc-13 39 | CXX: g++-13 40 | 41 | - name: Build all applications 42 | run: cmake --build ${{github.workspace}}/build 43 | 44 | - name: Run tests 45 | run: ctest --test-dir ${{github.workspace}}/build/tests 46 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows 2 | 3 | # Controls when the workflow will run 4 | on: 5 | # Triggers the workflow on push or pull request events but only for the master and dev branch 6 | push: 7 | branches: [ master ] 8 | 9 | pull_request: 10 | branches: [ master ] 11 | 12 | # Allows you to run this workflow manually from the Actions tab 13 | workflow_dispatch: 14 | 15 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 16 | jobs: 17 | # This workflow contains a single job called "build" 18 | build: 19 | # https://github.blog/changelog/2021-02-08-github-actions-skip-pull-request-and-push-workflows-with-skip-ci/ 20 | if: "!contains(github.event.commits[0].message, '[skip windows]')" 21 | runs-on: windows-2022 22 | 23 | # Steps represent a sequence of tasks that will be executed as part of the job 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v4 27 | 28 | - name: Configure cmake 29 | # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. 30 | # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type 31 | run: cmake -B ${{github.workspace}}/build -D CMAKE_BUILD_TYPE=Release 32 | 33 | - name: Build all applications 34 | run: cmake --build ${{github.workspace}}/build 35 | 36 | - name: Run tests 37 | run: ctest -C Debug --test-dir ${{github.workspace}}/build/tests 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #Ignore thumbnails created by Windows 2 | Thumbs.db 3 | 4 | #Ignore tool config 5 | .vscode/ 6 | 7 | #Ignore files related to cmake 8 | [Bb]uild*/ 9 | CMakeUserPresets.json 10 | 11 | #Ignore files related to conan 12 | conan.lock 13 | conanbuildinfo.cmake 14 | conanbuildinfo.txt 15 | conanfile.txt 16 | conaninfo.txt 17 | 18 | #Ignore files built by Visual Studio 19 | *.obj 20 | *.exe 21 | *.pdb 22 | *.user 23 | *.aps 24 | *.pch 25 | *.vspscc 26 | *_i.c 27 | *_p.c 28 | *.ncb 29 | *.suo 30 | *.tlb 31 | *.tlh 32 | *.bak 33 | *.cache 34 | *.ilk 35 | *.log 36 | [Bb]in 37 | [Dd]ebug*/ 38 | *.lib 39 | *.sbr 40 | obj/ 41 | [Rr]elease*/ 42 | _ReSharper*/ 43 | [Tt]est[Rr]esult* 44 | out/ 45 | packages/ 46 | .vs/ 47 | 48 | #Ignore generated doc files (for now) 49 | doc/latex/*.pdf 50 | doc/latex/*.gz 51 | doc/latex/*.dvi 52 | doc/latex/*.log 53 | doc/latex/*.blg 54 | doc/latex/*.bbl 55 | doc/latex/*.out 56 | doc/latex/*.toc 57 | 58 | #Ignore test & example output 59 | test/output/ 60 | example/CppCon2022/output/ 61 | 62 | checks.json 63 | 64 | # Sphinx related 65 | .DS_Store 66 | __pycache__ 67 | _build 68 | _doxygen 69 | _api 70 | 71 | # Demo / Benchmark related 72 | # *.tsv 73 | # *.csv 74 | # *.mtx 75 | 76 | #Ignore externals directory 77 | externals/ 78 | 79 | # Ignore pulled repositories 80 | csv-parser/ 81 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeList.txt : Top-level CMake project file, do global configuration 2 | # and include sub-projects here. 3 | # 4 | cmake_minimum_required (VERSION 3.20) 5 | 6 | # Set the project name to your project name, my project isn't very descriptive 7 | set(GRAPH_VERSION 0.2.0) 8 | project("graph" VERSION ${GRAPH_VERSION} LANGUAGES CXX) 9 | include(cmake/StandardProjectSettings.cmake) 10 | 11 | set (CMAKE_CXX_STANDARD 20) 12 | set (CMAKE_CXX_STANDARD_REQUIRED ON) 13 | set (CMAKE_EXPORT_COMPILE_COMMANDS ON) 14 | 15 | # Link this 'library' to set the c++ standard / compile-time options requested 16 | add_library(project_options INTERFACE) 17 | target_compile_features(project_options INTERFACE cxx_std_20) 18 | target_compile_options(project_options INTERFACE $<$:>) 19 | target_compile_options(project_options INTERFACE $<$:--concepts>) 20 | target_compile_options(project_options INTERFACE $<$:/Zc:preprocessor>) 21 | target_compile_options(project_options INTERFACE $<$:/Zc:__cplusplus>) 22 | target_compile_options(project_options INTERFACE $<$:/utf-8>) 23 | set(CMAKE_CXX_EXTENSIONS OFF) 24 | 25 | if(MSVC) 26 | set(CMAKE_CXX_STANDARD 23) # use std=c++latest in MSVC for concepts 27 | elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 28 | option(ENABLE_BUILD_WITH_TIME_TRACE "Enable -ftime-trace to generate time tracing .json files on clang" OFF) 29 | if(ENABLE_BUILD_WITH_TIME_TRACE) 30 | target_compile_options(project_options INTERFACE -ftime-trace) 31 | endif() 32 | endif() 33 | 34 | # Link this 'library' to use the warnings specified in CompilerWarnings.cmake 35 | add_library(project_warnings INTERFACE) 36 | 37 | # enable cache system 38 | # include(cmake/Cache.cmake) 39 | 40 | # Add linker configuration 41 | include(cmake/Linker.cmake) 42 | configure_linker(project_options) 43 | 44 | # standard compiler warnings 45 | include(cmake/CompilerWarnings.cmake) 46 | set_project_warnings(project_warnings) 47 | 48 | # sanitizer options if supported by compiler 49 | include(cmake/Sanitizers.cmake) 50 | enable_sanitizers(project_options) 51 | 52 | # enable doxygen 53 | include(cmake/Doxygen.cmake) 54 | enable_doxygen() 55 | 56 | # allow for static analysis options 57 | include(cmake/StaticAnalyzers.cmake) 58 | 59 | option(BUILD_SHARED_LIBS "Enable compilation of shared libraries" OFF) 60 | option(ENABLE_TESTING "Enable Test Builds" ON) 61 | option(ENABLE_FUZZING "Enable Fuzzing Builds" OFF) 62 | option(ENABLE_EXAMPLES "Enable Example Builds" ON) 63 | option(ENABLE_BENCHMARKING "Enable Benchmark Builds" OFF) 64 | 65 | # Very basic PCH example 66 | option(ENABLE_PCH "Enable Precompiled Headers" OFF) 67 | if (ENABLE_PCH) 68 | # This sets a global PCH parameter, each project will build its own PCH, which is a good idea if any #define's change 69 | # 70 | # consider breaking this out per project as necessary 71 | target_precompile_headers( 72 | project_options 73 | INTERFACE 74 | 75 | 76 | 77 | ) 78 | endif() 79 | 80 | 81 | # Add thirdparty libraries 82 | include(${PROJECT_SOURCE_DIR}/cmake/FetchCatch.cmake) 83 | 84 | add_library(graph INTERFACE) 85 | target_include_directories(graph INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/") 86 | 87 | if(ENABLE_TESTING) 88 | enable_testing() 89 | message(STATUS "Building tests.") 90 | set(TEST_DATA_ROOT_DIR "${CMAKE_SOURCE_DIR}/data/") 91 | set(TEST_OUTPUT_ROOT_DIR "${CMAKE_SOURCE_DIR}/tests/") 92 | add_subdirectory(tests) 93 | endif() 94 | 95 | if(ENABLE_EXAMPLES) 96 | set(EXAMPLE_ROOT_DIR "${CMAKE_SOURCE_DIR}/example/") 97 | add_subdirectory(example) 98 | endif() 99 | 100 | if(ENABLE_BENCHMARKING) 101 | message(STATUS "Building benchmarks.") 102 | include(${PROJECT_SOURCE_DIR}/cmake/FetchFastMM.cmake) 103 | set(BENCHMARK_ROOT_DIR "${CMAKE_SOURCE_DIR}/benchmark/") 104 | set(BENCHMARK_OUTPUT_DIR "${CMAKE_SOURCE_DIR}/benchmark/results/") 105 | 106 | # This is for Phil's home machine. It needs to be made more general 107 | if(CMAKE_SYSTEM_NAME STREQUAL "Windows") 108 | set(BENCHMARK_DATA_DIR "${CMAKE_SOURCE_DIR}/../data/") 109 | elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") 110 | set(BENCHMARK_DATA_DIR "/mnt/c/dev_graph/data/") 111 | endif() 112 | 113 | add_subdirectory(benchmark) 114 | endif() 115 | 116 | #if(ENABLE_FUZZING) 117 | # message("Building Fuzz Tests, using fuzzing sanitizer https://www.llvm.org/docs/LibFuzzer.html") 118 | # add_subdirectory(fuzz_test) 119 | #endif() 120 | 121 | #add_subdirectory(src) 122 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | phil.ratzloff@sas.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | >⚡By contributing to graph-v2, you agree that your contributions will be offered under the Boost Software License 1.0. For more information, see the [LICENSE](https://github.com/stdgraph/graph-v2/blob/master/LICENSE). 3 | 4 | Thank you for contributing! This guide serves to make the process easier. 5 | 6 | ## Issues 7 | We use GitHub issues to track bugs and feature requests. Please ensure your description is clear and sufficient, and that you report as much as possible to sufficiently reproduce the bug (and/or be able to fully understand the feature request). 8 | 9 | ## Pull Requests (PR) 10 | We actively welcome pull requests, please see the following process for submitting a PR: 11 | 1. We follow the git fork workflow for external pull requests, please see the following for more details: [GitHub Forking](https://gist.github.com/Chaser324/ce0505fbed06b947d962). 12 | 2. Once a PR is created, GitHub will run automatic tests and build the changes. 13 | 3. If the PR successfully builds, a reviewer manually assigns themselves to the PR and either requests changes or approves/merges it. 14 | 4. Congratulations and thank you for successfully contributing! 15 | 16 | ## Discussions 17 | For general community discussions and questions, we use GitHub [discussions](https://github.com/stdgraph/graph-v2/discussions). 18 | 19 | ## Proposal 20 | To contribute to the C++ proposal, please see the following repository: [stdgraph/P1709](https://github.com/stdgraph/P1709) 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /Notes.md: -------------------------------------------------------------------------------- 1 | LaTeX 2 | 1. https://miktex.org/ 3 | 2. https://tug.org/FontCatalogue/mathfonts.html 4 | 3. https://www.overleaf.com/ online LaTeX (sharable) 5 | 4. http://tug.ctan.org/macros/latex/contrib/minted/minted.pdf: AL 6 | 5. https://github.com/cplusplus/draft 7 | 8 | gcc requires views and their iterators to be default-constructible (cf bfs_vertex_range & bfs_edge_range) 9 | 10 | P2300r5 4.19 parallel algorithms 11 | : In the future, we expect additional papers will propose asynchronous forms of the parallel algorithms 12 | which (1) return senders rather than values or void and (2) where a customization point pairing a sender 13 | with an execution policy would similarly be used to obtain an object of implementation-defined type to 14 | be provided as the first argument to the algorithm. 15 | 16 | # Conferences and Events (potential presentation) 17 | - [ ] ACCU: 1st week of April 18 | - [ ] Cpp on Sea: 1st week of July 19 | - [ ] CppCon: 2nd week of Sep 20 | -------------------------------------------------------------------------------- /benchmark/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Simple benmarking for the graph library, and more specifically the dijkstra variants 2 | 3 | # C++23 needed for zip view 4 | set (CMAKE_CXX_STANDARD 23) 5 | 6 | add_library(common_bench INTERFACE) 7 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 8 | target_compile_options(common_bench INTERFACE -Wno-sign-conversion) 9 | endif() 10 | target_link_libraries(common_bench INTERFACE project_warnings project_options fmt::fmt) 11 | 12 | add_executable(graph_bench graph_bench.cpp "mm_simple.cpp" "mm_load_example.cpp" "mm_bench_dijkstra.cpp" "timer.cpp" "mm_files.cpp") 13 | target_link_libraries(graph_bench PRIVATE common_bench graph fast_matrix_market::fast_matrix_market) 14 | target_compile_definitions(graph_bench PRIVATE BENCHMARK_DATA_DIR="${BENCHMARK_DATA_DIR}") 15 | #if (MSVC) 16 | # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /PROFILE") 17 | # #target_link_options(graph_bench PRIVATE -pthread) 18 | #endif() 19 | 20 | # An executable to sort a matrix market file 21 | add_executable(sort_matrix_market "sort_matrix_market.cpp" "timer.cpp") 22 | target_link_libraries(sort_matrix_market PRIVATE common_bench fast_matrix_market::fast_matrix_market) 23 | -------------------------------------------------------------------------------- /benchmark/graph_bench.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifdef _MSC_VER 4 | # include 5 | #endif 6 | 7 | 8 | void mm_simple1(); 9 | void mm_load_example(); 10 | void mm_load_file_example(); 11 | void bench_dijkstra_main(); 12 | void bench_dijkstra_runner(); 13 | 14 | int main() { 15 | #ifdef _MSC_VER 16 | SetConsoleOutputCP(CP_UTF8); // Change console from OEM to UTF-8 in Windows 17 | #endif 18 | setvbuf(stdout, nullptr, _IOFBF, 1000); // avoid shearing multi-byte characters across buffer boundaries 19 | std::locale::global(std::locale("")); 20 | //mm_simple1(); 21 | //mm_load_example(); 22 | //mm_load_file_example(); 23 | //bench_dijkstra_main(); 24 | bench_dijkstra_runner(); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /benchmark/mm_files.cpp: -------------------------------------------------------------------------------- 1 | #include "mm_files.hpp" 2 | 3 | using std::filesystem::path; 4 | using std::vector; 5 | 6 | path gap = path(BENCHMARK_DATA_DIR) / "GAP"; 7 | bench_files gap_road(gap, "GAP-road", "GAP-road.mtx", "GAP-road.sorted.mtx", "GAP-road_sources.mtx"); 8 | bench_files gap_twitter(gap, "GAP-twitter", "GAP-twitter.mtx", "GAP-twitter.sorted.mtx", "GAP-twitter_sources.mtx"); 9 | bench_files gap_web(gap, "GAP-web", "GAP-web.mtx", "GAP-web.sorted.mtx", "GAP-web_sources.mtx"); 10 | bench_files gap_kron(gap, "GAP-kron", "GAP-kron.mtx", "GAP-kron.sorted.mtx", "GAP-kron_sources.mtx"); 11 | bench_files gap_urand(gap, "GAP-urand", "GAP-urand.mtx", "GAP-urand.sorted.mtx", "GAP-urand_sources.mtx"); 12 | 13 | 14 | path g2bench = path(BENCHMARK_DATA_DIR) / "g2bench"; 15 | bench_files g2bench_chesapeake(g2bench, "", "chesapeake.mtx", "chesapeake.sorted.mtx", "sources.mtx"); 16 | bench_files g2bench_bips98_606(g2bench, "", "bips98_606.mtx", "bips98_606.sorted.mtx", "sources.mtx"); 17 | // sources.mtx is a generic set of sources that can be used with either g2bench graph 18 | 19 | vector datasets = {gap_road, gap_twitter, gap_web, gap_kron, 20 | gap_urand, g2bench_chesapeake, g2bench_bips98_606}; 21 | -------------------------------------------------------------------------------- /benchmark/mm_files.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | /** 7 | * A simple triplet sparse matrix. 8 | */ 9 | template 10 | struct triplet_matrix { 11 | int64_t nrows = 0, ncols = 0; 12 | std::vector rows; 13 | std::vector cols; 14 | std::vector vals; 15 | }; 16 | 17 | /** 18 | * A simple dense matrix. 19 | */ 20 | template 21 | struct array_matrix { 22 | int64_t nrows = 0, ncols = 0; 23 | std::vector vals; 24 | }; 25 | 26 | /** 27 | * Benchmark matrix market files. 28 | */ 29 | struct bench_files { 30 | std::filesystem::path mtx_path; 31 | std::filesystem::path mtx_sorted_path; 32 | std::filesystem::path sources_path; 33 | std::string suite; // GAP, g2bench, etc. (last directory of the base_path) 34 | std::string name; // GAP-road, GAP-twitter, etc. (stem of the mtx_path) 35 | 36 | bench_files() = delete; 37 | bench_files(const std::filesystem::path& base_path, 38 | const std::string_view& subpath, 39 | const std::string_view& mtx_file, 40 | const std::string_view& mtx_sorted_file, 41 | const std::string_view& sources_file) 42 | : mtx_path(base_path / subpath / mtx_file) 43 | , mtx_sorted_path(base_path / subpath / mtx_sorted_file) 44 | , sources_path(base_path / subpath / sources_file) 45 | , suite(base_path.filename().string()) 46 | , name(mtx_path.stem().string()) {} 47 | }; 48 | 49 | extern bench_files gap_road; // 599MB 50 | extern bench_files gap_twitter; // 29.2GB 51 | extern bench_files gap_web; // 38.1GB; sort= 490.4s 52 | extern bench_files gap_kron; // 43.1GB; sort=1261.9s 53 | extern bench_files gap_urand; // 43.8GB; sort=1377.7s 54 | 55 | 56 | extern bench_files g2bench_chesapeake; // 13KB 57 | extern bench_files g2bench_bips98_606; //944KB 58 | 59 | extern std::vector datasets; 60 | -------------------------------------------------------------------------------- /benchmark/mm_load_example.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mm_load.hpp" 5 | 6 | using std::tuple; 7 | using std::vector; 8 | 9 | using namespace graph::container; 10 | 11 | // Dataset: gap_twitter, symmetry_type::general, 1,468,364,884 rows 12 | // Deb/Rel parallel_ok num_threads Read Rows/Sec LoadSimple Edges/Sec LoadCompressed Edges/Sec 13 | // ------- ----------- ----------- ----------- ---------- ---------- ----------- -------------- ----------- 14 | // Debug false 1 6m0s(360) 4,077,499 5m32s(332) 4,077,499 5m49s(348) 4,213,302 15 | // Debug true 2 12m42s(761) 1,927,867 5m13s(313) 4,688,601 5m36s(335) 4,373,910 16 | // Release false 1 2m18s(138) 10,619,350 1m24s(83) 17,557,093 1m2s(62) 23,531,613 17 | // Release true 2 1m19s(78) 18,625,828 18 | // Release true 4 1m20s(79) 18,460,595 1m18s(78) 18,752,507 0m45s(44) 32,708,977 19 | 20 | void mm_load_file_example() { 21 | 22 | triplet_matrix triplet; 23 | array_matrix sources; 24 | 25 | load_matrix_market(gap_road, triplet, sources, true); 26 | 27 | // Load a simple graph: vector>> 28 | { 29 | vector>> g; 30 | graph_stats stats = load_graph(triplet, g); 31 | fmt::println("Graph stats: {}", stats); 32 | } 33 | 34 | // Load a compressed_graph 35 | { 36 | compressed_graph g; 37 | graph_stats stats = load_graph(triplet, g); 38 | fmt::println("Graph stats: {}", stats); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /benchmark/mm_simple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #ifdef _MSC_VER 5 | # pragma warning(push) 6 | # pragma warning(disable : 4242) // '=': conversion from 'int' to 'char', possible loss of data 7 | # pragma warning(disable : 4701) // potentially uninitialized local variable 'value' used 8 | #else 9 | # pragma GCC diagnostic push 10 | # pragma GCC diagnostic ignored "-Wshadow" 11 | # pragma GCC diagnostic ignored "-Wsign-conversion" 12 | # pragma GCC diagnostic ignored "-Wuseless-cast" 13 | # pragma GCC diagnostic ignored "-Wold-style-cast" 14 | #endif 15 | #include 16 | #ifdef _MSC_VER 17 | # pragma warning(pop) 18 | #else 19 | # pragma GCC diagnostic pop 20 | #endif 21 | 22 | 23 | // If you prefer more concise code then you can use this to abbreviate the 24 | // rather long namespace name. Then just use `fmm::` instead of `fast_matrix_market::`. 25 | // This is not used below only to make the code simpler to understand at a glance and for easy copy/paste. 26 | namespace fmm = fast_matrix_market; 27 | 28 | /** 29 | * A simple triplet sparse matrix. 30 | */ 31 | template 32 | struct triplet_matrix { 33 | int64_t nrows = 0, ncols = 0; 34 | std::vector rows; 35 | std::vector cols; 36 | std::vector vals; 37 | }; 38 | 39 | /** 40 | * A simple dense matrix. 41 | */ 42 | template 43 | struct array_matrix { 44 | int64_t nrows = 0, ncols = 0; 45 | std::vector vals; 46 | }; 47 | 48 | void mm_simple1() { 49 | // Create a matrix 50 | triplet_matrix triplet; 51 | 52 | triplet.nrows = 4; 53 | triplet.ncols = 4; 54 | 55 | triplet.rows = {1, 2, 3, 3}; 56 | triplet.cols = {0, 1, 2, 3}; 57 | triplet.vals = {1.0, 5, 2E5, 19}; 58 | 59 | std::string mm; 60 | 61 | // Write triplet to Matrix Market. Use std::ostringstream to write to a string. 62 | { 63 | std::ostringstream oss; 64 | 65 | // The `nrows` and `ncols` below are a brace initialization of the header. 66 | // If you are interested in the other aspects of the Matrix Market header then 67 | // construct an instance of fast_matrix_market::matrix_market_header. 68 | // This is how you would manipulate the comment field: header.comment = std::string("comment"); 69 | // You may also set header.field = fast_matrix_market::pattern to write a pattern file (only indices, no values). 70 | // Non-pattern field types (integer, real, complex) are deduced from the template type and cannot be overriden. 71 | 72 | fast_matrix_market::write_matrix_market_triplet(oss, {triplet.nrows, triplet.ncols}, triplet.rows, triplet.cols, 73 | triplet.vals); 74 | 75 | mm = oss.str(); 76 | std::cout << mm << std::endl << std::endl; 77 | } 78 | 79 | // Read Matrix Market into another triplet 80 | { 81 | triplet_matrix triplet2; 82 | std::istringstream iss(mm); 83 | fast_matrix_market::read_matrix_market_triplet(iss, triplet2.nrows, triplet2.ncols, triplet2.rows, triplet2.cols, 84 | triplet2.vals); 85 | 86 | assert(triplet.nrows == triplet2.nrows && triplet.ncols == triplet2.ncols && triplet.rows == triplet2.rows && 87 | triplet.cols == triplet2.cols && triplet.vals == triplet2.vals); 88 | } 89 | 90 | // Read Matrix Market into complex dense array 91 | array_matrix> array; 92 | { 93 | // Dense arrays can be row- or column-major. FMM defaults to row-major but can be used with either. 94 | // Use the ordering that your code expects. 95 | // Using the wrong one can lead to transposed values (for square matrices) or scrambled values. 96 | // 97 | // read_matrix_market_array() accepts any resizable vector type, such as std::vector, and will resize 98 | // it to match the contents of the Matrix Market file. 99 | // 100 | // Note that the file being read happens to be a coordinate (sparse) file. That is ok, FMM performs the 101 | // conversion automatically and efficiently. In this case the resulting dense array is allocated 102 | // (and default initialized to zero by std::vector::resize()) then FMM writes only the values specified in the file. 103 | std::istringstream iss(mm); 104 | fast_matrix_market::read_matrix_market_array(iss, array.nrows, array.ncols, array.vals, 105 | fast_matrix_market::row_major); 106 | } 107 | 108 | // Write dense array to Matrix Market 109 | { 110 | std::ostringstream oss; 111 | fast_matrix_market::write_matrix_market_array(oss, {array.nrows, array.ncols}, array.vals, 112 | fast_matrix_market::row_major); 113 | 114 | mm = oss.str(); 115 | std::cout << mm << std::endl << std::endl; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /benchmark/nwgraph_dijkstra.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | // from nwgraph with minor refactoring to use graph-v2 5 | template 6 | static auto nwgraph_dijkstra( 7 | Graph&& graph, const Sources& sources, Weight weight = [](auto& e) -> auto& { return std::get<1>(e); }) { 8 | using namespace graph; 9 | using vertex_id_type = vertex_id_t; 10 | 11 | using distance_t = int64_t; 12 | std::vector dist(num_vertices(graph), std::numeric_limits::max() / 4); 13 | 14 | //using queue_t = std::priority_queue, std::greater>; 15 | //queue_t mq; 16 | //auto mq = nw::graph::make_priority_queue( 17 | // [&dist](const vertex_id_type& a, vertex_id_type& b) { return dist[a] > dist[b]; }); 18 | auto compare = [&dist](vertex_id_type& a, vertex_id_type& b) { 19 | return dist[static_cast(a)] > dist[static_cast(b)]; 20 | }; 21 | using queue_t = std::priority_queue, decltype(compare)>; 22 | queue_t mq(compare); 23 | 24 | for (auto&& source : sources) { 25 | mq.push(source); 26 | dist[static_cast(source)] = 0; 27 | } 28 | 29 | #if defined(ENABLE_POP_COUNT) || defined(ENABLE_EDGE_VISITED_COUNT) 30 | size_t pop_cnt = 0, edge_cnt = 0; 31 | #endif 32 | while (!mq.empty()) { 33 | auto u = mq.top(); 34 | mq.pop(); 35 | #if defined(ENABLE_POP_COUNT) 36 | ++pop_cnt; 37 | #endif 38 | #if defined(ENABLE_EDGE_VISITED_COUNT) 39 | edge_cnt += size(edges(graph, u)); 40 | #endif 41 | for (auto&& elt : graph[static_cast(u)]) { 42 | auto&& v = target_id(graph, elt); 43 | auto&& w = weight(elt); 44 | 45 | auto tw = dist[static_cast(u)] + w; 46 | if (tw < dist[static_cast(v)]) { 47 | dist[static_cast(v)] = tw; 48 | mq.push(v); 49 | } 50 | } 51 | } 52 | 53 | #if defined(ENABLE_POP_COUNT) || defined(ENABLE_EDGE_VISITED_COUNT) 54 | fmt::print("dijkstra_with_visitor: pop_cnt = {:L}, edge_cnt = {:L}\n", pop_cnt, edge_cnt); 55 | #endif 56 | return dist; 57 | } 58 | -------------------------------------------------------------------------------- /benchmark/sort_matrix_market.cpp: -------------------------------------------------------------------------------- 1 | // Copied from fast_matrix_market/examples/sort_matrix_market.cpp 2 | // Modifiled for integer-only column values to reduce memory use and improve performance on GAP data 3 | 4 | // Copyright (C) 2023 Adam Lugowski. All rights reserved. 5 | // Use of this source code is governed by the BSD 2-clause license found in the LICENSE.txt file. 6 | // SPDX-License-Identifier: BSD-2-Clause 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "timer.hpp" 16 | 17 | namespace fmm = fast_matrix_market; 18 | 19 | template 20 | void sort_file(const std::filesystem::path& in_path, const std::filesystem::path& out_path) { 21 | std::vector original_rows, sorted_rows; 22 | std::vector original_cols, sorted_cols; 23 | std::vector original_vals, sorted_vals; 24 | 25 | fmm::matrix_market_header header; 26 | timer total_time("Total time"); 27 | 28 | // Load 29 | { 30 | timer read_time("Reading"); 31 | //std::cout << "Reading " << in_path << std::endl; 32 | fmm::read_options options; 33 | options.generalize_symmetry = false; 34 | std::ifstream f(in_path); 35 | fmm::read_matrix_market_triplet(f, header, original_rows, original_cols, original_vals, options); 36 | } 37 | 38 | // Find sort permutation 39 | std::vector perm(original_rows.size()); 40 | { 41 | timer sort_time("Sorting"); 42 | //std::cout << "Sorting" << std::endl; 43 | std::iota(perm.begin(), perm.end(), 0); 44 | std::sort(perm.begin(), perm.end(), [&](std::size_t i, std::size_t j) { 45 | if (original_rows[i] != original_rows[j]) 46 | return original_rows[i] < original_rows[j]; 47 | if (original_cols[i] != original_cols[j]) 48 | return original_cols[i] < original_cols[j]; 49 | 50 | return false; 51 | }); 52 | } 53 | 54 | // Apply permutation 55 | { 56 | timer permute_time("Apply permutation"); 57 | //std::cout << "Applying permutation" << std::endl; 58 | sorted_rows.reserve(original_rows.size()); 59 | std::transform(perm.begin(), perm.end(), std::back_inserter(sorted_rows), [&](auto i) { return original_rows[i]; }); 60 | original_rows = std::vector(); 61 | 62 | sorted_cols.reserve(original_cols.size()); 63 | std::transform(perm.begin(), perm.end(), std::back_inserter(sorted_cols), [&](auto i) { return original_cols[i]; }); 64 | original_cols = std::vector(); 65 | 66 | sorted_vals.reserve(original_vals.size()); 67 | std::transform(perm.begin(), perm.end(), std::back_inserter(sorted_vals), [&](auto i) { return original_vals[i]; }); 68 | original_vals = std::vector(); 69 | } 70 | 71 | // Write 72 | { 73 | timer write_time("Writing"); 74 | //std::cout << "Writing " << out_path << std::endl; 75 | fmm::write_options options; 76 | options.fill_header_field_type = false; 77 | std::ofstream f(out_path); 78 | fmm::write_matrix_market_triplet(f, header, sorted_rows, sorted_cols, sorted_vals, options); 79 | } 80 | } 81 | 82 | 83 | int main(int argc, char** argv) { 84 | std::locale::global(std::locale("")); 85 | if (argc < 2) { 86 | std::cout << "Sort the elements of a .mtx file by coordinate (row, column)." << std::endl; 87 | std::cout << std::endl; 88 | std::cout << "Usage:" << std::endl; 89 | std::cout << argv[0] << " .mtx" << std::endl; 90 | std::cout << std::endl; 91 | std::cout << "will create a file named '.sorted.mtx' in the current working directory." << std::endl; 92 | return 0; 93 | } 94 | 95 | std::filesystem::path in_path{argv[1]}; 96 | std::filesystem::path out_path{argv[1]}; 97 | out_path.replace_extension(".sorted.mtx"); 98 | 99 | // find the type 100 | fmm::matrix_market_header header; 101 | { 102 | std::ifstream f(in_path); 103 | fmm::read_header(f, header); 104 | } 105 | 106 | if (header.format == fmm::array) { 107 | std::cout << "Array .mtx file is already sorted." << std::endl; 108 | return 0; 109 | } 110 | 111 | //sort_file(in_path, out_path); 112 | sort_file(in_path, 113 | out_path); // change value type to int64_t for performance & memory use on GAP data 114 | 115 | return 0; 116 | } 117 | -------------------------------------------------------------------------------- /benchmark/timer.cpp: -------------------------------------------------------------------------------- 1 | #include "timer.hpp" 2 | #include 3 | #include 4 | 5 | using std::cout; 6 | using std::endl; 7 | 8 | double simple_timer::elapsed() const { 9 | return std::chrono::duration_cast>(std::chrono::steady_clock::now() - start_time_) 10 | .count(); 11 | } 12 | 13 | timer::timer(const std::string& name, bool include_start) : name_(name), _include_start(include_start) { 14 | if (_include_start) 15 | fmt::print("{} started...", name_); 16 | reset(); 17 | } 18 | timer ::~timer() { output_ellapsed(); } 19 | 20 | void timer::reset() { start_time_ = std::chrono::steady_clock::now(); } 21 | 22 | double timer::elapsed() const { 23 | return std::chrono::duration_cast>(std::chrono::steady_clock::now() - start_time_) 24 | .count(); 25 | } 26 | 27 | void timer::set_count(int64_t count, const std::string_view& desc) { 28 | count_ = static_cast(count); 29 | count_name_ = desc; 30 | } 31 | 32 | // write the elapsed time to the console, including minutes and seconds, and total seconds 33 | // the seconds should be displayed with 3 decimal places 34 | void timer::output_ellapsed() { 35 | double seconds = elapsed(); 36 | double hr = trunc(seconds / 3600.); 37 | double min = trunc((seconds - hr * 3600.) / 60.); 38 | double sec = seconds - min * 60.; 39 | 40 | if (!_include_start) 41 | fmt::print("{}", name_); 42 | fmt::print(" took {}h{}m{:.0f}s ({:.3f})", hr, min, sec, seconds); 43 | if (count_ > 0) 44 | fmt::print(", {:.0Lf} {} at {:.0Lf} {}/sec", count_, count_name_, (count_ / seconds), count_name_); 45 | fmt::print("\n"); 46 | } 47 | -------------------------------------------------------------------------------- /benchmark/timer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | class simple_timer { 7 | std::chrono::steady_clock::time_point start_time_ = std::chrono::steady_clock::now(); 8 | 9 | public: 10 | simple_timer() = default; 11 | double elapsed() const; // seconds 12 | }; 13 | 14 | 15 | class timer { 16 | std::chrono::steady_clock::time_point start_time_ = std::chrono::steady_clock::now(); 17 | std::string name_; 18 | double count_ = 0; 19 | std::string count_name_; // e.g., "rows" 20 | bool _include_start = false; 21 | 22 | public: 23 | explicit timer(const std::string& name, bool include_start = false); 24 | ~timer(); 25 | 26 | double elapsed() const; // seconds 27 | 28 | void reset(); 29 | void set_count(int64_t count, const std::string_view& desc); 30 | void output_ellapsed(); 31 | }; 32 | -------------------------------------------------------------------------------- /cmake/CompilerWarnings.cmake: -------------------------------------------------------------------------------- 1 | # from here: 2 | # 3 | # https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md 4 | 5 | function(set_project_warnings project_name) 6 | option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" FALSE) 7 | 8 | set(MSVC_WARNINGS 9 | /W4 # Baseline reasonable warnings 10 | /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data 11 | /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data 12 | /w14263 # 'function': member function does not override any base class virtual member function 13 | /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not 14 | # be destructed correctly 15 | /w14287 # 'operator': unsigned/negative constant mismatch 16 | /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside 17 | # the for-loop scope 18 | /w14296 # 'operator': expression is always 'boolean_value' 19 | /w14311 # 'variable': pointer truncation from 'type1' to 'type2' 20 | /w14545 # expression before comma evaluates to a function which is missing an argument list 21 | /w14546 # function call before comma missing argument list 22 | /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect 23 | /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'? 24 | /w14555 # expression has no effect; expected expression with side- effect 25 | /w14619 # pragma warning: there is no warning number 'number' 26 | /w14640 # Enable warning on thread un-safe static member initialization 27 | /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior. 28 | /w14905 # wide string literal cast to 'LPSTR' 29 | /w14906 # string literal cast to 'LPWSTR' 30 | /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied 31 | /wd4100 # 'x': unreferenced formal parameter 32 | /wd4189 # 'x': local variable is initialized but not referenced 33 | /wd4459 # declaration of 'x' hides global declaration (in range-v3 sort) 34 | /D_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING 35 | ) 36 | 37 | set(CLANG_WARNINGS 38 | -Wall 39 | -Wextra # reasonable and standard 40 | -Wshadow # warn the user if a variable declaration shadows one from a parent context 41 | -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps 42 | # catch hard to track down memory errors 43 | -Wold-style-cast # warn for c-style casts 44 | -Wcast-align # warn for potential performance problem casts 45 | -Wunused # warn on anything being unused 46 | -Woverloaded-virtual # warn if you overload (not override) a virtual function 47 | -Wpedantic # warn if non-standard C++ is used 48 | -Wconversion # warn on type conversions that may lose data 49 | -Wsign-conversion # warn on sign conversions 50 | -Wnull-dereference # warn if a null dereference is detected 51 | -Wdouble-promotion # warn if float is implicit promoted to double 52 | -Wformat=2 # warn on security issues around functions that format output (ie printf) 53 | -Wimplicit-fallthrough # warn on statements that fallthrough without an explicit annotation 54 | -Wno-unused-variable 55 | -Wno-unused-parameter 56 | -Wno-unused-but-set-variable 57 | ) 58 | 59 | if (WARNINGS_AS_ERRORS) 60 | set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) 61 | set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX) 62 | endif() 63 | 64 | set(GCC_WARNINGS 65 | ${CLANG_WARNINGS} 66 | -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist 67 | -Wduplicated-cond # warn if if / else chain has duplicated conditions 68 | -Wduplicated-branches # warn if if / else branches have duplicated code 69 | -Wlogical-op # warn about logical operations being used where bitwise were probably wanted 70 | -Wuseless-cast # warn if you perform a cast to the same type 71 | -Wno-unused-variable 72 | -Wno-unused-parameter 73 | -Wno-unused-but-set-variable 74 | -ftemplate-backtrace-limit=30 75 | ) 76 | 77 | if(MSVC) 78 | set(PROJECT_WARNINGS ${MSVC_WARNINGS}) 79 | elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 80 | set(PROJECT_WARNINGS ${CLANG_WARNINGS}) 81 | elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 82 | set(PROJECT_WARNINGS ${GCC_WARNINGS}) 83 | else() 84 | message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") 85 | endif() 86 | 87 | target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) 88 | 89 | endfunction() 90 | -------------------------------------------------------------------------------- /cmake/Doxygen.cmake: -------------------------------------------------------------------------------- 1 | function(enable_doxygen) 2 | option(ENABLE_DOXYGEN "Enable doxygen doc builds of source" OFF) 3 | if(ENABLE_DOXYGEN) 4 | set(DOXYGEN_CALLER_GRAPH YES) 5 | set(DOXYGEN_CALL_GRAPH YES) 6 | set(DOXYGEN_EXTRACT_ALL YES) 7 | find_package(Doxygen REQUIRED dot) 8 | doxygen_add_docs(doxygen-docs ${PROJECT_SOURCE_DIR}) 9 | 10 | endif() 11 | endfunction() 12 | -------------------------------------------------------------------------------- /cmake/FetchBoost.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: boost") 5 | 6 | # See https://github.com/boostorg/cmake for documentation 7 | set(BOOST_ENABLE_CMAKE ON) 8 | set(BOOST_INCLUDE_LIBRARIES cobalt) # Identify the libraries we're using to minimize build time 9 | set(BOOST_ENABLE_MPI OFF) 10 | set(BOOST_ENABLE_PYTHON OFF) 11 | set(BUILD_SHARED_LIBS OFF) # We want static libraries 12 | 13 | FetchContent_Declare( 14 | boost 15 | GIT_REPOSITORY https://github.com/boostorg/boost.git 16 | GIT_TAG boost-1.84.0 17 | ) 18 | 19 | FetchContent_GetProperties(boost) 20 | if(NOT boost_POPULATED) 21 | FetchContent_Populate(boost) 22 | add_subdirectory( 23 | ${boost_SOURCE_DIR} 24 | ${boost_BINARY_DIR} 25 | EXCLUDE_FROM_ALL 26 | ) 27 | endif() 28 | 29 | set(BOOST_SOURCE_DIR "${boost_SOURCE_DIR}") 30 | # Defining BOOST_INCLUDE_DIR doesn't make sense because library in boost has its own include directory 31 | 32 | FetchContent_MakeAvailable(boost) 33 | -------------------------------------------------------------------------------- /cmake/FetchCSVParser.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: csv-parser") 5 | 6 | FetchContent_Declare( 7 | csv_parser 8 | GIT_REPOSITORY https://github.com/pratzl/csv-parser.git 9 | GIT_TAG 2.1.3 10 | ) 11 | FetchContent_MakeAvailable(csv_parser) 12 | 13 | set(CSVPARSER_INCLUDE_DIR "${csv_parser_SOURCE_DIR}/single_include") 14 | 15 | -------------------------------------------------------------------------------- /cmake/FetchCatch.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: catch2") 5 | 6 | FetchContent_Declare( 7 | catch2 8 | GIT_REPOSITORY https://github.com/catchorg/Catch2.git 9 | GIT_TAG v3.7.1 10 | ) 11 | FetchContent_MakeAvailable(catch2) 12 | set(CATCH2_SOURCE_DIR "${catch2_SOURCE_DIR}") 13 | set(CATCH2_INCLUDE_DIR "${catch2_INCLUDE_DIR}") 14 | 15 | -------------------------------------------------------------------------------- /cmake/FetchDocopt.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: docopt.cpp") 5 | 6 | FetchContent_Declare( 7 | docopt 8 | GIT_REPOSITORY https://github.com/docopt/docopt.cpp.git 9 | GIT_TAG v0.6.3 10 | ) 11 | FetchContent_MakeAvailable(docopt) 12 | set(DOCOPT_SOURCE_DIR "${docopt_SOURCE_DIR}") 13 | set(DOCOPT_INCLUDE_DIR "${docopt_INCLUDE_DIR}") 14 | 15 | -------------------------------------------------------------------------------- /cmake/FetchFMT.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: fmt") 5 | 6 | FetchContent_Declare( 7 | fmt 8 | GIT_REPOSITORY https://github.com/fmtlib/fmt.git 9 | GIT_TAG 11.0.2 10 | ) 11 | FetchContent_MakeAvailable(fmt) 12 | set(FMT_SOURCE_DIR "${fmt_SOURCE_DIR}") 13 | set(FMT_INCLUDE_DIR "${fmt_INCLUDE_DIR}") 14 | 15 | 16 | -------------------------------------------------------------------------------- /cmake/FetchFastMM.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: fast_matrix_market") 5 | 6 | FetchContent_Declare( 7 | fast_matrix_market 8 | GIT_REPOSITORY https://github.com/alugowski/fast_matrix_market 9 | GIT_TAG main 10 | GIT_SHALLOW TRUE 11 | ) 12 | FetchContent_MakeAvailable(fast_matrix_market) 13 | #set(FMT_SOURCE_DIR "${fmt_SOURCE_DIR}") 14 | #set(FMT_INCLUDE_DIR "${fmt_INCLUDE_DIR}") 15 | 16 | #target_link_libraries(YOUR_TARGET fast_matrix_market::fast_matrix_market) 17 | -------------------------------------------------------------------------------- /cmake/FetchRange.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: range-v3") 5 | 6 | FetchContent_Declare( 7 | range 8 | GIT_REPOSITORY https://github.com/ericniebler/range-v3.git 9 | GIT_TAG 0.11.0 10 | ) 11 | FetchContent_MakeAvailable(range) 12 | set(RANGE_SOURCE_DIR "${range_SOURCE_DIR}") 13 | set(RANGE_INCLUDE_DIR "${range_INCLUDE_DIR}") 14 | 15 | -------------------------------------------------------------------------------- /cmake/FetchSPDLog.cmake: -------------------------------------------------------------------------------- 1 | include(FetchContent) 2 | set(FETCHCONTENT_QUIET ON) 3 | 4 | message(STATUS "Cloning External Project: spdlog") 5 | 6 | FetchContent_Declare( 7 | spdlog 8 | GIT_REPOSITORY https://github.com/gabime/spdlog.git 9 | GIT_TAG v1.9.2 10 | ) 11 | FetchContent_MakeAvailable(spdlog) 12 | set(SPDLOG_SOURCE_DIR "${spdlog_SOURCE_DIR}") 13 | set(SPDLOG_INCLUDE_DIR "${spdlog_INCLUDE_DIR}") 14 | 15 | -------------------------------------------------------------------------------- /cmake/Linker.cmake: -------------------------------------------------------------------------------- 1 | option(ENABLE_USER_LINKER "Enable a specific linker if available" OFF) 2 | 3 | include(CheckCXXCompilerFlag) 4 | 5 | set(USER_LINKER_OPTION 6 | "lld" 7 | CACHE STRING "Linker to be used") 8 | set(USER_LINKER_OPTION_VALUES "lld" "gold" "bfd") 9 | set_property(CACHE USER_LINKER_OPTION PROPERTY STRINGS ${USER_LINKER_OPTION_VALUES}) 10 | list( 11 | FIND 12 | USER_LINKER_OPTION_VALUES 13 | ${USER_LINKER_OPTION} 14 | USER_LINKER_OPTION_INDEX) 15 | 16 | if(${USER_LINKER_OPTION_INDEX} EQUAL -1) 17 | message( 18 | STATUS 19 | "Using custom linker: '${USER_LINKER_OPTION}', explicitly supported entries are ${USER_LINKER_OPTION_VALUES}") 20 | endif() 21 | 22 | function(configure_linker project_name) 23 | if(NOT ENABLE_USER_LINKER) 24 | return() 25 | endif() 26 | 27 | set(LINKER_FLAG "-fuse-ld=${USER_LINKER_OPTION}") 28 | 29 | check_cxx_compiler_flag(${LINKER_FLAG} CXX_SUPPORTS_USER_LINKER) 30 | if(CXX_SUPPORTS_USER_LINKER) 31 | target_compile_options(${project_name} INTERFACE ${LINKER_FLAG}) 32 | endif() 33 | endfunction() 34 | -------------------------------------------------------------------------------- /cmake/PreventInSourceBuilds.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # This function will prevent in-source builds 3 | function(AssureOutOfSourceBuilds) 4 | # make sure the user doesn't play dirty with symlinks 5 | get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH) 6 | get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH) 7 | 8 | # disallow in-source builds 9 | if("${srcdir}" STREQUAL "${bindir}") 10 | message("######################################################") 11 | message("Warning: in-source builds are disabled") 12 | message("Please create a separate build directory and run cmake from there") 13 | message("######################################################") 14 | message(FATAL_ERROR "Quitting configuration") 15 | endif() 16 | endfunction() 17 | 18 | assureoutofsourcebuilds() 19 | -------------------------------------------------------------------------------- /cmake/Sanitizers.cmake: -------------------------------------------------------------------------------- 1 | function(enable_sanitizers project_name) 2 | 3 | if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 4 | option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" OFF) 5 | 6 | if(ENABLE_COVERAGE) 7 | target_compile_options(${project_name} INTERFACE --coverage -O0 -g) 8 | target_link_libraries(${project_name} INTERFACE --coverage) 9 | endif() 10 | 11 | set(SANITIZERS "") 12 | 13 | option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" OFF) 14 | if(ENABLE_SANITIZER_ADDRESS) 15 | list(APPEND SANITIZERS "address") 16 | endif() 17 | 18 | option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" OFF) 19 | if(ENABLE_SANITIZER_LEAK) 20 | list(APPEND SANITIZERS "leak") 21 | endif() 22 | 23 | option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" OFF) 24 | if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) 25 | list(APPEND SANITIZERS "undefined") 26 | endif() 27 | 28 | option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" OFF) 29 | if(ENABLE_SANITIZER_THREAD) 30 | if("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) 31 | message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled") 32 | else() 33 | list(APPEND SANITIZERS "thread") 34 | endif() 35 | endif() 36 | 37 | option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" OFF) 38 | if(ENABLE_SANITIZER_MEMORY AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 39 | message(WARNING "Memory sanitizer requires all the code (including libc++) to be MSan-instrumented otherwise it reports false positives") 40 | if("address" IN_LIST SANITIZERS 41 | OR "thread" IN_LIST SANITIZERS 42 | OR "leak" IN_LIST SANITIZERS) 43 | message(WARNING "Memory sanitizer does not work with Address, Thread and Leak sanitizer enabled") 44 | else() 45 | list(APPEND SANITIZERS "memory") 46 | endif() 47 | endif() 48 | 49 | list( 50 | JOIN 51 | SANITIZERS 52 | "," 53 | LIST_OF_SANITIZERS) 54 | 55 | endif() 56 | 57 | if(LIST_OF_SANITIZERS) 58 | if(NOT 59 | "${LIST_OF_SANITIZERS}" 60 | STREQUAL 61 | "") 62 | target_compile_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) 63 | target_link_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) 64 | endif() 65 | endif() 66 | 67 | endfunction() 68 | -------------------------------------------------------------------------------- /cmake/StandardProjectSettings.cmake: -------------------------------------------------------------------------------- 1 | # Set a default build type if none was specified 2 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 3 | message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") 4 | set(CMAKE_BUILD_TYPE 5 | RelWithDebInfo 6 | CACHE STRING "Choose the type of build." FORCE) 7 | # Set the possible values of build type for cmake-gui, ccmake 8 | set_property( 9 | CACHE CMAKE_BUILD_TYPE 10 | PROPERTY STRINGS 11 | "Debug" 12 | "Release" 13 | "MinSizeRel" 14 | "RelWithDebInfo") 15 | endif() 16 | 17 | # Generate compile_commands.json to make it easier to work with clang based tools 18 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 19 | 20 | option(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF) 21 | 22 | if(ENABLE_IPO) 23 | include(CheckIPOSupported) 24 | check_ipo_supported( 25 | RESULT 26 | result 27 | OUTPUT 28 | output) 29 | if(result) 30 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) 31 | else() 32 | message(SEND_ERROR "IPO is not supported: ${output}") 33 | endif() 34 | endif() 35 | if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") 36 | add_compile_options(-fcolor-diagnostics) 37 | elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 38 | add_compile_options(-fdiagnostics-color=always) 39 | else() 40 | message(STATUS "No colored compiler diagnostic set for '${CMAKE_CXX_COMPILER_ID}' compiler.") 41 | endif() 42 | 43 | -------------------------------------------------------------------------------- /cmake/StaticAnalyzers.cmake: -------------------------------------------------------------------------------- 1 | option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF) 2 | option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF) 3 | option(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF) 4 | 5 | if(ENABLE_CPPCHECK) 6 | find_program(CPPCHECK cppcheck) 7 | if(CPPCHECK) 8 | set(CMAKE_CXX_CPPCHECK 9 | ${CPPCHECK} 10 | --suppress=missingInclude 11 | --enable=all 12 | --inline-suppr 13 | --inconclusive 14 | -i 15 | ${CMAKE_SOURCE_DIR}/imgui/lib) 16 | if(WARNINGS_AS_ERRORS) 17 | list(APPEND CMAKE_CXX_CPPCHECK --error-exitcode=2) 18 | endif() 19 | else() 20 | message(SEND_ERROR "cppcheck requested but executable not found") 21 | endif() 22 | endif() 23 | 24 | if(ENABLE_CLANG_TIDY) 25 | find_program(CLANGTIDY clang-tidy) 26 | if(CLANGTIDY) 27 | set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) 28 | if(WARNINGS_AS_ERRORS) 29 | list(APPEND CMAKE_CXX_CLANG_TIDY -warnings-as-errors=*) 30 | endif() 31 | else() 32 | message(SEND_ERROR "clang-tidy requested but executable not found") 33 | endif() 34 | endif() 35 | 36 | if(ENABLE_INCLUDE_WHAT_YOU_USE) 37 | find_program(INCLUDE_WHAT_YOU_USE include-what-you-use) 38 | if(INCLUDE_WHAT_YOU_USE) 39 | set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${INCLUDE_WHAT_YOU_USE}) 40 | else() 41 | message(SEND_ERROR "include-what-you-use requested but executable not found") 42 | endif() 43 | endif() 44 | -------------------------------------------------------------------------------- /data/bktest1.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate real general 2 | %------------------------------------------------------------------------------- 3 | 12 12 34 4 | 1 2 5 5 | 2 1 5 6 | 2 3 10 7 | 3 2 10 8 | 4 5 10 9 | 5 4 10 10 | 5 6 5 11 | 6 5 5 12 | 7 8 5 13 | 8 7 5 14 | 8 9 10 15 | 9 8 10 16 | 10 11 10 17 | 11 10 10 18 | 11 12 5 19 | 12 11 5 20 | 1 4 5 21 | 4 1 5 22 | 4 7 10 23 | 7 4 10 24 | 7 10 5 25 | 10 7 5 26 | 2 5 10 27 | 5 2 10 28 | 5 8 5 29 | 8 5 5 30 | 8 11 10 31 | 11 8 10 32 | 3 6 5 33 | 6 3 5 34 | 6 9 10 35 | 9 6 10 36 | 9 12 5 37 | 12 9 5 38 | -------------------------------------------------------------------------------- /data/bktest2.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate real general 2 | %------------------------------------------------------------------------------- 3 | 27 27 50 4 | 1 2 5 5 | 2 3 10 6 | 3 4 5 7 | 4 5 10 8 | 6 7 10 9 | 7 8 5 10 | 8 9 10 11 | 9 10 5 12 | 11 12 10 13 | 12 13 15 14 | 13 14 10 15 | 14 15 15 16 | 16 17 20 17 | 17 18 25 18 | 18 19 20 19 | 19 20 25 20 | 21 22 30 21 | 22 23 35 22 | 23 24 30 23 | 24 25 35 24 | 1 6 5 25 | 6 11 10 26 | 11 16 15 27 | 16 21 20 28 | 2 7 5 29 | 7 12 10 30 | 12 17 15 31 | 17 22 20 32 | 3 8 5 33 | 8 13 10 34 | 13 18 15 35 | 18 23 20 36 | 4 9 5 37 | 9 14 10 38 | 14 19 15 39 | 19 24 20 40 | 5 10 5 41 | 10 15 10 42 | 15 20 15 43 | 20 25 20 44 | 26 1 30 45 | 26 6 30 46 | 26 11 30 47 | 26 16 30 48 | 26 21 30 49 | 5 27 20 50 | 10 27 20 51 | 15 27 20 52 | 20 27 20 53 | 25 27 20 54 | -------------------------------------------------------------------------------- /data/cc_directed.csv: -------------------------------------------------------------------------------- 1 | From,To,Distance 2 | A,B,1 3 | B,C,1 4 | C,D,1 5 | D,A,1 6 | B,E,1 7 | E,F,1 8 | F,G,1 9 | G,H,1 10 | H,E,1 11 | G,Q,1 12 | Q,N,1 13 | N,O,1 14 | O,P,1 15 | P,M,1 16 | M,R,1 17 | R,H,1 18 | J,R,1 19 | J,K,1 20 | K,L,1 21 | L,I,1 22 | I,J,1 23 | -------------------------------------------------------------------------------- /data/cc_undirected.csv: -------------------------------------------------------------------------------- 1 | From,To,Distance 2 | A,H,1 3 | H,A,1 4 | B,C,1 5 | C,B,1 6 | B,F,1 7 | F,B,1 8 | B,G,1 9 | G,B,1 10 | C,F,1 11 | F,C,1 12 | D,E,1 13 | E,D,1 14 | H,I,1 15 | I,H,1 16 | -------------------------------------------------------------------------------- /data/germany_routes.csv: -------------------------------------------------------------------------------- 1 | From,To,Distance 2 | Frankfürt,Mannheim,85 3 | Frankfürt,Würzburg,217 4 | Frankfürt,Kassel,173 5 | Mannheim,Karlsruhe,80 6 | Karlsruhe,Augsburg,250 7 | Augsburg,München,84 8 | Würzburg,Erfurt,186 9 | Würzburg,Nürnberg,103 10 | Nürnberg,Stuttgart,183 11 | Nürnberg,München,167 12 | Kassel,München,502 13 | -------------------------------------------------------------------------------- /data/karate.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate pattern symmetric 2 | %------------------------------------------------------------------------------- 3 | % UF Sparse Matrix Collection, Tim Davis 4 | % http://www.cise.ufl.edu/research/sparse/matrices/Newman/karate 5 | % name: Newman/karate 6 | % [Karate club, from Wayne Zachary, 1977] 7 | % id: 2399 8 | % date: 1977 9 | % author: W. Zachary 10 | % ed: M. Newman 11 | % fields: name title A id date author kind notes ed 12 | % kind: undirected graph 13 | %------------------------------------------------------------------------------- 14 | % notes: 15 | % Network collection from M. Newman 16 | % http://www-personal.umich.edu/~mejn/netdata/ 17 | % 18 | % The graph "karate" contains the network of friendships between the 34 19 | % members of a karate club at a US university, as described by Wayne Zachary 20 | % in 1977. If you use these data in your work, please cite W. W. Zachary, An 21 | % information flow model for conflict and fission in small groups, Journal of 22 | % Anthropological Research 33, 452-473 (1977). 23 | %------------------------------------------------------------------------------- 24 | 34 34 78 25 | 2 1 26 | 3 1 27 | 4 1 28 | 5 1 29 | 6 1 30 | 7 1 31 | 8 1 32 | 9 1 33 | 11 1 34 | 12 1 35 | 13 1 36 | 14 1 37 | 18 1 38 | 20 1 39 | 22 1 40 | 32 1 41 | 3 2 42 | 4 2 43 | 8 2 44 | 14 2 45 | 18 2 46 | 20 2 47 | 22 2 48 | 31 2 49 | 4 3 50 | 8 3 51 | 9 3 52 | 10 3 53 | 14 3 54 | 28 3 55 | 29 3 56 | 33 3 57 | 8 4 58 | 13 4 59 | 14 4 60 | 7 5 61 | 11 5 62 | 7 6 63 | 11 6 64 | 17 6 65 | 17 7 66 | 31 9 67 | 33 9 68 | 34 9 69 | 34 10 70 | 34 14 71 | 33 15 72 | 34 15 73 | 33 16 74 | 34 16 75 | 33 19 76 | 34 19 77 | 34 20 78 | 33 21 79 | 34 21 80 | 33 23 81 | 34 23 82 | 26 24 83 | 28 24 84 | 30 24 85 | 33 24 86 | 34 24 87 | 26 25 88 | 28 25 89 | 32 25 90 | 32 26 91 | 30 27 92 | 34 27 93 | 34 28 94 | 32 29 95 | 34 29 96 | 33 30 97 | 34 30 98 | 33 31 99 | 34 31 100 | 33 32 101 | 34 32 102 | 34 33 103 | -------------------------------------------------------------------------------- /data/tc_test.csv: -------------------------------------------------------------------------------- 1 | FROM,TO,DIST 2 | A,B,1 3 | A,C,1 4 | A,D,1 5 | A,E,1 6 | B,C,1 7 | B,D,1 8 | B,E,1 9 | B,F,1 10 | C,D,1 11 | C,E,1 12 | D,E,1 13 | E,F,1 14 | E,G,1 15 | F,H,1 16 | G,H,1 17 | -------------------------------------------------------------------------------- /doc/Identifiers.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/doc/Identifiers.docx -------------------------------------------------------------------------------- /docs/sphinx/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf8 -*- 2 | ######################################################################################## 3 | # This file is part of exhale. Copyright (c) 2017-2022, Stephen McDowell. # 4 | # Full BSD 3-Clause license available here: # 5 | # # 6 | # https://github.com/svenevs/exhale/blob/master/LICENSE # 7 | ######################################################################################## 8 | 9 | from __future__ import unicode_literals 10 | 11 | __version__ = "0.3.1" 12 | 13 | 14 | def environment_ready(app): 15 | # Defer importing configs until sphinx is running. 16 | from . import configs 17 | from . import utils 18 | from . import deploy 19 | # First, setup the extension and verify all of the configurations. 20 | configs.apply_sphinx_configurations(app) 21 | ####### Next, perform any cleanup 22 | 23 | # Generate the full API! 24 | try: 25 | deploy.explode() 26 | except: 27 | utils.fancyError("Exhale: could not generate reStructuredText documents :/") 28 | 29 | 30 | # TODO: 31 | # This is not the correct event for cleanup of this project, as we want to allow the 32 | # users to view the generated reStructuredText / Doxygen xml. What needs to be done is 33 | # figure out how to hook an extension into `make clean`. It does not appear to be 34 | # possible at this point in time? 35 | def cleanup_files(app, env, docname): 36 | raise RuntimeError("you made it.") 37 | 38 | 39 | def setup(app): 40 | app.setup_extension("breathe") 41 | app.add_config_value("exhale_args", {}, "env") 42 | 43 | app.connect("builder-inited", environment_ready) 44 | # app.connect("env-purge-doc", cleanup_files) 45 | 46 | return { 47 | "version": __version__, 48 | # Because Exhale hooks into / generates *BEFORE* any reading or writing occurs, 49 | # it is parallel safe by default. 50 | "parallel_read_safe": True, 51 | "parallel_write_safe": True 52 | } 53 | -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView-bootstrap/bootstrap-treeview/apply-bootstrap-treview.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | // apply the class view hierarchy 3 | $("#class-treeView").treeview({ 4 | data: getClassViewTree(), 5 | enableLinks: true 6 | }); 7 | 8 | // apply the directory view hierarchy 9 | $("#directory-treeView").treeview({ 10 | data: getDirectoryViewTree(), 11 | enableLinks: true 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView-bootstrap/bootstrap-treeview/bootstrap-treeview.min.css: -------------------------------------------------------------------------------- 1 | .treeview .list-group-item{cursor:pointer}.treeview span.indent{margin-left:10px;margin-right:10px}.treeview span.icon{width:12px;margin-right:5px}.treeview .node-disabled{color:silver;cursor:not-allowed} -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/LICENSE.md: -------------------------------------------------------------------------------- 1 | This code is the fruit of Kate Morley's labor, taken from here: 2 | 3 | - http://code.iamkate.com/javascript/collapsible-lists/ 4 | 5 | She includes a generous CC0 1.0 license for all materials on her site: 6 | 7 | - http://code.iamkate.com/ 8 | -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/button-closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/button-closed.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/button-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/button-open.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/button.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-contents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-contents.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-last-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-last-open.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-last.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-last.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-open.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item-root.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stdgraph/graph-v2/3411334bccc69fc02e48aaf10fa2b0702a515ca2/docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/list-item.png -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/css/tree_view.css: -------------------------------------------------------------------------------- 1 | /* Source taken directly from: 2 | * view-source:http://code.iamkate.com/javascript/collapsible-lists/ 3 | * 4 | * Kate Morley's license for this code is CC0: 5 | * Created by [Kate Morley](http://iamkate.com/). Except where explicitly 6 | * stated otherwise, all content is released under the terms of the 7 | * [CC0 1.0 Universal legal code](http://creativecommons.org/publicdomain/zero/1.0/legalcode). 8 | */ 9 | .treeView{ 10 | -moz-user-select:none; 11 | position:relative; 12 | } 13 | 14 | .treeView ul{ 15 | margin:0 0 0 -1.5em ! important; 16 | padding:0 0 0 1.5em ! important; 17 | } 18 | 19 | .treeView ul ul{ 20 | background:url('list-item-contents.png') repeat-y left ! important; 21 | } 22 | 23 | .treeView li.lastChild > ul{ 24 | background-image:none ! important; 25 | } 26 | 27 | .treeView li{ 28 | margin:0 ! important; 29 | padding:0 ! important; 30 | background:url('list-item-root.png') no-repeat top left ! important; 31 | list-style-position:inside ! important; 32 | list-style-image:url('button.png') ! important; 33 | cursor:auto; 34 | } 35 | 36 | .treeView li.collapsibleListOpen{ 37 | list-style-image:url('button-open.png') ! important; 38 | cursor:pointer; 39 | } 40 | 41 | .treeView li.collapsibleListClosed{ 42 | list-style-image:url('button-closed.png') ! important; 43 | cursor:pointer; 44 | } 45 | 46 | .treeView li li{ 47 | background-image:url('list-item.png') ! important; 48 | padding-left:1.5em ! important; 49 | } 50 | 51 | .treeView li.lastChild{ 52 | background-image:url('list-item-last.png') ! important; 53 | } 54 | 55 | .treeView li.collapsibleListOpen{ 56 | background-image:url('list-item-open.png') ! important; 57 | } 58 | 59 | .treeView li.collapsibleListOpen.lastChild{ 60 | background-image:url('list-item-last-open.png') ! important; 61 | } 62 | -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/js/CollapsibleLists.compressed.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | CollapsibleLists.js 4 | 5 | An object allowing lists to dynamically expand and collapse 6 | 7 | Created by Kate Morley - http://code.iamkate.com/ - and released under 8 | the terms of the CC0 1.0 Universal legal code: 9 | 10 | http://creativecommons.org/publicdomain/zero/1.0/legalcode 11 | 12 | */ 13 | 14 | var CollapsibleLists=new function(){ 15 | this.apply=function(_1){ 16 | var _2=document.getElementsByTagName("ul"); 17 | for(var _3=0;_3<_2.length;_3++){ 18 | if(_2[_3].className.match(/(^| )collapsibleList( |$)/)){ 19 | this.applyTo(_2[_3],true); 20 | if(!_1){ 21 | var _4=_2[_3].getElementsByTagName("ul"); 22 | for(var _5=0;_5<_4.length;_5++){ 23 | _4[_5].className+=" collapsibleList"; 24 | } 25 | } 26 | } 27 | } 28 | }; 29 | this.applyTo=function(_6,_7){ 30 | var _8=_6.getElementsByTagName("li"); 31 | for(var _9=0;_9<_8.length;_9++){ 32 | if(!_7||_6==_8[_9].parentNode){ 33 | if(_8[_9].addEventListener){ 34 | _8[_9].addEventListener("mousedown",function(e){ 35 | e.preventDefault(); 36 | },false); 37 | }else{ 38 | _8[_9].attachEvent("onselectstart",function(){ 39 | event.returnValue=false; 40 | }); 41 | } 42 | if(_8[_9].addEventListener){ 43 | _8[_9].addEventListener("click",_a(_8[_9]),false); 44 | }else{ 45 | _8[_9].attachEvent("onclick",_a(_8[_9])); 46 | } 47 | _b(_8[_9]); 48 | } 49 | } 50 | }; 51 | function _a(_c){ 52 | return function(e){ 53 | if(!e){ 54 | e=window.event; 55 | } 56 | var _d=(e.target?e.target:e.srcElement); 57 | while(_d.nodeName!="LI"){ 58 | _d=_d.parentNode; 59 | } 60 | if(_d==_c){ 61 | _b(_c); 62 | } 63 | }; 64 | }; 65 | function _b(_e){ 66 | var _f=_e.className.match(/(^| )collapsibleListClosed( |$)/); 67 | var uls=_e.getElementsByTagName("ul"); 68 | for(var _10=0;_100){ 79 | _e.className+=" collapsibleList"+(_f?"Open":"Closed"); 80 | } 81 | }; 82 | }(); 83 | 84 | -------------------------------------------------------------------------------- /docs/sphinx/_extensions/nw_exhale/data/treeView/collapsible-lists/js/apply-collapsible-lists.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | CollapsibleLists.apply(); 3 | }); 4 | -------------------------------------------------------------------------------- /docs/sphinx/_static/css/custom.css: -------------------------------------------------------------------------------- 1 | .tight-table td { 2 | white-space: normal !important; 3 | } 4 | 5 | .sig.sig-object.cpp { 6 | background: #f2f2f2 !important; 7 | color: #555555 !important; 8 | border-top: 3px solid #777777 !important; 9 | } 10 | 11 | .sig.sig-object.cpp .k .pre { color: #AA22FF; font-weight: bold; font-style: normal } /* Keyword */ 12 | .kt { color: #00A000; font-weight: bold } /* Keyword.Type */ 13 | .p { color: #666666 } /* Operator */ 14 | .sig.sig-object.cpp .n .pre { color: #444444; } 15 | .sig.sig-object.cpp .sig-name.descname .n .pre { color: #0000FF; } 16 | .sig.sig-object.cpp .sig-prename.descclassname .n .pre { color: #0000FF;} 17 | 18 | /* Newlines (\a) and spaces (\20) before each parameter */ 19 | .sig-param::before { 20 | content: "\a\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20"; 21 | white-space: pre; 22 | } 23 | 24 | /* Newline after the last parameter (so the closing bracket is on a new line) */ 25 | dt em.sig-param:last-of-type::after { 26 | content: "\a"; 27 | white-space: pre; 28 | } 29 | 30 | /* To have blue background of width of the block (instead of width of content) */ 31 | dl.class > dt:first-of-type { 32 | display: block !important; 33 | } -------------------------------------------------------------------------------- /docs/sphinx/_templates/layout.html: -------------------------------------------------------------------------------- 1 | {% if meta is defined and meta is not none and meta.layout is defined%} 2 | {%- extends (meta.layout+".html")|default('!layout.html') %} 3 | {% else %} 4 | {%- extends "!layout.html" %} 5 | {% endif %} -------------------------------------------------------------------------------- /docs/sphinx/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | import os 14 | import sys 15 | import textwrap 16 | 17 | sys.path.insert(0, os.path.abspath('.')) 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = 'graph-v2' 23 | copyright = '2022, Phil Ratzloff, Andrew Lumsdaine, Kevin Deweese, Muhammad Osama' 24 | author = 'Phil Ratzloff, Andrew Lumsdaine, Kevin Deweese, Muhammad Osama' 25 | 26 | # The full version, including alpha/beta/rc tags 27 | release = '0.8.30' 28 | 29 | 30 | # -- General configuration --------------------------------------------------- 31 | 32 | sys.path.append(os.path.abspath('_extensions')) 33 | 34 | # Add any Sphinx extension module names here, as strings. They can be 35 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 36 | # ones. 37 | extensions = [ 38 | 'sphinx.ext.mathjax', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode', 'sphinx.ext.graphviz', 39 | 'sphinxcontrib.bibtex', 40 | 'sphinx_toolbox.more_autodoc.overloads', 41 | # 'sphinx_book_theme', 42 | #'sphinx_rtd_theme', 43 | 'breathe', 44 | 'nw_exhale', 45 | 'myst_parser' 46 | ] 47 | 48 | source_suffix = { 49 | '.md': 'markdown', 50 | '.rst': 'restructuredtext', 51 | } 52 | 53 | # Add any paths that contain templates here, relative to this directory. 54 | templates_path = ['_templates', '_layouts', '_includes'] 55 | 56 | # List of patterns, relative to source directory, that match files and 57 | # directories to ignore when looking for source files. 58 | # This pattern also affects html_static_path and html_extra_path. 59 | exclude_patterns = [ 60 | '_build', 'Thumbs.db', '.DS_Store', '_api', '_bpi' 61 | ] 62 | 63 | highlight_language = 'c++' 64 | pygments_style = 'emacs' 65 | 66 | # Enable numref 67 | numfig = True 68 | 69 | # -- Options for MathJax ----------------------------------------------------- 70 | 71 | mathjax_options = { 72 | } 73 | mathjax3_config = { 74 | 'TeX': { 75 | 'Macros': { 76 | 'RR': "{\\mathbb R}", 77 | 'Real': "{\\mathbb R}", 78 | 'Complex': "{\\mathbb C}", 79 | 'mat' :["{\\mathbf{#1}}",1], 80 | 'vec' :["{\\mathbf{#1}}",1], 81 | 'bold': ["{\\bf #1}",1], 82 | 'Spc': ["\\mathbb{#1}",1], 83 | 'norm': ["|| #1 ||",1] 84 | } 85 | } 86 | } 87 | 88 | 89 | # -- Options for HTML output ------------------------------------------------- 90 | 91 | html_theme_path = [ "_themes" ] 92 | #html_theme = 'sphinx13' 93 | html_theme = 'sphinx_rtd_theme' 94 | # html_theme = 'sphinx_book_theme' 95 | html_title = "graph Documentation" 96 | 97 | # Add any paths that contain custom static files (such as style sheets) here, 98 | # relative to this directory. They are copied after the builtin static files, 99 | # so a file named "default.css" will overwrite the builtin "default.css". 100 | html_static_path = ['_static'] 101 | 102 | html_css_files = [ 103 | 'css/custom.css' 104 | ] 105 | 106 | html_theme_options = { 107 | "repository_url": "https://github.com/stdgraph/graph-v2", 108 | } 109 | 110 | # html_favicon = nwgraph.ico 111 | # html_additional_pages = [] 112 | # html_copy_source = True 113 | # html_show_source_link = True 114 | 115 | # -- Options for the C++ Domain ---------------------------------------------- 116 | 117 | cpp_index_common_prefix = ['std::', 'graph::'] 118 | 119 | 120 | # -- Options for Breathe ----------------------------------------------------- 121 | 122 | #sys.path.append('_breathe') 123 | 124 | breathe_projects = { "graph-v2": "./_doxygen/xml"} 125 | breathe_default_project = "graph-v2" 126 | 127 | #breathe_projects_source = { 128 | # "graph-v2" : "../../include" 129 | #} 130 | 131 | # Tell sphinx what the primary language being documented is. 132 | primary_domain = 'cpp' 133 | 134 | todo_include_todos = False 135 | 136 | 137 | # -- Options for Exhale ------------------------------------------------------ 138 | 139 | # Setup the exhale extension 140 | exhale_args = { 141 | # These arguments are required 142 | "containmentFolder": "./_api", 143 | "rootFileName": "library_root.rst", 144 | "doxygenStripFromPath": "../..", 145 | # Heavily encouraged optional argument (see docs) 146 | "rootFileTitle": "graph-v2 API", 147 | # Suggested optional arguments 148 | "createTreeView": True, 149 | # TIP: if using the sphinx-bootstrap-theme, you need 150 | # "treeViewIsBootstrap": True, 151 | "exhaleExecutesDoxygen": True, 152 | "exhaleDoxygenStdin": textwrap.dedent(''' 153 | INPUT = ../../include 154 | CLANG_ASSISTED_PARSING = YES 155 | CLANG_OPTIONS = -std=c++20 156 | CLANG_DATABASE_PATH = ../../build/ 157 | BUILTIN_STL_SUPPORT = YES 158 | EXTRACT_ALL = NO 159 | GENERATE_HTML = YES 160 | HIDE_UNDOC_CLASSES = YES 161 | HIDE_UNDOC_MEMBERS = YES 162 | LAYOUT_FILE = "/Users/lums/Contrib/stdgraph/graph-v2/docs/sphinx/layout.xml" 163 | HTML_COLORSTYLE_HUE = 75 164 | HTML_DYNAMIC_SECTIONS = YES 165 | HTML_INDEX_NUM_ENTRIES = 0 166 | DISABLE_INDEX = YES 167 | GENERATE_TREEVIEW = YES 168 | TREEVIEW_WIDTH = 270 169 | '''), 170 | # "verboseBuild": True, 171 | "listingExclude": [ r'.*_tag_invoke*', 'edge_list_c' ], 172 | "unabridgedOrphanKinds": { "namespace", "page" } 173 | } 174 | 175 | 176 | # -- Options for bibtex -- --------------------------------------------------- 177 | 178 | bibtex_bibfiles = ['userguide/refs.bib'] 179 | -------------------------------------------------------------------------------- /docs/sphinx/graph-v2-api.rst: -------------------------------------------------------------------------------- 1 | 2 | Graph-V2 API Reference 3 | ====================== 4 | 5 | .. highlight:: c++ 6 | 7 | 8 | Concepts 9 | -------- 10 | 11 | .. doxygenconcept:: graph::vertex_range 12 | 13 | .. doxygenconcept:: graph::targeted_edge 14 | 15 | .. doxygenconcept:: graph::sourced_edge 16 | 17 | .. doxygenconcept:: graph::adjacency_list 18 | 19 | .. doxygenconcept:: graph::sourced_adjacency_list 20 | 21 | .. doxygenconcept:: graph::has_degree 22 | 23 | .. doxygenconcept:: graph::has_find_vertex 24 | 25 | .. doxygenconcept:: graph::has_contains_edge 26 | 27 | .. doxygenconcept:: graph::ordered_edge 28 | 29 | .. doxygenconcept:: graph::unordered_edge 30 | 31 | 32 | -------------------------------- 33 | 34 | -------------------------------- 35 | 36 | 37 | Algorithms 38 | ---------- 39 | 40 | .. doxygenfunction:: graph::dijkstra_shortest_distances 41 | 42 | .. doxygenfunction:: graph::dijkstra_shortest_paths 43 | 44 | .. doxygenfunction:: graph::bellman_ford_shortest_distances 45 | 46 | .. doxygenfunction:: graph::bellman_ford_shortest_paths 47 | 48 | -------------------------------- 49 | 50 | -------------------------------- 51 | 52 | 53 | Data Structures 54 | --------------- 55 | 56 | -------------------------------- 57 | 58 | -------------------------------- 59 | 60 | 61 | Views / Adaptors 62 | ---------------- 63 | 64 | -------------------------------- 65 | 66 | -------------------------------- 67 | 68 | 69 | Graph Construction 70 | ------------------ 71 | 72 | -------------------------------- 73 | 74 | -------------------------------- 75 | 76 | 77 | Graph I/O 78 | --------- 79 | 80 | -------------------------------- 81 | 82 | -------------------------------- 83 | 84 | 85 | Utilities 86 | --------- 87 | 88 | -------------------------------- 89 | 90 | -------------------------------- 91 | -------------------------------------------------------------------------------- /docs/sphinx/index.rst: -------------------------------------------------------------------------------- 1 | .. graph-v2 documentation master file, created by 2 | sphinx-quickstart on Tue Aug 30 09:09:16 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | ==================================== 7 | Welcome to graph-v2's documentation! 8 | ==================================== 9 | 10 | .. toctree:: 11 | :maxdepth: 2 12 | :caption: Contents: 13 | 14 | 15 | 16 | ================= 17 | Reference Manual 18 | ================= 19 | 20 | .. toctree:: 21 | :maxdepth: 2 22 | 23 | graph-v2-api.rst 24 | 25 | 26 | 27 | .. api/library_root 28 | .. doxyref/index.rst 29 | 30 | 31 | 32 | ================== 33 | Indices and tables 34 | ================== 35 | 36 | * :ref:`genindex` 37 | * :ref:`modindex` 38 | * :ref:`search` 39 | -------------------------------------------------------------------------------- /docs/sphinx/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/sphinx/requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx==5.3.0 2 | breathe 3 | exhale 4 | sphinxcontrib-bibtex==2.5.0 5 | jinja2-highlight==0.6.1 6 | myst-parser==0.18.1 7 | sphinx-copybutton 8 | sphinx-book-theme 9 | sphinx-rtd-theme 10 | sphinx-toolbox 11 | -------------------------------------------------------------------------------- /example/AdaptingThirdPartyGraph/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # example/AdaptingThirdPartyGraph/CMakeLists.txt 2 | 3 | set(EXAMPLE_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/output/") 4 | add_compile_definitions(EXAMPLE_OUTPUT_DIR="${EXAMPLE_OUTPUT_DIR}") 5 | 6 | #add_library(catch_main STATIC catch_main.cpp) 7 | #target_link_libraries(catch_main PUBLIC Catch2::Catch2) 8 | #target_link_libraries(catch_main PRIVATE project_options) 9 | #target_link_options(catch_main INTERFACE $<$:-pthread -fconcepts-diagnostics-depth=1>) 10 | 11 | add_executable(AdaptingThirdPartyGraph "adapting_a_third_party_graph.cpp") 12 | target_link_libraries(AdaptingThirdPartyGraph PRIVATE project_warnings project_options catch_main Catch2::Catch2WithMain graph) 13 | -------------------------------------------------------------------------------- /example/AdaptingThirdPartyGraph/adapting_a_third_party_graph.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 Andrzej Krzemienski. 2 | // 3 | // Use, modification, and distribution is subject to the Boost Software 4 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | // 7 | // This test file demonstrates how one can adapt one's own graph container for use with 8 | // this Graph Library 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | namespace MyLibrary { // custom graph container, conceptually an adjacency list 18 | 19 | struct MyEdge { 20 | std::string content; 21 | int indexOfTarget; 22 | }; 23 | 24 | struct MyVertex { 25 | std::string content; 26 | std::vector outEdges; 27 | }; 28 | 29 | class MyGraph { 30 | std::vector _vertices; 31 | 32 | public: 33 | MyVertex const* getVertexByIndex(int index) const { return &_vertices[static_cast(index)]; } 34 | 35 | std::vector const& getAllVertices() const // !! one of customization points 36 | { 37 | return _vertices; 38 | } // forced me to add this fun 39 | 40 | void setTopology(std::vector t) { _vertices = std::move(t); } 41 | }; 42 | 43 | } // namespace MyLibrary 44 | 45 | namespace MyLibrary { // customization for graph, unintrusive 46 | // although forcing me to provide `vertices()` is superfluous 47 | 48 | auto vertices(MyGraph const& g) { return std::views::all(g.getAllVertices()); } // for vertex_range_t 49 | 50 | auto edges(MyGraph const&, const MyLibrary::MyVertex& v) { return std::views::all(v.outEdges); } 51 | 52 | auto edges(MyGraph const& g, int i) { return edges(g, *g.getVertexByIndex(i)); } 53 | 54 | int vertex_id(MyGraph const& g, std::vector::const_iterator it) { 55 | return static_cast(std::distance(g.getAllVertices().begin(), it)); 56 | } 57 | 58 | int target_id(MyGraph const&, MyEdge const& uv) { return uv.indexOfTarget; } 59 | 60 | } // namespace MyLibrary 61 | 62 | 63 | int main() { 64 | static_assert(graph::adjacency_list); 65 | 66 | const MyLibrary::MyGraph g = [] { // populate the graph 67 | MyLibrary::MyGraph r; 68 | std::vector topo{ 69 | // A | 70 | /*0*/ {"A", {{"", 1}, {"", 2}}}, // / \ | 71 | /*1*/ {"B", {{"", 3}}}, // B C | 72 | /*2*/ {"C", {{"", 3}}}, // \ / | 73 | /*3*/ {"D", {}} // D | 74 | }; 75 | r.setTopology(std::move(topo)); 76 | return r; 77 | }(); 78 | 79 | for (auto const& [vid, v] : graph::views::vertices_depth_first_search(g, 0)) 80 | std::cout << v.content << " "; 81 | 82 | std::cout << std::endl; 83 | } -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | add_subdirectory(CppCon2021) 4 | add_subdirectory(CppCon2022) 5 | add_subdirectory(AdaptingThirdPartyGraph) 6 | -------------------------------------------------------------------------------- /example/CppCon2021/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | # Build errors with MSVC 4 | set(EXAMPLE_OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/output/") 5 | 6 | add_library(cppcon21_headers INTERFACE) 7 | target_include_directories(cppcon21_headers INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/graphs/" ) 8 | target_include_directories(cppcon21_headers INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include/") 9 | 10 | add_subdirectory(examples) 11 | -------------------------------------------------------------------------------- /example/CppCon2021/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # example/CppCon2022/CMakeLists.txt 2 | 3 | add_executable(graphs "graphs.cpp") 4 | target_link_libraries(graphs PRIVATE cppcon21_headers project_warnings project_options graph) 5 | 6 | add_executable(bacon "bacon.cpp") 7 | target_link_libraries(bacon PRIVATE cppcon21_headers project_warnings project_options graph) 8 | 9 | add_executable(ospf "ospf.cpp") 10 | target_link_libraries(ospf PRIVATE cppcon21_headers project_warnings project_options graph) 11 | 12 | add_executable(imdb "imdb.cpp") 13 | target_link_libraries(imdb PRIVATE cppcon21_headers project_warnings project_options graph) 14 | -------------------------------------------------------------------------------- /example/CppCon2021/examples/bacon.cpp: -------------------------------------------------------------------------------- 1 | #include "graph/views/breadth_first_search.hpp" 2 | #include "imdb-graph.hpp" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | std::vector> costars{{1, 5, 6}, {7, 10, 0, 5, 12}, {4, 3, 11}, {2, 11}, {8, 9, 2, 12}, {0, 1}, 9 | {7, 0}, {6, 1, 10}, {4, 9}, {4, 8}, {7, 1}, {2, 3}, 10 | {1, 4}}; 11 | 12 | int main() { 13 | 14 | std::vector bacon_number(size(actors)); 15 | 16 | // for (auto&& [u, v] : bfs_edge_range(costars, 1)) { 17 | for (auto&& [u, v, uv] : graph::views::sourced_edges_breadth_first_search(costars, 1)) { 18 | bacon_number[v] = bacon_number[u] + 1; 19 | } 20 | 21 | for (size_t i = 0; i < size(actors); ++i) { 22 | std::cout << actors[i] << " has Bacon number " << bacon_number[i] << std::endl; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /example/CppCon2021/examples/imdb.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Authors 3 | // Copyright 4 | // License 5 | // No Warranty Disclaimer 6 | // 7 | 8 | // IMDB Example 9 | 10 | #if defined(__GNUC__) || defined(__clang__) 11 | #elif defined(_MSC_VER) 12 | # pragma warning(push) 13 | # pragma warning(disable : 4267) // warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data 14 | #endif 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "graph/views/breadth_first_search.hpp" 21 | //#include "bfs_edge_range.hpp" 22 | #include "imdb-graph.hpp" 23 | #include "utilities.hpp" 24 | 25 | int main() { 26 | 27 | // Get actor-movie and movie-actor graphs 28 | auto&& [G, H] = make_plain_bipartite_graphs<>(movies, actors, movies_actors); 29 | 30 | // Will also work with this type of graph 31 | auto&& [J, K] = make_bipartite_graphs<>(movies, actors, movies_actors); 32 | 33 | // Create actor-actor graph 34 | auto L = join(G, H); 35 | auto M = join(H, G); 36 | 37 | // Can also join this way 38 | auto N = join>>>(G, H); 39 | auto O = join>>>(H, G); 40 | 41 | size_t kevin_bacon = 1; 42 | std::vector distance(L.size()); 43 | std::vector parents(L.size()); 44 | std::vector together_in(L.size()); 45 | 46 | //for (auto&& [u, v, k] : bfs_edge_range(L, kevin_bacon)) { 47 | auto kprop = [&L](auto&& e) { return std::get<1>(graph::edge_value(L, e)); }; 48 | for (auto&& [u, v, uv, k] : graph::views::sourced_edges_breadth_first_search(L, kevin_bacon, kprop)) { 49 | distance[v] = distance[u] + 1; 50 | parents[v] = u; 51 | together_in[v] = k; 52 | } 53 | 54 | std::cout << actors[kevin_bacon] << " has a bacon number of " << distance[kevin_bacon] << std::endl; 55 | std::cout << std::endl; 56 | 57 | // Iterate through all actors (other than Kevin Bacon) 58 | for (size_t i = 0; i < actors.size(); ++i) { 59 | if (i != kevin_bacon) { 60 | auto bacon_number = distance[i]; 61 | std::cout << actors[i] << " has a bacon number of " << distance[i] << std::endl; 62 | 63 | auto k = i; 64 | size_t d = distance[k]; 65 | while (k != kevin_bacon) { 66 | std::cout << " " << actors[k] << " starred with " << actors[parents[k]] << " in " << movies[together_in[k]] 67 | << std::endl; 68 | k = parents[k]; 69 | if (d-- == 0) { 70 | break; 71 | } 72 | } 73 | std::cout << std::endl; 74 | } 75 | } 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /example/CppCon2021/examples/ospf.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Authors 3 | // Copyright 4 | // License 5 | // No Warranty Disclaimer 6 | // 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | //#include "dijkstra.hpp" 13 | #include "graph/algorithm/dijkstra_shortest_paths.hpp" 14 | #include "ospf-graph.hpp" 15 | #include "utilities.hpp" 16 | 17 | int main() { 18 | 19 | static_assert(graph::adjacency_list); 20 | 21 | //auto d = dijkstra(ospf_index_adjacency_list, 5UL); 22 | std::vector d(size(ospf_index_adjacency_list)); 23 | std::vector p(size(ospf_index_adjacency_list)); 24 | graph::init_shortest_paths(d, p); 25 | graph::dijkstra_shortest_paths(ospf_index_adjacency_list, 5UL, d, p, [](auto&& ee) { return std::get<1>(ee); }); 26 | 27 | std::cout << "----------------" << std::endl; 28 | std::cout << "Contents of ospf_index_adjacency_list (the correct answer)" << std::endl; 29 | 30 | for (size_t i = 0; i < size(ospf_vertices); ++i) { 31 | std::cout << std::setw(6) << ospf_vertices[i] << std::setw(6) << d[i] << std::endl; 32 | } 33 | 34 | std::cout << "----------------" << std::endl; 35 | std::cout << "Results from make_property_graph(osp_vertices)" << std::endl; 36 | 37 | auto G = make_property_graph(ospf_vertices, ospf_edges, true); 38 | 39 | // Alternatively 40 | auto H = make_property_graph>>>(ospf_vertices, ospf_edges, true); 42 | auto I = make_property_graph>>>(ospf_vertices, ospf_edges, true); 44 | 45 | static_assert(graph::adjacency_list); 46 | 47 | //auto e = dijkstra(G, 5UL, [](auto&& ee) { return std::get<1>(ee); }); 48 | p.resize(graph::num_vertices(G)); 49 | std::vector e(graph::num_vertices(G)); 50 | graph::init_shortest_paths(e, p); 51 | graph::dijkstra_shortest_paths(G, 5UL, e, p, [](auto&& ee) { return std::get<1>(ee); }); 52 | 53 | bool pass = true; 54 | for (size_t i = 0; i < size(ospf_vertices); ++i) { 55 | std::cout << std::setw(6) << ospf_vertices[i] << std::setw(6) << e[i] << std::endl; 56 | if (e[i] != d[i]) 57 | pass = false; 58 | } 59 | std::cout << (pass ? "***PASS***" : "***FAIL***") << std::endl; 60 | 61 | std::cout << "----------------" << std::endl; 62 | std::cout << "Results from make_index_graph(osp_vertices)" << std::endl; 63 | 64 | auto J = make_index_graph(ospf_vertices, ospf_edges, true); 65 | 66 | //graph::dijkstra_shortest_paths(G, 5UL, e, p, w); 67 | 68 | //auto f = dijkstra(J, 5, [](auto&& ee) { return std::get<2>(ospf_edges[std::get<1>(ee)]); }); 69 | p.resize(graph::num_vertices(G)); 70 | std::vector f(graph::num_vertices(G)); 71 | graph::init_shortest_paths(f, p); 72 | graph::dijkstra_shortest_paths(J, 5UL, f, p, [](auto&& ee) { return std::get<2>(ospf_edges[std::get<1>(ee)]); }); 73 | 74 | bool pass2 = true; 75 | for (size_t i = 0; i < size(ospf_vertices); ++i) { 76 | std::cout << std::setw(6) << ospf_vertices[i] << std::setw(6) << e[i] << std::endl; 77 | if (e[i] != d[i]) 78 | pass2 = false; 79 | } 80 | std::cout << (pass2 ? "***PASS***" : "***FAIL***") << std::endl; 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /example/CppCon2021/graphs/karate-graph.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | // clang-format off 7 | 8 | std::vector> karate_index_edge_list { 9 | { 1, 0 }, 10 | { 2, 0 }, 11 | { 3, 0 }, 12 | { 4, 0 }, 13 | { 5, 0 }, 14 | { 6, 0 }, 15 | { 7, 0 }, 16 | { 8, 0 }, 17 | { 10, 0 }, 18 | { 11, 0 }, 19 | { 12, 0 }, 20 | { 13, 0 }, 21 | { 17, 0 }, 22 | { 19, 0 }, 23 | { 21, 0 }, 24 | { 31, 0 }, 25 | { 2, 1 }, 26 | { 3, 1 }, 27 | { 7, 1 }, 28 | { 13, 1 }, 29 | { 17, 1 }, 30 | { 19, 1 }, 31 | { 21, 1 }, 32 | { 30, 1 }, 33 | { 3, 2 }, 34 | { 7, 2 }, 35 | { 8, 2 }, 36 | { 9, 2 }, 37 | { 13, 2 }, 38 | { 27, 2 }, 39 | { 28, 2 }, 40 | { 32, 2 }, 41 | { 7, 3 }, 42 | { 12, 3 }, 43 | { 13, 3 }, 44 | { 6, 4 }, 45 | { 10, 4 }, 46 | { 6, 5 }, 47 | { 10, 5 }, 48 | { 16, 5 }, 49 | { 16, 6 }, 50 | { 30, 8 }, 51 | { 32, 8 }, 52 | { 33, 8 }, 53 | { 33, 9 }, 54 | { 33, 13 }, 55 | { 32, 14 }, 56 | { 33, 14 }, 57 | { 32, 15 }, 58 | { 33, 15 }, 59 | { 32, 18 }, 60 | { 33, 18 }, 61 | { 33, 19 }, 62 | { 32, 20 }, 63 | { 33, 20 }, 64 | { 32, 22 }, 65 | { 33, 22 }, 66 | { 25, 23 }, 67 | { 27, 23 }, 68 | { 29, 23 }, 69 | { 32, 23 }, 70 | { 33, 23 }, 71 | { 25, 24 }, 72 | { 27, 24 }, 73 | { 31, 24 }, 74 | { 31, 25 }, 75 | { 29, 26 }, 76 | { 33, 26 }, 77 | { 33, 27 }, 78 | { 31, 28 }, 79 | { 33, 28 }, 80 | { 32, 29 }, 81 | { 33, 29 }, 82 | { 32, 30 }, 83 | { 33, 30 }, 84 | { 32, 31 }, 85 | { 33, 31 }, 86 | { 33, 32 }, 87 | }; 88 | 89 | std::vector> karate_directed_adjacency_list { 90 | /* 0*/ { }, 91 | /* 1*/ { 0,}, 92 | /* 2*/ { 0, 1,}, 93 | /* 3*/ { 0, 1, 2,}, 94 | /* 4*/ { 0,}, 95 | /* 5*/ { 0,}, 96 | /* 6*/ { 0, 4, 5,}, 97 | /* 7*/ { 0, 1, 2, 3,}, 98 | /* 8*/ { 0, 2,}, 99 | /* 9*/ { 2,}, 100 | /* 10*/ { 0, 4, 5,}, 101 | /* 11*/ { 0,}, 102 | /* 12*/ { 0, 3,}, 103 | /* 13*/ { 0, 1, 2, 3,}, 104 | /* 14*/ { }, 105 | /* 15*/ { }, 106 | /* 16*/ { 5, 6,}, 107 | /* 17*/ { 0, 1,}, 108 | /* 18*/ { }, 109 | /* 19*/ { 0, 1,}, 110 | /* 20*/ { }, 111 | /* 21*/ { 0, 1,}, 112 | /* 22*/ { }, 113 | /* 23*/ { }, 114 | /* 24*/ { }, 115 | /* 25*/ { 23, 24,}, 116 | /* 26*/ { }, 117 | /* 27*/ { 2, 23, 24,}, 118 | /* 28*/ { 2,}, 119 | /* 29*/ { 23, 26,}, 120 | /* 30*/ { 1, 8,}, 121 | /* 31*/ { 0, 24, 25, 28,}, 122 | /* 32*/ { 2, 8, 14, 15, 18, 20, 22, 23, 29, 30, 31,}, 123 | /* 33*/ { 8, 9, 13, 14, 15, 18, 19, 20, 22, 23, 26, 27, 28, 29, 30, 31, 32,}, 124 | }; 125 | 126 | std::vector> karate_undirected_adjacency_list { 127 | /* 0*/ { 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 17, 19, 21, 31,}, 128 | /* 1*/ { 0, 2, 3, 7, 13, 17, 19, 21, 30,}, 129 | /* 2*/ { 0, 1, 3, 7, 8, 9, 13, 27, 28, 32,}, 130 | /* 3*/ { 0, 1, 2, 7, 12, 13,}, 131 | /* 4*/ { 0, 6, 10,}, 132 | /* 5*/ { 0, 6, 10, 16,}, 133 | /* 6*/ { 0, 4, 5, 16,}, 134 | /* 7*/ { 0, 1, 2, 3,}, 135 | /* 8*/ { 0, 2, 30, 32, 33,}, 136 | /* 9*/ { 2, 33,}, 137 | /* 10*/ { 0, 4, 5,}, 138 | /* 11*/ { 0,}, 139 | /* 12*/ { 0, 3,}, 140 | /* 13*/ { 0, 1, 2, 3, 33,}, 141 | /* 14*/ { 32, 33,}, 142 | /* 15*/ { 32, 33,}, 143 | /* 16*/ { 5, 6,}, 144 | /* 17*/ { 0, 1,}, 145 | /* 18*/ { 32, 33,}, 146 | /* 19*/ { 0, 1, 33,}, 147 | /* 20*/ { 32, 33,}, 148 | /* 21*/ { 0, 1,}, 149 | /* 22*/ { 32, 33,}, 150 | /* 23*/ { 25, 27, 29, 32, 33,}, 151 | /* 24*/ { 25, 27, 31,}, 152 | /* 25*/ { 23, 24, 31,}, 153 | /* 26*/ { 29, 33,}, 154 | /* 27*/ { 2, 23, 24, 33,}, 155 | /* 28*/ { 2, 31, 33,}, 156 | /* 29*/ { 23, 26, 32, 33,}, 157 | /* 30*/ { 1, 8, 32, 33,}, 158 | /* 31*/ { 0, 24, 25, 28, 32, 33,}, 159 | /* 32*/ { 2, 8, 14, 15, 18, 20, 22, 23, 29, 30, 31, 33,}, 160 | /* 33*/ { 8, 9, 13, 14, 15, 18, 19, 20, 22, 23, 26, 27, 28, 29, 30, 31, 32,}, 161 | }; 162 | 163 | // clang-format on 164 | -------------------------------------------------------------------------------- /example/CppCon2021/graphs/ospf-graph.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Authors 3 | // Copyright 4 | // License 5 | // No Warranty Disclaimer 6 | // 7 | #pragma once 8 | 9 | // Data and graph from OSPF example in Boost Graph Library book 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | // clang-format off 16 | 17 | std::vector ospf_vertices { 18 | "RT1", 19 | "RT2", 20 | "RT3", 21 | "RT4", 22 | "RT5", 23 | "RT6", 24 | "RT7", 25 | "RT8", 26 | "RT9", 27 | "RT10", 28 | "RT11", 29 | "RT12", 30 | "N1", 31 | "N2", 32 | "N3", 33 | "N4", 34 | "N6", 35 | "N7", 36 | "N8", 37 | "N9", 38 | "N10", 39 | "N11", 40 | "N12", 41 | "N13", 42 | "N14", 43 | "N15", 44 | "H1", 45 | }; 46 | 47 | std::vector> ospf_edges { 48 | {"RT1", "N1", 3}, 49 | {"RT1", "N3", 1}, 50 | {"RT2", "N2", 3}, 51 | {"RT2", "N3", 1}, 52 | {"RT3", "RT6", 8}, 53 | {"RT3", "N3", 1}, 54 | {"RT3", "N4", 2}, 55 | {"RT4", "N3", 1}, 56 | {"RT4", "RT5", 8}, 57 | {"RT5", "RT4", 8}, 58 | {"RT5", "RT6", 7}, 59 | {"RT5", "RT7", 6}, 60 | {"RT5", "N12", 8}, 61 | {"RT5", "N13", 8}, 62 | {"RT5", "N14", 8}, 63 | {"RT6", "RT3", 6}, 64 | {"RT6", "RT5", 6}, 65 | {"RT6", "RT10", 7}, 66 | {"RT7", "RT5", 6}, 67 | {"RT7", "N6", 1}, 68 | {"RT7", "N12", 2}, 69 | {"RT7", "N15", 9}, 70 | {"RT8", "N6", 1}, 71 | {"RT8", "N7", 4}, 72 | {"RT9", "N9", 1}, 73 | {"RT9", "N11", 3}, 74 | {"RT10", "RT6", 5}, 75 | {"RT10", "N6", 1}, 76 | {"RT10", "N8", 3}, 77 | {"RT11", "N8", 2}, 78 | {"RT11", "N9", 1}, 79 | {"RT12", "N9", 1}, 80 | {"RT12", "N10", 2}, 81 | {"RT12", "H1", 10}, 82 | {"N3", "RT1", 0}, 83 | {"N3", "RT2", 0}, 84 | {"N3", "RT3", 0}, 85 | {"N3", "RT4", 0}, 86 | {"N6", "RT7", 0}, 87 | {"N6", "RT8", 0}, 88 | {"N6", "RT10", 0}, 89 | {"N8", "RT10", 0}, 90 | {"N8", "RT11", 0}, 91 | {"N9", "RT9", 0}, 92 | {"N9", "RT11", 0}, 93 | {"N9", "RT12", 0}, 94 | }; 95 | 96 | std::vector> ospf_index_edge_list { 97 | { 0, 12, 3}, 98 | { 0, 14, 1}, 99 | { 1, 13, 3}, 100 | { 1, 14, 1}, 101 | { 2, 5, 8}, 102 | { 2, 14, 1}, 103 | { 2, 15, 2}, 104 | { 3, 14, 1}, 105 | { 3, 4, 8}, 106 | { 4, 3, 8}, 107 | { 4, 5, 7}, 108 | { 4, 6, 6}, 109 | { 4, 22, 8}, 110 | { 4, 23, 8}, 111 | { 4, 24, 8}, 112 | { 5, 2, 6}, 113 | { 5, 4, 6}, 114 | { 5, 9, 7}, 115 | { 6, 4, 6}, 116 | { 6, 16, 1}, 117 | { 6, 22, 2}, 118 | { 6, 25, 9}, 119 | { 7, 16, 1}, 120 | { 7, 17, 4}, 121 | { 8, 19, 1}, 122 | { 8, 21, 3}, 123 | { 9, 5, 5}, 124 | { 9, 16, 1}, 125 | { 9, 18, 3}, 126 | { 10, 18, 2}, 127 | { 10, 19, 1}, 128 | { 11, 19, 1}, 129 | { 11, 20, 2}, 130 | { 11, 26, 10}, 131 | { 14, 0, 0}, 132 | { 14, 1, 0}, 133 | { 14, 2, 0}, 134 | { 14, 3, 0}, 135 | { 16, 6, 0}, 136 | { 16, 7, 0}, 137 | { 16, 9, 0}, 138 | { 18, 9, 0}, 139 | { 18, 10, 0}, 140 | { 19, 8, 0}, 141 | { 19, 10, 0}, 142 | { 19, 11, 0}, 143 | }; 144 | 145 | std::vector>> ospf_index_adjacency_list { 146 | /* 0 */ { { 12, 3 },{ 14, 1 },}, 147 | /* 1 */ { { 13, 3 },{ 14, 1 },}, 148 | /* 2 */ { { 5, 8 },{ 14, 1 },{ 15, 2 },}, 149 | /* 3 */ { { 14, 1 },{ 4, 8 },}, 150 | /* 4 */ { { 3, 8 },{ 5, 7 },{ 6, 6 },{ 22, 8 },{ 23, 8 },{ 24, 8 },}, 151 | /* 5 */ { { 2, 6 },{ 4, 6 },{ 9, 7 },}, 152 | /* 6 */ { { 4, 6 },{ 16, 1 },{ 22, 2 },{ 25, 9 },}, 153 | /* 7 */ { { 16, 1 },{ 17, 4 },}, 154 | /* 8 */ { { 19, 1 },{ 21, 3 },}, 155 | /* 9 */ { { 5, 5 },{ 16, 1 },{ 18, 3 },}, 156 | /* 10 */ { { 18, 2 },{ 19, 1 },}, 157 | /* 11 */ { { 19, 1 },{ 20, 2 },{ 26, 10 },}, 158 | /* 12 */ { }, 159 | /* 13 */ { }, 160 | /* 14 */ { { 0, 0 },{ 1, 0 },{ 2, 0 },{ 3, 0 },}, 161 | /* 15 */ { }, 162 | /* 16 */ { { 6, 0 },{ 7, 0 },{ 9, 0 },}, 163 | /* 17 */ { }, 164 | /* 18 */ { { 9, 0 },{ 10, 0 },}, 165 | /* 19 */ { { 8, 0 },{ 10, 0 },{ 11, 0 },}, 166 | /* 20 */ { }, 167 | /* 21 */ { }, 168 | /* 22 */ { }, 169 | /* 23 */ { }, 170 | /* 24 */ { }, 171 | /* 25 */ { }, 172 | /* 26 */ { }, 173 | }; 174 | 175 | std::vector> ospf_shortest_path_distances { 176 | { "RT1", 7 }, 177 | { "RT2", 7 }, 178 | { "RT3", 6 }, 179 | { "RT4", 7 }, 180 | { "RT5", 6 }, 181 | { "RT6", 0 }, 182 | { "RT7", 8 }, 183 | { "RT8", 8 }, 184 | { "RT9", 11 }, 185 | { "RT10", 7 }, 186 | { "RT11", 10 }, 187 | { "RT12", 11 }, 188 | { "N1", 10 }, 189 | { "N2", 10 }, 190 | { "N3", 7 }, 191 | { "N4", 8 }, 192 | { "N6", 8 }, 193 | { "N7", 12 }, 194 | { "N8", 10 }, 195 | { "N9", 11 }, 196 | { "N10", 13 }, 197 | { "N11", 14 }, 198 | { "N12", 10 }, 199 | { "N13", 14 }, 200 | { "N14", 14 }, 201 | { "N15", 17 }, 202 | { "H1", 21 }, 203 | }; 204 | 205 | // clang-format on 206 | -------------------------------------------------------------------------------- /example/CppCon2021/graphs/spice-graph.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Authors 3 | // Copyright 4 | // License 5 | // No Warranty Disclaimer 6 | // 7 | 8 | // Data and graph from Spice example in Cppcon slides 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | // clang-format off 15 | 16 | std::vector spice_vertices { 17 | "GND", 18 | "n0", 19 | "Vdd", 20 | "n1", 21 | "out", 22 | "n2", 23 | }; 24 | 25 | std::vector spice_elements { 26 | "C1", 27 | "AC", 28 | "R2", 29 | "R0", 30 | "R1", 31 | "L1", 32 | "C0", 33 | "R3", 34 | }; 35 | 36 | std::vector> spice_elements_values { 37 | { "C1", 1.e-6 }, 38 | { "AC", 3 }, 39 | { "R2", 1.e4 }, 40 | { "R0", 2.7e3 }, 41 | { "R1", 3.3e4 }, 42 | { "L1", 1.e-4 }, 43 | { "C0", 10.e-9}, 44 | { "R3", 1.e3 }, 45 | }; 46 | 47 | std::vector> spice_edges { 48 | { "n0", "n1", "C1" }, 49 | { "Vdd", "GND", "AC" }, 50 | { "n0", "Vdd", "R2" }, 51 | { "n2", "Vdd", "R0" }, 52 | { "GND", "n2", "R1" }, 53 | { "n2", "Vout", "L1" }, 54 | { "GND", "n0", "C0"}, 55 | { "n2", "n1", "R3"}, 56 | }; 57 | 58 | std::vector> spice_edges_values { 59 | { "n0", "n1", "C1", 1.e-6 }, 60 | { "Vdd", "GND", "AC", 3 }, 61 | { "n0", "Vdd", "R2", 1.e4 }, 62 | { "n2", "Vdd", "R0", 2.7e3 }, 63 | { "GND", "n2", "R1", 3.3e4 }, 64 | { "n2", "Vout", "L1", 1.e-4 }, 65 | { "GND", "n0", "C0", 10.e-9}, 66 | { "n2", "n1", "R3", 1.e3 }, 67 | }; 68 | 69 | std::vector> spice_index_edge_list { 70 | { 1, 3, 0 }, 71 | { 2, 0, 1 }, 72 | { 1, 2, 2 }, 73 | { 5, 2, 3 }, 74 | { 0, 5, 4 }, 75 | { 5, 4, 5 }, 76 | { 0, 1, 6 }, 77 | { 5, 3, 7 }, 78 | }; 79 | 80 | std::vector> spice_property_edge_list { 81 | { 1, 3, "C1" }, 82 | { 2, 0, "AC" }, 83 | { 1, 2, "R2" }, 84 | { 5, 2, "R0" }, 85 | { 0, 5, "R1" }, 86 | { 5, 4, "L1" }, 87 | { 0, 1, "C0" }, 88 | { 5, 3, "R3" }, 89 | }; 90 | 91 | std::vector> spice_property_edge_list_values { 92 | { 1, 3, "C1", 1.e-6 }, 93 | { 1, 0, "AC", 3 }, 94 | { 1, 2, "R2", 1.e4 }, 95 | { 5, 2, "R0", 2.7e3 }, 96 | { 0, 5, "R1", 3.3e4 }, 97 | { 5, 4, "L1", 1.e-4 }, 98 | { 0, 1, "C0", 10.e-9}, 99 | { 5, 3, "R3", 1.e3 }, 100 | }; 101 | 102 | std::vector>> spice_index_adjacency_list { 103 | /* 0 */ { { 1, 6 }, { 5, 4 } }, 104 | /* 1 */ { { 2, 2 }, { 3, 0 } }, 105 | /* 2 */ { { 0, 1 } }, 106 | /* 3 */ { }, 107 | /* 4 */ { }, 108 | /* 5 */ { { 2, 3 }, { 4, 5 }, { 3, 7 } }, 109 | }; 110 | 111 | std::vector>> spice_property_adjacency_list { 112 | /* 0 */ { { 1, "C0" }, { 5, "R1" }, }, 113 | /* 1 */ { { 2, "R2" }, { 3, "C1" } }, 114 | /* 2 */ { { 0, "AC" } }, 115 | /* 3 */ { }, 116 | /* 4 */ { }, 117 | /* 5 */ { { 2, "R0" }, { 4, "L1" }, { 3, "R3" } }, 118 | }; 119 | 120 | std::vector>> spice_property_adjacency_list_values { 121 | /* 0 */ { { 1, "C0", 10.e-9 }, { 5, "R1", 3.3e4 } }, 122 | /* 1 */ { { 2, "R2", 1.e-4 }, { 3, "C1", 1.e-6 } }, 123 | /* 2 */ { { 0, "AC", 3 } }, 124 | /* 3 */ { }, 125 | /* 4 */ { }, 126 | /* 5 */ { { 2, "R0", 2.7e3 }, { 4, "L1", 1.e-4 }, { 3, "R3", 1.e3 } }, 127 | }; 128 | 129 | // clang-format on 130 | -------------------------------------------------------------------------------- /example/CppCon2021/include/bfs.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Authors 3 | // Copyright 4 | // License 5 | // No Warranty Disclaimer 6 | // 7 | 8 | // Basic index adjacency list graph bfs 9 | 10 | #ifndef NWGRAPH_BFS_HPP 11 | #define NWGRAPH_BFS_HPP 12 | 13 | #include "graph_concepts.hpp" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | enum COLOR { WHITE, BLACK, GREY }; 25 | 26 | template 27 | auto bfs(const Graph& graph, vertex_id_t source) { 28 | using vertex_id_type = vertex_id_t; 29 | 30 | std::vector color(size(graph)); 31 | for (vertex_id_type u = 0; u < size(graph); ++u) { 32 | color[u] = WHITE; 33 | } 34 | color[source] = GREY; 35 | 36 | std::queue Q; 37 | Q.push(source); 38 | 39 | while (!Q.empty()) { 40 | auto u = Q.front(); 41 | Q.pop(); 42 | for (auto&& e : graph[u]) { 43 | auto v = target(graph, e); // neighbor vertex 44 | if (color[v] == WHITE) { 45 | color[v] == GREY; 46 | Q.push(v); 47 | } 48 | } 49 | color[u] = BLACK; 50 | } 51 | } 52 | 53 | #endif // NWGRAPH_BFS_HPP 54 | -------------------------------------------------------------------------------- /example/CppCon2021/include/dijkstra.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Authors 3 | // Copyright 4 | // License 5 | // No Warranty Disclaimer 6 | // 7 | 8 | // Dijkstra, assuming graph stores vertex id and edge id 9 | 10 | #ifndef NWGRAPH_DIJKSTRA_HPP 11 | #define NWGRAPH_DIJKSTRA_HPP 12 | 13 | #include "graph_concepts.hpp" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | template > WeightFunction = 25 | std::function>(const inner_value_t&)>> 26 | auto dijkstra( 27 | const Graph& graph, vertex_id_t source, WeightFunction weights = [](const inner_value_t& e) { 28 | return std::get<1>(e); 29 | }) { 30 | using vertex_id_type = vertex_id_t; 31 | using weight_type = std::invoke_result_t>; 32 | using weighted_vertex = std::tuple; 33 | 34 | std::vector distance(size(graph), std::numeric_limits::max()); 35 | distance[source] = 0; 36 | 37 | std::priority_queue, 38 | decltype([](auto&& a, auto&& b) { return (std::get<1>(a) > std::get<1>(b)); })> 39 | Q; 40 | Q.push({source, distance[source]}); 41 | 42 | while (!Q.empty()) { 43 | auto u = std::get<0>(Q.top()); 44 | Q.pop(); 45 | 46 | for (auto&& e : graph[u]) { 47 | auto v = target(graph, e); // neighbor vertex 48 | if (distance[u] + weights(e) < distance[v]) { // relax 49 | distance[v] = distance[u] + weights(e); 50 | Q.push({v, distance[v]}); 51 | } 52 | } 53 | } 54 | return distance; 55 | } 56 | 57 | #endif // NWGRAPH_DIJKSTRA_HPP 58 | -------------------------------------------------------------------------------- /example/CppCon2021/include/graph_concepts.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Authors 3 | // Copyright 4 | // License 5 | // No Warranty Disclaimer 6 | // 7 | 8 | #ifndef NWGRAPH_GRAPH_CONCEPTS_HPP 9 | #define NWGRAPH_GRAPH_CONCEPTS_HPP 10 | 11 | #include 12 | #include 13 | 14 | #if 0 15 | template 16 | class graph_traits { 17 | using vertex_id_type = typename T::vertex_id_type; 18 | }; 19 | 20 | template 21 | using vertex_id_t = typename graph_traits::vertex_id_type; 22 | 23 | template 24 | concept graph = std::semiregular && requires(G g) { 25 | typename vertex_id_t; 26 | }; 27 | 28 | template 29 | using inner_range_t = std::ranges::range_value_t; 30 | 31 | template 32 | using inner_value_t = std::ranges::range_value_t>; 33 | 34 | DECL_TAG_INVOKE(degree); 35 | DECL_TAG_INVOKE(target); 36 | DECL_TAG_INVOKE(untarget); 37 | 38 | template 39 | concept adjacency_list = graph && std::ranges::random_access_range && std::ranges::forward_range> && 40 | std::convertible_to, std::ranges::range_difference_t> && requires(G g, vertex_id_t u, inner_value_t e) { 41 | { g[u] } -> std::convertible_to>; 42 | { target(g, e) } -> std::convertible_to>; 43 | }; 44 | 45 | template 46 | concept degree_enumerable = adjacency_list && requires(G g, vertex_id_t u) { 47 | { degree(g[u]) } -> std::convertible_to>; 48 | }; 49 | 50 | template 51 | concept edge_range = graph && requires(G g, std::ranges::range_value_t e) { 52 | { source(g, e) } -> std::convertible_to>; 53 | { target(g, e) } -> std::convertible_to>; 54 | }; 55 | 56 | template