diff --git a/.clang-format b/.clang-format index 05baf03..d8c0600 100644 --- a/.clang-format +++ b/.clang-format @@ -1,4 +1,8 @@ --- +BasedOnStyle: Llvm +IndentWidth: 2 +UseTab: Never +--- Language: Cpp AccessModifierOffset: -2 AlignAfterOpenBracket: Align @@ -110,7 +114,7 @@ IncludeCategories: Priority: 2 SortPriority: 0 CaseSensitive: false - - Regex: '^(<|"(gtest|isl|json)/)' + - Regex: '^(<|"(beman|gtest|isl|json)/)' Priority: 3 SortPriority: 0 CaseSensitive: false @@ -184,7 +188,7 @@ RequiresClausePosition: OwnLine RequiresExpressionIndentation: OuterScope SeparateDefinitionBlocks: Leave ShortNamespaceLines: 1 -SortIncludes: Never +SortIncludes: true SortJavaStaticImport: Before SortUsingDeclarations: LexicographicNumeric SpaceAfterCStyleCast: false diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index e1662e7..a9deb40 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,16 +1,16 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the -// README at: https://github.com/devcontainers/templates/tree/main/src/cpp + // README at: https://github.com/devcontainers/templates/tree/main/src/cpp -{ - "name": "Beman Project Generic Devcontainer", - "image": "ghcr.io/bemanproject/devcontainers-gcc:14", - "postCreateCommand": "pre-commit", - "customizations": { - "vscode": { - "extensions": [ - "ms-vscode.cpptools", - "ms-vscode.cmake-tools" - ] - } - } -} + { + "name": "Beman Project Generic Devcontainer", + "image": "ghcr.io/bemanproject/devcontainers-gcc:14", + "postCreateCommand": "pre-commit", + "customizations": { + "vscode": { + "extensions": [ + "ms-vscode.cpptools", + "ms-vscode.cmake-tools" + ] + } + } + } diff --git a/.gitignore b/.gitignore index 286a38e..29dc555 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ +/CMakeUserPresets.json /compile_commands.json /build +/.cache diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8fd4a37..91fdddb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,33 +4,34 @@ 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 + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + exclude: ^\.clang-(format|tidy)$ + - 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: v21.1.2 + rev: v21.1.5 hooks: - - id: clang-format - types_or: [c++, c] + - id: clang-format + types_or: [c++, c, json] # CMake linting and formatting - repo: https://github.com/BlankSpruce/gersemi - rev: 0.22.3 + rev: 0.23.1 hooks: - - id: gersemi - name: CMake linting + - id: gersemi + name: CMake linting # Markdown linting # Config file: .markdownlint.yaml - repo: https://github.com/igorshubovych/markdownlint-cli - rev: v0.45.0 + rev: v0.46.0 hooks: - - id: markdownlint + - id: markdownlint - repo: https://github.com/codespell-project/codespell rev: v2.4.1 diff --git a/CMakeLists.txt b/CMakeLists.txt index e69a90f..707213b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,18 @@ option( ${PROJECT_IS_TOP_LEVEL} ) +option( + ENABLE_TEST_COVERAGE + "Compile with test-coverage flags" + ${PROJECT_IS_TOP_LEVEL} +) +if(UNIX AND ENABLE_TEST_COVERAGE AND CMAKE_BUILD_TYPE STREQUAL Debug) + message(WARNING "ENABLE_TEST_COVERAGE is set!") + add_compile_options(-O0 -g -fprofile-arcs -ftest-coverage) + add_link_options(-fprofile-arcs -ftest-coverage) + # TODO(CK): add_compile_definitions(TARGET_CODE_COVERAGE) +endif() + include(CTest) add_subdirectory(src/beman/cstring_view) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 857a14a..2e88398 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -18,4 +18,8 @@ foreach(example ${ALL_EXAMPLES}) beman.cstring_view.examples.${example} PRIVATE beman::cstring_view ) + add_test( + NAME beman.cstring_view.examples.${example} + COMMAND beman.cstring_view.examples.${example} + ) endforeach() diff --git a/examples/example.cpp b/examples/example.cpp index 5811bc2..55fa9a3 100644 --- a/examples/example.cpp +++ b/examples/example.cpp @@ -7,20 +7,25 @@ using namespace std::literals; using namespace beman::literals; +namespace { std::string_view to_string(std::strong_ordering order) { if (order == std::strong_ordering::equal) { return "equal"; - } else if (order == std::strong_ordering::equivalent) { + } + if (order == std::strong_ordering::equivalent) { return "equivalent"; - } else if (order == std::strong_ordering::less) { + } + if (order == std::strong_ordering::less) { return "less"; - } else if (order == std::strong_ordering::greater) { + } + if (order == std::strong_ordering::greater) { return "greater"; - } else { - assert(false); - return "internal error"; } + + assert(false); + return "internal error"; } +} // namespace int main() { std::string s = "hello world"; @@ -33,7 +38,7 @@ int main() { std::cout << z0.starts_with("hello") << "\n"; std::cout << z0.starts_with("hello"_csv) << "\n"; std::cout << std::hash{}(z1) << "\n"; - std::cout << z1 << std::endl; + std::cout << z1 << "\n"; std::cout << ("hello"_csv == "hello"sv) << "\n"; std::cout << ("hello"_csv == "hello"_csv) << "\n"; std::cout << ("hello"_csv != "goodbye"sv) << "\n"; @@ -55,7 +60,7 @@ int main() { std::cout << wz0.starts_with(L"hello") << "\n"; std::cout << wz0.starts_with(L"hello"_csv) << "\n"; std::cout << std::hash{}(wz1) << "\n"; - std::wcout << wz1 << std::endl; + std::wcout << wz1 << "\n"; std::cout << (L"hello"_csv == L"hello"sv) << "\n"; std::cout << (L"hello"_csv == L"hello"_csv) << "\n"; std::cout << (L"hello"_csv != L"goodbye"sv) << "\n"; diff --git a/gcovr.cfg b/gcovr.cfg new file mode 100644 index 0000000..9850b03 --- /dev/null +++ b/gcovr.cfg @@ -0,0 +1,26 @@ +root = . +search-path = build + +filter = src/* +filter = include/* +filter = examples/* +# NO! filter = tests/* +exclude = tests + +exclude-directories = build/_deps +exclude-directories = coverage +exclude-directories = docs +exclude-directories = build/stagedir +exclude-directories = papers +exclude-directories = infra +exclude-directories = .cache +exclude-directories = .direnv +exclude-directories = .venv + +gcov-ignore-parse-errors = all +print-summary = yes + +html-details = build/debug/gcovr.html + +# cobertura-pretty = yes +# cobertura = build/debug/cobertura.xml diff --git a/include/beman/cstring_view/cstring_view.hpp b/include/beman/cstring_view/cstring_view.hpp index e71da41..98b5900 100644 --- a/include/beman/cstring_view/cstring_view.hpp +++ b/include/beman/cstring_view/cstring_view.hpp @@ -2,13 +2,13 @@ #define BEMAN_CSTRING_VIEW_HPP #include -#include #include +#include #include #include #include -#include #include +#include namespace beman { diff --git a/tests/beman/cstring_view/cstring_view.test.cpp b/tests/beman/cstring_view/cstring_view.test.cpp index 9d7e8b7..a3d0a05 100644 --- a/tests/beman/cstring_view/cstring_view.test.cpp +++ b/tests/beman/cstring_view/cstring_view.test.cpp @@ -1,5 +1,6 @@ -#include #include + +#include #include #include @@ -7,9 +8,9 @@ using namespace beman::literals; using namespace std::literals; TEST(StringView, ConstructionDestruction) { - std::string s = "hello"; - beman::cstring_view h1 = "hello"; - beman::cstring_view h2 = h1; + std::string s{"hello"}; + constexpr beman::cstring_view h1{"hello"}; + const beman::cstring_view h2{h1}; EXPECT_EQ(h1.c_str(), h2.c_str()); EXPECT_NE(h1.c_str(), s.c_str()); @@ -27,4 +28,18 @@ TEST(StringView, ConstructionDestruction) { EXPECT_TRUE((std::is_same_v)); EXPECT_EQ(first, "he"); EXPECT_EQ(end, "llo"); + + auto str = " trim me "s; + beman::cstring_view v = str; + v.remove_prefix(std::min(v.find_first_not_of(" "), v.size())); + EXPECT_TRUE(v.starts_with("trim")); + + // TODO: v.remove_suffix(std::min(v.find_last_not_of(" "), v.size())); + std::string_view strv{v.begin(), v.end()}; + EXPECT_TRUE(std::min(strv.find_last_not_of("\t\n\r "), strv.size()) < strv.size()); + + // TODO: s = first + end; + s = first; + s += end; // append() + EXPECT_TRUE(s == h1); }