From 4068f91c214c2b017fb4d873f668646ce6683a03 Mon Sep 17 00:00:00 2001 From: Aryan Naraghi Date: Fri, 8 May 2026 15:33:48 -0600 Subject: [PATCH] Stamp out exemplar template --- .beman-tidy.yaml | 2 +- .exemplar_version | 1 + .github/CODEOWNERS | 2 +- .github/workflows/catch2_exemplar_test.yml | 29 -- .github/workflows/ci_tests.yml | 16 +- .github/workflows/cookiecutter_test.yml | 19 - .github/workflows/pre-commit-update.yml | 2 +- .github/workflows/todo_exemplar_test.yml | 31 -- .github/workflows/vcpkg-release.yml | 2 +- .pre-commit-config.yaml | 6 + CMakeLists.txt | 48 +-- CMakePresets.json | 2 +- CONTRIBUTING.md | 20 +- README.md | 166 ++------ cookiecutter/check_cookiecutter.sh | 101 ----- cookiecutter/cookiecutter.json | 16 - cookiecutter/hooks/post_gen_project.py | 26 -- .../.beman-tidy.yaml | 15 - .../.clang-format | 242 ------------ .../.gitattributes | 5 - .../.github/CODEOWNERS | 7 - .../implementation-deficiency.md | 35 -- .../ISSUE_TEMPLATE/infrastructure-issues.md | 29 -- .../ISSUE_TEMPLATE/paper-discussion.md | 33 -- .../.github/pull_request_template.md | 5 - .../.github/workflows/ci_tests.yml | 203 ---------- .../.github/workflows/pre-commit-check.yml | 20 - .../.github/workflows/pre-commit-update.yml | 18 - .../.github/workflows/vcpkg-release.yml | 16 - .../{{cookiecutter.project_name}}/.gitignore | 18 - .../.markdownlint.yaml | 11 - .../.pre-commit-config.yaml | 51 --- .../CMakeLists.txt | 94 ----- .../CMakePresets.json | 373 ------------------ .../CONTRIBUTING.md | 139 ------- .../{{cookiecutter.project_name}}/LICENSE | 219 ---------- .../{{cookiecutter.project_name}}/README.md | 267 ------------- .../examples/CMakeLists.txt | 37 -- .../identity_as_default_projection.cpp | 78 ---- .../examples/identity_direct_usage.cpp | 24 -- .../CMakeLists.txt | 27 -- .../{{cookiecutter.project_name}}/config.hpp | 12 - .../config_generated.hpp.in | 8 - .../identity.hpp | 63 --- .../{{cookiecutter.project_name}}.cppm | 11 - .../{{cookiecutter.project_name}}.hpp | 20 - .../infra/.beman_submodule | 3 - .../infra/.github/CODEOWNERS | 1 - .../infra/.github/workflows/pre-commit.yml | 79 ---- ...reusable-beman-create-issue-when-fault.yml | 28 -- .../infra/.gitignore | 59 --- .../infra/.pre-commit-config.yaml | 22 -- .../infra/LICENSE | 219 ---------- .../infra/README.md | 88 ----- .../infra/cmake/BuildTelemetry.cmake | 5 - .../infra/cmake/BuildTelemetryConfig.cmake | 59 --- .../infra/cmake/Config.cmake.in | 12 - .../infra/cmake/appleclang-toolchain.cmake | 44 --- .../infra/cmake/beman-install-library.cmake | 325 --------------- .../enable-experimental-import-std.cmake | 190 --------- .../infra/cmake/gnu-toolchain.cmake | 41 -- .../infra/cmake/llvm-libc++-toolchain.cmake | 20 - .../infra/cmake/llvm-toolchain.cmake | 41 -- .../infra/cmake/msvc-toolchain.cmake | 41 -- .../infra/cmake/telemetry.sh | 119 ------ .../infra/cmake/use-fetch-content.cmake | 205 ---------- .../lockfile.json | 22 -- .../port/portfile.cmake.in | 38 -- .../port/vcpkg.json.in | 22 -- .../CMakeLists.txt | 33 -- .../identity.test.cpp | 117 ------ .../vcpkg-configuration.json | 15 - .../{{cookiecutter.project_name}}/vcpkg.json | 23 -- examples/CMakeLists.txt | 28 +- examples/identity_as_default_projection.cpp | 78 ---- examples/identity_direct_usage.cpp | 17 - examples/todo.cpp | 8 + images/use-this-template.png | Bin 51407 -> 0 bytes include/beman/exemplar/CMakeLists.txt | 26 -- include/beman/exemplar/config.hpp | 12 - .../beman/exemplar/config_generated.hpp.in | 8 - include/beman/exemplar/exemplar.hpp | 19 - include/beman/exemplar/identity.hpp | 55 --- include/beman/str_split/CMakeLists.txt | 26 ++ include/beman/str_split/config.hpp | 12 + .../beman/str_split/config_generated.hpp.in | 8 + .../str_split.cppm} | 6 +- include/beman/str_split/str_split.hpp | 19 + include/beman/str_split/todo.hpp | 23 ++ port/portfile.cmake.in | 12 +- port/vcpkg.json.in | 8 +- stamp.sh | 44 --- tests/beman/exemplar/CMakeLists.txt | 19 - tests/beman/exemplar/identity.test.cpp | 59 --- tests/beman/str_split/CMakeLists.txt | 19 + tests/beman/str_split/todo.test.cpp | 10 + vcpkg.json | 4 +- 97 files changed, 234 insertions(+), 4726 deletions(-) create mode 100644 .exemplar_version delete mode 100644 .github/workflows/catch2_exemplar_test.yml delete mode 100644 .github/workflows/cookiecutter_test.yml delete mode 100644 .github/workflows/todo_exemplar_test.yml delete mode 100755 cookiecutter/check_cookiecutter.sh delete mode 100644 cookiecutter/cookiecutter.json delete mode 100755 cookiecutter/hooks/post_gen_project.py delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.clang-format delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.gitattributes delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.gitignore delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/LICENSE delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/README.md delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/README.md delete mode 100755 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetry.cmake delete mode 100755 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetryConfig.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/Config.cmake.in delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/enable-experimental-import-std.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake delete mode 100755 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/telemetry.sh delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/lockfile.json delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/vcpkg-configuration.json delete mode 100644 cookiecutter/{{cookiecutter.project_name}}/vcpkg.json delete mode 100644 examples/identity_as_default_projection.cpp delete mode 100644 examples/identity_direct_usage.cpp create mode 100644 examples/todo.cpp delete mode 100644 images/use-this-template.png delete mode 100644 include/beman/exemplar/CMakeLists.txt delete mode 100644 include/beman/exemplar/config.hpp delete mode 100644 include/beman/exemplar/config_generated.hpp.in delete mode 100644 include/beman/exemplar/exemplar.hpp delete mode 100644 include/beman/exemplar/identity.hpp create mode 100644 include/beman/str_split/CMakeLists.txt create mode 100644 include/beman/str_split/config.hpp create mode 100644 include/beman/str_split/config_generated.hpp.in rename include/beman/{exemplar/exemplar.cppm => str_split/str_split.cppm} (55%) create mode 100644 include/beman/str_split/str_split.hpp create mode 100644 include/beman/str_split/todo.hpp delete mode 100755 stamp.sh delete mode 100644 tests/beman/exemplar/CMakeLists.txt delete mode 100644 tests/beman/exemplar/identity.test.cpp create mode 100644 tests/beman/str_split/CMakeLists.txt create mode 100644 tests/beman/str_split/todo.test.cpp diff --git a/.beman-tidy.yaml b/.beman-tidy.yaml index ac91fe3..24d798b 100644 --- a/.beman-tidy.yaml +++ b/.beman-tidy.yaml @@ -5,6 +5,6 @@ # https://github.com/bemanproject/beman-tidy/blob/main/README.md disabled_rules: - - readme.title + # None ignored_paths: # None diff --git a/.exemplar_version b/.exemplar_version new file mode 100644 index 0000000..2367afa --- /dev/null +++ b/.exemplar_version @@ -0,0 +1 @@ +29fd521a15439a3338272cb91c4940f63aa01cc5 diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c9a2615..37780dc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,3 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -* @ednolan @bretbrownjr @camio @dietmarkuehl @steve-downey @wusatosi +* @aryann,bartholomaios diff --git a/.github/workflows/catch2_exemplar_test.yml b/.github/workflows/catch2_exemplar_test.yml deleted file mode 100644 index 60ee257..0000000 --- a/.github/workflows/catch2_exemplar_test.yml +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: Catch2 Exemplar Test -on: - push: - branches: - - main - pull_request: - -jobs: - catch2-exemplar-test: - runs-on: ubuntu-latest - container: ghcr.io/bemanproject/infra-containers-gcc:latest - name: "Catch2 exemplar smoke test" - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Test catch2 exemplar - run: | - cd cookiecutter - source ./check_cookiecutter.sh - cookiecutter_venv_path=$(mktemp --directory --dry-run) - setup_venv "$cookiecutter_venv_path" - stamp "$PWD" "./catch2_exemplar" "catch2" "true" - cd catch2_exemplar/exemplar - cmake -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake -DCMAKE_CXX_STANDARD=20 -DCMAKE_INSTALL_PREFIX=$PWD/dist - cmake --build build - ctest --test-dir build - cmake --install build diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 6e6615a..b47cead 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -9,7 +9,7 @@ on: pull_request: workflow_dispatch: schedule: - - cron: '30 15 * * 6' + - cron: '30 16 * * 2' concurrency: group: ${{format('{0}:{1}', github.repository, github.ref)}} @@ -48,7 +48,7 @@ jobs: "tests": [ "Debug.Default", "Release.Default", "Release.TSan", "Release.MaxSan", "Debug.Werror", - "Debug.Coverage", "Debug.-DBEMAN_EXEMPLAR_USE_MODULES=On" + "Debug.Coverage", "Debug.-DBEMAN_STR_SPLIT_USE_MODULES=On" ] } ] @@ -57,7 +57,7 @@ jobs: "tests": [ { "stdlibs": ["libstdc++"], "tests": [ - "Release.Default", "Debug.-DBEMAN_EXEMPLAR_USE_MODULES=On" + "Release.Default", "Debug.-DBEMAN_STR_SPLIT_USE_MODULES=On" ] } ] @@ -73,7 +73,7 @@ jobs: "tests": [ { "stdlibs": ["libstdc++"], "tests": [ - "Release.Default", "Debug.-DBEMAN_EXEMPLAR_USE_MODULES=On" + "Release.Default", "Debug.-DBEMAN_STR_SPLIT_USE_MODULES=On" ] } ] @@ -108,7 +108,7 @@ jobs: "tests": [ "Debug.Default", "Release.Default", "Release.TSan", "Release.MaxSan", "Debug.Werror", - "Debug.-DBEMAN_EXEMPLAR_USE_MODULES=On" + "Debug.-DBEMAN_STR_SPLIT_USE_MODULES=On" ] } ] @@ -117,7 +117,7 @@ jobs: "tests": [ { "stdlibs": ["libstdc++", "libc++"], "tests": [ - "Release.Default", "Debug.-DBEMAN_EXEMPLAR_USE_MODULES=On" + "Release.Default", "Debug.-DBEMAN_STR_SPLIT_USE_MODULES=On" ] } ] @@ -176,7 +176,7 @@ jobs: { "stdlibs": ["stl"], "tests": [ "Debug.Default", "Release.Default", "Release.MaxSan", - "Debug.-DBEMAN_EXEMPLAR_USE_MODULES=On" + "Debug.-DBEMAN_STR_SPLIT_USE_MODULES=On" ] } ] @@ -189,7 +189,7 @@ jobs: vcpkg-ci: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-vcpkg-ci.yml@1.7.2 with: - port_name: beman-exemplar + port_name: beman-str-split feature_combinations: | [ {"features": {}}, diff --git a/.github/workflows/cookiecutter_test.yml b/.github/workflows/cookiecutter_test.yml deleted file mode 100644 index 04cdd05..0000000 --- a/.github/workflows/cookiecutter_test.yml +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: Cookiecutter Test -on: - push: - branches: - - main - pull_request: - -jobs: - cookiecutter-test: - runs-on: ubuntu-latest - name: "Check cookiecutter for consistency" - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: beman cookiecutter consistency check - run: | - ./cookiecutter/check_cookiecutter.sh diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index 7ab44ac..db1b677 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -5,7 +5,7 @@ name: Weekly pre-commit autoupdate on: workflow_dispatch: schedule: - - cron: "0 16 * * 0" + - cron: "50 13 * * 0" jobs: auto-update-pre-commit: diff --git a/.github/workflows/todo_exemplar_test.yml b/.github/workflows/todo_exemplar_test.yml deleted file mode 100644 index e7b4c33..0000000 --- a/.github/workflows/todo_exemplar_test.yml +++ /dev/null @@ -1,31 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: TODO Exemplar Test -on: - push: - branches: - - main - pull_request: - -jobs: - static-exemplar-test: - runs-on: ubuntu-latest - container: ghcr.io/bemanproject/infra-containers-gcc:latest - name: "TODO exemplar smoke test" - steps: - - name: Checkout - uses: actions/checkout@v6 - - name: Test static exemplar - run: | - cd cookiecutter - source ./check_cookiecutter.sh - cookiecutter_venv_path=$(mktemp --directory --dry-run) - setup_venv "$cookiecutter_venv_path" - stamp "$PWD" "./static_exemplar" "gtest" "false" - cd static_exemplar/exemplar - grep -r 'identity' . && exit 1 - find . -name '*identity*' | grep . && exit 1 - cmake -B build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake -DCMAKE_CXX_STANDARD=20 -DCMAKE_INSTALL_PREFIX=$PWD/dist - cmake --build build - ctest --test-dir build - cmake --install build diff --git a/.github/workflows/vcpkg-release.yml b/.github/workflows/vcpkg-release.yml index cc10bea..114dfe1 100644 --- a/.github/workflows/vcpkg-release.yml +++ b/.github/workflows/vcpkg-release.yml @@ -8,6 +8,6 @@ jobs: vcpkg-release: uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-vcpkg-release.yml@1.7.2 with: - port_name: beman-exemplar + port_name: beman-str-split secrets: VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b3dc48c..4f63c43 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,4 +40,10 @@ repos: hooks: - id: codespell + # Beman Standard checking via beman-tidy + - repo: https://github.com/bemanproject/beman-tidy + rev: v0.3.1 + hooks: + - id: beman-tidy + exclude: 'cookiecutter/|infra/|port/' diff --git a/CMakeLists.txt b/CMakeLists.txt index 07d744c..2a90806 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,35 +5,35 @@ cmake_minimum_required(VERSION 3.30...4.3) include(infra/cmake/enable-experimental-import-std.cmake) project( - beman.exemplar - DESCRIPTION "A Beman Library Exemplar" + beman.str_split + DESCRIPTION "Stand-alone, easy-to-use string split utilities" LANGUAGES CXX - VERSION 2.4.0 + VERSION 0.1.0 ) # [CMAKE.SKIP_TESTS] option( - BEMAN_EXEMPLAR_BUILD_TESTS + BEMAN_STR_SPLIT_BUILD_TESTS "Enable building tests and test infrastructure. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." ${PROJECT_IS_TOP_LEVEL} ) # [CMAKE.SKIP_EXAMPLES] option( - BEMAN_EXEMPLAR_BUILD_EXAMPLES + BEMAN_STR_SPLIT_BUILD_EXAMPLES "Enable building examples. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." ${PROJECT_IS_TOP_LEVEL} ) -option(BEMAN_EXEMPLAR_USE_MODULES "Provide beman.exemplar as a C++ module" OFF) +option(BEMAN_STR_SPLIT_USE_MODULES "Provide beman.str_split as a C++ module" OFF) -if(BEMAN_EXEMPLAR_USE_MODULES) +if(BEMAN_STR_SPLIT_USE_MODULES) set(CMAKE_CXX_SCAN_FOR_MODULES ON) endif() configure_file( - "${PROJECT_SOURCE_DIR}/include/beman/exemplar/config_generated.hpp.in" - "${PROJECT_BINARY_DIR}/include/beman/exemplar/config_generated.hpp" + "${PROJECT_SOURCE_DIR}/include/beman/str_split/config_generated.hpp.in" + "${PROJECT_BINARY_DIR}/include/beman/str_split/config_generated.hpp" @ONLY ) @@ -41,16 +41,16 @@ configure_file( include(infra/cmake/beman-install-library.cmake) include(infra/cmake/BuildTelemetryConfig.cmake) -if(BEMAN_EXEMPLAR_USE_MODULES) - add_library(beman.exemplar STATIC) +if(BEMAN_STR_SPLIT_USE_MODULES) + add_library(beman.str_split STATIC) else() - add_library(beman.exemplar INTERFACE) + add_library(beman.str_split INTERFACE) endif() -add_library(beman::exemplar ALIAS beman.exemplar) +add_library(beman::str_split ALIAS beman.str_split) -if(BEMAN_EXEMPLAR_USE_MODULES) +if(BEMAN_STR_SPLIT_USE_MODULES) target_sources( - beman.exemplar + beman.str_split PUBLIC FILE_SET CXX_MODULES FILE_SET HEADERS @@ -58,11 +58,11 @@ if(BEMAN_EXEMPLAR_USE_MODULES) "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" ) - set_target_properties(beman.exemplar PROPERTIES CXX_MODULE_STD ON) - target_compile_features(beman.exemplar PUBLIC cxx_std_23) + set_target_properties(beman.str_split PROPERTIES CXX_MODULE_STD ON) + target_compile_features(beman.str_split PUBLIC cxx_std_23) else() target_sources( - beman.exemplar + beman.str_split PUBLIC FILE_SET HEADERS BASE_DIRS @@ -70,21 +70,21 @@ else() "${CMAKE_CURRENT_BINARY_DIR}/include" ) set_target_properties( - beman.exemplar + beman.str_split PROPERTIES VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL} ) endif() -add_subdirectory(include/beman/exemplar) +add_subdirectory(include/beman/str_split) -beman_install_library(beman.exemplar TARGETS beman.exemplar) +beman_install_library(beman.str_split TARGETS beman.str_split) configure_build_telemetry() -if(BEMAN_EXEMPLAR_BUILD_TESTS) +if(BEMAN_STR_SPLIT_BUILD_TESTS) enable_testing() - add_subdirectory(tests/beman/exemplar) + add_subdirectory(tests/beman/str_split) endif() -if(BEMAN_EXEMPLAR_BUILD_EXAMPLES) +if(BEMAN_STR_SPLIT_BUILD_EXAMPLES) add_subdirectory(examples) endif() diff --git a/CMakePresets.json b/CMakePresets.json index aa46219..bd35911 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -7,7 +7,7 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { - "CMAKE_CXX_STANDARD": "17", + "CMAKE_CXX_STANDARD": "23", "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", "CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "./infra/cmake/use-fetch-content.cmake" } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42e2f3d..28ed571 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,7 +43,7 @@ that this requires GoogleTest to be installed. cmake \ -B build \ -S . \ - -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_CXX_STANDARD=23 \ # Your extra arguments here. cmake --build build ctest --test-dir build @@ -85,7 +85,7 @@ vcpkg. ### FetchContent Instead of installing the project's dependencies via a package manager, you can optionally -configure beman.exemplar to fetch them automatically via CMake FetchContent. +configure beman.str_split to fetch them automatically via CMake FetchContent. To do so, specify `-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake`. This will @@ -97,7 +97,7 @@ Example commands: cmake \ -B build \ -S . \ - -DCMAKE_CXX_STANDARD=17 \ + -DCMAKE_CXX_STANDARD=23 \ -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake cmake --build build ctest --test-dir build @@ -108,32 +108,32 @@ acquired by FetchContent. ## Project-specific configure arguments -Project-specific options are prefixed with `BEMAN_EXEMPLAR`. +Project-specific options are prefixed with `BEMAN_STR_SPLIT`. You can see the list of available options with: ```bash -cmake -LH -S . -B build | grep "BEMAN_EXEMPLAR" -C 2 +cmake -LH -S . -B build | grep "BEMAN_STR_SPLIT" -C 2 ```
Some project-specific configure arguments -### `BEMAN_EXEMPLAR_BUILD_TESTS` +### `BEMAN_STR_SPLIT_BUILD_TESTS` Enable building tests and test infrastructure. Default: `ON`. Values: `{ ON, OFF }`. -### `BEMAN_EXEMPLAR_BUILD_EXAMPLES` +### `BEMAN_STR_SPLIT_BUILD_EXAMPLES` Enable building examples. Default: `ON`. Values: `{ ON, OFF }`. -### `BEMAN_EXEMPLAR_INSTALL_CONFIG_FILE_PACKAGE` +### `BEMAN_STR_SPLIT_INSTALL_CONFIG_FILE_PACKAGE` Enable installing the CMake config file package. Default: `ON`. Values: `{ ON, OFF }`. -This is required so that users of `beman.exemplar` can use -`find_package(beman.exemplar)` to locate the library. +This is required so that users of `beman.str_split` can use +`find_package(beman.str_split)` to locate the library.
diff --git a/README.md b/README.md index 0399d20..082bc75 100644 --- a/README.md +++ b/README.md @@ -1,125 +1,25 @@ -# How to Use This Template - -To create a new Beman library, first click the "Use this template" dropdown in the -top-right and select "Create a new repository": - -
- -
- -This will create a new repository that's an exact copy of exemplar. The next step is to -customize it for your use case. - -To do so, execute the bash script `stamp.sh`. This script will prompt for parameters like -the new library's name, paper number, and description. Then it will replace your exemplar -copy with a stamped-out template containing these parameters and create a corresponding -git commit and branch: - -``` -$ ./stamp.sh - [1/6] project_name (my_project_name): example_library - [2/6] maintainer (your_github_username): your_username - [3/6] minimum_cpp_build_version (20): - [4/6] paper (PnnnnRr): P9999R9 - [5/6] description (Short project description.): - [6/6] Select unit_test_library - 1 - gtest - 2 - catch2 - Choose from [1/2] (1): -Switched to a new branch 'stamp' -Successfully stamped out exemplar template to the new branch 'stamp'. -Try 'git push origin stamp' to push the branch upstream, -then create a pull request. -``` - -From there, you can simply fill in all the remaining parts of the repository that are -labeled 'todo'. - -What follow is an example of a Beman library README. - -# beman.exemplar: A Beman Library Exemplar +# beman.str_split: Stand-alone, easy-to-use string split utilities -![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/bemanproject/exemplar/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/bemanproject/exemplar/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/bemanproject/exemplar/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/exemplar?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg) [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/4qEPK87va) +![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/bemanproject/str_split/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/bemanproject/str_split/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/bemanproject/str_split/badge.svg?branch=main)](https://coveralls.io/github/bemanproject/str_split?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg) -`beman.exemplar` is a minimal C++ library conforming to [The Beman Standard](https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md). -This can be used as a template for those intending to write Beman libraries. -It may also find use as a minimal and modern C++ project structure. +`beman.str_split` is (... TODO: description). -**Implements**: `std::identity` proposed in [Standard Library Concepts (P0898R3)](https://wg21.link/P0898R3). +**Implements**: `std::todo` proposed in [TODO (PnnnnRr)](https://wg21.link/PnnnnRr). **Status**: [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#under-development-and-not-yet-ready-for-production-use) ## License -`beman.exemplar` is licensed under the Apache License v2.0 with LLVM Exceptions. +`beman.str_split` is licensed under the Apache License v2.0 with LLVM Exceptions. ## Usage -`std::identity` is a function object type whose `operator()` returns its argument unchanged. -`std::identity` serves as the default projection in constrained algorithms. -Its direct usage is usually not needed. - -### Usage: default projection in constrained algorithms - -The following code snippet illustrates how we can achieve a default projection using `beman::exemplar::identity`: - -```cpp -#include - -namespace exe = beman::exemplar; - -// Class with a pair of values. -struct Pair -{ - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream &operator<<(std::ostream &os, const Pair &p) - { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print(const std::string_view rem, R &&range, Projection projection = exe::identity>) -{ - std::cout << rem << '{'; - std::ranges::for_each( - range, - [O = 0](const auto &o) mutable - { std::cout << (O++ ? ", " : "") << o; }, - projection); - std::cout << "}\n"; -}; - -int main() -{ - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - print("\tpairs with beman: ", pairs); - - return 0; -} - -``` +TODO Full runnable examples can be found in [`examples/`](examples/). @@ -129,11 +29,11 @@ Full runnable examples can be found in [`examples/`](examples/). This project requires at least the following to build: -* A C++ compiler that conforms to the C++17 standard or greater +* A C++ compiler that conforms to the C++23 standard or greater * CMake 3.30 or later * (Test Only) GoogleTest -You can disable building tests by setting CMake option `BEMAN_EXEMPLAR_BUILD_TESTS` to +You can disable building tests by setting CMake option `BEMAN_STR_SPLIT_BUILD_TESTS` to `OFF` when configuring the project. ### Supported Platforms @@ -154,11 +54,11 @@ You can disable building tests by setting CMake option `BEMAN_EXEMPLAR_BUILD_TES See the [Contributing Guidelines](CONTRIBUTING.md). -## Integrate beman.exemplar into your project +## Integrate beman.str_split into your project ### Build -You can build exemplar using a CMake workflow preset: +You can build str_split using a CMake workflow preset: ```bash cmake --workflow --preset gcc-release @@ -170,23 +70,23 @@ To list available workflow presets, you can invoke: cmake --list-presets=workflow ``` -For details on building beman.exemplar without using a CMake preset, refer to the +For details on building beman.str_split without using a CMake preset, refer to the [Contributing Guidelines](CONTRIBUTING.md). ### Installation #### Vcpkg -The preferred way to install exemplar is via vcpkg. To do so, after installing vcpkg +The preferred way to install str_split is via vcpkg. To do so, after installing vcpkg itself, you need to add support for the Beman project's [vcpkg registry](https://github.com/bemanproject/vcpkg-registry) by configuring a -`vcpkg-configuration.json` file (which exemplar [provides](vcpkg-configuration.json)). +`vcpkg-configuration.json` file (which str_split [provides](vcpkg-configuration.json)). -Then, simply run `vcpkg install beman-exemplar`. +Then, simply run `vcpkg install beman-str-split`. #### Manual -To install beman.exemplar globally after building with the `gcc-release` preset, you can +To install beman.str_split globally after building with the `gcc-release` preset, you can run: ```bash @@ -205,47 +105,47 @@ This will generate the following directory structure: /opt/beman ├── include │ └── beman -│ └── exemplar -│ ├── exemplar.hpp +│ └── str_split +│ ├── str_split.hpp │ └── ... └── lib └── cmake - └── beman.exemplar - ├── beman.exemplar-config-version.cmake - ├── beman.exemplar-config.cmake - └── beman.exemplar-targets.cmake + └── beman.str_split + ├── beman.str_split-config-version.cmake + ├── beman.str_split-config.cmake + └── beman.str_split-targets.cmake ``` ### CMake Configuration -If you installed beman.exemplar to a prefix, you can specify that prefix to your CMake +If you installed beman.str_split to a prefix, you can specify that prefix to your CMake project using `CMAKE_PREFIX_PATH`; for example, `-DCMAKE_PREFIX_PATH=/opt/beman`. -You need to bring in the `beman.exemplar` package to define the `beman::exemplar` CMake +You need to bring in the `beman.str_split` package to define the `beman::str_split` CMake target: ```cmake -find_package(beman.exemplar REQUIRED) +find_package(beman.str_split REQUIRED) ``` -You will then need to add `beman::exemplar` to the link libraries of any libraries or -executables that include `beman.exemplar` headers. +You will then need to add `beman::str_split` to the link libraries of any libraries or +executables that include `beman.str_split` headers. ```cmake -target_link_libraries(yourlib PUBLIC beman::exemplar) +target_link_libraries(yourlib PUBLIC beman::str_split) ``` -### Using beman.exemplar +### Using beman.str_split -To use `beman.exemplar` in your C++ project, -include an appropriate `beman.exemplar` header from your source code. +To use `beman.str_split` in your C++ project, +include an appropriate `beman.str_split` header from your source code. ```c++ -#include +#include ``` > [!NOTE] > -> `beman.exemplar` headers are to be included with the `beman/exemplar/` prefix. +> `beman.str_split` headers are to be included with the `beman/str_split/` prefix. > Altering include search paths to spell the include target another way (e.g. -> `#include `) is unsupported. +> `#include `) is unsupported. diff --git a/cookiecutter/check_cookiecutter.sh b/cookiecutter/check_cookiecutter.sh deleted file mode 100755 index 394cca7..0000000 --- a/cookiecutter/check_cookiecutter.sh +++ /dev/null @@ -1,101 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#!/usr/bin/env bash - -set -euo pipefail - -declare script_dir=$(realpath $(dirname "$BASH_SOURCE")) - -function stamp() { - local cookiecutter_dir="$1" ; shift - local output_dir="$1" ; shift - local unit_test_library="$1" ; shift - local generating_exemplar="$1" ; shift - python3 \ - -m cookiecutter \ - --no-input \ - --output-dir "$output_dir" \ - "$cookiecutter_dir" \ - project_name="exemplar" \ - minimum_cpp_build_version="17" \ - paper="P0898R3" \ - description="A Beman Library Exemplar" \ - unit_test_library="$unit_test_library" \ - _generating_exemplar="$generating_exemplar" \ - _ci_tests_cron="30 15 * * 6" \ - _pre_commit_update_cron="0 16 * * 0" -} - -function check_consistency() { - local out_dir_path - out_dir_path=$(mktemp --directory --dry-run) - cd /tmp - stamp "$script_dir" "$out_dir_path" "gtest" "true" - cp "$script_dir"/../.github/workflows/cookiecutter_test.yml "$out_dir_path"/exemplar/.github/workflows - cp "$script_dir"/../.github/workflows/catch2_exemplar_test.yml "$out_dir_path"/exemplar/.github/workflows - cp "$script_dir"/../.github/workflows/todo_exemplar_test.yml "$out_dir_path"/exemplar/.github/workflows - mkdir "$out_dir_path"/exemplar/images - cp "$script_dir"/../images/use-this-template.png "$out_dir_path"/exemplar/images/use-this-template.png - cp "$script_dir"/../stamp.sh "$out_dir_path"/exemplar/stamp.sh - local diff_path - diff_path=$(mktemp) - diff -r "$script_dir/.." "$out_dir_path/exemplar" \ - | grep -v -e 'cookiecutter$' -e '.git$' > "$diff_path" || true - rm -rf "$out_dir_path" - if [[ $(wc -l "$diff_path" | cut -d' ' -f1) -gt 0 ]] ; then - echo "Discrepancy between exemplar and cookiecutter:" >&2 - cat "$diff_path" - rm "$diff_path" - exit 1 - fi - rm "$diff_path" -} - -function check_templating() { - local out_dir_path - out_dir_path=$(mktemp --directory --dry-run) - cd /tmp - python3 \ - -m cookiecutter \ - --no-input \ - --output-dir "$out_dir_path" \ - "$script_dir" \ - project_name="RLZrmX9NfS" \ - minimum_cpp_build_version="17" \ - paper="P0898R3" \ - description="A Beman Library RLZrmX9NfS" \ - _generating_exemplar="false" \ - _ci_tests_cron="30 15 * * 6" \ - _pre_commit_update_cron="0 16 * * 0" - rm -rf "$out_dir_path/RLZrmX9NfS/infra" - local grep_path - grep_path=$(mktemp) - grep \ - --dereference-recursive --context=5 --color=always \ - -e "exemplar" -e "identity" "$out_dir_path/RLZrmX9NfS" > "$grep_path" || true - rm -rf "$out_dir_path" - if [[ $(wc -l "$grep_path" | cut -d' ' -f1) -gt 0 ]] ; then - echo "Untemplated \"exemplar\" or \"identity\" in cookiecutter:" >&2 - cat "$grep_path" - rm "$grep_path" - exit 1 - fi - rm "$grep_path" -} - -function setup_venv() { - local path="$1" ; shift - python3 -m venv "$cookiecutter_venv_path" - source "$cookiecutter_venv_path/bin/activate" - python3 -m pip install cookiecutter >& /dev/null -} - -function main() { - local cookiecutter_venv_path - cookiecutter_venv_path=$(mktemp --directory --dry-run) - setup_venv "$cookiecutter_venv_path" - check_consistency - check_templating - rm -rf "$cookiecutter_venv_path" -} - -[[ "${BASH_SOURCE[0]}" != "${0}" ]] || main "$@" diff --git a/cookiecutter/cookiecutter.json b/cookiecutter/cookiecutter.json deleted file mode 100644 index bb406fe..0000000 --- a/cookiecutter/cookiecutter.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "project_name": "my_project_name", - "maintainer": "your_github_username", - "minimum_cpp_build_version": "20", - "paper": "PnnnnRr", - "description": "Short project description.", - "unit_test_library": ["gtest", "catch2"], - "_generating_exemplar": false, - "_owner": "bemanproject", - "_ci_tests_cron": "", - "_pre_commit_update_cron": "", - "_copy_without_render": [ - "infra" - ], - "_jinja2_env_vars": {"trim_blocks": true} -} diff --git a/cookiecutter/hooks/post_gen_project.py b/cookiecutter/hooks/post_gen_project.py deleted file mode 100755 index 9965c4c..0000000 --- a/cookiecutter/hooks/post_gen_project.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -import shutil -import subprocess -from pathlib import Path -import os - -project_name = "{{ cookiecutter.project_name }}" -generating_exemplar = "{{ cookiecutter._generating_exemplar }}" == "True" - -if not generating_exemplar: - os.rename("include/beman/" + project_name + "/identity.hpp", "include/beman/" + project_name + "/todo.hpp") - os.rename("examples/identity_direct_usage.cpp", "examples/todo.cpp") - os.remove("examples/identity_as_default_projection.cpp") - os.rename("tests/beman/" + project_name + "/identity.test.cpp", "tests/beman/" + project_name + "/todo.test.cpp") - - # Record the exemplar commit this project was stamped from. - result = subprocess.run( - ["git", "ls-remote", "https://github.com/bemanproject/exemplar.git", "HEAD"], - capture_output=True, - text=True, - check=True, - ) - sha = result.stdout.split()[0] - Path(".exemplar_version").write_text(sha + "\n") diff --git a/cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml b/cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml deleted file mode 100644 index 527ca1e..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.beman-tidy.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This is the config file for beman-tidy, which checks compliance with the Beman Standard (https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md) -# Check documentation for beman-tidy here: -# https://github.com/bemanproject/beman-tidy/blob/main/README.md - -{% if cookiecutter._generating_exemplar %} -disabled_rules: - - readme.title -{% else %} -disabled_rules: - # None -{% endif %} -ignored_paths: - # None diff --git a/cookiecutter/{{cookiecutter.project_name}}/.clang-format b/cookiecutter/{{cookiecutter.project_name}}/.clang-format deleted file mode 100644 index 74f95dc..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.clang-format +++ /dev/null @@ -1,242 +0,0 @@ ---- -Language: Cpp -AccessModifierOffset: -2 -AlignAfterOpenBracket: Align -AlignArrayOfStructures: None -AlignConsecutiveAssignments: - Enabled: true - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: true -AlignConsecutiveBitFields: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: false -AlignConsecutiveDeclarations: - Enabled: true - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: true -AlignConsecutiveMacros: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCompound: false - PadOperators: false -AlignConsecutiveShortCaseStatements: - Enabled: false - AcrossEmptyLines: false - AcrossComments: false - AlignCaseColons: false -AlignEscapedNewlines: Left -AlignOperands: Align -AlignTrailingComments: - Kind: Always - OverEmptyLines: 0 -AllowAllArgumentsOnNextLine: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: Never -AllowShortCaseLabelsOnASingleLine: false -AllowShortEnumsOnASingleLine: true -AllowShortFunctionsOnASingleLine: All -AllowShortIfStatementsOnASingleLine: Never -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: Yes -AttributeMacros: - - __capability -BinPackArguments: false -BinPackParameters: false -BitFieldColonSpacing: Both -BraceWrapping: - AfterCaseLabel: false - AfterClass: false - AfterControlStatement: Never - AfterEnum: false - AfterExternBlock: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: false - BeforeElse: false - BeforeLambdaBody: false - BeforeWhile: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakAfterAttributes: Never -BreakAfterJavaFieldAnnotations: false -BreakArrays: true -BreakBeforeBinaryOperators: None -BreakBeforeConceptDeclarations: Always -BreakBeforeBraces: Custom -BreakBeforeInlineASMColon: OnlyMultiline -BreakBeforeTernaryOperators: true -BreakConstructorInitializers: BeforeColon -BreakInheritanceList: BeforeColon -BreakStringLiterals: true -# Please update .markdownlint.yaml if this line is to be updated -ColumnLimit: 119 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -EmptyLineAfterAccessModifier: Never -EmptyLineBeforeAccessModifier: LogicalBlock -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IfMacros: - - KJ_IF_MAYBE -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - CaseSensitive: false - - Regex: '^(<|"(gtest|isl|json)/)' - Priority: 3 - SortPriority: 0 - CaseSensitive: false - - Regex: '.*' - Priority: 1 - SortPriority: 0 - CaseSensitive: false -IncludeIsMainRegex: '$' -IncludeIsMainSourceRegex: '' -IndentAccessModifiers: false -IndentCaseBlocks: false -IndentCaseLabels: false -IndentExternBlock: AfterExternBlock -IndentGotoLabels: true -IndentPPDirectives: BeforeHash -IndentRequiresClause: true -IndentWidth: 4 -IndentWrappedFunctionNames: false -InsertBraces: false -InsertNewlineAtEOF: false -InsertTrailingCommas: None -IntegerLiteralSeparator: - Binary: 0 - BinaryMinDigits: 0 - Decimal: 0 - DecimalMinDigits: 0 - Hex: 0 - HexMinDigits: 0 -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -KeepEmptyLinesAtEOF: false -LambdaBodyIndentation: Signature -LineEnding: DeriveLF -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBinPackProtocolList: Auto -ObjCBlockIndentWidth: 4 -ObjCBreakBeforeNestedBlockParam: true -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PackConstructorInitializers: NextLine -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 19 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakOpenParenthesis: 0 -PenaltyBreakString: 1000 -PenaltyBreakTemplateDeclaration: 10 -PenaltyExcessCharacter: 1000000 -PenaltyIndentedWhitespace: 0 -PenaltyReturnTypeOnItsOwnLine: 60 -PointerAlignment: Left -PPIndentWidth: -1 -QualifierAlignment: Custom -QualifierOrder: - - inline - - static - - constexpr - - const - - volatile - - type -ReferenceAlignment: Pointer -ReflowComments: true -RemoveBracesLLVM: false -RemoveParentheses: Leave -RemoveSemicolon: false -RequiresClausePosition: OwnLine -RequiresExpressionIndentation: OuterScope -SeparateDefinitionBlocks: Leave -ShortNamespaceLines: 1 -SortIncludes: Never -SortJavaStaticImport: Before -SortUsingDeclarations: LexicographicNumeric -SpaceAfterCStyleCast: false -SpaceAfterLogicalNot: false -SpaceAfterTemplateKeyword: true -SpaceAroundPointerQualifiers: Default -SpaceBeforeAssignmentOperators: true -SpaceBeforeCaseColon: false -SpaceBeforeCpp11BracedList: false -SpaceBeforeCtorInitializerColon: true -SpaceBeforeInheritanceColon: true -SpaceBeforeJsonColon: false -SpaceBeforeParens: ControlStatements -SpaceBeforeParensOptions: - AfterControlStatements: true - AfterForeachMacros: true - AfterFunctionDefinitionName: false - AfterFunctionDeclarationName: false - AfterIfMacros: true - AfterOverloadedOperator: false - AfterRequiresInClause: false - AfterRequiresInExpression: false - BeforeNonEmptyParentheses: false -SpaceBeforeRangeBasedForLoopColon: true -SpaceBeforeSquareBrackets: false -SpaceInEmptyBlock: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: Never -SpacesInContainerLiterals: true -SpacesInLineCommentPrefix: - Minimum: 1 - Maximum: -1 -SpacesInParens: Never -SpacesInParensOptions: - InCStyleCasts: false - InConditionalStatements: false - InEmptyParentheses: false - Other: false -SpacesInSquareBrackets: false -Standard: Auto -StatementAttributeLikeMacros: - - Q_EMIT -StatementMacros: - - Q_UNUSED - - QT_REQUIRE_VERSION -TabWidth: 8 -UseTab: Never -VerilogBreakBetweenInstancePorts: true -WhitespaceSensitiveMacros: - - STRINGIZE - - PP_STRINGIZE - - BOOST_PP_STRINGIZE - - NS_SWIFT_NAME - - CF_SWIFT_NAME -... diff --git a/cookiecutter/{{cookiecutter.project_name}}/.gitattributes b/cookiecutter/{{cookiecutter.project_name}}/.gitattributes deleted file mode 100644 index 793dce7..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.gitattributes +++ /dev/null @@ -1,5 +0,0 @@ -infra/** linguist-vendored -cookiecutter/** linguist-vendored -*.bib -linguist-detectable -*.tex -linguist-detectable -papers/* linguist-documentation diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS b/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS deleted file mode 100644 index cced7b3..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/CODEOWNERS +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -{% if cookiecutter._generating_exemplar %} -* @ednolan @bretbrownjr @camio @dietmarkuehl @steve-downey @wusatosi -{% else %} -* @{{ cookiecutter.maintainer }} -{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md b/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md deleted file mode 100644 index 4a0ee77..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/implementation-deficiency.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: Implementation Deficiency -about: Report a bug or performance issue of our implementation -title: '' -labels: bug -assignees: '' - ---- - - - -## Describe the deficiency - -A clear and concise description of what the deficiency is. -Link all relevant issues. -This could be a bug, or a performance problem. - -## To Reproduce - -```c++ -// Use case -``` - -## Expected Behavior - -A clear and concise description of what you expected to happen. - -## Additional Discussions - -Add any other context about the problem here. -If you believe your issue is platform dependent, -please post your compiler versions here. diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md b/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md deleted file mode 100644 index 11fbd13..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/infrastructure-issues.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: Infrastructure Issues -about: Report a bug or feature request with our Infrastructure -title: '' -labels: infra -assignees: '' - ---- - - - -## I am attempting to - -Describe what you were attempting to do. - -## Expected Behavior - -A clear and concise description of what you expected to happen. - -## Current Behavior - -A clear and concise description of what actually happened. - -## Additional Discussions - -Add any other context about the problem here. diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md b/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md deleted file mode 100644 index 14c9e4f..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/ISSUE_TEMPLATE/paper-discussion.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: Paper Discussion -about: Provide feedback to current API -title: '' -labels: '' -assignees: '' - ---- - - - -## Use case - -Describe your concerns about adding this change to the C++ Standard Library. - -```c++ -// example snippet -``` - -## What I like - -Let us know what you find positive about current approach / design. - -## What I dislike - -Let us know what you find negative about current approach / design. - -## Discussion - -Let us know if you have any more remarks. diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md b/cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md deleted file mode 100644 index 071cb28..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/pull_request_template.md +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml deleted file mode 100644 index 94d3bf1..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/ci_tests.yml +++ /dev/null @@ -1,203 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: Continuous Integration Tests - -on: - push: - branches: - - main - pull_request: - workflow_dispatch: - schedule: - - cron: '{% if cookiecutter._ci_tests_cron %}{{ cookiecutter._ci_tests_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}' - -concurrency: - group: {% raw %}${{format('{0}:{1}', github.repository, github.ref)}}{% endraw %} - - cancel-in-progress: true - -jobs: - beman-submodule-check: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-submodule-check.yml@1.7.2 - - preset-test: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-preset-test.yml@1.7.2 - with: - matrix_config: > - [ - {"preset": "gcc-debug", "image": "ghcr.io/bemanproject/infra-containers-gcc:latest"}, - {"preset": "gcc-release", "image": "ghcr.io/bemanproject/infra-containers-gcc:latest"}, - {"preset": "llvm-debug", "image": "ghcr.io/bemanproject/infra-containers-clang:latest"}, - {"preset": "llvm-release", "image": "ghcr.io/bemanproject/infra-containers-clang:latest"}, - {"preset": "appleclang-debug", "runner": "macos-latest"}, - {"preset": "appleclang-release", "runner": "macos-latest"}, - {"preset": "msvc-debug", "runner": "windows-latest"}, - {"preset": "msvc-release", "runner": "windows-latest"} - ] - - build-and-test: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-build-and-test.yml@1.7.2 - with: - matrix_config: > - { - "gcc": [ - { "versions": ["16"], - "tests": [ - { "cxxversions": ["c++26"], - "tests": [ - { "stdlibs": ["libstdc++"], - "tests": [ - "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", - "Debug.Coverage", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" - ] - } - ] - }, - { "cxxversions": ["c++23"], - "tests": [ - { "stdlibs": ["libstdc++"], - "tests": [ - "Release.Default", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" - ] - } - ] - }, - { "cxxversions": ["c++20", "c++17"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - }, - { "versions": ["15"], - "tests": [ - { "cxxversions": ["c++26", "c++23"], - "tests": [ - { "stdlibs": ["libstdc++"], - "tests": [ - "Release.Default", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" - ] - } - ] - }, - { "cxxversions": ["c++20", "c++17"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - }, - { "versions": ["14", "13"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - }, - { - "versions": ["12", "11"], - "tests": [ - { "cxxversions": ["c++23", "c++20", "c++17"], - "tests": [{ "stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - } - ], - "clang": [ - { "versions": ["22"], - "tests": [ - {"cxxversions": ["c++26"], - "tests": [ - { "stdlibs": ["libstdc++", "libc++"], - "tests": [ - "Debug.Default", "Release.Default", "Release.TSan", - "Release.MaxSan", "Debug.Werror", - "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" - ] - } - ] - }, - { "cxxversions": ["c++23"], - "tests": [ - { "stdlibs": ["libstdc++", "libc++"], - "tests": [ - "Release.Default", "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" - ] - } - ] - }, - { "cxxversions": ["c++20", "c++17"], - "tests": [ - {"stdlibs": ["libstdc++", "libc++"], "tests": ["Release.Default"]} - ] - } - ] - }, - { "versions": ["21", "20", "19"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [ - {"stdlibs": ["libstdc++", "libc++"], "tests": ["Release.Default"]} - ] - } - ] - }, - { "versions": ["18"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [{"stdlibs": ["libc++"], "tests": ["Release.Default"]}] - }, - { "cxxversions": ["c++23", "c++20", "c++17"], - "tests": [{"stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - }, - { "versions": ["17"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [{"stdlibs": ["libc++"], "tests": ["Release.Default"]}] - }, - { "cxxversions": ["c++20", "c++17"], - "tests": [{"stdlibs": ["libstdc++"], "tests": ["Release.Default"]}] - } - ] - } - ], - "appleclang": [ - { "versions": ["latest"], - "tests": [ - { "cxxversions": ["c++26", "c++23", "c++20", "c++17"], - "tests": [{ "stdlibs": ["libc++"], "tests": ["Release.Default"]}] - } - ] - } - ], - "msvc": [ - { "versions": ["latest"], - "tests": [ - { "cxxversions": ["c++23"], - "tests": [ - { "stdlibs": ["stl"], - "tests": [ - "Debug.Default", "Release.Default", "Release.MaxSan", - "Debug.-DBEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES=On" - ] - } - ] - } - ] - } - ] - } - - vcpkg-ci: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-vcpkg-ci.yml@1.7.2 - with: - port_name: beman-{{cookiecutter.project_name.replace('_', '-')}} - feature_combinations: | - [ - {"features": {}}, - {"features": {"modules": true}} - ] - - create-issue-when-fault: - needs: [preset-test, build-and-test] - if: failure() && github.event_name == 'schedule' - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-create-issue-when-fault.yml@1.7.2 diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml deleted file mode 100644 index 2ab92f2..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-check.yml +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -name: Lint Check (pre-commit) - -on: - # We have to use pull_request_target here as pull_request does not grant - # enough permission for reviewdog - pull_request_target: - push: - branches: - - main - -permissions: - contents: read - checks: write - issues: write - pull-requests: write - -jobs: - pre-commit: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-pre-commit.yml@1.7.2 diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml deleted file mode 100644 index 5b54ccb..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/pre-commit-update.yml +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: Weekly pre-commit autoupdate - -on: - workflow_dispatch: - schedule: - - cron: "{% if cookiecutter._pre_commit_update_cron %}{{ cookiecutter._pre_commit_update_cron }}{% else %}{{ range(0, 60) | random }} {{ range(13, 18) | random }} * * {{ range(0, 7) | random }}{% endif %}" - -{% raw -%} -jobs: - auto-update-pre-commit: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-update-pre-commit.yml@1.7.2 - secrets: - APP_ID: ${{ secrets.AUTO_PR_BOT_APP_ID }} - PRIVATE_KEY: ${{ secrets.AUTO_PR_BOT_PRIVATE_KEY }} -{%- endraw %} - diff --git a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml b/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml deleted file mode 100644 index f603636..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.github/workflows/vcpkg-release.yml +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: vcpkg registry release -on: - release: - types: [published] -jobs: - vcpkg-release: - uses: bemanproject/infra-workflows/.github/workflows/reusable-beman-vcpkg-release.yml@1.7.2 - with: - port_name: beman-{{cookiecutter.project_name.replace('_', '-')}} -{%- raw %} - secrets: - VCPKG_REGISTRY_TOKEN: ${{ secrets.VCPKG_REGISTRY_TOKEN }} -{%- endraw %} - diff --git a/cookiecutter/{{cookiecutter.project_name}}/.gitignore b/cookiecutter/{{cookiecutter.project_name}}/.gitignore deleted file mode 100644 index d62996c..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -/.cache -/compile_commands.json -/build - -# ignore emacs temp files -*~ -\#*\# - -# ignore vscode settings -.vscode - -# ignore vim swap files -.swp - -# ignore merge/patch backup files -.orig diff --git a/cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml b/cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml deleted file mode 100644 index 48269b5..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.markdownlint.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# MD033/no-inline-html : Inline HTML : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md033.md -# Disable inline html linter is needed for
-MD033: false - -# MD013/line-length : Line length : https://github.com/DavidAnson/markdownlint/blob/v0.35.0/doc/md013.md -# Conforms to .clang-format ColumnLimit -# Update the comment in .clang-format if we no-longer tie these two column limits. -MD013: - line_length: 119 - code_blocks: false diff --git a/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml b/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml deleted file mode 100644 index 3845c97..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/.pre-commit-config.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# See https://pre-commit.com for more information -# See https://pre-commit.com/hooks.html for more hooks -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files - - # Clang-format for C++ - # This brings in a portable version of clang-format. - # See also: https://github.com/ssciwr/clang-format-wheel - - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v22.1.4 - hooks: - - id: clang-format - types_or: [c++, c] - - # CMake linting and formatting - - repo: https://github.com/BlankSpruce/gersemi-pre-commit - rev: 0.27.2 - hooks: - - id: gersemi - name: CMake linting - exclude: ^.*/tests/.*/data/ # Exclude test data directories - - # Markdown linting - # Config file: .markdownlint.yaml - # Commented out to disable this by default. Uncomment to enable markdown linting. - # - repo: https://github.com/igorshubovych/markdownlint-cli - # rev: v0.42.0 - # hooks: - # - id: markdownlint - - - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 - hooks: - - id: codespell - -{% if not cookiecutter._generating_exemplar %} - # Beman Standard checking via beman-tidy - - repo: https://github.com/bemanproject/beman-tidy - rev: v0.3.1 - hooks: - - id: beman-tidy - -{% endif %} -exclude: 'cookiecutter/|infra/|port/' diff --git a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index 8018142..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,94 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -cmake_minimum_required(VERSION 3.30...4.3) - -include(infra/cmake/enable-experimental-import-std.cmake) - -project( - beman.{{cookiecutter.project_name}} - DESCRIPTION "{{cookiecutter.description}}" - LANGUAGES CXX -{% if cookiecutter._generating_exemplar %} - VERSION 2.4.0 -{% else %} - VERSION 0.1.0 -{% endif %} -) - -# [CMAKE.SKIP_TESTS] -option( - BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS - "Enable building tests and test infrastructure. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." - ${PROJECT_IS_TOP_LEVEL} -) - -# [CMAKE.SKIP_EXAMPLES] -option( - BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES - "Enable building examples. Default: ${PROJECT_IS_TOP_LEVEL}. Values: { ON, OFF }." - ${PROJECT_IS_TOP_LEVEL} -) - -option(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES "Provide beman.{{cookiecutter.project_name}} as a C++ module" OFF) - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - set(CMAKE_CXX_SCAN_FOR_MODULES ON) -endif() - -configure_file( - "${PROJECT_SOURCE_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in" - "${PROJECT_BINARY_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp" - @ONLY -) - -# for find of beman_install_library and configure_build_telemetry -include(infra/cmake/beman-install-library.cmake) -include(infra/cmake/BuildTelemetryConfig.cmake) - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - add_library(beman.{{cookiecutter.project_name}} STATIC) -else() - add_library(beman.{{cookiecutter.project_name}} INTERFACE) -endif() -add_library(beman::{{cookiecutter.project_name}} ALIAS beman.{{cookiecutter.project_name}}) - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET CXX_MODULES - FILE_SET HEADERS - BASE_DIRS - "${CMAKE_CURRENT_SOURCE_DIR}/include" - "${CMAKE_CURRENT_BINARY_DIR}/include" - ) - set_target_properties(beman.{{cookiecutter.project_name}} PROPERTIES CXX_MODULE_STD ON) - target_compile_features(beman.{{cookiecutter.project_name}} PUBLIC cxx_std_23) -else() - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET HEADERS - BASE_DIRS - "${CMAKE_CURRENT_SOURCE_DIR}/include" - "${CMAKE_CURRENT_BINARY_DIR}/include" - ) - set_target_properties( - beman.{{cookiecutter.project_name}} - PROPERTIES VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL} - ) -endif() - -add_subdirectory(include/beman/{{cookiecutter.project_name}}) - -beman_install_library(beman.{{cookiecutter.project_name}} TARGETS beman.{{cookiecutter.project_name}}) -configure_build_telemetry() - -if(BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS) - enable_testing() - add_subdirectory(tests/beman/{{cookiecutter.project_name}}) -endif() - -if(BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES) - add_subdirectory(examples) -endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json b/cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json deleted file mode 100644 index cd426be..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/CMakePresets.json +++ /dev/null @@ -1,373 +0,0 @@ -{ - "version": 6, - "configurePresets": [ - { - "name": "_root-config", - "hidden": true, - "generator": "Ninja", - "binaryDir": "${sourceDir}/build/${presetName}", - "cacheVariables": { - "CMAKE_CXX_STANDARD": "{{cookiecutter.minimum_cpp_build_version}}", - "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", - "CMAKE_PROJECT_TOP_LEVEL_INCLUDES": "./infra/cmake/use-fetch-content.cmake" - } - }, - { - "name": "_debug-base", - "hidden": true, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Debug", - "BEMAN_BUILDSYS_SANITIZER": "MaxSan" - } - }, - { - "name": "_release-base", - "hidden": true, - "cacheVariables": { - "CMAKE_BUILD_TYPE": "RelWithDebInfo" - } - }, - { - "name": "gcc-debug", - "displayName": "GCC Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/gnu-toolchain.cmake" - } - }, - { - "name": "gcc-release", - "displayName": "GCC Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/gnu-toolchain.cmake" - } - }, - { - "name": "llvm-debug", - "displayName": "Clang Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-toolchain.cmake" - } - }, - { - "name": "llvm-release", - "displayName": "Clang Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/llvm-toolchain.cmake" - } - }, - { - "name": "appleclang-debug", - "displayName": "Appleclang Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/appleclang-toolchain.cmake" - } - }, - { - "name": "appleclang-release", - "displayName": "Appleclang Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/appleclang-toolchain.cmake" - } - }, - { - "name": "msvc-debug", - "displayName": "MSVC Debug Build", - "inherits": [ - "_root-config", - "_debug-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake" - } - }, - { - "name": "msvc-release", - "displayName": "MSVC Release Build", - "inherits": [ - "_root-config", - "_release-base" - ], - "cacheVariables": { - "CMAKE_TOOLCHAIN_FILE": "infra/cmake/msvc-toolchain.cmake" - } - } - ], - "buildPresets": [ - { - "name": "_root-build", - "hidden": true, - "jobs": 0 - }, - { - "name": "gcc-debug", - "configurePreset": "gcc-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "gcc-release", - "configurePreset": "gcc-release", - "inherits": [ - "_root-build" - ] - }, - { - "name": "llvm-debug", - "configurePreset": "llvm-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "llvm-release", - "configurePreset": "llvm-release", - "inherits": [ - "_root-build" - ] - }, - { - "name": "appleclang-debug", - "configurePreset": "appleclang-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "appleclang-release", - "configurePreset": "appleclang-release", - "inherits": [ - "_root-build" - ] - }, - { - "name": "msvc-debug", - "configurePreset": "msvc-debug", - "inherits": [ - "_root-build" - ] - }, - { - "name": "msvc-release", - "configurePreset": "msvc-release", - "inherits": [ - "_root-build" - ] - } - ], - "testPresets": [ - { - "name": "_test_base", - "hidden": true, - "output": { - "outputOnFailure": true - }, - "execution": { - "noTestsAction": "error", - "stopOnFailure": true - } - }, - { - "name": "gcc-debug", - "inherits": "_test_base", - "configurePreset": "gcc-debug" - }, - { - "name": "gcc-release", - "inherits": "_test_base", - "configurePreset": "gcc-release" - }, - { - "name": "llvm-debug", - "inherits": "_test_base", - "configurePreset": "llvm-debug" - }, - { - "name": "llvm-release", - "inherits": "_test_base", - "configurePreset": "llvm-release" - }, - { - "name": "appleclang-debug", - "inherits": "_test_base", - "configurePreset": "appleclang-debug" - }, - { - "name": "appleclang-release", - "inherits": "_test_base", - "configurePreset": "appleclang-release" - }, - { - "name": "msvc-debug", - "inherits": "_test_base", - "configurePreset": "msvc-debug" - }, - { - "name": "msvc-release", - "inherits": "_test_base", - "configurePreset": "msvc-release" - } - ], - "workflowPresets": [ - { - "name": "gcc-debug", - "steps": [ - { - "type": "configure", - "name": "gcc-debug" - }, - { - "type": "build", - "name": "gcc-debug" - }, - { - "type": "test", - "name": "gcc-debug" - } - ] - }, - { - "name": "gcc-release", - "steps": [ - { - "type": "configure", - "name": "gcc-release" - }, - { - "type": "build", - "name": "gcc-release" - }, - { - "type": "test", - "name": "gcc-release" - } - ] - }, - { - "name": "llvm-debug", - "steps": [ - { - "type": "configure", - "name": "llvm-debug" - }, - { - "type": "build", - "name": "llvm-debug" - }, - { - "type": "test", - "name": "llvm-debug" - } - ] - }, - { - "name": "llvm-release", - "steps": [ - { - "type": "configure", - "name": "llvm-release" - }, - { - "type": "build", - "name": "llvm-release" - }, - { - "type": "test", - "name": "llvm-release" - } - ] - }, - { - "name": "appleclang-debug", - "steps": [ - { - "type": "configure", - "name": "appleclang-debug" - }, - { - "type": "build", - "name": "appleclang-debug" - }, - { - "type": "test", - "name": "appleclang-debug" - } - ] - }, - { - "name": "appleclang-release", - "steps": [ - { - "type": "configure", - "name": "appleclang-release" - }, - { - "type": "build", - "name": "appleclang-release" - }, - { - "type": "test", - "name": "appleclang-release" - } - ] - }, - { - "name": "msvc-debug", - "steps": [ - { - "type": "configure", - "name": "msvc-debug" - }, - { - "type": "build", - "name": "msvc-debug" - }, - { - "type": "test", - "name": "msvc-debug" - } - ] - }, - { - "name": "msvc-release", - "steps": [ - { - "type": "configure", - "name": "msvc-release" - }, - { - "type": "build", - "name": "msvc-release" - }, - { - "type": "test", - "name": "msvc-release" - } - ] - } - ] -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md b/cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md deleted file mode 100644 index d15f284..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/CONTRIBUTING.md +++ /dev/null @@ -1,139 +0,0 @@ - - -# Development - -## Configure and Build the Project Using CMake Presets - -The simplest way of configuring and building the project is to use [CMake -Presets](https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html). Appropriate -presets for major compilers have been included by default. You can use `cmake ---list-presets=workflow` to see all available presets. - -Here is an example of invoking the `gcc-debug` preset: - -```shell -cmake --workflow --preset gcc-debug -``` - -Generally, there are two kinds of presets, `debug` and `release`. - -The `debug` presets are designed to aid development, so they have debuginfo and sanitizers -enabled. - -> [!NOTE] -> -> The sanitizers that are enabled vary from compiler to compiler. See the toolchain files -> under ([`infra/cmake`](infra/cmake/)) to determine the exact configuration used for each -> preset. - -The `release` presets are designed for production use, and -consequently have the highest optimization turned on (e.g. `O3`). - -## Configure and Build Manually - -If the presets are not suitable for your use case, a traditional CMake invocation will -provide more configurability. - -To configure, build and test the project manually, you can run this set of commands. Note -that this requires GoogleTest to be installed. - -```bash -cmake \ - -B build \ - -S . \ - -DCMAKE_CXX_STANDARD={{cookiecutter.minimum_cpp_build_version}} \ - # Your extra arguments here. -cmake --build build -ctest --test-dir build -``` - -> [!IMPORTANT] -> -> Beman projects are [passive projects]( -> https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md#cmakepassive_projects), -> so you need to specify the C++ version via `CMAKE_CXX_STANDARD` when manually -> configuring the project. - -## Dependency Management - -### vcpkg - -The best way to install the project's dependencies is to use the vcpkg workflow. - -To do so, make sure vcpkg is installed and `VCPKG_ROOT` is defined in your environment, -then specify -`-DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake"`. Vcpkg will handle -the project's dependencies, including GoogleTest. - -Example commands: - -```shell -cmake \ - -B build \ - -S . \ - -DCMAKE_CXX_STANDARD=17 \ - -DCMAKE_TOOLCHAIN_FILE="$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" -cmake --build build -ctest --test-dir build -``` - -The file `./vcpkg.json` configures the list of dependencies that will be configured by -vcpkg. - -### FetchContent - -Instead of installing the project's dependencies via a package manager, you can optionally -configure beman.{{cookiecutter.project_name}} to fetch them automatically via CMake FetchContent. - -To do so, specify -`-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake`. This will -bring in GoogleTest automatically along with any other dependency the project may require. - -Example commands: - -```shell -cmake \ - -B build \ - -S . \ - -DCMAKE_CXX_STANDARD={{cookiecutter.minimum_cpp_build_version}} \ - -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=./infra/cmake/use-fetch-content.cmake -cmake --build build -ctest --test-dir build -``` - -The file `./lockfile.json` configures the list of dependencies and versions that will be -acquired by FetchContent. - -## Project-specific configure arguments - -Project-specific options are prefixed with `BEMAN_{{cookiecutter.project_name.upper()}}`. -You can see the list of available options with: - -```bash -cmake -LH -S . -B build | grep "BEMAN_{{cookiecutter.project_name.upper()}}" -C 2 -``` - -
- -Some project-specific configure arguments - -### `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS` - -Enable building tests and test infrastructure. Default: `ON`. -Values: `{ ON, OFF }`. - -### `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES` - -Enable building examples. Default: `ON`. Values: `{ ON, OFF }`. - -### `BEMAN_{{cookiecutter.project_name.upper()}}_INSTALL_CONFIG_FILE_PACKAGE` - -Enable installing the CMake config file package. Default: `ON`. -Values: `{ ON, OFF }`. - -This is required so that users of `beman.{{cookiecutter.project_name}}` can use -`find_package(beman.{{cookiecutter.project_name}})` to locate the library. - -
diff --git a/cookiecutter/{{cookiecutter.project_name}}/LICENSE b/cookiecutter/{{cookiecutter.project_name}}/LICENSE deleted file mode 100644 index f6db814..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/LICENSE +++ /dev/null @@ -1,219 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. diff --git a/cookiecutter/{{cookiecutter.project_name}}/README.md b/cookiecutter/{{cookiecutter.project_name}}/README.md deleted file mode 100644 index e316112..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/README.md +++ /dev/null @@ -1,267 +0,0 @@ -{% if cookiecutter._generating_exemplar %} -# How to Use This Template - -To create a new Beman library, first click the "Use this template" dropdown in the -top-right and select "Create a new repository": - -
- -
- -This will create a new repository that's an exact copy of exemplar. The next step is to -customize it for your use case. - -To do so, execute the bash script `stamp.sh`. This script will prompt for parameters like -the new library's name, paper number, and description. Then it will replace your exemplar -copy with a stamped-out template containing these parameters and create a corresponding -git commit and branch: - -``` -$ ./stamp.sh - [1/6] project_name (my_project_name): example_library - [2/6] maintainer (your_github_username): your_username - [3/6] minimum_cpp_build_version (20): - [4/6] paper (PnnnnRr): P9999R9 - [5/6] description (Short project description.): - [6/6] Select unit_test_library - 1 - gtest - 2 - catch2 - Choose from [1/2] (1): -Switched to a new branch 'stamp' -Successfully stamped out exemplar template to the new branch 'stamp'. -Try 'git push origin stamp' to push the branch upstream, -then create a pull request. -``` - -From there, you can simply fill in all the remaining parts of the repository that are -labeled 'todo'. - -What follow is an example of a Beman library README. - -{% endif %} -# beman.{{cookiecutter.project_name}}: {{cookiecutter.description}} - - - - -![Library Status](https://raw.githubusercontent.com/bemanproject/beman/refs/heads/main/images/badges/beman_badge-beman_library_under_development.svg) ![Continuous Integration Tests](https://github.com/{{cookiecutter._owner}}/{{cookiecutter.project_name}}/actions/workflows/ci_tests.yml/badge.svg) ![Lint Check (pre-commit)](https://github.com/{{cookiecutter._owner}}/{{cookiecutter.project_name}}/actions/workflows/pre-commit-check.yml/badge.svg) [![Coverage](https://coveralls.io/repos/github/{{cookiecutter._owner}}/{{cookiecutter.project_name}}/badge.svg?branch=main)](https://coveralls.io/github/{{cookiecutter._owner}}/{{cookiecutter.project_name}}?branch=main) ![Standard Target](https://github.com/bemanproject/beman/blob/main/images/badges/cpp29.svg){% if cookiecutter._generating_exemplar %} [![Compiler Explorer Example](https://img.shields.io/badge/Try%20it%20on%20Compiler%20Explorer-grey?logo=compilerexplorer&logoColor=67c52a)](https://godbolt.org/z/4qEPK87va){% endif %} - - -{% if cookiecutter._generating_exemplar %} -`beman.exemplar` is a minimal C++ library conforming to [The Beman Standard](https://github.com/bemanproject/beman/blob/main/docs/beman_standard.md). -This can be used as a template for those intending to write Beman libraries. -It may also find use as a minimal and modern C++ project structure. -{% else %} -`beman.{{cookiecutter.project_name}}` is (... TODO: description). -{% endif %} - -{% if cookiecutter._generating_exemplar %} -**Implements**: `std::identity` proposed in [Standard Library Concepts ({{cookiecutter.paper}})](https://wg21.link/{{cookiecutter.paper}}). -{% else %} -**Implements**: `std::todo` proposed in [TODO ({{cookiecutter.paper}})](https://wg21.link/{{cookiecutter.paper}}). -{% endif %} - -**Status**: [Under development and not yet ready for production use.](https://github.com/bemanproject/beman/blob/main/docs/beman_library_maturity_model.md#under-development-and-not-yet-ready-for-production-use) - -## License - -`beman.{{cookiecutter.project_name}}` is licensed under the Apache License v2.0 with LLVM Exceptions. - -## Usage - -{% if cookiecutter._generating_exemplar %} -`std::identity` is a function object type whose `operator()` returns its argument unchanged. -`std::identity` serves as the default projection in constrained algorithms. -Its direct usage is usually not needed. - -### Usage: default projection in constrained algorithms - -The following code snippet illustrates how we can achieve a default projection using `beman::{{cookiecutter.project_name}}::identity`: - -```cpp -#include - -namespace exe = beman::{{cookiecutter.project_name}}; - -// Class with a pair of values. -struct Pair -{ - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream &operator<<(std::ostream &os, const Pair &p) - { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print(const std::string_view rem, R &&range, Projection projection = exe::identity>) -{ - std::cout << rem << '{'; - std::ranges::for_each( - range, - [O = 0](const auto &o) mutable - { std::cout << (O++ ? ", " : "") << o; }, - projection); - std::cout << "}\n"; -}; - -int main() -{ - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - print("\tpairs with beman: ", pairs); - - return 0; -} - -``` - -{% else %} -TODO - -{% endif %} -Full runnable examples can be found in [`examples/`](examples/). - -## Dependencies - -### Build Environment - -This project requires at least the following to build: - -* A C++ compiler that conforms to the C++{{cookiecutter.minimum_cpp_build_version}} standard or greater -* CMake 3.30 or later -* (Test Only) GoogleTest - -You can disable building tests by setting CMake option `BEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS` to -`OFF` when configuring the project. - -### Supported Platforms - -| Compiler | Version | C++ Standards | Standard Library | -|------------|---------|---------------|-------------------| -| GCC | 16-13 | C++26-C++17 | libstdc++ | -| GCC | 12-11 | C++23-C++17 | libstdc++ | -| Clang | 22-19 | C++26-C++17 | libstdc++, libc++ | -| Clang | 18 | C++26-C++17 | libc++ | -| Clang | 18 | C++23-C++17 | libstdc++ | -| Clang | 17 | C++26-C++17 | libc++ | -| Clang | 17 | C++20, C++17 | libstdc++ | -| AppleClang | latest | C++26-C++17 | libc++ | -| MSVC | latest | C++23 | MSVC STL | - -## Development - -See the [Contributing Guidelines](CONTRIBUTING.md). - -## Integrate beman.{{cookiecutter.project_name}} into your project - -### Build - -You can build {{cookiecutter.project_name}} using a CMake workflow preset: - -```bash -cmake --workflow --preset gcc-release -``` - -To list available workflow presets, you can invoke: - -```bash -cmake --list-presets=workflow -``` - -For details on building beman.{{cookiecutter.project_name}} without using a CMake preset, refer to the -[Contributing Guidelines](CONTRIBUTING.md). - -### Installation - -#### Vcpkg - -The preferred way to install {{cookiecutter.project_name}} is via vcpkg. To do so, after installing vcpkg -itself, you need to add support for the Beman project's [vcpkg -registry](https://github.com/bemanproject/vcpkg-registry) by configuring a -`vcpkg-configuration.json` file (which {{cookiecutter.project_name}} [provides](vcpkg-configuration.json)). - -Then, simply run `vcpkg install beman-{{cookiecutter.project_name.replace("_", "-")}}`. - -#### Manual - -To install beman.{{cookiecutter.project_name}} globally after building with the `gcc-release` preset, you can -run: - -```bash -sudo cmake --install build/gcc-release -``` - -Alternatively, to install to a prefix, for example `/opt/beman`, you can run: - -```bash -sudo cmake --install build/gcc-release --prefix /opt/beman -``` - -This will generate the following directory structure: - -```txt -/opt/beman -├── include -│ └── beman -│ └── {{cookiecutter.project_name}} -│ ├── {{cookiecutter.project_name}}.hpp -│ └── ... -└── lib - └── cmake - └── beman.{{cookiecutter.project_name}} - ├── beman.{{cookiecutter.project_name}}-config-version.cmake - ├── beman.{{cookiecutter.project_name}}-config.cmake - └── beman.{{cookiecutter.project_name}}-targets.cmake -``` - -### CMake Configuration - -If you installed beman.{{cookiecutter.project_name}} to a prefix, you can specify that prefix to your CMake -project using `CMAKE_PREFIX_PATH`; for example, `-DCMAKE_PREFIX_PATH=/opt/beman`. - -You need to bring in the `beman.{{cookiecutter.project_name}}` package to define the `beman::{{cookiecutter.project_name}}` CMake -target: - -```cmake -find_package(beman.{{cookiecutter.project_name}} REQUIRED) -``` - -You will then need to add `beman::{{cookiecutter.project_name}}` to the link libraries of any libraries or -executables that include `beman.{{cookiecutter.project_name}}` headers. - -```cmake -target_link_libraries(yourlib PUBLIC beman::{{cookiecutter.project_name}}) -``` - -### Using beman.{{cookiecutter.project_name}} - -To use `beman.{{cookiecutter.project_name}}` in your C++ project, -include an appropriate `beman.{{cookiecutter.project_name}}` header from your source code. - -```c++ -#include -``` - -> [!NOTE] -> -> `beman.{{cookiecutter.project_name}}` headers are to be included with the `beman/{{cookiecutter.project_name}}/` prefix. -> Altering include search paths to spell the include target another way (e.g. -> `#include <{{cookiecutter.project_name}}.hpp>`) is unsupported. diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt deleted file mode 100644 index fddbf1f..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -{% if cookiecutter._generating_exemplar %} -set(ALL_EXAMPLES identity_direct_usage) - -# Example `identity_as_default_projection` need ranges support: -include(CheckCXXSymbolExists) -check_cxx_symbol_exists(__cpp_lib_ranges "ranges" HAS_RANGES) - -if(HAS_RANGES) - list(APPEND ALL_EXAMPLES identity_as_default_projection) -else() - message( - WARNING - "Missing range support! Skip: identity_as_default_projection" - ) -endif() - -{% else %} -set(ALL_EXAMPLES todo) -{% endif %} -message("Examples to be built: ${ALL_EXAMPLES}") - -foreach(example ${ALL_EXAMPLES}) - add_executable(beman.{{cookiecutter.project_name}}.examples.${example}) - target_sources(beman.{{cookiecutter.project_name}}.examples.${example} PRIVATE ${example}.cpp) - target_link_libraries( - beman.{{cookiecutter.project_name}}.examples.${example} - PRIVATE beman::{{cookiecutter.project_name}} - ) - if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - set_target_properties( - beman.{{cookiecutter.project_name}}.examples.${example} - PROPERTIES CXX_MODULE_STD ON - ) - endif() -endforeach() diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp b/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp deleted file mode 100644 index 20a95e8..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_as_default_projection.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -// This example demonstrates the usage of beman::{{cookiecutter.project_name}}::identity as a default projection in a range-printer. -// Requires: range support (C++20) and std::identity support (C++20). - -#include -#include - -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() -import std; -#else - #include - #include // std::identity - #include - #include - #include - #include -#endif - -namespace exe = beman::{{cookiecutter.project_name}}; - -// Class with a pair of values. -struct Pair { - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream& operator<<(std::ostream& os, const Pair& p) { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print_helper(const std::string_view rem, R&& range, Projection projection) { - std::cout << rem << '{'; - std::ranges::for_each(range, [O = 0](const auto& o) mutable { std::cout << (O++ ? ", " : "") << o; }, projection); - std::cout << "}\n"; -}; - -// Print wrapper with exe::identity. -template // <- Notice the default projection. -void print_beman(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -// Print wrapper with std::identity. -template // <- Notice the default projection. -void print_std(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -int main() { - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - std::cout << "Default projection:\n"; - print_beman("\tpairs with beman: ", pairs); - print_std("\tpairs with std: ", pairs); - - // Print the pairs using a custom projection. - std::cout << "Custom projection:\n"; - print_beman("\tpairs with beman: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - print_std("\tpairs with std: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - - return 0; -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp b/cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp deleted file mode 100644 index 0284d36..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/examples/identity_direct_usage.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -#include -#include - -{% if cookiecutter._generating_exemplar %} -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() -import std; -#else - #include -#endif - -namespace exe = beman::{{cookiecutter.project_name}}; - -int main() { - std::cout << exe::identity()(2024) << '\n'; - return 0; -} -{% else %} -int main() { - // TODO -} -{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index 352eb05..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -if(BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES) - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET CXX_MODULES FILES {{cookiecutter.project_name}}.cppm - FILE_SET HEADERS - FILES - config.hpp - {{cookiecutter.project_name}}.hpp - {{identity}}.hpp - "${PROJECT_BINARY_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp" - ) -else() - target_sources( - beman.{{cookiecutter.project_name}} - PUBLIC - FILE_SET HEADERS - FILES - config.hpp - {{cookiecutter.project_name}}.hpp - {{identity}}.hpp - "${PROJECT_BINARY_DIR}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp" - ) -endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp deleted file mode 100644 index 7b86494..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_HPP - -#if !defined(__has_include) || __has_include() - #include -#else - #define BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() 0 -#endif - -#endif diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in deleted file mode 100644 index 90941a1..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/config_generated.hpp.in +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_GENERATED_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_CONFIG_GENERATED_HPP - -#cmakedefine01 BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() - -#endif diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp deleted file mode 100644 index bdea366..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/identity.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_{{identity.upper()}}_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_{{identity.upper()}}_HPP - -#include - -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) - -import beman.{{cookiecutter.project_name}}; - -#else - -{% if cookiecutter._generating_exemplar %} - // C++ Standard Library: std::identity equivalent. - // See https://eel.is/c++draft/func.identity: - // - // 22.10.12 Class identity [func.identity] - // - // struct identity { - // template - // constexpr T&& operator()(T&& t) const noexcept; - // - // using is_transparent = unspecified; - // }; - // - // template - // constexpr T&& operator()(T&& t) const noexcept; - // - // Effects: Equivalent to: return std::forward(t); - - #if !BEMAN_EXEMPLAR_USE_MODULES() - #include // std::forward - #endif - -{% endif %} -namespace beman::{{cookiecutter.project_name}} { - -{% if cookiecutter._generating_exemplar %} -struct __is_transparent; // not defined - -// A function object that returns its argument unchanged. -struct identity { - // Returns `t`. - template - constexpr T&& operator()(T&& t) const noexcept { - return std::forward(t); - } - - using is_transparent = __is_transparent; -}; - -{% else %} -// TODO - -{% endif %} -} // namespace beman::{{cookiecutter.project_name}} - -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && - // !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) - -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_{{identity.upper()}}_HPP diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm deleted file mode 100644 index 96b1548..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.cppm +++ /dev/null @@ -1,11 +0,0 @@ -export module beman.{{cookiecutter.project_name}}; - -import std; - -#define BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT -export { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" -#include -#pragma clang diagnostic pop -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp b/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp deleted file mode 100644 index 7df9cb8..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/include/beman/{{cookiecutter.project_name}}/{{cookiecutter.project_name}}.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -#ifndef BEMAN_{{cookiecutter.project_name.upper()}}_{{cookiecutter.project_name.upper()}}_HPP -#define BEMAN_{{cookiecutter.project_name.upper()}}_{{cookiecutter.project_name.upper()}}_HPP - -#include - -#if BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) - -import beman.{{cookiecutter.project_name}}; - -#else - - #include - -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES() && - // !defined(BEMAN_{{cookiecutter.project_name.upper()}}_INCLUDED_FROM_INTERFACE_UNIT) - -#endif // BEMAN_{{cookiecutter.project_name.upper()}}_{{cookiecutter.project_name.upper()}}_HPP diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule b/cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule deleted file mode 100644 index 7367e0e..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.beman_submodule +++ /dev/null @@ -1,3 +0,0 @@ -[beman_submodule] -remote=https://github.com/bemanproject/infra.git -commit_hash=eb7b7c3688bd8f26ab0c145e3147df9a8f2ec8ce diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS deleted file mode 100644 index 4ff90a4..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ -* @ednolan @neatudarius @rishyak @wusatosi @JeffGarland diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml deleted file mode 100644 index 7051c13..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/pre-commit.yml +++ /dev/null @@ -1,79 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -name: Lint Check (pre-commit) - -on: - # We have to use pull_request_target here as pull_request does not grant - # enough permission for reviewdog - pull_request_target: - push: - branches: - - main - -jobs: - pre-commit-push: - name: Pre-Commit check on Push - runs-on: ubuntu-latest - if: ${{ github.event_name == 'push' }} - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.13 - - # We wish to run pre-commit on all files instead of the changes - # only made in the push commit. - # - # So linting error persists when there's formatting problem. - - uses: pre-commit/action@v3.0.1 - - pre-commit-pr: - name: Pre-Commit check on PR - runs-on: ubuntu-latest - if: ${{ github.event_name == 'pull_request_target' }} - - permissions: - contents: read - checks: write - issues: write - pull-requests: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # pull_request_target checkout the base of the repo - # We need to checkout the actual pr to lint the changes. - - name: Checkout pr - run: gh pr checkout ${{ github.event.number }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: 3.13 - - # we only lint on the changed file in PR. - - name: Get Changed Files - id: changed-files - uses: tj-actions/changed-files@v45 - - # See: - # https://github.com/tj-actions/changed-files?tab=readme-ov-file#using-local-git-directory- - - uses: pre-commit/action@v3.0.1 - id: run-pre-commit - with: - extra_args: --files ${{ steps.changed-files.outputs.all_changed_files }} - - # Review dog posts the suggested change from pre-commit to the pr. - - name: suggester / pre-commit - uses: reviewdog/action-suggester@v1 - if: ${{ failure() && steps.run-pre-commit.conclusion == 'failure' }} - with: - tool_name: pre-commit - level: warning - reviewdog_flags: "-fail-level=error" diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml b/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml deleted file mode 100644 index 024a51f..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.github/workflows/reusable-beman-create-issue-when-fault.yml +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -name: 'Beman issue creation workflow' -on: - workflow_call: - workflow_dispatch: -jobs: - create-issue: - runs-on: ubuntu-latest - steps: - # See https://github.com/cli/cli/issues/5075 - - uses: actions/checkout@v4 - - name: Create issue - run: | - issue_num=$(gh issue list -s open -S "[SCHEDULED-BUILD] infra repo CI job failure" -L 1 --json number | jq 'if length == 0 then -1 else .[0].number end') - body="**CI job failure Report** - - **Time of Failure**: $(date -u '+%B %d, %Y, %H:%M %Z') - - **Commit**: [${{ github.sha }}](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) - - **Action Run**: [View logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) - The scheduled job triggered by cron has failed. - Please investigate the logs and recent changes associated with this commit or rerun the workflow if you believe this is an error." - if [[ $issue_num -eq -1 ]]; then - gh issue create --repo ${{ github.repository }} --title "[SCHEDULED-BUILD] infra repo CI job failure" --body "$body" --assignee ${{ github.actor }} - else - gh issue comment --repo ${{ github.repository }} $issue_num --body "$body" - fi - env: - GH_TOKEN: ${{ github.token }} diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore b/cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore deleted file mode 100644 index b7cdbb5..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.gitignore +++ /dev/null @@ -1,59 +0,0 @@ -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Python -__pycache__/ -.pytest_cache/ -*.pyc -*.pyo -*.pyd -*.pyw -*.pyz -*.pywz -*.pyzw -*.pyzwz -*.delete_me - -# MAC OS -*.DS_Store - -# Editor files -.vscode/ -.idea/ - -# Build directories -infra.egg-info/ -beman_tidy.egg-info/ -*.egg-info/ -build/ -dist/ diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml b/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml deleted file mode 100644 index 6fe1e85..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/.pre-commit-config.yaml +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v6.0.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files - - - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 - hooks: - - id: codespell - - # CMake linting and formatting - - repo: https://github.com/BlankSpruce/gersemi-pre-commit - rev: 0.27.2 - hooks: - - id: gersemi - name: CMake linting - exclude: ^.*/tests/.*/data/ # Exclude test data directories diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE b/cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE deleted file mode 100644 index f6db814..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/LICENSE +++ /dev/null @@ -1,219 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/README.md b/cookiecutter/{{cookiecutter.project_name}}/infra/README.md deleted file mode 100644 index 6cb8dd6..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/README.md +++ /dev/null @@ -1,88 +0,0 @@ -# Beman Project Infrastructure Repository - - - -This repository contains the infrastructure for The Beman Project. This is NOT a library repository, -so it does not respect the usual structure of a Beman library repository nor The Beman Standard! - -## Description - -* `cmake/`: CMake modules and toolchain files used by Beman libraries. -* `containers/`: Containers used for CI builds and tests in the Beman org. - -## Usage - -This repository is intended to be used as a beman-submodule in other Beman repositories. See -[the beman-submodule documentation](https://github.com/bemanproject/beman-submodule) for details. - - -### CMake Modules - - -#### `beman_install_library` - -The CMake modules in this repository are intended to be used by Beman libraries. Use the -`beman_install_library()` function to install your library, along with header -files, any metadata files, and a CMake config file for `find_package()` support. - -```cmake -add_library(beman.something) -add_library(beman::something ALIAS beman.something) - -# ... configure your target as needed ... - -include(infra/cmake/beman-install-library.cmake) -beman_install_library(beman.something) -``` - -Note that the target must be created before calling `beman_install_library()`. The module -also assumes that the target is named using the `beman.something` convention, and it -uses that assumption to derive the names to match other Beman standards and conventions. -If your target does not follow that convention, raise an issue or pull request to add -more configurability to the module. - -The module will configure the target to install: - -* The library target itself -* Any public headers associated with the target -* CMake files for `find_package(beman.something)` support - -Some options for the project and target will also be supported: - -* `BEMAN_INSTALL_CONFIG_FILE_PACKAGES` - a list of package names (e.g., `beman.something`) for which to install the config file - (default: all packages) -* `_INSTALL_CONFIG_FILE_PACKAGE` - a per-project option to enable/disable config file installation (default: `ON` if the project is top-level, `OFF` otherwise). For instance for `beman.something`, the option would be `BEMAN_SOMETHING_INSTALL_CONFIG_FILE_PACKAGE`. - -# BuildTelemetry - -The cmake modules in this library provide access to CMake instrumentation data in Google Trace format which is visualizable with chrome://tracing and https://ui.perfetto.dev. - -Telemetry may be enabled in several ways: - -## `include` - -```cmake -include (infra/cmake/BuildTelemetry.cmake) -configure_build_telemetry() -``` - -## `find_package` - -```cmake -find_package(BuildTelemetry) -configure_build_telemetry() -``` - -as long as [BuildTelemetryConfig.cmake](./cmake/BuildTelemetryConfig.cmake) is in your module path. - -## `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` -A non-invasive way to inject this telemetry into a CMake build you do not want to modify. -Add: -```sh --DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=infra/cmake/BuildTelemetry.cmake -``` -To the cmake invocation. - -In any form, CMake will call `telemetry.sh` which will copy the trace data in json format into a `.trace` subdirectory within the build directory. - -Multiple calls to `configure_build_telemetry` will only configure the callback hooks once, so it is safe to enable multiple times, including by TOP_LEVEL_INCLUDE. diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetry.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetry.cmake deleted file mode 100755 index cc94f40..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetry.cmake +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -include_guard(GLOBAL) - -include(${CMAKE_CURRENT_LIST_DIR}/BuildTelemetryConfig.cmake) -configure_build_telemetry() diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetryConfig.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetryConfig.cmake deleted file mode 100755 index 2160c34..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/BuildTelemetryConfig.cmake +++ /dev/null @@ -1,59 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -include_guard(GLOBAL) - -set(BUILD_TELEMETRY_DIR ${CMAKE_CURRENT_LIST_DIR}) - -function(configure_build_telemetry) - if(NOT BUILD_TELEMETRY_CONFIGURATION) - # Check if the CMake version is at least 4.3 - if(CMAKE_VERSION VERSION_LESS "4.3") - message( - STATUS - "CMake version is less than 4.3, configuring cmake_instrumentation is unavailable." - ) - return() - else() - message(STATUS "Configuring Build Telemetry") - endif() - - # Find bash and jq for the telemetry callback script. - # On Windows, Git for Windows provides bash if available. - find_program(BEMAN_BASH bash) - find_program(BEMAN_JQ jq) - if(NOT BEMAN_BASH OR NOT BEMAN_JQ) - message( - STATUS - "bash or jq not found, build telemetry disabled on this platform." - ) - return() - endif() - - # Telemetry query - cmake_instrumentation( - API_VERSION 1 - DATA_VERSION 1 - OPTIONS staticSystemInformation dynamicSystemInformation trace - HOOKS - postGenerate - preBuild - postBuild - preCMakeBuild - postCMakeBuild - postCMakeInstall - postCTest - CALLBACK ${BEMAN_BASH} - ${BUILD_TELEMETRY_DIR}/telemetry.sh - ) - message( - DEBUG - "using callback script ${BUILD_TELEMETRY_DIR}/telemetry.sh via ${BEMAN_BASH}" - ) - - # Mark configuration as done in cache - set(BUILD_TELEMETRY_CONFIGURATION - TRUE - CACHE INTERNAL - "Flag to ensure Build Telemetry configured only once" - ) - endif() -endfunction(configure_build_telemetry) diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/Config.cmake.in b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/Config.cmake.in deleted file mode 100644 index df903cf..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/Config.cmake.in +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -# cmake/Config.cmake.in -*-makefile-*- - -include(CMakeFindDependencyMacro) - -@BEMAN_INSTALL_FIND_DEPENDENCIES@ - -@PACKAGE_INIT@ - -include(${CMAKE_CURRENT_LIST_DIR}/@BEMAN_INSTALL_BASE_PKG_NAME@-targets.cmake) - -check_required_components(@BEMAN_INSTALL_BASE_PKG_NAME@) diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake deleted file mode 100644 index 70ef548..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/appleclang-toolchain.cmake +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for apple clang family of compiler. -# Note this is different from LLVM toolchain. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures clang and clang++ to use all available non-conflicting -# sanitizers. Note that apple clang does not support leak sanitizer. -# - TSan: configures clang and clang++ to enable the use of thread sanitizer. - -include_guard(GLOBAL) - -# Prevent PATH collision with an LLVM clang installation by using the system -# compiler shims -set(CMAKE_C_COMPILER cc) -set(CMAKE_CXX_COMPILER c++) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - set(SANITIZER_FLAGS - "-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined" - ) -elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") - set(SANITIZER_FLAGS "-fsanitize=thread") -endif() - -set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") -set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library.cmake deleted file mode 100644 index df2dbe9..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/beman-install-library.cmake +++ /dev/null @@ -1,325 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -include_guard(GLOBAL) - -include(CMakePackageConfigHelpers) -include(GNUInstallDirs) - -# beman_install_library -# ===================== -# -# Installs a library (or set of targets) along with headers, C++ modules, -# and optional CMake package configuration files. -# -# Usage: -# ------ -# beman_install_library( -# TARGETS [ ...] -# [DEPENDENCIES [ ...]] -# [NAMESPACE ] -# [EXPORT_NAME ] -# [DESTINATION ] -# ) -# -# Arguments: -# ---------- -# -# name -# Logical package name (e.g. "beman.utility"). -# Used to derive config file names and cache variable prefixes. -# -# TARGETS (required) -# List of CMake targets to install. -# -# DEPENDENCIES (optional) -# Semicolon-separated list, one dependency per entry. -# Each entry is a valid find_dependency() argument list. -# Note: you must use the bracket form for quoting if not only a package name is used! -# "[===[beman.inplace_vector 1.0.0]===] [===[beman.scope 0.0.1 EXACT]===] fmt" -# -# NAMESPACE (optional) -# Namespace for exported targets. -# Defaults to "beman::". -# -# EXPORT_NAME (optional) -# Name of the CMake export set. -# Defaults to "-targets". -# -# DESTINATION (optional) -# The install destination for CXX_MODULES. -# Defaults to ${CMAKE_INSTALL_LIBDIR}/cmake/${name}/modules. -# -# Brief -# ----- -# -# This function installs the specified project TARGETS and its FILE_SET -# HEADERS to the default CMAKE install destination. -# -# It also handles the installation of the CMake config package files if -# needed. If the given targets has a PUBLIC FILE_SET CXX_MODULE, it will also -# installed to the given DESTINATION -# -# Cache variables: -# ---------------- -# -# BEMAN_INSTALL_CONFIG_FILE_PACKAGES -# List of package names for which config files should be installed. -# -# _INSTALL_CONFIG_FILE_PACKAGE -# Per-package override to enable/disable config file installation. -# is the uppercased package name with dots replaced by underscores. -# -# Caveats -# ------- -# -# **Only one `PUBLIC FILE_SET CXX_MODULES` is yet supported to install with this -# function!** -# -# **Only header files contained in a `PUBLIC FILE_SET TYPE HEADERS` will be -# install with this function!** - -function(beman_install_library name) - # ---------------------------- - # Argument parsing - # ---------------------------- - set(oneValueArgs NAMESPACE EXPORT_NAME DESTINATION) - set(multiValueArgs TARGETS DEPENDENCIES) - - cmake_parse_arguments( - BEMAN_INSTALL - "${options}" - "${oneValueArgs}" - "${multiValueArgs}" - ${ARGN} - ) - - if(NOT BEMAN_INSTALL_TARGETS) - message( - FATAL_ERROR - "beman_install_library(${name}): TARGETS must be specified" - ) - endif() - - if(CMAKE_SKIP_INSTALL_RULES) - message( - WARNING - "beman_install_library(${name}): not installing targets '${BEMAN_INSTALL_TARGETS}' due to CMAKE_SKIP_INSTALL_RULES" - ) - return() - endif() - - set(_config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${name}") - - # ---------------------------- - # Defaults - # ---------------------------- - if(NOT BEMAN_INSTALL_NAMESPACE) - set(BEMAN_INSTALL_NAMESPACE "beman::") - endif() - - if(NOT BEMAN_INSTALL_EXPORT_NAME) - set(BEMAN_INSTALL_EXPORT_NAME "${name}-targets") - endif() - - if(NOT BEMAN_INSTALL_DESTINATION) - set(BEMAN_INSTALL_DESTINATION - "${CMAKE_INSTALL_DATADIR}/${name}/modules" - ) - endif() - - string(REPLACE "beman." "" install_component_name "${name}") - message( - VERBOSE - "beman-install-library(${name}): COMPONENT '${install_component_name}'" - ) - - # -------------------------------------------------- - # Install each target with all of its file sets - # -------------------------------------------------- - foreach(_tgt IN LISTS BEMAN_INSTALL_TARGETS) - if(NOT TARGET "${_tgt}") - message( - WARNING - "beman_install_library(${name}): '${_tgt}' is not a target" - ) - continue() - endif() - - # Given foo.bar, the component name is bar - string(REPLACE "." ";" name_parts "${_tgt}") - # fail if the name doesn't look like foo.bar - list(LENGTH name_parts name_parts_length) - if(NOT name_parts_length EQUAL 2) - message( - FATAL_ERROR - "beman_install_library(${name}): expects a name of the form 'beman.', got '${_tgt}'" - ) - endif() - list(GET name_parts -1 component_name) - set_target_properties( - "${_tgt}" - PROPERTIES EXPORT_NAME "${component_name}" - ) - message( - VERBOSE - "beman_install_library(${name}): EXPORT_NAME ${component_name} for TARGET '${_tgt}'" - ) - - # Get the list of interface header sets, exact one expected! - set(_install_header_set_args) - get_target_property( - _available_header_sets - ${_tgt} - INTERFACE_HEADER_SETS - ) - if(_available_header_sets) - message( - VERBOSE - "beman-install-library(${name}): '${_tgt}' has INTERFACE_HEADER_SETS=${_available_header_sets}" - ) - foreach(_install_header_set IN LISTS _available_header_sets) - list( - APPEND _install_header_set_args - FILE_SET - "${_install_header_set}" - COMPONENT - "${install_component_name}_Development" - ) - endforeach() - else() - set(_install_header_set_args FILE_SET HEADERS) # Note: empty FILE_SET in this case! CK - endif() - - # Detect presence of PUBLIC C++ module file sets. Note: exact one is expected! - get_target_property(_module_sets "${_tgt}" INTERFACE_CXX_MODULE_SETS) - if(_module_sets) - message( - VERBOSE - "beman-install-library(${name}): '${_tgt}' has INTERFACE_CXX_MODULE_SETS=${_module_sets}" - ) - install( - TARGETS "${_tgt}" - EXPORT ${BEMAN_INSTALL_EXPORT_NAME} - ARCHIVE COMPONENT "${install_component_name}_Development" - LIBRARY - COMPONENT "${install_component_name}_Runtime" - NAMELINK_COMPONENT "${install_component_name}_Development" - RUNTIME COMPONENT "${install_component_name}_Runtime" - ${_install_header_set_args} - FILE_SET ${_module_sets} - DESTINATION "${BEMAN_INSTALL_DESTINATION}" - COMPONENT "${install_component_name}_Development" - # NOTE: There's currently no convention for this location! CK - CXX_MODULES_BMI - DESTINATION - ${CMAKE_INSTALL_DATADIR}/${name}/bmi-${CMAKE_CXX_COMPILER_ID}_$ - COMPONENT "${install_component_name}_Development" - ) - else() - install( - TARGETS "${_tgt}" - EXPORT ${BEMAN_INSTALL_EXPORT_NAME} - ARCHIVE COMPONENT "${install_component_name}_Development" - LIBRARY - COMPONENT "${install_component_name}_Runtime" - NAMELINK_COMPONENT "${install_component_name}_Development" - RUNTIME COMPONENT "${install_component_name}_Runtime" - ${_install_header_set_args} - ) - endif() - endforeach() - - # -------------------------------------------------- - # Export targets - # -------------------------------------------------- - # gersemi: off - install( - EXPORT ${BEMAN_INSTALL_EXPORT_NAME} - NAMESPACE ${BEMAN_INSTALL_NAMESPACE} - CXX_MODULES_DIRECTORY cxx-modules - DESTINATION ${_config_install_dir} - COMPONENT "${install_component_name}_Development" - ) - # gersemi: on - - # ---------------------------------------- - # Config file installation logic - # - # Precedence (highest to lowest): - # 1. Per-package variable _INSTALL_CONFIG_FILE_PACKAGE - # 2. Allow-list BEMAN_INSTALL_CONFIG_FILE_PACKAGES (if defined) - # 3. Default: ON - # ---------------------------------------- - string(TOUPPER "${name}" _pkg_upper) - string(REPLACE "." "_" _pkg_prefix "${_pkg_upper}") - - option( - ${_pkg_prefix}_INSTALL_CONFIG_FILE_PACKAGE - "Enable creating and installing a CMake config-file package. Default: ON. Values: { ON, OFF }." - ON - ) - - set(_pkg_var "${_pkg_prefix}_INSTALL_CONFIG_FILE_PACKAGE") - - # Default: install config files - set(_install_config ON) - - # If the allow-list is defined, only install for packages in the list - if(DEFINED BEMAN_INSTALL_CONFIG_FILE_PACKAGES) - if(NOT "${name}" IN_LIST BEMAN_INSTALL_CONFIG_FILE_PACKAGES) - set(_install_config OFF) - endif() - endif() - - # Per-package override takes highest precedence - if(DEFINED ${_pkg_var}) - set(_install_config ${${_pkg_var}}) - endif() - - # ---------------------------------------- - # expand dependencies - # ---------------------------------------- - set(_beman_find_deps "") - foreach(dep IN LISTS BEMAN_INSTALL_DEPENDENCIES) - message( - VERBOSE - "beman-install-library(${name}): Add find_dependency(${dep})" - ) - string(APPEND _beman_find_deps "find_dependency(${dep})\n") - endforeach() - set(BEMAN_INSTALL_FIND_DEPENDENCIES "${_beman_find_deps}") - - # ---------------------------------------- - # Generate + install config files - # ---------------------------------------- - if(_install_config) - set(BEMAN_INSTALL_BASE_PKG_NAME ${name}) - configure_package_config_file( - "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/Config.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/${name}-config.cmake" - INSTALL_DESTINATION ${_config_install_dir} - ) - - write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/${name}-config-version.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion - ) - - install( - FILES - "${CMAKE_CURRENT_BINARY_DIR}/${name}-config.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${name}-config-version.cmake" - DESTINATION ${_config_install_dir} - COMPONENT "${install_component_name}_Development" - ) - else() - message( - WARNING - "beman-install-library(${name}): Not installing a config package for '${name}'" - ) - endif() -endfunction() - -set(CPACK_GENERATOR TGZ) -include(CPack) diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/enable-experimental-import-std.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/enable-experimental-import-std.cmake deleted file mode 100644 index 20fc302..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/enable-experimental-import-std.cmake +++ /dev/null @@ -1,190 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -if(CMAKE_VERSION VERSION_EQUAL "3.30.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.30.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.10") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.11") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.12") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.8") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "3.31.9") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "a9e1cf81-9932-4810-974b-6eccaf14e457" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.0.7") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.1.6") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.3") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.4") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.2.5") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "d0edc3af-4c50-42ea-a356-e2862fe7a444" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.0") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.1") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -elseif(CMAKE_VERSION VERSION_EQUAL "4.3.2") - set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD - "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" - ) -endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake deleted file mode 100644 index d3b9f92..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/gnu-toolchain.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for GNU family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures gcc and g++ to use all available non-conflicting -# sanitizers. -# - TSan: configures gcc and g++ to enable the use of thread sanitizer - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER gcc) -set(CMAKE_CXX_COMPILER g++) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - set(SANITIZER_FLAGS - "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fsanitize-undefined-trap-on-error" - ) -elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") - set(SANITIZER_FLAGS "-fsanitize=thread") -endif() - -set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") -set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake deleted file mode 100644 index eabf363..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-libc++-toolchain.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for LLVM family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures clang and clang++ to use all available non-conflicting -# sanitizers. -# - TSan: configures clang and clang++ to enable the use of thread sanitizer. - -include(${CMAKE_CURRENT_LIST_DIR}/llvm-toolchain.cmake) - -if(NOT CMAKE_CXX_FLAGS MATCHES "-stdlib=libc\\+\\+") - string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++") -endif() diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake deleted file mode 100644 index f1623b7..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/llvm-toolchain.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for LLVM family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures clang and clang++ to use all available non-conflicting -# sanitizers. -# - TSan: configures clang and clang++ to enable the use of thread sanitizer. - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER clang) -set(CMAKE_CXX_COMPILER clang++) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - set(SANITIZER_FLAGS - "-fsanitize=address -fsanitize=leak -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fsanitize-undefined-trap-on-error" - ) -elseif(BEMAN_BUILDSYS_SANITIZER STREQUAL "TSan") - set(SANITIZER_FLAGS "-fsanitize=thread") -endif() - -set(CMAKE_C_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") -set(CMAKE_CXX_FLAGS_DEBUG_INIT "${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "-O3 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake deleted file mode 100644 index bdc24de..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/msvc-toolchain.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -# This toolchain file is not meant to be used directly, -# but to be invoked by CMake preset and GitHub CI. -# -# This toolchain file configures for MSVC family of compiler. -# -# BEMAN_BUILDSYS_SANITIZER: -# This optional CMake parameter is not meant for public use and is subject to -# change. -# Possible values: -# - MaxSan: configures cl to use all available non-conflicting sanitizers. -# -# Note that in other toolchain files, TSan is also a possible value for -# BEMAN_BUILDSYS_SANITIZER, however, MSVC does not support thread sanitizer, -# thus this value is omitted. - -include_guard(GLOBAL) - -set(CMAKE_C_COMPILER cl) -set(CMAKE_CXX_COMPILER cl) - -if(BEMAN_BUILDSYS_SANITIZER STREQUAL "MaxSan") - # /Zi flag (add debug symbol) is needed when using address sanitizer - # See C5072: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-c5072 - set(SANITIZER_FLAGS "/fsanitize=address /Zi") -endif() - -set(CMAKE_CXX_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") -set(CMAKE_C_FLAGS_DEBUG_INIT "/EHsc /permissive- ${SANITIZER_FLAGS}") - -set(RELEASE_FLAGS "/EHsc /permissive- /O2 ${SANITIZER_FLAGS}") - -set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "${RELEASE_FLAGS}") - -set(CMAKE_C_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE_INIT "${RELEASE_FLAGS}") - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/telemetry.sh b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/telemetry.sh deleted file mode 100755 index cb5fd88..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/telemetry.sh +++ /dev/null @@ -1,119 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#!/usr/bin/env bash - -set -o nounset -set -o errexit -trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR -set -o errtrace -set -o pipefail -IFS=$'\n\t' - -############################################################################### -# Environment -############################################################################### - -# $_ME -# -# This program's basename. -_ME="$(basename "${0}")" - -############################################################################### -# Help -############################################################################### - -# _print_help() -# -# Usage: -# _print_help -# -# Print the program help information. -_print_help() { - cat <] - ${_ME} -h | --help - -Options: - -h --help Show this screen. - -Environment: - Setting DEBUG_TELEMETRY in the environment will enable DEBUG logging -HEREDOC -} - -############################################################################### -# Program Functions -############################################################################### -_debug_print() { - if [[ -n "${DEBUG_TELEMETRY:-}" ]]; then - printf "[DEBUG] $(date +'%H:%M:%S'): %s \n" "$1" >&2 - fi -} - -_check_file_exists() { - local file="$1" - if [[ ! -f "${file}" ]]; then - echo "Error: File not found: ${file}" >&2 - exit 1 # Exit the entire script with a non-zero status - fi -} - -_process_index() { - indexFile=${1:-} - _check_file_exists "${indexFile}" - _debug_print "$(cat "${indexFile}")" - - local buildDir - buildDir=$(jq -r '.buildDir' "${1:-}") - _debug_print "$(printf "buildDir is |%q|" "${buildDir}")" - - local dataDir - dataDir=$(jq -r '.dataDir' "${1:-}") - _debug_print "$(printf "dataDir is |%q|" "${dataDir}")" - - local hook - hook=$(jq -r '.hook' "${1:-}") - _debug_print "$(printf "hook is |%q|" "${hook}")" - - local trace - trace=$(jq -r '.trace' "${1:-}") - _debug_print "$(printf "trace is |%q|" "${trace}")" - - local outputDir - outputDir="${buildDir}/.trace" - _debug_print "$(printf "Copy trace to |%q|" "${outputDir}")" - mkdir -p "${outputDir}" - - local traceDestFile - traceDestFile="${outputDir}/${hook}-$(basename "${trace}")" - _debug_print "$(printf "traceDestFile: |%q|" "${traceDestFile}")" - cp "${dataDir}/${trace}" "${outputDir}/${hook}-$(basename "${trace}")" -} - -############################################################################### -# Main -############################################################################### - -# _main() -# -# Usage: -# _main [] [] -# -# Description: -# Entry point for the program, handling basic option parsing and dispatching. -_main() { - # Avoid complex option parsing when only one program option is expected. - if [[ "${1:-}" =~ ^-h|--help$ ]] - then - _print_help - else - _process_index "$@" - fi -} - -# Call `_main` after everything has been defined. -_main "$@" diff --git a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake b/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake deleted file mode 100644 index 3c7136d..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/infra/cmake/use-fetch-content.cmake +++ /dev/null @@ -1,205 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -cmake_minimum_required(VERSION 3.24) - -include(FetchContent) - -if(NOT BEMAN_LOCKFILE) - set(BEMAN_LOCKFILE - "lockfile.json" - CACHE FILEPATH - "Path to the dependency lockfile for the Beman project." - ) -endif() - -set(Beman_projectDir "${CMAKE_CURRENT_LIST_DIR}/../..") -message(TRACE "Beman_projectDir=\"${Beman_projectDir}\"") - -message(TRACE "BEMAN_LOCKFILE=\"${BEMAN_LOCKFILE}\"") -file( - REAL_PATH "${BEMAN_LOCKFILE}" - Beman_lockfile - BASE_DIRECTORY "${Beman_projectDir}" - EXPAND_TILDE -) -message(DEBUG "Using lockfile: \"${Beman_lockfile}\"") - -# Force CMake to reconfigure the project if the lockfile changes -set_property( - DIRECTORY "${Beman_projectDir}" - APPEND - PROPERTY CMAKE_CONFIGURE_DEPENDS "${Beman_lockfile}" -) - -# For more on the protocol for this function, see: -# https://cmake.org/cmake/help/latest/command/cmake_language.html#provider-commands -function(Beman_provideDependency method package_name) - # Read the lockfile - file(READ "${Beman_lockfile}" Beman_rootObj) - - # Get the "dependencies" field and store it in Beman_dependenciesObj - string( - JSON Beman_dependenciesObj - ERROR_VARIABLE Beman_error - GET "${Beman_rootObj}" - "dependencies" - ) - if(Beman_error) - message(FATAL_ERROR "${Beman_lockfile}: ${Beman_error}") - endif() - - # Get the length of the libraries array and store it in Beman_dependenciesObj - string( - JSON Beman_numDependencies - ERROR_VARIABLE Beman_error - LENGTH "${Beman_dependenciesObj}" - ) - if(Beman_error) - message(FATAL_ERROR "${Beman_lockfile}: ${Beman_error}") - endif() - - if(Beman_numDependencies EQUAL 0) - return() - endif() - - # Loop over each dependency object - math(EXPR Beman_maxIndex "${Beman_numDependencies} - 1") - foreach(Beman_index RANGE "${Beman_maxIndex}") - set(Beman_errorPrefix "${Beman_lockfile}, dependency ${Beman_index}") - - # Get the dependency object at Beman_index - # and store it in Beman_depObj - string( - JSON Beman_depObj - ERROR_VARIABLE Beman_error - GET "${Beman_dependenciesObj}" - "${Beman_index}" - ) - if(Beman_error) - message(FATAL_ERROR "${Beman_errorPrefix}: ${Beman_error}") - endif() - - # Get the "name" field and store it in Beman_name - string( - JSON Beman_name - ERROR_VARIABLE Beman_error - GET "${Beman_depObj}" - "name" - ) - if(Beman_error) - message(FATAL_ERROR "${Beman_errorPrefix}: ${Beman_error}") - endif() - - # Get the "package_name" field and store it in Beman_pkgName - string( - JSON Beman_pkgName - ERROR_VARIABLE Beman_error - GET "${Beman_depObj}" - "package_name" - ) - if(Beman_error) - message(FATAL_ERROR "${Beman_errorPrefix}: ${Beman_error}") - endif() - - # Get the "git_repository" field and store it in Beman_repo - string( - JSON Beman_repo - ERROR_VARIABLE Beman_error - GET "${Beman_depObj}" - "git_repository" - ) - if(Beman_error) - message(FATAL_ERROR "${Beman_errorPrefix}: ${Beman_error}") - endif() - - # Get the "git_tag" field and store it in Beman_tag - string( - JSON Beman_tag - ERROR_VARIABLE Beman_error - GET "${Beman_depObj}" - "git_tag" - ) - if(Beman_error) - message(FATAL_ERROR "${Beman_errorPrefix}: ${Beman_error}") - endif() - - if(method STREQUAL "FIND_PACKAGE") - if(package_name STREQUAL Beman_pkgName) - string( - APPEND Beman_debug - "Redirecting find_package calls for ${Beman_pkgName} " - "to FetchContent logic.\n" - ) - string( - APPEND Beman_debug - "Fetching ${Beman_repo} at " - "${Beman_tag} according to ${Beman_lockfile}." - ) - message(DEBUG "${Beman_debug}") - FetchContent_Declare( - "${Beman_name}" - GIT_REPOSITORY "${Beman_repo}" - GIT_TAG "${Beman_tag}" - EXCLUDE_FROM_ALL - ) - - # Apply per-dependency cmake_args from the lockfile - string( - JSON Beman_cmakeArgs - ERROR_VARIABLE Beman_cmakeArgsError - GET "${Beman_depObj}" - "cmake_args" - ) - if(NOT Beman_cmakeArgsError) - string(JSON Beman_numCmakeArgs LENGTH "${Beman_cmakeArgs}") - if(Beman_numCmakeArgs GREATER 0) - math(EXPR Beman_maxArgIndex "${Beman_numCmakeArgs} - 1") - foreach(Beman_argIndex RANGE "${Beman_maxArgIndex}") - string( - JSON Beman_argKey - MEMBER "${Beman_cmakeArgs}" - "${Beman_argIndex}" - ) - string( - JSON Beman_argValue - GET "${Beman_cmakeArgs}" - "${Beman_argKey}" - ) - message( - DEBUG - "Setting ${Beman_argKey}=${Beman_argValue} for ${Beman_name}" - ) - set("${Beman_argKey}" "${Beman_argValue}") - endforeach() - endif() - endif() - - FetchContent_MakeAvailable("${Beman_name}") - - # Catch2's CTest integration module isn't on CMAKE_MODULE_PATH - # when brought in via FetchContent. Add it so that - # `include(Catch)` works. - if(Beman_pkgName STREQUAL "Catch2") - list( - APPEND CMAKE_MODULE_PATH - "${${Beman_name}_SOURCE_DIR}/extras" - ) - set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE) - endif() - - # Important! _FOUND tells CMake that `find_package` is - # not needed for this package anymore - set("${Beman_pkgName}_FOUND" TRUE PARENT_SCOPE) - endif() - endif() - endforeach() -endfunction() - -set(BEMAN_USE_FETCH_CONTENT_ENABLED ON) - -cmake_language( - SET_DEPENDENCY_PROVIDER Beman_provideDependency - SUPPORTED_METHODS FIND_PACKAGE -) - -# Add this dir to the module path so that `find_package(beman-install-library)` works -list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}") diff --git a/cookiecutter/{{cookiecutter.project_name}}/lockfile.json b/cookiecutter/{{cookiecutter.project_name}}/lockfile.json deleted file mode 100644 index f3388cf..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/lockfile.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "dependencies": [ -{% if cookiecutter.unit_test_library == "gtest" %} - { - "name": "googletest", - "package_name": "GTest", - "git_repository": "https://github.com/google/googletest.git", - "git_tag": "6910c9d9165801d8827d628cb72eb7ea9dd538c5", - "cmake_args": { - "INSTALL_GTEST": "OFF" - } - } -{% elif cookiecutter.unit_test_library == "catch2" %} - { - "name": "Catch2", - "package_name": "Catch2", - "git_repository": "https://github.com/catchorg/Catch2.git", - "git_tag": "25319fd3047c6bdcf3c0170e76fa526c77f99ca9" - } -{% endif %} - ] -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in b/cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in deleted file mode 100644 index 1f13b31..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/port/portfile.cmake.in +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -vcpkg_from_github( - OUT_SOURCE_PATH SOURCE_PATH - REPO bemanproject/{{cookiecutter.project_name}} - REF "v@VERSION@" - SHA512 @SHA512@ - HEAD_REF main -) - -vcpkg_check_features( - OUT_FEATURE_OPTIONS FEATURE_OPTIONS - FEATURES - modules BEMAN_{{cookiecutter.project_name.upper()}}_USE_MODULES -) - -vcpkg_cmake_configure( - SOURCE_PATH "${SOURCE_PATH}" - OPTIONS - ${FEATURE_OPTIONS} - -DBEMAN_{{cookiecutter.project_name.upper()}}_BUILD_TESTS=OFF - -DBEMAN_{{cookiecutter.project_name.upper()}}_BUILD_EXAMPLES=OFF -) - -vcpkg_cmake_install() - -vcpkg_cmake_config_fixup( - PACKAGE_NAME beman.{{cookiecutter.project_name}} - CONFIG_PATH lib/cmake/beman.{{cookiecutter.project_name}} -) - -if(NOT "modules" IN_LIST FEATURES) - file(REMOVE_RECURSE - "${CURRENT_PACKAGES_DIR}/debug" - "${CURRENT_PACKAGES_DIR}/lib" - ) -endif() - -vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE") diff --git a/cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in b/cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in deleted file mode 100644 index 81a58a5..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/port/vcpkg.json.in +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "beman-{{cookiecutter.project_name.replace('_', '-')}}", - "version-semver": "@VERSION@", - "description": "{{cookiecutter.description}}", - "homepage": "https://github.com/bemanproject/{{cookiecutter.project_name}}", - "license": "Apache-2.0 WITH LLVM-exception", - "dependencies": [ - { - "name": "vcpkg-cmake", - "host": true - }, - { - "name": "vcpkg-cmake-config", - "host": true - } - ], - "features": { - "modules": { - "description": "Provide beman.{{cookiecutter.project_name}} as a C++ module" - } - } -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt b/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt deleted file mode 100644 index 4450cd8..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -{% if cookiecutter.unit_test_library == "gtest" %} -find_package(GTest REQUIRED) -{% elif cookiecutter.unit_test_library == "catch2" %} -find_package(Catch2 3 REQUIRED) -{% endif %} - -add_executable(beman.{{cookiecutter.project_name}}.tests.{{identity}}) -target_sources(beman.{{cookiecutter.project_name}}.tests.{{identity}} PRIVATE {{identity}}.test.cpp) -target_link_libraries( - beman.{{cookiecutter.project_name}}.tests.{{identity}} -{% if cookiecutter.unit_test_library == "gtest" %} - PRIVATE beman::{{cookiecutter.project_name}} GTest::gtest_main -{% elif cookiecutter.unit_test_library == "catch2" %} - PRIVATE beman::{{cookiecutter.project_name}} Catch2::Catch2WithMain -{% endif %} -) -if(BEMAN_EXEMPLAR_USE_MODULES) - set_target_properties( - beman.{{cookiecutter.project_name}}.tests.{{identity}} - PROPERTIES CXX_MODULE_STD ON - ) -endif() - -{% if cookiecutter.unit_test_library == "gtest" %} -include(GoogleTest) -gtest_discover_tests(beman.{{cookiecutter.project_name}}.tests.{{identity}} DISCOVERY_TIMEOUT 60) -{% elif cookiecutter.unit_test_library == "catch2" %} -include(Catch) -catch_discover_tests(beman.{{cookiecutter.project_name}}.tests.{{identity}}) -{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp b/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp deleted file mode 100644 index 2b4c069..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/tests/beman/{{cookiecutter.project_name}}/identity.test.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -{% set identity = "identity" if cookiecutter._generating_exemplar else "todo" %} - -#include -{% if cookiecutter.unit_test_library == "gtest" %} -#include -{% elif cookiecutter.unit_test_library == "catch2" %} -#include -{% endif %} -#include - -{% if cookiecutter._generating_exemplar %} -#if BEMAN_EXEMPLAR_USE_MODULES() -import std; -#else - #include - #include -#endif - -namespace exe = beman::{{cookiecutter.project_name}}; - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, call_identity_with_int) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("can call identity with int", "[{{cookiecutter.project_name}}::call_identity_with_int]") { -{% endif %} - for (int i = -100; i < 100; ++i) { -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(i, exe::identity()(i)); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(i == exe::identity()(i)); -{% endif %} - } -} - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, call_identity_with_custom_type) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("can call identity with custom type", "[{{cookiecutter.project_name}}::call_identity_with_custom_type]") { -{% endif %} - struct S { - int i; - }; - - for (int i = -100; i < 100; ++i) { - const S s{i}; - const S s_id = exe::identity()(s); -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(s.i, s_id.i); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(s.i == s_id.i); -{% endif %} - } -} - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, compare_std_vs_beman) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("compare std vs beman", "[{{cookiecutter.project_name}}::compare_std_vs_beman]") { -{% endif %} -// Requires: std::identity support. -#if defined(__cpp_lib_type_identity) - std::identity std_id; - exe::identity beman_id; - for (int i = -100; i < 100; ++i) { -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(std_id(i), beman_id(i)); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(std_id(i) == beman_id(i)); -{% endif %} - } -#endif -} - -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(IdentityTest, check_is_transparent) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("check is transparent", "[{{cookiecutter.project_name}}::check_is_transparent]") { -{% endif %} -// Requires: transparent operators support. -#if defined(__cpp_lib_transparent_operators) - - exe::identity id; - - const auto container = {1, 2, 3, 4, 5}; - auto it = std::find(std::begin(container), std::end(container), 3); -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(3, *it); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(3 == *it); -{% endif %} - auto it_with_id = std::find(std::begin(container), std::end(container), id(3)); -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_EQ(3, *it_with_id); - - EXPECT_EQ(it, it_with_id); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(3 == *it_with_id); - - CHECK(it == it_with_id); -{% endif %} -#endif -} -{% else %} -{% if cookiecutter.unit_test_library == "gtest" %} -TEST(TodoTest, todo) { -{% elif cookiecutter.unit_test_library == "catch2" %} -TEST_CASE("todo", "[{{cookiecutter.project_name}}::todo]") { -{% endif %} - const bool todo = true; -{% if cookiecutter.unit_test_library == "gtest" %} - EXPECT_TRUE(todo); -{% elif cookiecutter.unit_test_library == "catch2" %} - CHECK(todo); -{% endif %} -} -{% endif %} diff --git a/cookiecutter/{{cookiecutter.project_name}}/vcpkg-configuration.json b/cookiecutter/{{cookiecutter.project_name}}/vcpkg-configuration.json deleted file mode 100644 index db23b90..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/vcpkg-configuration.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "default-registry": { - "kind": "git", - "repository": "https://github.com/microsoft/vcpkg.git", - "baseline": "522253caf47268c1724f486a035e927a42a90092" - }, - "registries": [ - { - "kind": "git", - "repository": "https://github.com/bemanproject/vcpkg-registry.git", - "baseline": "28992b34d1e39368f5d1214a557fd61949de39fb", - "packages": ["beman-*"] - } - ] -} diff --git a/cookiecutter/{{cookiecutter.project_name}}/vcpkg.json b/cookiecutter/{{cookiecutter.project_name}}/vcpkg.json deleted file mode 100644 index 89ea514..0000000 --- a/cookiecutter/{{cookiecutter.project_name}}/vcpkg.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "beman-{{cookiecutter.project_name.replace('_', '-')}}", -{% if cookiecutter._generating_exemplar %} - "version-semver": "2.4.0", -{% else %} - "version-semver": "0.1.0", -{% endif %} -{% if cookiecutter.unit_test_library == "gtest" %} - "dependencies": [ - { - "name": "gtest", - "host": true - } - ] -{% elif cookiecutter.unit_test_library == "catch2" %} - "dependencies": [ - { - "name": "catch2", - "host": true - } - ] -{% endif %} -} diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ed8ed52..3544044 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,32 +1,18 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -set(ALL_EXAMPLES identity_direct_usage) - -# Example `identity_as_default_projection` need ranges support: -include(CheckCXXSymbolExists) -check_cxx_symbol_exists(__cpp_lib_ranges "ranges" HAS_RANGES) - -if(HAS_RANGES) - list(APPEND ALL_EXAMPLES identity_as_default_projection) -else() - message( - WARNING - "Missing range support! Skip: identity_as_default_projection" - ) -endif() - +set(ALL_EXAMPLES todo) message("Examples to be built: ${ALL_EXAMPLES}") foreach(example ${ALL_EXAMPLES}) - add_executable(beman.exemplar.examples.${example}) - target_sources(beman.exemplar.examples.${example} PRIVATE ${example}.cpp) + add_executable(beman.str_split.examples.${example}) + target_sources(beman.str_split.examples.${example} PRIVATE ${example}.cpp) target_link_libraries( - beman.exemplar.examples.${example} - PRIVATE beman::exemplar + beman.str_split.examples.${example} + PRIVATE beman::str_split ) - if(BEMAN_EXEMPLAR_USE_MODULES) + if(BEMAN_STR_SPLIT_USE_MODULES) set_target_properties( - beman.exemplar.examples.${example} + beman.str_split.examples.${example} PROPERTIES CXX_MODULE_STD ON ) endif() diff --git a/examples/identity_as_default_projection.cpp b/examples/identity_as_default_projection.cpp deleted file mode 100644 index 0fe7210..0000000 --- a/examples/identity_as_default_projection.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -// This example demonstrates the usage of beman::exemplar::identity as a default projection in a range-printer. -// Requires: range support (C++20) and std::identity support (C++20). - -#include -#include - -#if BEMAN_EXEMPLAR_USE_MODULES() -import std; -#else - #include - #include // std::identity - #include - #include - #include - #include -#endif - -namespace exe = beman::exemplar; - -// Class with a pair of values. -struct Pair { - int n; - std::string s; - - // Output the pair in the form {n, s}. - // Used by the range-printer if no custom projection is provided (default: identity projection). - friend std::ostream& operator<<(std::ostream& os, const Pair& p) { - return os << "Pair" << '{' << p.n << ", " << p.s << '}'; - } -}; - -// A range-printer that can print projected (modified) elements of a range. -// All the elements of the range are printed in the form {element1, element2, ...}. -// e.g., pairs with identity: Pair{1, one}, Pair{2, two}, Pair{3, three} -// e.g., pairs with custom projection: {1:one, 2:two, 3:three} -template -void print_helper(const std::string_view rem, R&& range, Projection projection) { - std::cout << rem << '{'; - std::ranges::for_each(range, [O = 0](const auto& o) mutable { std::cout << (O++ ? ", " : "") << o; }, projection); - std::cout << "}\n"; -}; - -// Print wrapper with exe::identity. -template // <- Notice the default projection. -void print_beman(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -// Print wrapper with std::identity. -template // <- Notice the default projection. -void print_std(const std::string_view rem, R&& range, Projection projection = {}) { - print_helper(rem, range, projection); -} - -int main() { - // A vector of pairs to print. - const std::vector pairs = { - {1, "one"}, - {2, "two"}, - {3, "three"}, - }; - - // Print the pairs using the default projection. - std::cout << "Default projection:\n"; - print_beman("\tpairs with beman: ", pairs); - print_std("\tpairs with std: ", pairs); - - // Print the pairs using a custom projection. - std::cout << "Custom projection:\n"; - print_beman("\tpairs with beman: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - print_std("\tpairs with std: ", pairs, [](const auto& p) { return std::to_string(p.n) + ':' + p.s; }); - - return 0; -} diff --git a/examples/identity_direct_usage.cpp b/examples/identity_direct_usage.cpp deleted file mode 100644 index c45f057..0000000 --- a/examples/identity_direct_usage.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include -#include - -#if BEMAN_EXEMPLAR_USE_MODULES() -import std; -#else - #include -#endif - -namespace exe = beman::exemplar; - -int main() { - std::cout << exe::identity()(2024) << '\n'; - return 0; -} diff --git a/examples/todo.cpp b/examples/todo.cpp new file mode 100644 index 0000000..276064d --- /dev/null +++ b/examples/todo.cpp @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include + +int main() { + // TODO +} diff --git a/images/use-this-template.png b/images/use-this-template.png deleted file mode 100644 index a09ad69427bf90bd649b5edfb5ed3939620940e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51407 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 oOdeGK<<0+U_5X() - #include -#else - #define BEMAN_EXEMPLAR_USE_MODULES() 0 -#endif - -#endif diff --git a/include/beman/exemplar/config_generated.hpp.in b/include/beman/exemplar/config_generated.hpp.in deleted file mode 100644 index a36a5f0..0000000 --- a/include/beman/exemplar/config_generated.hpp.in +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_EXEMPLAR_CONFIG_GENERATED_HPP -#define BEMAN_EXEMPLAR_CONFIG_GENERATED_HPP - -#cmakedefine01 BEMAN_EXEMPLAR_USE_MODULES() - -#endif diff --git a/include/beman/exemplar/exemplar.hpp b/include/beman/exemplar/exemplar.hpp deleted file mode 100644 index 447218e..0000000 --- a/include/beman/exemplar/exemplar.hpp +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_EXEMPLAR_EXEMPLAR_HPP -#define BEMAN_EXEMPLAR_EXEMPLAR_HPP - -#include - -#if BEMAN_EXEMPLAR_USE_MODULES() && !defined(BEMAN_EXEMPLAR_INCLUDED_FROM_INTERFACE_UNIT) - -import beman.exemplar; - -#else - - #include - -#endif // BEMAN_EXEMPLAR_USE_MODULES() && - // !defined(BEMAN_EXEMPLAR_INCLUDED_FROM_INTERFACE_UNIT) - -#endif // BEMAN_EXEMPLAR_EXEMPLAR_HPP diff --git a/include/beman/exemplar/identity.hpp b/include/beman/exemplar/identity.hpp deleted file mode 100644 index c8e03fb..0000000 --- a/include/beman/exemplar/identity.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#ifndef BEMAN_EXEMPLAR_IDENTITY_HPP -#define BEMAN_EXEMPLAR_IDENTITY_HPP - -#include - -#if BEMAN_EXEMPLAR_USE_MODULES() && !defined(BEMAN_EXEMPLAR_INCLUDED_FROM_INTERFACE_UNIT) - -import beman.exemplar; - -#else - - // C++ Standard Library: std::identity equivalent. - // See https://eel.is/c++draft/func.identity: - // - // 22.10.12 Class identity [func.identity] - // - // struct identity { - // template - // constexpr T&& operator()(T&& t) const noexcept; - // - // using is_transparent = unspecified; - // }; - // - // template - // constexpr T&& operator()(T&& t) const noexcept; - // - // Effects: Equivalent to: return std::forward(t); - - #if !BEMAN_EXEMPLAR_USE_MODULES() - #include // std::forward - #endif - -namespace beman::exemplar { - -struct __is_transparent; // not defined - -// A function object that returns its argument unchanged. -struct identity { - // Returns `t`. - template - constexpr T&& operator()(T&& t) const noexcept { - return std::forward(t); - } - - using is_transparent = __is_transparent; -}; - -} // namespace beman::exemplar - -#endif // BEMAN_EXEMPLAR_USE_MODULES() && - // !defined(BEMAN_EXEMPLAR_INCLUDED_FROM_INTERFACE_UNIT) - -#endif // BEMAN_EXEMPLAR_IDENTITY_HPP diff --git a/include/beman/str_split/CMakeLists.txt b/include/beman/str_split/CMakeLists.txt new file mode 100644 index 0000000..a4a50c2 --- /dev/null +++ b/include/beman/str_split/CMakeLists.txt @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +if(BEMAN_STR_SPLIT_USE_MODULES) + target_sources( + beman.str_split + PUBLIC + FILE_SET CXX_MODULES FILES str_split.cppm + FILE_SET HEADERS + FILES + config.hpp + str_split.hpp + todo.hpp + "${PROJECT_BINARY_DIR}/include/beman/str_split/config_generated.hpp" + ) +else() + target_sources( + beman.str_split + PUBLIC + FILE_SET HEADERS + FILES + config.hpp + str_split.hpp + todo.hpp + "${PROJECT_BINARY_DIR}/include/beman/str_split/config_generated.hpp" + ) +endif() diff --git a/include/beman/str_split/config.hpp b/include/beman/str_split/config.hpp new file mode 100644 index 0000000..7fdf13f --- /dev/null +++ b/include/beman/str_split/config.hpp @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_STR_SPLIT_CONFIG_HPP +#define BEMAN_STR_SPLIT_CONFIG_HPP + +#if !defined(__has_include) || __has_include() + #include +#else + #define BEMAN_STR_SPLIT_USE_MODULES() 0 +#endif + +#endif diff --git a/include/beman/str_split/config_generated.hpp.in b/include/beman/str_split/config_generated.hpp.in new file mode 100644 index 0000000..dada6ff --- /dev/null +++ b/include/beman/str_split/config_generated.hpp.in @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_STR_SPLIT_CONFIG_GENERATED_HPP +#define BEMAN_STR_SPLIT_CONFIG_GENERATED_HPP + +#cmakedefine01 BEMAN_STR_SPLIT_USE_MODULES() + +#endif diff --git a/include/beman/exemplar/exemplar.cppm b/include/beman/str_split/str_split.cppm similarity index 55% rename from include/beman/exemplar/exemplar.cppm rename to include/beman/str_split/str_split.cppm index 0a59630..1a646cb 100644 --- a/include/beman/exemplar/exemplar.cppm +++ b/include/beman/str_split/str_split.cppm @@ -1,11 +1,11 @@ -export module beman.exemplar; +export module beman.str_split; import std; -#define BEMAN_EXEMPLAR_INCLUDED_FROM_INTERFACE_UNIT +#define BEMAN_STR_SPLIT_INCLUDED_FROM_INTERFACE_UNIT export { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" -#include +#include #pragma clang diagnostic pop } diff --git a/include/beman/str_split/str_split.hpp b/include/beman/str_split/str_split.hpp new file mode 100644 index 0000000..308ad99 --- /dev/null +++ b/include/beman/str_split/str_split.hpp @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_STR_SPLIT_STR_SPLIT_HPP +#define BEMAN_STR_SPLIT_STR_SPLIT_HPP + +#include + +#if BEMAN_STR_SPLIT_USE_MODULES() && !defined(BEMAN_STR_SPLIT_INCLUDED_FROM_INTERFACE_UNIT) + +import beman.str_split; + +#else + + #include + +#endif // BEMAN_STR_SPLIT_USE_MODULES() && + // !defined(BEMAN_STR_SPLIT_INCLUDED_FROM_INTERFACE_UNIT) + +#endif // BEMAN_STR_SPLIT_STR_SPLIT_HPP diff --git a/include/beman/str_split/todo.hpp b/include/beman/str_split/todo.hpp new file mode 100644 index 0000000..a4b9c5a --- /dev/null +++ b/include/beman/str_split/todo.hpp @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef BEMAN_STR_SPLIT_TODO_HPP +#define BEMAN_STR_SPLIT_TODO_HPP + +#include + +#if BEMAN_STR_SPLIT_USE_MODULES() && !defined(BEMAN_STR_SPLIT_INCLUDED_FROM_INTERFACE_UNIT) + +import beman.str_split; + +#else + +namespace beman::str_split { + +// TODO + +} // namespace beman::str_split + +#endif // BEMAN_STR_SPLIT_USE_MODULES() && + // !defined(BEMAN_STR_SPLIT_INCLUDED_FROM_INTERFACE_UNIT) + +#endif // BEMAN_STR_SPLIT_TODO_HPP diff --git a/port/portfile.cmake.in b/port/portfile.cmake.in index ba7eeac..c1097e7 100644 --- a/port/portfile.cmake.in +++ b/port/portfile.cmake.in @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH - REPO bemanproject/exemplar + REPO bemanproject/str_split REF "v@VERSION@" SHA512 @SHA512@ HEAD_REF main @@ -10,22 +10,22 @@ vcpkg_from_github( vcpkg_check_features( OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES - modules BEMAN_EXEMPLAR_USE_MODULES + modules BEMAN_STR_SPLIT_USE_MODULES ) vcpkg_cmake_configure( SOURCE_PATH "${SOURCE_PATH}" OPTIONS ${FEATURE_OPTIONS} - -DBEMAN_EXEMPLAR_BUILD_TESTS=OFF - -DBEMAN_EXEMPLAR_BUILD_EXAMPLES=OFF + -DBEMAN_STR_SPLIT_BUILD_TESTS=OFF + -DBEMAN_STR_SPLIT_BUILD_EXAMPLES=OFF ) vcpkg_cmake_install() vcpkg_cmake_config_fixup( - PACKAGE_NAME beman.exemplar - CONFIG_PATH lib/cmake/beman.exemplar + PACKAGE_NAME beman.str_split + CONFIG_PATH lib/cmake/beman.str_split ) if(NOT "modules" IN_LIST FEATURES) diff --git a/port/vcpkg.json.in b/port/vcpkg.json.in index 9a7ddab..24cea9e 100644 --- a/port/vcpkg.json.in +++ b/port/vcpkg.json.in @@ -1,8 +1,8 @@ { - "name": "beman-exemplar", + "name": "beman-str-split", "version-semver": "@VERSION@", - "description": "A Beman Library Exemplar", - "homepage": "https://github.com/bemanproject/exemplar", + "description": "Stand-alone, easy-to-use string split utilities", + "homepage": "https://github.com/bemanproject/str_split", "license": "Apache-2.0 WITH LLVM-exception", "dependencies": [ { @@ -16,7 +16,7 @@ ], "features": { "modules": { - "description": "Provide beman.exemplar as a C++ module" + "description": "Provide beman.str_split as a C++ module" } } } diff --git a/stamp.sh b/stamp.sh deleted file mode 100755 index 7dc9ee8..0000000 --- a/stamp.sh +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#!/usr/bin/env bash - -{ - if [[ "$1" == "-h" || "$1" == "--help" ]] ; then - cat <<-'EOF' - stamp.sh -- beman exemplar template library creation tool - - This script is intended to be run on a fork of exemplar. - - It sets up cookiecutter, runs it on the cookiecutter template, replaces the - repository's current contents with the result, runs pre-commit, - switches to a new branch 'stamp', and creates a git commit. - - All parameters are passed through to the cookiecutter invocation. -EOF - fi - set -eu - if ! type -P python3 >/dev/null ; then - echo "Couldn't find python3 in PATH" >&2 - exit 1 - fi - declare repo_dir=$(realpath $(dirname "$BASH_SOURCE")) - cd "$repo_dir" - declare cookiecutter_venv_path - cookiecutter_venv_path=$(mktemp --directory --dry-run) - python3 -m venv "$cookiecutter_venv_path" - source "$cookiecutter_venv_path/bin/activate" - python3 -m pip install cookiecutter pre-commit >& /dev/null - declare cookiecutter_out_path - cookiecutter_out_path=$(mktemp --directory) - python3 -m cookiecutter "$repo_dir/cookiecutter" -o "$cookiecutter_out_path" "$@" - git rm -rf . &>/dev/null - cp -r "$cookiecutter_out_path"/*/. . - git add . &>/dev/null - pre-commit run --all-files &>/dev/null || true - git add . &>/dev/null - git checkout -b stamp - git commit -q -m "Stamp out exemplar template" - echo "Successfully stamped out exemplar template to the new branch 'stamp'." - echo "Try 'git push origin stamp' to push the branch upstream," - echo "then create a pull request." - rm -r "$cookiecutter_venv_path" "$cookiecutter_out_path" -}; exit diff --git a/tests/beman/exemplar/CMakeLists.txt b/tests/beman/exemplar/CMakeLists.txt deleted file mode 100644 index 597b375..0000000 --- a/tests/beman/exemplar/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -find_package(GTest REQUIRED) - -add_executable(beman.exemplar.tests.identity) -target_sources(beman.exemplar.tests.identity PRIVATE identity.test.cpp) -target_link_libraries( - beman.exemplar.tests.identity - PRIVATE beman::exemplar GTest::gtest_main -) -if(BEMAN_EXEMPLAR_USE_MODULES) - set_target_properties( - beman.exemplar.tests.identity - PROPERTIES CXX_MODULE_STD ON - ) -endif() - -include(GoogleTest) -gtest_discover_tests(beman.exemplar.tests.identity DISCOVERY_TIMEOUT 60) diff --git a/tests/beman/exemplar/identity.test.cpp b/tests/beman/exemplar/identity.test.cpp deleted file mode 100644 index 694fa88..0000000 --- a/tests/beman/exemplar/identity.test.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - -#include -#include -#include - -#if BEMAN_EXEMPLAR_USE_MODULES() -import std; -#else - #include - #include -#endif - -namespace exe = beman::exemplar; - -TEST(IdentityTest, call_identity_with_int) { - for (int i = -100; i < 100; ++i) { - EXPECT_EQ(i, exe::identity()(i)); - } -} - -TEST(IdentityTest, call_identity_with_custom_type) { - struct S { - int i; - }; - - for (int i = -100; i < 100; ++i) { - const S s{i}; - const S s_id = exe::identity()(s); - EXPECT_EQ(s.i, s_id.i); - } -} - -TEST(IdentityTest, compare_std_vs_beman) { -// Requires: std::identity support. -#if defined(__cpp_lib_type_identity) - std::identity std_id; - exe::identity beman_id; - for (int i = -100; i < 100; ++i) { - EXPECT_EQ(std_id(i), beman_id(i)); - } -#endif -} - -TEST(IdentityTest, check_is_transparent) { -// Requires: transparent operators support. -#if defined(__cpp_lib_transparent_operators) - - exe::identity id; - - const auto container = {1, 2, 3, 4, 5}; - auto it = std::find(std::begin(container), std::end(container), 3); - EXPECT_EQ(3, *it); - auto it_with_id = std::find(std::begin(container), std::end(container), id(3)); - EXPECT_EQ(3, *it_with_id); - - EXPECT_EQ(it, it_with_id); -#endif -} diff --git a/tests/beman/str_split/CMakeLists.txt b/tests/beman/str_split/CMakeLists.txt new file mode 100644 index 0000000..be75247 --- /dev/null +++ b/tests/beman/str_split/CMakeLists.txt @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +find_package(GTest REQUIRED) + +add_executable(beman.str_split.tests.todo) +target_sources(beman.str_split.tests.todo PRIVATE todo.test.cpp) +target_link_libraries( + beman.str_split.tests.todo + PRIVATE beman::str_split GTest::gtest_main +) +if(BEMAN_EXEMPLAR_USE_MODULES) + set_target_properties( + beman.str_split.tests.todo + PROPERTIES CXX_MODULE_STD ON + ) +endif() + +include(GoogleTest) +gtest_discover_tests(beman.str_split.tests.todo DISCOVERY_TIMEOUT 60) diff --git a/tests/beman/str_split/todo.test.cpp b/tests/beman/str_split/todo.test.cpp new file mode 100644 index 0000000..f1c0082 --- /dev/null +++ b/tests/beman/str_split/todo.test.cpp @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include + +TEST(TodoTest, todo) { + const bool todo = true; + EXPECT_TRUE(todo); +} diff --git a/vcpkg.json b/vcpkg.json index ba9121e..9eebba5 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { - "name": "beman-exemplar", - "version-semver": "2.4.0", + "name": "beman-str-split", + "version-semver": "0.1.0", "dependencies": [ { "name": "gtest",