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 all 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
Copy link
Member

Choose a reason for hiding this comment

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

Why are we moving this? Seems unrelated to this PR? I think this PR is complicated enough that if there are any other changes to the setup, like ClangFormat, let's do them in a separate PR?

File renamed without changes.
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-*'
# 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 apt update && sudo apt install llvm
- 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
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,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 @@ -33,6 +34,10 @@ if(PROJECT_IS_TOP_LEVEL)
sourcemeta_enable_simd()
endif()

if(SOURCEMETA_CORE_CLANG_TIDY)
sourcemeta_set_clang_tidy_config(HEADER_FILTER "${PROJECT_SOURCE_DIR}/src/*")
endif()

# TODO: Turn this into a re-usable utility CMake function
if(SOURCEMETA_CORE_INSTALL)
include(GNUInstallDirs)
Expand Down Expand Up @@ -120,7 +125,6 @@ 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()

# Testing
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
2 changes: 1 addition & 1 deletion cmake/common/targets/clang-format.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function(sourcemeta_target_clang_format)
file(GLOB_RECURSE SOURCEMETA_TARGET_CLANG_FORMAT_FILES
${SOURCEMETA_TARGET_CLANG_FORMAT_SOURCES})

set(CLANG_FORMAT_CONFIG "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clang-format.config")
set(CLANG_FORMAT_CONFIG "${PROJECT_SOURCE_DIR}/.clang-format")
if(CMAKE_SYSTEM_NAME STREQUAL "MSYS")
# Because `clang-format` is typically a Windows `.exe`, transform the path accordingly
execute_process(COMMAND cygpath -w "${CLANG_FORMAT_CONFIG}"
Expand Down
134 changes: 11 additions & 123 deletions cmake/common/targets/clang-tidy.cmake
Original file line number Diff line number Diff line change
@@ -1,130 +1,18 @@
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}")
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()
function(sourcemeta_find_clang_tidy)
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
find_program(CLANG_TIDY_BIN NAMES clang-tidy REQUIRED)
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")
message(FATAL_ERROR "Incompatible compiler toolchain. Clang-tidy is only tested to be working with clang toolchain")
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()
endfunction()

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)
function(sourcemeta_set_clang_tidy_config)
cmake_parse_arguments(SOURCEMETA_SET_CLANG_TIDY_CONFIG "" "HEADER_FILTER" "" ${ARGN})
if(NOT SOURCEMETA_SET_CLANG_TIDY_CONFIG_HEADER_FILTER)
message(FATAL_ERROR "HEADER_FILTER is required for clang-tidy.")
endif()

set_target_properties(clang_tidy PROPERTIES FOLDER "Linting")
sourcemeta_find_clang_tidy()
set(SOURCEMETA_CXX_CLANG_TIDY "${CLANG_TIDY_BIN};--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy;-header-filter=${SOURCEMETA_SET_CLANG_TIDY_CONFIG_HEADER_FILTER}" PARENT_SCOPE)
endfunction()
22 changes: 0 additions & 22 deletions cmake/common/targets/clang-tidy.config

This file was deleted.

9 changes: 8 additions & 1 deletion cmake/common/targets/library.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function(sourcemeta_library)
cmake_parse_arguments(SOURCEMETA_LIBRARY ""
"NAMESPACE;PROJECT;NAME;VARIANT" "PRIVATE_HEADERS;SOURCES" ${ARGN})
"NAMESPACE;PROJECT;NAME;VARIANT" "PRIVATE_HEADERS;SOURCES;CLANG_TIDY" ${ARGN})

if(NOT SOURCEMETA_LIBRARY_PROJECT)
message(FATAL_ERROR "You must pass the project name using the PROJECT option")
Expand Down Expand Up @@ -115,6 +115,13 @@ function(sourcemeta_library)
target_include_directories(${TARGET_NAME}
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>")
endif()

if(SOURCEMETA_LIBRARY_CLANG_TIDY)
message(STATUS "setting CXX_CLANG_TIDY target property to ${SOURCEMETA_LIBRARY_CLANG_TIDY} on ${TARGET_NAME}")
set_target_properties(${TARGET_NAME}
PROPERTIES
CXX_CLANG_TIDY "${SOURCEMETA_LIBRARY_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.

Are you sure this is correct? The documentation seems to imply that you have to set this to the binary, and not just to ON?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I think it stopped working for me

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm I find this whole thing still very confusing. Let me try to shoot a WIP PR myself too to play around with this. I still feel there must be a simpler way

endif()
endfunction()

function(sourcemeta_library_install)
Expand Down
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