Skip to content

Commit f9f7206

Browse files
committed
Reformat code, and add clang-tidy.
1 parent 8e1cebe commit f9f7206

13 files changed

Lines changed: 2375 additions & 866 deletions

.clang-format

Lines changed: 229 additions & 421 deletions
Large diffs are not rendered by default.

.clang-tidy

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
Checks:
3+
# Essential diagnostic and static analysis
4+
- clang-diagnostic-*
5+
- clang-analyzer-*
6+
# Common best practices and bug detection
7+
- bugprone-*
8+
- cert-*
9+
- cppcoreguidelines-*
10+
- modernize-*
11+
- performance-*
12+
- portability-*
13+
- readability-*
14+
# Specific checks for better maintainability and correctness
15+
- misc-braces-around-statements
16+
# Exclusions (removing unnecessary or restrictive checks)
17+
- -altera-unroll-loops
18+
- -altera-struct-pack-align
19+
- -altera-id-dependent-backward-branch
20+
- -llvm-header-guard
21+
- -modernize-return-braced-init-list
22+
- -modernize-use-default-member-init
23+
- -modernize-use-nodiscard
24+
- -modernize-type-traits
25+
- -modernize-concat-nested-namespaces
26+
- -bugprone-return-const-ref-from-parameter
27+
- -bugprone-easily-swappable-parameters
28+
- -readability-non-const-parameter
29+
- -readability-magic-numbers
30+
- -readability-identifier-length
31+
- -google-runtime-int
32+
- -cppcoreguidelines-avoid-non-const-global-variables
33+
- -cppcoreguidelines-avoid-magic-numbers
34+
- -cppcoreguidelines-avoid-do-while
35+
- -cppcoreguidelines-use-default-member-init
36+
- -readability-redundant-member-init
37+
38+
WarningsAsErrors: ''
39+
HeaderFileExtensions:
40+
- h
41+
- hh
42+
- hpp
43+
- hxx
44+
ImplementationFileExtensions:
45+
- c
46+
- cc
47+
- cpp
48+
- cxx
49+
FormatStyle: none
50+
SystemHeaders: false
51+
HeaderFilterRegex: ''
52+
ExcludeHeaderFilterRegex: ('^/usr/.*' | '^/lib/.*')
53+
User: enrico
54+
CheckOptions:
55+
cert-dcl16-c.NewSuffixes: 'L;LL;LU;LLU'
56+
cert-err33-c.AllowCastToVoid: 'true'
57+
cert-err33-c.CheckedFunctions: '^::aligned_alloc;^::asctime_s;^::at_quick_exit;^::atexit;^::bsearch;^::bsearch_s;^::btowc;^::c16rtomb;^::c32rtomb;^::calloc;^::clock;^::cnd_broadcast;^::cnd_init;^::cnd_signal;^::cnd_timedwait;^::cnd_wait;^::ctime_s;^::fclose;^::fflush;^::fgetc;^::fgetpos;^::fgets;^::fgetwc;^::fopen;^::fopen_s;^::fprintf;^::fprintf_s;^::fputc;^::fputs;^::fputwc;^::fputws;^::fread;^::freopen;^::freopen_s;^::fscanf;^::fscanf_s;^::fseek;^::fsetpos;^::ftell;^::fwprintf;^::fwprintf_s;^::fwrite;^::fwscanf;^::fwscanf_s;^::getc;^::getchar;^::getenv;^::getenv_s;^::gets_s;^::getwc;^::getwchar;^::gmtime;^::gmtime_s;^::localtime;^::localtime_s;^::malloc;^::mbrtoc16;^::mbrtoc32;^::mbsrtowcs;^::mbsrtowcs_s;^::mbstowcs;^::mbstowcs_s;^::memchr;^::mktime;^::mtx_init;^::mtx_lock;^::mtx_timedlock;^::mtx_trylock;^::mtx_unlock;^::printf_s;^::putc;^::putwc;^::raise;^::realloc;^::remove;^::rename;^::scanf;^::scanf_s;^::setlocale;^::setvbuf;^::signal;^::snprintf;^::snprintf_s;^::sprintf;^::sprintf_s;^::sscanf;^::sscanf_s;^::strchr;^::strerror_s;^::strftime;^::strpbrk;^::strrchr;^::strstr;^::strtod;^::strtof;^::strtoimax;^::strtok;^::strtok_s;^::strtol;^::strtold;^::strtoll;^::strtoul;^::strtoull;^::strtoumax;^::strxfrm;^::swprintf;^::swprintf_s;^::swscanf;^::swscanf_s;^::thrd_create;^::thrd_detach;^::thrd_join;^::thrd_sleep;^::time;^::timespec_get;^::tmpfile;^::tmpfile_s;^::tmpnam;^::tmpnam_s;^::tss_create;^::tss_get;^::tss_set;^::ungetc;^::ungetwc;^::vfprintf;^::vfprintf_s;^::vfscanf;^::vfscanf_s;^::vfwprintf;^::vfwprintf_s;^::vfwscanf;^::vfwscanf_s;^::vprintf_s;^::vscanf;^::vscanf_s;^::vsnprintf;^::vsnprintf_s;^::vsprintf;^::vsprintf_s;^::vsscanf;^::vsscanf_s;^::vswprintf;^::vswprintf_s;^::vswscanf;^::vswscanf_s;^::vwprintf_s;^::vwscanf;^::vwscanf_s;^::wcrtomb;^::wcschr;^::wcsftime;^::wcspbrk;^::wcsrchr;^::wcsrtombs;^::wcsrtombs_s;^::wcsstr;^::wcstod;^::wcstof;^::wcstoimax;^::wcstok;^::wcstok_s;^::wcstol;^::wcstold;^::wcstoll;^::wcstombs;^::wcstombs_s;^::wcstoul;^::wcstoull;^::wcstoumax;^::wcsxfrm;^::wctob;^::wctrans;^::wctype;^::wmemchr;^::wprintf_s;^::wscanf;^::wscanf_s;'
58+
cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField: 'false'
59+
cert-str34-c.DiagnoseSignedUnsignedCharComparisons: 'false'
60+
cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: 'true'
61+
google-readability-braces-around-statements.ShortStatementLines: '1'
62+
google-readability-function-size.StatementThreshold: '800'
63+
google-readability-namespace-comments.ShortNamespaceLines: '10'
64+
google-readability-namespace-comments.SpacesBeforeComments: '2'
65+
llvm-else-after-return.WarnOnConditionVariables: 'false'
66+
llvm-else-after-return.WarnOnUnfixable: 'false'
67+
llvm-qualified-auto.AddConstToQualified: 'false'
68+
...

CMakeLists.txt

Lines changed: 143 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ mark_as_advanced(FORCE
3434

3535
option(STRICT_WARNINGS "Enable strict compiler warnings" ON)
3636
option(WARNINGS_AS_ERRORS "Treat all warnings as errors" OFF)
37-
option(BUILD_EXAMPLES "Build examples" OFF)
38-
option(BUILD_TESTS "Build tests" OFF)
37+
38+
option(BUILD_EXAMPLES "Build examples" ON)
39+
option(BUILD_TESTS "Build tests" ON)
3940

4041
# -----------------------------------------------------------------------------
4142
# DEPENDENCIES
@@ -44,6 +45,8 @@ option(BUILD_TESTS "Build tests" OFF)
4445
# We want doxygen for the documentation.
4546
find_package(Doxygen)
4647

48+
find_program(CLANG_TIDY_EXE NAMES clang-tidy)
49+
4750
# -----------------------------------------------------------------------------
4851
# LIBRARY
4952
# -----------------------------------------------------------------------------
@@ -61,30 +64,54 @@ target_compile_features(${PROJECT_NAME} INTERFACE cxx_std_17)
6164
# -----------------------------------------------------------------------------
6265

6366
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
64-
# Disable warnings that suggest using MSVC-specific safe functions
67+
# Disable warnings for MSVC-specific "safe" functions like strcpy_s, etc.,
68+
# which are not portable and may clutter warning logs.
6569
target_compile_definitions(${PROJECT_NAME} INTERFACE _CRT_SECURE_NO_WARNINGS)
6670

71+
# Disable warning C4702: unreachable code.
72+
add_compile_options(/wd4702)
73+
6774
if(WARNINGS_AS_ERRORS)
75+
# Treat all warnings as errors to enforce stricter code quality.
6876
target_compile_options(${PROJECT_NAME} INTERFACE /WX)
6977
endif()
70-
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
71-
if(WARNINGS_AS_ERRORS)
72-
target_compile_options(${PROJECT_NAME} INTERFACE -Werror)
73-
endif()
74-
endif()
7578

76-
if(STRICT_WARNINGS)
77-
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
78-
# Mark system headers as external for MSVC explicitly
79-
# https://devblogs.microsoft.com/cppblog/broken-warnings-theory
79+
if(STRICT_WARNINGS)
80+
# Enable external header management to suppress warnings in system and
81+
# external headers, making it easier to focus on project-specific issues.
8082
target_compile_options(${PROJECT_NAME} INTERFACE /experimental:external)
8183
target_compile_options(${PROJECT_NAME} INTERFACE /external:I ${CMAKE_BINARY_DIR})
8284
target_compile_options(${PROJECT_NAME} INTERFACE /external:anglebrackets)
8385
target_compile_options(${PROJECT_NAME} INTERFACE /external:W0)
8486

87+
# Use a high warning level to catch as many potential issues as possible.
8588
target_compile_options(${PROJECT_NAME} INTERFACE /W4)
86-
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
87-
target_compile_options(${PROJECT_NAME} INTERFACE -Wall -Wextra -Wconversion -pedantic)
89+
90+
# Enforce standards-compliant behavior to avoid relying on MSVC-specific extensions.
91+
target_compile_options(${PROJECT_NAME} INTERFACE /permissive-)
92+
endif()
93+
94+
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
95+
if(WARNINGS_AS_ERRORS)
96+
# Treat all warnings as errors to enforce stricter code quality.
97+
target_compile_options(${PROJECT_NAME} INTERFACE -Werror)
98+
endif()
99+
100+
if(STRICT_WARNINGS)
101+
# Enable a broad set of warnings to catch common and subtle issues:
102+
target_compile_options(${PROJECT_NAME} INTERFACE
103+
-Wall # Enable most general-purpose warnings.
104+
-Wextra # Enable extra warnings not included in -Wall.
105+
-Wconversion # Warn about implicit type conversions that may lose data.
106+
-pedantic # Enforce strict compliance with the C++ standard.
107+
-Wshadow # Warn about variable shadowing, which can cause subtle bugs.
108+
-Wnon-virtual-dtor # Warn when a class with virtual functions lacks a virtual destructor.
109+
-Wnull-dereference # Warn about potential null pointer dereferences.
110+
-Wformat=2 # Enable strict checks for printf/scanf format strings.
111+
-Woverloaded-virtual # Warn when a derived class function hides a base class virtual function.
112+
-Wfloat-equal # Warn about direct comparisons of floating-point values, which can be imprecise.
113+
)
114+
88115
endif()
89116
endif()
90117

@@ -96,7 +123,6 @@ if(BUILD_EXAMPLES)
96123

97124
# Add the example.
98125
add_executable(${PROJECT_NAME}_example examples/example.cpp)
99-
# Set the linked libraries.
100126
target_link_libraries(${PROJECT_NAME}_example PUBLIC ${PROJECT_NAME})
101127

102128
endif()
@@ -122,59 +148,132 @@ if(BUILD_TESTS)
122148
target_link_libraries(${PROJECT_NAME}_test_shift ${PROJECT_NAME})
123149
add_test(${PROJECT_NAME}_test_shift_run ${PROJECT_NAME}_test_shift)
124150

125-
# add_executable(${PROJECT_NAME}_test_operators ${PROJECT_SOURCE_DIR}/tests/test_operators.cpp)
126-
# target_link_libraries(${PROJECT_NAME}_test_operators ${PROJECT_NAME})
127-
# add_test(${PROJECT_NAME}_test_operators_run ${PROJECT_NAME}_test_operators)
151+
add_executable(${PROJECT_NAME}_test_comparison tests/test_comparison.cpp)
152+
target_link_libraries(${PROJECT_NAME}_test_comparison ${PROJECT_NAME})
153+
add_test(${PROJECT_NAME}_test_comparison_run ${PROJECT_NAME}_test_comparison)
128154

129-
# add_executable(${PROJECT_NAME}_test_comparison tests/test_comparison.cpp)
130-
# target_link_libraries(${PROJECT_NAME}_test_comparison ${PROJECT_NAME})
131-
# add_test(${PROJECT_NAME}_test_comparison_run ${PROJECT_NAME}_test_comparison)
155+
add_executable(${PROJECT_NAME}_test_math ${PROJECT_SOURCE_DIR}/tests/test_math.cpp)
156+
target_link_libraries(${PROJECT_NAME}_test_math ${PROJECT_NAME})
157+
add_test(${PROJECT_NAME}_test_math_run ${PROJECT_NAME}_test_math)
132158

133159
endif()
134160

161+
# -----------------------------------------------------------------------------
162+
# CODE ANALYSIS
163+
# -----------------------------------------------------------------------------
164+
165+
if(CLANG_TIDY_EXE)
166+
file(GLOB_RECURSE PROJECT_HEADERS_AND_SOURCES
167+
"${PROJECT_SOURCE_DIR}/include/**/*.hpp"
168+
"${PROJECT_SOURCE_DIR}/include/**/*.hh"
169+
"${PROJECT_SOURCE_DIR}/include/**/*.h"
170+
"${PROJECT_SOURCE_DIR}/include/*.hpp"
171+
"${PROJECT_SOURCE_DIR}/include/*.hh"
172+
"${PROJECT_SOURCE_DIR}/include/*.h"
173+
"${PROJECT_SOURCE_DIR}/src/**/*.cpp"
174+
"${PROJECT_SOURCE_DIR}/src/**/*.cc"
175+
"${PROJECT_SOURCE_DIR}/src/**/*.c"
176+
"${PROJECT_SOURCE_DIR}/src/*.cpp"
177+
"${PROJECT_SOURCE_DIR}/src/*.cc"
178+
"${PROJECT_SOURCE_DIR}/src/*.c"
179+
)
180+
add_custom_target(
181+
${PROJECT_NAME}_clang_tidy
182+
COMMAND ${CLANG_TIDY_EXE}
183+
--p=${CMAKE_BINARY_DIR}
184+
${PROJECT_HEADERS_AND_SOURCES}
185+
COMMENT "Running clang-tidy"
186+
VERBATIM
187+
)
188+
add_custom_target(
189+
${PROJECT_NAME}_clang_tidy_fix
190+
COMMAND ${CLANG_TIDY_EXE}
191+
--fix --fix-errors
192+
--p=${CMAKE_BINARY_DIR}
193+
${PROJECT_HEADERS_AND_SOURCES}
194+
COMMENT "Running clang-tidy-fix"
195+
VERBATIM
196+
)
197+
endif()
198+
135199
# -----------------------------------------------------------------------------
136200
# DOCUMENTATION
137201
# -----------------------------------------------------------------------------
138202

139203
if(DOXYGEN_FOUND)
140204

141-
# Record the options that describe how to populate the specified content.
142-
FetchContent_Declare(
143-
doxygenawesome
205+
# FetchContent: Doxygen Awesome CSS
206+
FetchContent_Declare(doxygenawesome
144207
GIT_REPOSITORY https://github.com/jothepro/doxygen-awesome-css
145-
GIT_TAG 4cd62308d825fe0396d2f66ffbab45d0e247724c # 2.0.3
208+
GIT_TAG main
146209
)
147-
# Retrieve the properties related to the content.
148-
FetchContent_GetProperties(doxygenawesome)
149-
# If not populated, make the content available.
150-
if(NOT doxygenawesome_POPULATED)
151-
message(STATUS "Retrieving `doxygen-awesome-css`...")
152-
# Ensures the named dependencies have been populated.
153-
FetchContent_MakeAvailable(doxygenawesome)
154-
# Hide fetchcontent variables, otherwise with ccmake it's a mess.
155-
mark_as_advanced(FORCE
156-
FETCHCONTENT_QUIET FETCHCONTENT_BASE_DIR FETCHCONTENT_FULLY_DISCONNECTED FETCHCONTENT_UPDATES_DISCONNECTED
157-
FETCHCONTENT_UPDATES_DISCONNECTED_DOXYGENAWESOME FETCHCONTENT_SOURCE_DIR_DOXYGENAWESOME
158-
)
159-
endif()
210+
FetchContent_MakeAvailable(doxygenawesome)
211+
212+
# Hide FetchContent variables to avoid clutter in ccmake.
213+
mark_as_advanced(FORCE
214+
FETCHCONTENT_UPDATES_DISCONNECTED_DOXYGENAWESOME
215+
FETCHCONTENT_SOURCE_DIR_DOXYGENAWESOME
216+
)
217+
218+
# Read the file with the version.
219+
file(READ ${PROJECT_SOURCE_DIR}/include/bvlib/bitvector.hpp version_file)
220+
# Extract the version.
221+
string(REGEX MATCH "BVLIB_MAJOR_VERSION ([0-9]*)" _ ${version_file})
222+
set(PROJECT_MAJOR_VERSION ${CMAKE_MATCH_1})
223+
string(REGEX MATCH "BVLIB_MINOR_VERSION ([0-9]*)" _ ${version_file})
224+
set(PROJECT_MINOR_VERSION ${CMAKE_MATCH_1})
225+
string(REGEX MATCH "BVLIB_MICRO_VERSION ([0-9]*)" _ ${version_file})
226+
set(PROJECT_MICRO_VERSION ${CMAKE_MATCH_1})
160227

161-
# = CUSTOMIZATION =========================================================
162-
set(DOXYGEN_PROJECT_NAME "Bitvector Library")
163-
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
228+
# Customization: Doxygen Configuration
229+
set(DOXYGEN_WARN_FORMAT "$file:$line:1: $text")
230+
set(DOXYGEN_PROJECT_NAME BVLib)
231+
set(DOXYGEN_PROJECT_BRIEF "A simple bitvector library for C++")
232+
set(DOXYGEN_PROJECT_NUMBER "${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}.${PROJECT_MICRO_VERSION}")
233+
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${PROJECT_SOURCE_DIR}/README.md)
164234
set(DOXYGEN_SHOW_INCLUDE_FILES NO)
165235
set(DOXYGEN_GENERATE_TREEVIEW YES)
236+
set(DOXYGEN_GENERATE_LATEX NO)
237+
set(DOXYGEN_GENERATE_MAN NO)
238+
239+
# Styling and UX enhancements using Doxygen Awesome
166240
set(DOXYGEN_HTML_HEADER ${doxygenawesome_SOURCE_DIR}/doxygen-custom/header.html)
167241
set(DOXYGEN_HTML_EXTRA_STYLESHEET ${doxygenawesome_SOURCE_DIR}/doxygen-awesome.css)
168242
set(DOXYGEN_HTML_EXTRA_FILES
169243
${doxygenawesome_SOURCE_DIR}/doxygen-awesome-fragment-copy-button.js
170244
${doxygenawesome_SOURCE_DIR}/doxygen-awesome-paragraph-link.js
171245
${doxygenawesome_SOURCE_DIR}/doxygen-awesome-darkmode-toggle.js
172246
)
247+
248+
# Set stricter warnings for better documentation quality
249+
set(DOXYGEN_WARN_IF_UNDOCUMENTED YES)
250+
set(DOXYGEN_WARN_IF_DOC_ERROR YES)
251+
set(DOXYGEN_WARN_NO_PARAMDOC YES)
252+
set(DOXYGEN_WARN_AS_ERROR YES) # Treat warnings as errors for CI
253+
254+
# Exclude certain files or directories from documentation (if needed)
255+
set(DOXYGEN_EXCLUDE_PATTERNS "${PROJECT_SOURCE_DIR}/tests/*" "${PROJECT_SOURCE_DIR}/examples/*")
256+
257+
# Add Doxygen documentation target.
258+
file(GLOB_RECURSE PROJECT_HEADERS_AND_SOURCES
259+
"${PROJECT_SOURCE_DIR}/include/**/*.hpp"
260+
"${PROJECT_SOURCE_DIR}/include/**/*.hh"
261+
"${PROJECT_SOURCE_DIR}/include/**/*.h"
262+
"${PROJECT_SOURCE_DIR}/include/*.hpp"
263+
"${PROJECT_SOURCE_DIR}/include/*.hh"
264+
"${PROJECT_SOURCE_DIR}/include/*.h"
265+
"${PROJECT_SOURCE_DIR}/src/**/*.cpp"
266+
"${PROJECT_SOURCE_DIR}/src/**/*.cc"
267+
"${PROJECT_SOURCE_DIR}/src/**/*.c"
268+
"${PROJECT_SOURCE_DIR}/src/*.cpp"
269+
"${PROJECT_SOURCE_DIR}/src/*.cc"
270+
"${PROJECT_SOURCE_DIR}/src/*.c"
271+
)
173272
doxygen_add_docs(
174273
${PROJECT_NAME}_documentation
175274
${PROJECT_SOURCE_DIR}/README.md
176-
${PROJECT_SOURCE_DIR}/include/bvlib/bitvector.hpp
177-
${PROJECT_SOURCE_DIR}/include/bvlib/math.hpp
178-
${PROJECT_SOURCE_DIR}/include/bvlib/io.hpp
275+
${PROJECT_SOURCE_DIR}/LICENSE.md
276+
${PROJECT_HEADERS_AND_SOURCES}
277+
COMMENT "Generating Doxygen documentation"
179278
)
180279
endif()

examples/example.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#include "bvlib/bitvector.hpp"
2-
#include "bvlib/math.hpp"
32
#include "bvlib/io.hpp"
3+
#include "bvlib/math.hpp"
44

55
#include <iomanip>
6-
#include <vector>
76
#include <random>
7+
#include <vector>
88

99
int main(int, char *[])
1010
{

0 commit comments

Comments
 (0)