Skip to content

Clang tidy separate ci job #1801

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 29 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
55ea0c0
Run ClangTidy on GitHub Actions
jviotti May 12, 2025
8c698ea
use llvm
bavulapati Jul 2, 2025
e48ea52
run llvm installation as root
bavulapati Jul 2, 2025
c845be0
use sudo
bavulapati Jul 2, 2025
6ee9722
remove redundant target call
bavulapati Jul 2, 2025
0c9e0d8
use macos instead of ubuntu
bavulapati Jul 2, 2025
f7a9f53
use brew
bavulapati Jul 2, 2025
291bc33
use llvm path
bavulapati Jul 2, 2025
12b3e3d
fix path
bavulapati Jul 2, 2025
70b925b
use a step to set path
bavulapati Jul 2, 2025
1bf2001
disable other jobs while you test the changes
bavulapati Jul 2, 2025
593833d
use bash
bavulapati Jul 2, 2025
d334af4
debug path
bavulapati Jul 2, 2025
996c687
use Github path
bavulapati Jul 2, 2025
81bc9ab
use ubuntu
bavulapati Jul 2, 2025
bdac96c
fix modernize-use-nodiscard checks
bavulapati Jul 2, 2025
dace288
remove verbose steps
bavulapati Jul 2, 2025
e1203af
use clang compiler
bavulapati Jul 2, 2025
eef5869
re-enable the ci jobs
bavulapati Jul 2, 2025
cbd24f8
Update cmake/common/targets/clang-tidy.cmake
bavulapati Jul 4, 2025
bc7cdda
install llvm via ubuntu packages
bavulapati Jul 4, 2025
9c7d718
Merge branch 'clang-tidy-separate-ci-job' of github.com:bavulapati/co…
bavulapati Jul 4, 2025
5a00eca
make clang-tidy required on ci job
bavulapati Jul 4, 2025
e9369fe
Error out if clang-tidy is invoked without clang tool chain
bavulapati Jul 4, 2025
847cea1
enable clang-tidy at target level
bavulapati Jul 8, 2025
dea5f3c
Enable clang-tidy modernize-* checks
bavulapati Jul 8, 2025
194cc51
Merge branch 'main' into clang-tidy-separate-ci-job
bavulapati Jul 8, 2025
26d0bbc
pass header-filter as a cmake function parameter
bavulapati Jul 8, 2025
0a76a8e
move .clang-format config to root directory
bavulapati Jul 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
# See https://clang.llvm.org/extra/clang-tidy/index.html
# First disable all default checks (with -*)
Checks: '-*,
modernize-use-nodiscard'
# TODO(bavulapati): iterate through the rules and enable them incrementally inorder to send smaller PRs
# bugprone-*,-bugprone-branch-clone,-bugprone-easily-swappable-parameters,-bugprone-empty-catch,
# clang-analyzer-*,
# clang-diagnostic-*,
# modernize-*,
# concurrency-*,
# cppcoreguidelines-*,-cppcoreguidelines-rvalue-reference-param-not-moved,
# performance-*,-performance-enum-size,
# portability-*,
# objc-*,
# misc-*,-misc-no-recursion,-misc-unused-parameters,-misc-const-correctness'
WarningsAsErrors: '*'
FormatStyle: none
UseColor: true
SystemHeaders: false
21 changes: 21 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,24 @@ jobs:
alert-threshold: '5%'
comment-always: true
fail-on-alert: false

clang-tidy:
runs-on: ubuntu-latest
env:
CC: clang
CXX: clang++
steps:
- uses: actions/checkout@v4
- run: cmake --version
- name: Install llvm
run: sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this? I thought we tweaked the CMake scripts to conveniently download ClangTidy binaries when configuring?

- run: >
cmake -S . -B ./build
-DCMAKE_BUILD_TYPE:STRING=Release
-DSOURCEMETA_CORE_TESTS:BOOL=OFF
-DSOURCEMETA_CORE_BENCHMARK:BOOL=OFF
-DSOURCEMETA_CORE_DOCS:BOOL=OFF
-DBUILD_SHARED_LIBS:BOOL=OFF
-DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON
-DSOURCEMETA_CORE_CLANG_TIDY:BOOL=ON
- run: cmake --build ./build --config Release
8 changes: 7 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ option(SOURCEMETA_CORE_CONTRIB_ZLIB "Build the ZLIB library for downstream consu
option(SOURCEMETA_CORE_CONTRIB_BEARSSL "Build the BearSSL library for downstream consumers" OFF)
option(SOURCEMETA_CORE_CONTRIB_GOOGLETEST "Build the GoogleTest library for downstream consumers" OFF)
option(SOURCEMETA_CORE_CONTRIB_GOOGLEBENCHMARK "Build the GoogleBenchmark library for downstream consumers" OFF)
option(SOURCEMETA_CORE_CLANG_TIDY "Run clang-tidy checks" OFF)

include(Sourcemeta)

Expand All @@ -32,6 +33,10 @@ if(PROJECT_IS_TOP_LEVEL)
sourcemeta_enable_simd()
endif()

if(SOURCEMETA_CORE_CLANG_TIDY)
sourcemeta_enable_clang_tidy()
endif()

# TODO: Turn this into a re-usable utility CMake function
if(SOURCEMETA_CORE_INSTALL)
include(GNUInstallDirs)
Expand Down Expand Up @@ -115,9 +120,10 @@ if(PROJECT_IS_TOP_LEVEL)
src/*.h src/*.cc
benchmark/*.h benchmark/*.cc
test/*.h test/*.cc)
sourcemeta_target_clang_tidy(SOURCES src/*.cc)
endif()

sourcemeta_disable_clang_tidy()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. Disabling looks a bit weird though. Now that I see this I wonder if it is possible to set CMAKE_CXX_CLANG_TIDY on a per-target level. If so, we could have a CLANG_TIDY option when declaring a library with sourcemeta_library (or executable with sourcemeta_executable). Then we don't have to worry about unsetting it, as we literally opt into it for specific things we are about?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can do it at the target level


# Testing

if(SOURCEMETA_CORE_CONTRIB_GOOGLETEST OR SOURCEMETA_CORE_TESTS)
Expand Down
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ compile: .always
$(CMAKE) --install ./build --prefix ./build/dist --config $(PRESET) --verbose \
--component sourcemeta_core_dev

lint: .always
$(CMAKE) --build ./build --config $(PRESET) --target clang_tidy

test: .always
$(CMAKE) -E env UBSAN_OPTIONS=print_stacktrace=1 \
$(CTEST) --test-dir ./build --build-config $(PRESET) \
Expand Down
132 changes: 5 additions & 127 deletions cmake/common/targets/clang-tidy.cmake
Original file line number Diff line number Diff line change
@@ -1,130 +1,8 @@
function(sourcemeta_target_clang_tidy_attempt_install)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I mentioned this before, but why cannot we pull ClangTidy pre-compiled binaries like before? Otherwise we are back at having it at the system level?

cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL "" "OUTPUT_DIRECTORY" "" ${ARGN})
if(NOT SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY)
message(FATAL_ERROR "You must pass the output directory in the OUTPUT_DIRECTORY option")
endif()

# See https://pypi.org/project/clang-tidy/
set(CLANG_TIDY_BINARY_VERSION "20.1.0")
set(CLANG_TIDY_BINARY_Windows_AMD64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-win_amd64.whl")
set(CLANG_TIDY_BINARY_MSYS_x86_64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-win_amd64.whl")
set(CLANG_TIDY_BINARY_Darwin_arm64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-macosx_11_0_arm64.whl")
set(CLANG_TIDY_BINARY_Darwin_x86_64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-macosx_10_9_x86_64.whl")
set(CLANG_TIDY_BINARY_Linux_aarch64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl")
set(CLANG_TIDY_BINARY_Linux_x86_64 "clang_tidy-${CLANG_TIDY_BINARY_VERSION}-py2.py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl")
set(CLANG_TIDY_BINARY_CHECKSUM_Windows_AMD64 "02/f0/dd985d9d9b76f8c39f1995aa475d8d5aabbea0d3e0cf498df44dc7bf1cb0")
set(CLANG_TIDY_BINARY_CHECKSUM_MSYS_x86_64 "02/f0/dd985d9d9b76f8c39f1995aa475d8d5aabbea0d3e0cf498df44dc7bf1cb0")
set(CLANG_TIDY_BINARY_CHECKSUM_Darwin_arm64 "95/02/838baf08764b08327322096bda55e8d1e2344e4a13b9308e5642cfaafd8e")
set(CLANG_TIDY_BINARY_CHECKSUM_Darwin_x86_64 "6d/5b/dcfc84b895d8544e00186738ca85132bbd14db4d11dbe39502630ece5391")
set(CLANG_TIDY_BINARY_CHECKSUM_Linux_aarch64 "be/61/9e1a0797639e81c41d38d7b8b2508a9be4b05b9a23baa9d64e7284d07238")
set(CLANG_TIDY_BINARY_CHECKSUM_Linux_x86_64 "52/76/42c61be1c1fdf8bacdbb265f0cd3e11321fee7362f91fa840717a6a41ad6")
set(CLANG_TIDY_BINARY_NAME_Windows_AMD64 "clang-tidy.exe")
set(CLANG_TIDY_BINARY_NAME_MSYS_x86_64 "clang-tidy.exe")
set(CLANG_TIDY_BINARY_NAME_Darwin_arm64 "clang-tidy")
set(CLANG_TIDY_BINARY_NAME_Darwin_x86_64 "clang-tidy")
set(CLANG_TIDY_BINARY_NAME_Linux_aarch64 "clang-tidy")
set(CLANG_TIDY_BINARY_NAME_Linux_x86_64 "clang-tidy")

# Determine the pre-built binary URL
string(REPLACE "." "_" CLANG_TIDY_BINARY_SYSTEM "${CMAKE_SYSTEM_NAME}")
string(REPLACE "." "_" CLANG_TIDY_BINARY_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
set(CLANG_TIDY_BINARY_URL_VAR "CLANG_TIDY_BINARY_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}")
set(CLANG_TIDY_BINARY_CHECKSUM_VAR "CLANG_TIDY_BINARY_CHECKSUM_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}")
set(CLANG_TIDY_BINARY_NAME_VAR "CLANG_TIDY_BINARY_NAME_${CLANG_TIDY_BINARY_SYSTEM}_${CLANG_TIDY_BINARY_ARCH}")
if(NOT DEFINED ${CLANG_TIDY_BINARY_URL_VAR} OR "${${CLANG_TIDY_BINARY_URL_VAR}}" STREQUAL "")
message(WARNING "Skipping `clang-tidy` download. No known pre-build binary URL")
return()
elseif(NOT DEFINED ${CLANG_TIDY_BINARY_CHECKSUM_VAR} OR "${${CLANG_TIDY_BINARY_CHECKSUM_VAR}}" STREQUAL "")
message(FATAL_ERROR "No known `clang-tidy` pre-build binary checksum")
elseif(NOT DEFINED ${CLANG_TIDY_BINARY_NAME_VAR} OR "${${CLANG_TIDY_BINARY_NAME_VAR}}" STREQUAL "")
message(FATAL_ERROR "No known `clang-tidy` pre-build binary name")
endif()
set(CLANG_TIDY_BINARY_URL "https://files.pythonhosted.org/packages/${${CLANG_TIDY_BINARY_CHECKSUM_VAR}}/${${CLANG_TIDY_BINARY_URL_VAR}}")

# Download and extract the pre-built binary ZIP if needed
set(CLANG_TIDY_BINARY_NAME "${${CLANG_TIDY_BINARY_NAME_VAR}}")
set(CLANG_TIDY_BINARY_OUTPUT "${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}/${CLANG_TIDY_BINARY_NAME}")
if(EXISTS "${CLANG_TIDY_BINARY_OUTPUT}")
message(STATUS "Found existing `clang-tidy` pre-built binary at ${CLANG_TIDY_BINARY_OUTPUT}")
return()
endif()
set(CLANG_TIDY_BINARY_DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/clang-tidy")
file(REMOVE_RECURSE "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}")
file(MAKE_DIRECTORY "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}")
set(CLANG_TIDY_BINARY_WHEEL "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}/clang-tidy.whl")
message(STATUS "Downloading `clang-tidy` pre-built binary from ${CLANG_TIDY_BINARY_URL}")
file(DOWNLOAD "${CLANG_TIDY_BINARY_URL}" "${CLANG_TIDY_BINARY_WHEEL}"
STATUS CLANG_TIDY_BINARY_DOWNLOAD_STATUS SHOW_PROGRESS TLS_VERIFY ON
LOG CLANG_TIDY_BINARY_DOWNLOAD_LOG)
list(GET CLANG_TIDY_BINARY_DOWNLOAD_STATUS 0 _code)
if(NOT _code EQUAL 0)
message(WARNING "Failed to download the `clang-tidy` pre-built binary")
message(WARNING "${CLANG_TIDY_BINARY_DOWNLOAD_LOG}")
file(REMOVE_RECURSE "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}")
return()
endif()
set(CLANG_TIDY_BINARY_EXTRACT_DIR "${CLANG_TIDY_BINARY_DOWNLOAD_DIR}/extracted")
file(MAKE_DIRECTORY "${CLANG_TIDY_BINARY_EXTRACT_DIR}")
file(ARCHIVE_EXTRACT INPUT "${CLANG_TIDY_BINARY_WHEEL}" DESTINATION "${CLANG_TIDY_BINARY_EXTRACT_DIR}")

# Install the binary
file(MAKE_DIRECTORY "${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}")
file(COPY "${CLANG_TIDY_BINARY_EXTRACT_DIR}/clang_tidy/data/bin/${CLANG_TIDY_BINARY_NAME}"
DESTINATION "${SOURCEMETA_TARGET_CLANG_TIDY_ATTEMPT_INSTALL_OUTPUT_DIRECTORY}")
file(CHMOD "${CLANG_TIDY_BINARY_OUTPUT}" PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
message(STATUS "Installed `clang-tidy` pre-built binary to ${CLANG_TIDY_BINARY_OUTPUT}")
function(sourcemeta_enable_clang_tidy)
find_program(CLANG_TIDY_BIN NAMES clang-tidy)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could still download ClangTidy on demand and set CMAKE_CXX_CLANG_TIDY to the downloaded files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having clang-tidy without rest of the llvm is causing trouble

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also keep in mind that this find_program invocation succeeds even if clang-tidy was not found. Maybe worth putting REQUIRED? Otherwise you might end up setting a non-sense CMAKE_CXX_CLANG_TIDY?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having clang-tidy without rest of the llvm is causing trouble

@bavulapati Even when installing clang-tidy from the Ubuntu packages? Because in theory Ubuntu consumes upstream LLVM.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can try that

set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy;-header-filter=${CMAKE_CURRENT_SOURCE_DIR}/src/*" PARENT_SCOPE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably fine for all projects right now, but maybe worth taking the -header-filter as an option to the CMake function? At least so that it is generic enough out of the box for all possible uses?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, does this work across compilers? i.e. can I enable this if I have ClangTidy available even if using MSVC? Or does it also require the Clang compiler? If so, it might be worth checking for this, so that nobody can accidentally enable it

endfunction()

function(sourcemeta_target_clang_tidy)
cmake_parse_arguments(SOURCEMETA_TARGET_CLANG_TIDY "REQUIRED" "" "SOURCES" ${ARGN})
sourcemeta_target_clang_tidy_attempt_install(OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")

if(SOURCEMETA_TARGET_CLANG_TIDY_REQUIRED)
find_program(CLANG_TIDY_BIN NAMES clang-tidy NO_DEFAULT_PATH
PATHS "${CMAKE_CURRENT_BINARY_DIR}/bin")
if(NOT CLANG_TIDY_BIN)
find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED)
endif()
else()
find_program(CLANG_TIDY_BIN NAMES clang-tidy NO_DEFAULT_PATH
PATHS "${CMAKE_CURRENT_BINARY_DIR}/bin")
if(NOT CLANG_TIDY_BIN)
find_program(CLANG_TIDY_BIN NAMES clang-tidy)
endif()
endif()


# This covers the empty list too
if(NOT SOURCEMETA_TARGET_CLANG_TIDY_SOURCES)
message(FATAL_ERROR "You must pass file globs to analyze in the SOURCES option")
endif()
file(GLOB_RECURSE SOURCEMETA_TARGET_CLANG_TIDY_FILES
${SOURCEMETA_TARGET_CLANG_TIDY_SOURCES})

set(CLANG_TIDY_CONFIG "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-tidy.config")

if(CMAKE_SYSTEM_NAME STREQUAL "MSYS")
# Because `clang-tidy` is typically a Windows `.exe`, transform the path accordingly
execute_process(COMMAND cygpath -w "${CLANG_TIDY_CONFIG}"
OUTPUT_VARIABLE CLANG_TIDY_CONFIG OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()

if(CLANG_TIDY_BIN)
add_custom_target(clang_tidy
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
VERBATIM
COMMAND "${CLANG_TIDY_BIN}" -p "${PROJECT_BINARY_DIR}"
--config-file "${CLANG_TIDY_CONFIG}"
${SOURCEMETA_TARGET_CLANG_TIDY_FILES}
COMMENT "Analyzing sources using ClangTidy")
else()
add_custom_target(clang_tidy
WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
VERBATIM
COMMAND "${CMAKE_COMMAND}" -E echo "Could not locate ClangTidy"
COMMAND "${CMAKE_COMMAND}" -E false)
endif()

set_target_properties(clang_tidy PROPERTIES FOLDER "Linting")
function(sourcemeta_disable_clang_tidy)
unset(CMAKE_CXX_CLANG_TIDY PARENT_SCOPE)
endfunction()
22 changes: 0 additions & 22 deletions cmake/common/targets/clang-tidy.config

This file was deleted.

24 changes: 16 additions & 8 deletions src/core/json/include/sourcemeta/core/json_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,39 @@ template <typename Value> class JSONArray {
/// Get a mutable end iterator on the array
auto end() noexcept -> iterator { return this->data.end(); }
/// Get a constant begin iterator on the array
auto begin() const noexcept -> const_iterator { return this->data.begin(); }
[[nodiscard]] auto begin() const noexcept -> const_iterator {
return this->data.begin();
}
/// Get a constant end iterator on the array
auto end() const noexcept -> const_iterator { return this->data.end(); }
[[nodiscard]] auto end() const noexcept -> const_iterator {
return this->data.end();
}
/// Get a constant begin iterator on the array
auto cbegin() const noexcept -> const_iterator { return this->data.cbegin(); }
[[nodiscard]] auto cbegin() const noexcept -> const_iterator {
return this->data.cbegin();
}
/// Get a constant end iterator on the array
auto cend() const noexcept -> const_iterator { return this->data.cend(); }
[[nodiscard]] auto cend() const noexcept -> const_iterator {
return this->data.cend();
}
/// Get a mutable reverse begin iterator on the array
auto rbegin() noexcept -> reverse_iterator { return this->data.rbegin(); }
/// Get a mutable reverse end iterator on the array
auto rend() noexcept -> reverse_iterator { return this->data.rend(); }
/// Get a constant reverse begin iterator on the array
auto rbegin() const noexcept -> const_reverse_iterator {
[[nodiscard]] auto rbegin() const noexcept -> const_reverse_iterator {
return this->data.rbegin();
}
/// Get a constant reverse end iterator on the array
auto rend() const noexcept -> const_reverse_iterator {
[[nodiscard]] auto rend() const noexcept -> const_reverse_iterator {
return this->data.rend();
}
/// Get a constant reverse begin iterator on the array
auto crbegin() const noexcept -> const_reverse_iterator {
[[nodiscard]] auto crbegin() const noexcept -> const_reverse_iterator {
return this->data.crbegin();
}
/// Get a constant reverse end iterator on the array
auto crend() const noexcept -> const_reverse_iterator {
[[nodiscard]] auto crend() const noexcept -> const_reverse_iterator {
return this->data.crend();
}

Expand Down
8 changes: 5 additions & 3 deletions src/core/json/include/sourcemeta/core/json_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ template <typename T> struct HashJSON {
return value.fast_hash();
}

inline auto is_perfect(const hash_type) const noexcept -> bool {
[[nodiscard]] inline auto is_perfect(const hash_type) const noexcept -> bool {
return false;
}
};
Expand Down Expand Up @@ -45,7 +45,8 @@ template <typename T> struct PropertyHashJSON {
}
};

inline auto perfect(const T &value, const std::size_t size) const noexcept
[[nodiscard]] inline auto perfect(const T &value,
const std::size_t size) const noexcept
-> hash_type {
hash_type result;
assert(!value.empty());
Expand Down Expand Up @@ -134,7 +135,8 @@ template <typename T> struct PropertyHashJSON {
}
}

inline auto is_perfect(const hash_type &hash) const noexcept -> bool {
[[nodiscard]] inline auto is_perfect(const hash_type &hash) const noexcept
-> bool {
// If there is anything written past the first byte,
// then it is a perfect hash
return hash.a > 255;
Expand Down
Loading