From 325a07fe406dd8e5ee346d53f673ec5034bf6861 Mon Sep 17 00:00:00 2001 From: David Sankel Date: Tue, 8 Oct 2024 18:18:06 -0400 Subject: [PATCH 01/10] Simplify CMakeLists.txt (#42) * Simplify CMakeLists.txt The `block()` isn't needed since we can set CMake options via. CMAKE_ARGS. * Remove CMAKE_ARGS parameter that wasn't working. CMAKE_ARGS isn't used when a directory is brought in via `add_subdirectory`. Instead, variables need to be set in a block. Additionally, the block is only needed for the `FetchContent_MakeAvailable` call. --- CMakeLists.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 828ed70..a1a4550 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,16 +14,16 @@ include(FetchContent) if(BUILD_TESTING) enable_testing() + # Fetch GoogleTest + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # release-1.14.0 + EXCLUDE_FROM_ALL + ) block() - # Disable installing google test dependency on cmake --install - set(INSTALL_GTEST OFF) - - # Fetch GoogleTest - FetchContent_Declare( - googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # release-1.14.0 - EXCLUDE_FROM_ALL CMAKE_ARGS -DBUILD_TESTING=OFF) + set(INSTALL_GTEST OFF) # Disable GoogleTest installation + set(BUILD_TESTING OFF) # Disable GoogleTest tests FetchContent_MakeAvailable(googletest) endblock() endif() From bd7ad354842e424ca7dd69da7dff5bfaab70e8f6 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Tue, 15 Oct 2024 16:36:59 -0400 Subject: [PATCH 02/10] Introduce basic linting infrastructure (#34) * introduce clang-format * update format * initalized pre-commit config * apply precommit * cmake format config * format cmake * add CI * format pre-commit config * remove cmake format * update ci dependency * format * format CMmakeList with gersemi * use gersemi to format cmake file in precommit * reformat * enable auto-formatting * add markdown lint * switch to igorshubovych/markdownlint-cli * update markdown linter config * format README * remove duplicative clang-format * add more documentation * using more up-to-date clang-format config * Update .pre-commit-config.yaml Co-authored-by: David Sankel * update pre-commit version * update CI * revert breaking change in CI * reformat directory * update doc on ColumnLimit --------- Co-authored-by: David Sankel --- .clang-format | 242 ++++++++++++++++++++ .github/CODEOWNERS | 2 +- .github/workflows/ci_tests.yml | 8 +- .github/workflows/pre-commit.yml | 24 ++ .markdownlint.yaml | 9 + .pre-commit-config.yaml | 33 +++ CMakeLists.txt | 36 +-- README.md | 28 ++- examples/CMakeLists.txt | 12 +- examples/identity_as_default_projection.cpp | 37 +-- include/beman/exemplar/identity.hpp | 8 +- src/beman/exemplar/CMakeLists.txt | 36 +-- src/beman/exemplar/identity.t.cpp | 26 +-- 13 files changed, 399 insertions(+), 102 deletions(-) create mode 100644 .clang-format create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .markdownlint.yaml create mode 100644 .pre-commit-config.yaml diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..05baf03 --- /dev/null +++ b/.clang-format @@ -0,0 +1,242 @@ +--- +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: None +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/.github/CODEOWNERS b/.github/CODEOWNERS index dd041dd..90d9ff2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # Codeowners for reviews on PRs -* @bretbrownjr @camio @dietmarkuehl @neatudarius @steve-downey +* @bretbrownjr @camio @dietmarkuehl @neatudarius @steve-downey diff --git a/.github/workflows/ci_tests.yml b/.github/workflows/ci_tests.yml index 84602e7..dfc7998 100644 --- a/.github/workflows/ci_tests.yml +++ b/.github/workflows/ci_tests.yml @@ -75,20 +75,20 @@ jobs: needs: [test] if: failure() && github.event_name == 'schedule' steps: - # See https://github.com/cli/cli/issues/5075 + # 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] Build & Test failure" -L 1 --json number | jq 'if length == 0 then -1 else .[0].number end') - + body="**Build-and-Test 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 build-and-test 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] Build & Test failure" --body "$body" else diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..57492d8 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,24 @@ +name: Lint Check (pre-commit) + +on: + pull_request: + push: + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.13' + + - 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 + with: + extra_args: --files ${{ steps.changed-files.outputs.all_changed_files }} diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..81f5fcd --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,9 @@ +# 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 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..a26bab0 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,33 @@ +# 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: v5.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: v18.1.8 + hooks: + - id: clang-format + types_or: [c++, c] + + # CMake linting and formatting + - repo: https://github.com/BlankSpruce/gersemi + rev: 0.15.1 + hooks: + - id: gersemi + name: CMake linting + + # Markdown linting + # Config file: .markdownlint.yaml + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: v0.42.0 + hooks: + - id: markdownlint diff --git a/CMakeLists.txt b/CMakeLists.txt index a1a4550..546b1b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,29 +3,31 @@ cmake_minimum_required(VERSION 3.25) project( - beman.exemplar # CMake Project Name, which is also the name of the top-level - # targets (e.g., library, executable, etc.). - DESCRIPTION "A Beman library exemplar" - LANGUAGES CXX) + beman.exemplar # CMake Project Name, which is also the name of the top-level + # targets (e.g., library, executable, etc.). + DESCRIPTION "A Beman library exemplar" + LANGUAGES CXX +) include(CTest) include(FetchContent) if(BUILD_TESTING) - enable_testing() + enable_testing() - # Fetch GoogleTest - FetchContent_Declare( - googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG f8d7d77c06936315286eb55f8de22cd23c188571 # release-1.14.0 - EXCLUDE_FROM_ALL - ) - block() - set(INSTALL_GTEST OFF) # Disable GoogleTest installation - set(BUILD_TESTING OFF) # Disable GoogleTest tests - FetchContent_MakeAvailable(googletest) - endblock() + # Fetch GoogleTest + FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG + f8d7d77c06936315286eb55f8de22cd23c188571 # release-1.14.0 + EXCLUDE_FROM_ALL + ) + block() + set(INSTALL_GTEST OFF) # Disable GoogleTest installation + set(BUILD_TESTING OFF) # Disable GoogleTest tests + FetchContent_MakeAvailable(googletest) + endblock() endif() add_subdirectory(src/beman/exemplar) diff --git a/README.md b/README.md index 66fcbb1..443a64f 100644 --- a/README.md +++ b/README.md @@ -6,22 +6,24 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception ![Continuous Integration Tests](https://github.com/beman-project/exemplar/actions/workflows/ci_tests.yml/badge.svg) -`beman.exemplar` is a minimal C++ library conforming to [The Beman Standard](https://github.com/beman-project/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.exemplar` is a minimal C++ library conforming to [The Beman Standard](https://github.com/beman-project/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. Implements: `std::identity` proposed in [Standard Library Concepts (P0898R3)](https://wg21.link/P0898R3). - ## 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. +`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 +#include namespace exe = beman::exemplar; @@ -131,7 +133,9 @@ apt-get install \ ### How to build beman.exemplar -This project strives to be as normal and simple a CMake project as possible. This build workflow in particular will work, producing a static `libbeman.exemplar.a` library, ready to package with its headers: +This project strives to be as normal and simple a CMake project as possible. +This build workflow in particular will work, +producing a static `libbeman.exemplar.a` library, ready to package with its headers: ```shell cmake -B build -S . -DCMAKE_CXX_STANDARD=20 @@ -231,7 +235,8 @@ $ tree /opt/beman.exemplar
Disable tests build -To build this project with tests disabled (and their dependencies), simply use `BUILD_TESTING=OFF` as documented in upstream [CMake documentation](https://cmake.org/cmake/help/latest/module/CTest.html): +To build this project with tests disabled (and their dependencies), +simply use `BUILD_TESTING=OFF` as documented in upstream [CMake documentation](https://cmake.org/cmake/help/latest/module/CTest.html): ```shell cmake -B build -S . -DBUILD_TESTING=OFF @@ -245,7 +250,8 @@ cmake -B build -S . -DBUILD_TESTING=OFF Use beman.exemplar directly from C++ -If you want to use `beman.exemplar` from your project, you can include `beman/exemplar/*.hpp` files from your C++ source files +If you want to use `beman.exemplar` from your project, +you can include `beman/exemplar/*.hpp` files from your C++ source files ```cpp #include @@ -273,7 +279,8 @@ For CMake based projects, you will need to use the `beman.exemplar` CMake module find_package(beman.exemplar REQUIRED) ``` -You will also need to add `beman::exemplar` to the link libraries of any libraries or executables that include `beman/exemplar/*.hpp` in their source or header file. +You will also need to add `beman::exemplar` +to the link libraries of any libraries or executables that include `beman/exemplar/*.hpp` in their source or header file. ```cmake target_link_libraries(yourlib PUBLIC beman::exemplar) @@ -286,7 +293,8 @@ target_link_libraries(yourlib PUBLIC beman::exemplar) -Build systems that support `pkg-config` by providing a `beman.exemplar.pc` file. Build systems that support interoperation via `pkg-config` should be able to detect `beman.exemplar` for you automatically. +Build systems that support `pkg-config` by providing a `beman.exemplar.pc` file. +Build systems that support interoperation via `pkg-config` should be able to detect `beman.exemplar` for you automatically.
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 60032ff..b0c64eb 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,11 +1,11 @@ # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -set(ALL_EXAMPLES - #identity_as_default_projection -identity_direct_usage) +set(ALL_EXAMPLES # identity_as_default_projection + identity_direct_usage +) foreach(example ${ALL_EXAMPLES}) - add_executable(beman.exemplar.examples.${example}) - target_sources(beman.exemplar.examples.${example} PRIVATE ${example}.cpp) - target_link_libraries(beman.exemplar.examples.${example} beman::exemplar) + add_executable(beman.exemplar.examples.${example}) + target_sources(beman.exemplar.examples.${example} PRIVATE ${example}.cpp) + target_link_libraries(beman.exemplar.examples.${example} beman::exemplar) endforeach() diff --git a/examples/identity_as_default_projection.cpp b/examples/identity_as_default_projection.cpp index a2139b7..eecabac 100644 --- a/examples/identity_as_default_projection.cpp +++ b/examples/identity_as_default_projection.cpp @@ -16,15 +16,13 @@ namespace exe = beman::exemplar; // Class with a pair of values. -struct Pair -{ - int n; +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) - { + friend std::ostream& operator<<(std::ostream& os, const Pair& p) { return os << "Pair" << '{' << p.n << ", " << p.s << '}'; } }; @@ -33,37 +31,28 @@ struct Pair // 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) -{ +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::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 = {}) -{ +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 = {}) -{ +void print_std(const std::string_view rem, R&& range, Projection projection = {}) { print_helper(rem, range, projection); } -int main() -{ +int main() { // A vector of pairs to print. const std::vector pairs = { {1, "one"}, @@ -78,12 +67,8 @@ int main() // 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; }); + 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/include/beman/exemplar/identity.hpp b/include/beman/exemplar/identity.hpp index 0a121eb..789c319 100644 --- a/include/beman/exemplar/identity.hpp +++ b/include/beman/exemplar/identity.hpp @@ -27,16 +27,14 @@ namespace beman::exemplar { struct __is_transparent; // not defined // A function object that returns its argument unchanged. -struct identity -{ +struct identity { // Returns `t`. template #if defined(__cpp_constexpr) constexpr #endif - T && - operator()(T &&t) const noexcept - { + T&& + operator()(T&& t) const noexcept { return std::forward(t); } diff --git a/src/beman/exemplar/CMakeLists.txt b/src/beman/exemplar/CMakeLists.txt index da3d195..9493be0 100644 --- a/src/beman/exemplar/CMakeLists.txt +++ b/src/beman/exemplar/CMakeLists.txt @@ -8,29 +8,33 @@ target_sources(beman.exemplar PRIVATE identity.cpp) set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/) target_sources( - beman.exemplar PUBLIC - FILE_SET HEADERS - BASE_DIRS ${INCLUDE_DIR} - FILES ${INCLUDE_DIR}/beman/exemplar/identity.hpp) + beman.exemplar + PUBLIC + FILE_SET HEADERS + BASE_DIRS ${INCLUDE_DIR} + FILES ${INCLUDE_DIR}/beman/exemplar/identity.hpp +) set_target_properties(beman.exemplar PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) install( - TARGETS beman.exemplar - EXPORT beman.exemplar - DESTINATION $<$:debug/>${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION $<$:debug/>${CMAKE_INSTALL_BINDIR} - FILE_SET HEADERS - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + TARGETS beman.exemplar + EXPORT beman.exemplar + DESTINATION + $<$:debug/>${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION $<$:debug/>${CMAKE_INSTALL_BINDIR} + FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) if(BUILD_TESTING) - include(GoogleTest) + include(GoogleTest) - add_executable(beman.exemplar.tests) - target_sources(beman.exemplar.tests PRIVATE identity.t.cpp) - target_link_libraries(beman.exemplar.tests - PRIVATE beman::exemplar GTest::gtest GTest::gtest_main) + add_executable(beman.exemplar.tests) + target_sources(beman.exemplar.tests PRIVATE identity.t.cpp) + target_link_libraries( + beman.exemplar.tests + PRIVATE beman::exemplar GTest::gtest GTest::gtest_main + ) - gtest_add_tests(beman.exemplar.tests "" AUTO) + gtest_add_tests(beman.exemplar.tests "" AUTO) endif() diff --git a/src/beman/exemplar/identity.t.cpp b/src/beman/exemplar/identity.t.cpp index 64a687c..7f68fdf 100644 --- a/src/beman/exemplar/identity.t.cpp +++ b/src/beman/exemplar/identity.t.cpp @@ -9,51 +9,43 @@ namespace exe = beman::exemplar; -TEST(IdentityTest, call_identity_with_int) -{ - for (int i = -100; i < 100; ++i) - { +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 - { +TEST(IdentityTest, call_identity_with_custom_type) { + struct S { int i; }; - for (int i = -100; i < 100; ++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) -{ +TEST(IdentityTest, compare_std_vs_beman) { // Requires: std::identity support. #if defined(__cpp_lib_identity) std::identity std_id; exe::identity beman_id; - for (int i = -100; i < 100; ++i) - { + for (int i = -100; i < 100; ++i) { EXPECT_EQ(std_id(i), beman_id(i)); } #endif } -TEST(IdentityTest, check_is_transparent) -{ +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); + 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); From a7e1a0f670254c1d66988296937f0cfc5a05dc0f Mon Sep 17 00:00:00 2001 From: Linus Boehm Date: Mon, 14 Oct 2024 15:33:12 -0400 Subject: [PATCH 03/10] feat: add automatic linting suggestion github workflow --- .github/workflows/pre-commit.yml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 57492d8..147b68b 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -7,11 +7,25 @@ on: jobs: pre-commit: runs-on: ubuntu-latest + name: pre-commit + permissions: + contents: read + pull-requests: write + steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.13 + + - name: Cache pre-commit hooks + uses: actions/cache@v2 with: - python-version: '3.13' + path: ~/.cache/pre-commit + key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} - name: Get Changed Files id: changed-files @@ -22,3 +36,11 @@ jobs: - uses: pre-commit/action@v3.0.1 with: extra_args: --files ${{ steps.changed-files.outputs.all_changed_files }} + continue-on-error: true + + - name: suggester / pre-commit + uses: reviewdog/action-suggester@v1 + with: + tool_name: pre-commit + fail_on_error: true + level: warning From 969d0e4eb02436749122794c1a99ec58c9b47f9e Mon Sep 17 00:00:00 2001 From: Linus Boehm Date: Wed, 16 Oct 2024 21:33:22 -0400 Subject: [PATCH 04/10] fix(readme): fix typos in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 443a64f..818063a 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ int main() ``` -Full runable examples can be found in `examples/` (e.g., [./examples/identity_as_default_projection.cpp.cpp](./examples/identity_as_default_projection.cpp.cpp)). +Full runnable examples can be found in `examples/` (e.g., [./examples/identity_as_default_projection.cpp](./examples/identity_as_default_projection.cpp)). ## Building beman.exemplar From ff3ac46f69174f440cd68da088e71a71a41556ce Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:38:56 -0400 Subject: [PATCH 05/10] update premissions --- .github/workflows/pre-commit.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 147b68b..eb2c2e7 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -10,6 +10,8 @@ jobs: name: pre-commit permissions: contents: read + checks: write + issues: write pull-requests: write steps: From c086db14012f7fd11320f29996fc636d2da380a4 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:49:44 -0400 Subject: [PATCH 06/10] fix -fail-on-error --- .github/workflows/pre-commit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index eb2c2e7..4dfd096 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -44,5 +44,5 @@ jobs: uses: reviewdog/action-suggester@v1 with: tool_name: pre-commit - fail_on_error: true level: warning + reviewdog_flags: "-fail-level=error" From d32a843a7b565e1f5f93344459a5dbca72e265f9 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:01:59 -0400 Subject: [PATCH 07/10] remove uncessary caching --- .github/workflows/pre-commit.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 4dfd096..635fa0b 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -23,12 +23,6 @@ jobs: with: python-version: 3.13 - - name: Cache pre-commit hooks - uses: actions/cache@v2 - with: - path: ~/.cache/pre-commit - key: ${{ runner.os }}-precommit-${{ hashFiles('.pre-commit-config.yaml') }} - - name: Get Changed Files id: changed-files uses: tj-actions/changed-files@v45 From 1fd7071f90fcb6d622af18f61c7656b7bc143c44 Mon Sep 17 00:00:00 2001 From: River <26424577+wusatosi@users.noreply.github.com> Date: Fri, 18 Oct 2024 19:02:48 -0400 Subject: [PATCH 08/10] only run review dog on prs --- .github/workflows/pre-commit.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 635fa0b..cc12949 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -35,6 +35,7 @@ jobs: continue-on-error: true - name: suggester / pre-commit + if: ${{ github.event_name == 'pull_request' }} uses: reviewdog/action-suggester@v1 with: tool_name: pre-commit From 6674144d4121a33f401f95ad19e3e25919828b2e Mon Sep 17 00:00:00 2001 From: David Sankel Date: Fri, 18 Oct 2024 20:26:10 -0400 Subject: [PATCH 09/10] Minor CMake change for readability PROJECT_SOURCE_DIR is easier to read than all the `../`'s. I also removed `INCLUDE_DIR` to (arguably) reduce complexity. --- src/beman/exemplar/CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/beman/exemplar/CMakeLists.txt b/src/beman/exemplar/CMakeLists.txt index 9493be0..328f408 100644 --- a/src/beman/exemplar/CMakeLists.txt +++ b/src/beman/exemplar/CMakeLists.txt @@ -5,14 +5,12 @@ add_library(beman::exemplar ALIAS beman.exemplar) target_sources(beman.exemplar PRIVATE identity.cpp) -set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../include/) - target_sources( beman.exemplar PUBLIC FILE_SET HEADERS - BASE_DIRS ${INCLUDE_DIR} - FILES ${INCLUDE_DIR}/beman/exemplar/identity.hpp + BASE_DIRS ${PROJET_SOURCE_DIR}/include + FILES ${PROJECT_SOURCE_DIR}/include/beman/exemplar/identity.hpp ) set_target_properties(beman.exemplar PROPERTIES VERIFY_INTERFACE_HEADER_SETS ON) From 959bf3b9c0ad949eeefee278eaf9118b27aa1d43 Mon Sep 17 00:00:00 2001 From: David Sankel Date: Fri, 18 Oct 2024 20:40:30 -0400 Subject: [PATCH 10/10] Fix typo. --- src/beman/exemplar/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/beman/exemplar/CMakeLists.txt b/src/beman/exemplar/CMakeLists.txt index 328f408..c887c7f 100644 --- a/src/beman/exemplar/CMakeLists.txt +++ b/src/beman/exemplar/CMakeLists.txt @@ -9,7 +9,7 @@ target_sources( beman.exemplar PUBLIC FILE_SET HEADERS - BASE_DIRS ${PROJET_SOURCE_DIR}/include + BASE_DIRS ${PROJECT_SOURCE_DIR}/include FILES ${PROJECT_SOURCE_DIR}/include/beman/exemplar/identity.hpp )