fix clang tidy workflow and warnings

This commit is contained in:
Joao Paulo Magalhaes
2025-01-12 21:16:13 +00:00
parent f480f0512f
commit 53d35e80bb
32 changed files with 448 additions and 281 deletions

111
.clang-tidy Normal file
View File

@@ -0,0 +1,111 @@
Checks:
- '*' # enable everything
# but disable the following:
- -altera-id-dependent-backward-branch # backward branch (for loop) is ID-dependent due to variable reference to 'n' and may cause performance degradation
- -altera-struct-pack-align # accessing fields in struct 'base64_wrapper_<char>' is inefficient due to poor alignment; currently aligned to 8 bytes, but recommended alignment is 16 bytes
- -altera-unroll-loops # kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive
- -bugprone-branch-clone # repeated branch body in conditional chain
- -bugprone-easily-swappable-parameters # 2 adjacent parameters of 'Tree' of similar type are easily swapped by mistake
- -bugprone-reserved-identifier # warnings on identifiers with leading _
- -bugprone-switch-missing-default-case # switching on non-enum value without default case may not cover all cases
- -cert-dcl37-c # warnings on identifiers with leading _
- -cert-dcl51-cpp # warnings on identifiers with leading _
- -cert-dcl59-cpp,fuchsia-header-anon-namespaces # do not use unnamed namespaces in header files
- -clang-analyzer-optin.core.EnumCastOutOfRange # The value '44' provided to the cast expression is not in the valid range of values for the enum
- -clang-diagnostic-pragma-system-header-outside-header # #pragma system_header ignored in main file
- -clang-diagnostic-unknown-warning-option # unknown compiler options
- -cppcoreguidelines-avoid-c-arrays # allow C arrays
- -cppcoreguidelines-avoid-do-while # avoid do-while loops
- -cppcoreguidelines-avoid-magic-numbers
- -cppcoreguidelines-avoid-non-const-global-variables # variable 's_default_callbacks' is non-const and globally accessible, consider making it const
- -cppcoreguidelines-init-variables # variable 'node' is not initialized
- -cppcoreguidelines-macro-to-enum # replace macro with enum
- -cppcoreguidelines-macro-usage # function-like macro 'c4append_' used; consider a 'constexpr' template function
- -cppcoreguidelines-no-malloc # do not manage memory manually; consider a container or a smart pointer
- -cppcoreguidelines-owning-memory # initializing non-owner 'void *' with a newly created 'gsl::owner<>'
- -cppcoreguidelines-pro-bounds-array-to-pointer-decay
- -cppcoreguidelines-pro-bounds-constant-array-index # do not use array subscript when the index is not an integer constant expression
- -cppcoreguidelines-pro-bounds-pointer-arithmetic # do not use pointer arithmetic
- -cppcoreguidelines-pro-type-cstyle-cast # do not use C-style cast to convert between unrelated types
- -cppcoreguidelines-pro-type-member-init # constructor does not initialize these fields: len
- -cppcoreguidelines-pro-type-vararg # do not call c-style vararg functions
- -cppcoreguidelines-use-default-member-init # use default member initializer for 'm_pos'
- -fuchsia-default-arguments-calls # calling a function that uses a default argument is disallowed
- -fuchsia-default-arguments-declarations # declaring a parameter with a default argument is disallowed
- -fuchsia-overloaded-operator # overloading 'operator[]' is disallowed
- -fuchsia-statically-constructed-objects # static objects are disallowed; if possible, use a constexpr constructor instead
- -fuchsia-trailing-return # a trailing return type is disallowed for this function declaration
- -google-build-namespaces # do not use unnamed namespaces in header files
- -google-build-using-namespace # do not use namespace using-directives; use using-declarations instead
- -google-explicit-constructor # single-argument constructors must be marked explicit to avoid unintentional implicit conversions
- -google-readability-braces-around-statements # statement should be inside braces
- -google-readability-casting # C-style casts are discouraged; use static_cast
- -google-readability-function-size # function '_handle_map_block' exceeds recommended size/complexity thresholds
- -google-readability-namespace-comments # anonymous namespace not terminated with a closing comment
- -google-readability-todo # missing username/bug in TODO
- -hicpp-avoid-c-arrays # allow C arrays
- -hicpp-braces-around-statements # statement should be inside braces
- -hicpp-deprecated-headers # inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
- -hicpp-explicit-conversions # single-argument constructors must be marked explicit to avoid unintentional implicit conversions
- -hicpp-function-size # function '_handle_map_block' exceeds recommended size/complexity thresholds
- -hicpp-member-init # constructor does not initialize these fields: len
- -hicpp-named-parameter # all parameters should be named in a function
- -hicpp-no-array-decay # do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead
- -hicpp-no-malloc # do not manage memory manually; consider a container or a smart pointer
- -hicpp-uppercase-literal-suffix # integer literal has suffix 'u', which is not uppercase
- -hicpp-use-auto,modernize-use-auto # use auto when initializing with a cast to avoid duplicating the type name
- -hicpp-vararg # do not call c-style vararg functions
- -llvm-else-after-return,readability-else-after-return # do not use 'else' after 'return'
- -llvm-header-guard # header guard does not follow preferred style
- -llvm-include-order # #includes are not sorted properly
- -llvm-namespace-comment # anonymous namespace not terminated with a closing comment
- -llvmlibc-callee-namespace # ... must resolve to a function declared within the namespace defined by the ... macro
- -llvmlibc-implementation-in-namespace # the outermost namespace should be the 'LIBC_NAMESPACE' macro
- -llvmlibc-inline-function-decl # '_is_idchar' must be tagged with the LIBC_INLINE macro; the macro should be placed at the beginning of the declaration
- -llvmlibc-restrict-system-libc-headers # system include stdlib.h not allowed
- -misc-const-correctness # variable 's2c' of type 'char' can be declared 'const'
- -misc-include-cleaner # no header providing ... is directly included
- -misc-no-recursion # function 'reserve' is within a recursive call chain
- -misc-non-private-member-variables-in-classes # member variable 'data' has public visibility
- -modernize-avoid-c-arrays # allow C arrays
- -modernize-concat-nested-namespaces # nested namespaces can be concatenated
- -modernize-deprecated-headers # inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
- -modernize-deprecated-headers # inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
- -modernize-loop-convert # use range-based for loop instead
- -modernize-macro-to-enum # replace macro with enum
- -modernize-return-braced-init-list # avoid repeating the return type from the declaration; use a braced initializer list instead
- -modernize-type-traits # use c++17 style variable templates
- -modernize-use-auto # use auto when initializing with a cast to avoid duplicating the type name
- -modernize-use-default-member-init # use default member initializer for 'm_pos'
- -modernize-use-nodiscard # function 'valid' should be marked nodiscard
- -modernize-use-trailing-return-type # don't care about this
- -modernize-use-using # use 'using' instead of 'typedef'
- -performance-enum-size # enum '_ppstate' uses a larger base type ('int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size
- -readability-avoid-nested-conditional-operator # conditional operator is used as sub-expression of parent conditional operator, refrain from using nested conditional operators
- -readability-avoid-unconditional-preprocessor-if # preprocessor condition is always 'false', consider removing both the condition and its contents
- -readability-braces-around-statements # statement should be inside braces
- -readability-else-after-return # do not use 'else' after 'return'
- -readability-function-cognitive-complexity # function ... has cognitive complexity of ... (threshold ...)
- -readability-function-size # function '_handle_map_block' exceeds recommended size/complexity thresholds
- -readability-identifier-length # variable name 'c' is too short, expected at least 3 characters
- -readability-implicit-bool-conversion # implicit conversion 'NodeData *' -> 'bool'
- -readability-inconsistent-declaration-parameter-name # definition with different parameter names
- -readability-isolate-declaration # multiple declarations in a single statement reduces readability
- -readability-magic-numbers # 16 is a magic number; consider replacing it with a named constant
- -readability-named-parameter # all parameters should be named in a function
- -readability-redundant-access-specifiers # redundant access specifier has the same accessibility as the previous access specifier
- -readability-redundant-member-init # initializer for member 'm_arena' is redundant
- -readability-redundant-declaration # redundant 'to_substr' declaration
- -readability-simplify-boolean-expr # boolean expression can be simplified by DeMorgan's theorem
- -readability-suspicious-call-argument # 1st argument 'after' (passed to 'node') looks like it might be swapped with the 2nd, 'node' (passed to 'sib')
- -readability-uppercase-literal-suffix # integer literal has suffix 'u', which is not uppercase
- -readability-use-anyofallof # replace loop by 'std::all_of()'
# Turn all the warnings from the checks above into errors.
WarningsAsErrors: '*'
#CheckOptions:
# - { key: readability-identifier-naming.ClassCase, value: CamelCase }
# - { key: readability-identifier-naming.MethodCase, value: CamelCase }
# - { key: readability-identifier-naming.MemberPrefix, value: m_ }
# - { key: readability-identifier-naming.MemberCase, value: lower_case }

View File

@@ -27,26 +27,26 @@ jobs:
fail-fast: false
matrix:
include:
- {std: 11, bt: Debug , arch: aarch64, distro: ubuntu20.04}
- {std: 11, bt: Release, arch: aarch64, distro: ubuntu20.04}
- {std: 14, bt: Debug , arch: aarch64, distro: ubuntu20.04}
- {std: 14, bt: Release, arch: aarch64, distro: ubuntu20.04}
- {std: 17, bt: Debug , arch: aarch64, distro: ubuntu20.04}
- {std: 17, bt: Release, arch: aarch64, distro: ubuntu20.04}
- {std: 11, bt: Debug , arch: aarch64, distro: ubuntu22.04}
- {std: 11, bt: Release, arch: aarch64, distro: ubuntu22.04}
- {std: 14, bt: Debug , arch: aarch64, distro: ubuntu22.04}
- {std: 14, bt: Release, arch: aarch64, distro: ubuntu22.04}
- {std: 17, bt: Debug , arch: aarch64, distro: ubuntu22.04}
- {std: 17, bt: Release, arch: aarch64, distro: ubuntu22.04}
#
- {std: 11, bt: Debug , arch: ppc64le, distro: ubuntu20.04}
- {std: 11, bt: Release, arch: ppc64le, distro: ubuntu20.04}
- {std: 14, bt: Debug , arch: ppc64le, distro: ubuntu20.04}
- {std: 14, bt: Release, arch: ppc64le, distro: ubuntu20.04}
- {std: 17, bt: Debug , arch: ppc64le, distro: ubuntu20.04}
- {std: 17, bt: Release, arch: ppc64le, distro: ubuntu20.04}
- {std: 11, bt: Debug , arch: ppc64le, distro: ubuntu22.04}
- {std: 11, bt: Release, arch: ppc64le, distro: ubuntu22.04}
- {std: 14, bt: Debug , arch: ppc64le, distro: ubuntu22.04}
- {std: 14, bt: Release, arch: ppc64le, distro: ubuntu22.04}
- {std: 17, bt: Debug , arch: ppc64le, distro: ubuntu22.04}
- {std: 17, bt: Release, arch: ppc64le, distro: ubuntu22.04}
#
- {std: 11, bt: Debug , arch: s390x , distro: ubuntu20.04}
- {std: 11, bt: Release, arch: s390x , distro: ubuntu20.04}
- {std: 14, bt: Debug , arch: s390x , distro: ubuntu20.04}
- {std: 14, bt: Release, arch: s390x , distro: ubuntu20.04}
- {std: 17, bt: Debug , arch: s390x , distro: ubuntu20.04}
- {std: 17, bt: Release, arch: s390x , distro: ubuntu20.04}
- {std: 11, bt: Debug , arch: s390x , distro: ubuntu22.04}
- {std: 11, bt: Release, arch: s390x , distro: ubuntu22.04}
- {std: 14, bt: Debug , arch: s390x , distro: ubuntu22.04}
- {std: 14, bt: Release, arch: s390x , distro: ubuntu22.04}
- {std: 17, bt: Debug , arch: s390x , distro: ubuntu22.04}
- {std: 17, bt: Release, arch: s390x , distro: ubuntu22.04}
#
#- {std: 11, bt: Debug , arch: armv6 , distro: bullseye}
#- {std: 11, bt: Release, arch: armv6 , distro: bullseye}
@@ -55,16 +55,16 @@ jobs:
#- {std: 17, bt: Debug , arch: armv6 , distro: bullseye}
#- {std: 17, bt: Release, arch: armv6 , distro: bullseye}
#
#- {std: 11, bt: Debug , arch: armv7 , distro: ubuntu20.04}
#- {std: 11, bt: Release, arch: armv7 , distro: ubuntu20.04}
#- {std: 14, bt: Debug , arch: armv7 , distro: ubuntu20.04}
#- {std: 14, bt: Release, arch: armv7 , distro: ubuntu20.04}
#- {std: 17, bt: Debug , arch: armv7 , distro: ubuntu20.04}
#- {std: 17, bt: Release, arch: armv7 , distro: ubuntu20.04}
#- {std: 11, bt: Debug , arch: armv7 , distro: ubuntu22.04}
#- {std: 11, bt: Release, arch: armv7 , distro: ubuntu22.04}
#- {std: 14, bt: Debug , arch: armv7 , distro: ubuntu22.04}
#- {std: 14, bt: Release, arch: armv7 , distro: ubuntu22.04}
#- {std: 17, bt: Debug , arch: armv7 , distro: ubuntu22.04}
#- {std: 17, bt: Release, arch: armv7 , distro: ubuntu22.04}
steps:
- {name: checkout, uses: actions/checkout@v3, with: {submodules: recursive}}
- name: test
uses: uraimo/run-on-arch-action@v2.3.0
uses: uraimo/run-on-arch-action@v2.8.1
with:
arch: ${{matrix.arch}}
distro: ${{matrix.distro}}

View File

@@ -154,31 +154,31 @@ jobs:
(!contains(github.event.head_commit.message, 'skip benchmarks')) ||
contains(github.event.head_commit.message, 'only benchmarks')
continue-on-error: true
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
include:
- {std: 17, bt: Release, arch: aarch64, distro: ubuntu20.04}
- {std: 17, bt: Release, arch: aarch64, distro: ubuntu22.04}
# the python dependencies cannot be installed for this one:
#- {std: 17, bt: Release, arch: ppc64le, distro: ubuntu20.04}
#- {std: 17, bt: Release, arch: ppc64le, distro: ubuntu22.04}
#
# the github runners are failing for the following:
#- {std: 11, bt: Release, arch: s390x , distro: ubuntu20.04}
#- {std: 17, bt: Release, arch: s390x , distro: ubuntu20.04}
#- {std: 11, bt: Release, arch: s390x , distro: ubuntu22.04}
#- {std: 17, bt: Release, arch: s390x , distro: ubuntu22.04}
##
#- {std: 11, bt: Release, arch: armv6 , distro: ubuntu18.04}
#- {std: 17, bt: Release, arch: armv6 , distro: ubuntu18.04}
#- {std: 11, bt: Release, arch: armv6 , distro: ubuntu22.04}
#- {std: 17, bt: Release, arch: armv6 , distro: ubuntu22.04}
##
#- {std: 11, bt: Release, arch: armv7 , distro: ubuntu18.04}
#- {std: 17, bt: Release, arch: armv7 , distro: ubuntu18.04}
#- {std: 11, bt: Release, arch: armv7 , distro: ubuntu22.04}
#- {std: 17, bt: Release, arch: armv7 , distro: ubuntu22.04}
steps:
- {name: checkout, uses: actions/checkout@v3, with: {submodules: recursive, fetch-depth: 0}}
- name: Download vars.sh
uses: actions/download-artifact@v3
with: {name: vars.sh, path: ./}
- name: test
uses: uraimo/run-on-arch-action@v2.3.0
uses: uraimo/run-on-arch-action@v2.8.1
with:
arch: ${{matrix.arch}}
distro: ${{matrix.distro}}

View File

@@ -28,47 +28,48 @@ jobs:
#----------------------------------------------------------------------------
clang_tidy:
name: clang_tidy/c++${{matrix.std}}/${{matrix.bt}}
continue-on-error: true
if: always() # https://stackoverflow.com/questions/62045967/github-actions-is-there-a-way-to-continue-on-error-while-still-getting-correct
runs-on: ubuntu-latest
container: ghcr.io/biojppm/c4core/ubuntu22.04:latest # use the docker image
if: always()
continue-on-error: false
runs-on: ubuntu-24.04
container: ghcr.io/biojppm/c4core/ubuntu22.04:latest
strategy:
fail-fast: false
matrix:
include:
# clang tidy takes a long time, so don't do multiple bits/linktypes
- {std: 11, cxx: clang++-17, bt: Debug , lint: clang-tidy, bitlinks: shared64}
- {std: 11, cxx: clang++-17, bt: Debug , lint: clang-tidy, bitlinks: shared32}
- {std: 11, cxx: clang++-17, bt: Debug , lint: clang-tidy, bitlinks: static64}
- {std: 11, cxx: clang++-17, bt: Debug , lint: clang-tidy, bitlinks: static32}
- {std: 11, cxx: clang++-17, bt: ReleaseWithDebInfo, lint: clang-tidy, bitlinks: shared64}
- {std: 11, cxx: clang++-17, bt: ReleaseWithDebInfo, lint: clang-tidy, bitlinks: shared32}
- {std: 11, cxx: clang++-17, bt: ReleaseWithDebInfo, lint: clang-tidy, bitlinks: static64}
- {std: 11, cxx: clang++-17, bt: ReleaseWithDebInfo, lint: clang-tidy, bitlinks: static32}
env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"}
- std: 11
clang: 18
bt: Debug
bits: 64
env:
STD: ${{matrix.std}}
CXX_: ${{matrix.cxx}}
BT: ${{matrix.bt}}
BITLINKS: ${{matrix.bitlinks}}
VG: ${{matrix.vg}}
SAN: ${{matrix.san}}
LINT: ${{matrix.lint}}
OS: ${{matrix.os}}
steps:
- {name: checkout, uses: actions/checkout@v4, with: {submodules: recursive}}
- run: git config --system --add safe.directory '*' # needed for running in the docker image. see https://github.com/actions/checkout/issues/1169
- run: c4core-install ${{matrix.cxx}}
- {name: show info, run: source .github/setenv.sh && c4_show_info}
- name: shared64-configure---------------------------------------------------
run: source .github/setenv.sh && c4_cfg_test shared64
- {name: shared64-build, run: source .github/setenv.sh && c4_build_test shared64}
- {name: shared64-run, run: source .github/setenv.sh && c4_run_test shared64}
- {name: shared64-pack, run: source .github/setenv.sh && c4_package shared64}
- name: static64-configure---------------------------------------------------
run: source .github/setenv.sh && c4_cfg_test static64
- {name: static64-build, run: source .github/setenv.sh && c4_build_test static64}
- {name: static64-run, run: source .github/setenv.sh && c4_run_test static64}
- {name: static64-pack, run: source .github/setenv.sh && c4_package static64}
- name: static32-configure---------------------------------------------------
run: source .github/setenv.sh && c4_cfg_test static32
- {name: static32-build, run: source .github/setenv.sh && c4_build_test static32}
- {name: static32-run, run: source .github/setenv.sh && c4_run_test static32}
- {name: static32-pack, run: source .github/setenv.sh && c4_package static32}
- name: shared32-configure---------------------------------------------------
run: source .github/setenv.sh && c4_cfg_test shared32
- {name: shared32-build, run: source .github/setenv.sh && c4_build_test shared32}
- {name: shared32-run, run: source .github/setenv.sh && c4_run_test shared32}
- {name: shared32-pack, run: source .github/setenv.sh && c4_package shared32}
- name: checkout (action + docker)
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- run: git config --system --add safe.directory '*'
- name: install
run: c4core-install clang++-${{matrix.clang}}
- name: configure
run: |
cmake -S . -B build \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DCMAKE_CXX_COMPILER=clang++-${{matrix.clang}} \
-DCMAKE_C_COMPILER=clang-${{matrix.clang}} \
-DCLANG_TIDY=/usr/bin/clang-tidy-${{matrix.clang}} \
-DCMAKE_BUILD_TYPE=${{matrix.bt}} \
-DC4CORE_DEV=ON \
-DC4CORE_VALGRIND=OFF \
-DC4CORE_BUILD_TESTS=OFF \
-DC4CORE_BUILD_BENCHMARKS=OFF \
-DC4CORE_DBG=OFF
- name: clang-tidy
run: cmake --build build --target c4core-clang-tidy --verbose

View File

@@ -115,3 +115,33 @@ c4_add_dev_targets()
if(C4CORE_INSTALL)
c4_pack_project(TYPE LIBRARY)
endif()
#-------------------------------------------------------
# clang-tidy
function(c4core_setup_clang_tidy rootdir)
get_target_property(srcs c4core SOURCES)
string(REPLACE "${rootdir}/" "./" srcs "${srcs}")
set(exclude ./c4/ext/.* .natvis)
foreach(e ${exclude})
list(FILTER srcs EXCLUDE REGEX ${e})
endforeach()
set(cmd ${srcs} -p ${CMAKE_BINARY_DIR}
"--config-file=${rootdir}/.clang-tidy"
"--header-filter=${rootdir}/src/c4/.*pp|${rootdir}/src/c4/std/.*pp")
add_custom_target(c4core-clang-tidy
COMMAND ${CMAKE_COMMAND} -E cat ${CMAKE_BINARY_DIR}/compile_commands.json
COMMAND ${CLANG_TIDY} --version
COMMAND ${CLANG_TIDY} ${cmd} --dump-config
COMMAND ${CLANG_TIDY} ${cmd} --list-checks
COMMAND ${CLANG_TIDY} ${cmd}
WORKING_DIRECTORY ${rootdir}
VERBATIM
)
endfunction()
find_program(CLANG_TIDY clang-tidy)
if(CLANG_TIDY)
c4core_setup_clang_tidy(${CMAKE_CURRENT_LIST_DIR})
endif()

View File

@@ -45,7 +45,7 @@ public:
MemRes() : m_resource(get_memory_resource()) {}
MemRes(MemoryResource* r) noexcept : m_resource(r ? r : get_memory_resource()) {}
inline MemoryResource* resource() const { return m_resource; }
MemoryResource* resource() const { return m_resource; }
private:
@@ -60,10 +60,10 @@ class MemResGlobal
{
public:
MemResGlobal() {}
MemResGlobal() = default;
MemResGlobal(MemoryResource* r) noexcept { C4_UNUSED(r); C4_ASSERT(r == get_memory_resource()); }
inline MemoryResource* resource() const { return get_memory_resource(); }
static MemoryResource* resource() { return get_memory_resource(); }
};
@@ -173,7 +173,7 @@ struct detail::_AllocatorUtil : public MemRes
* @param MemResProvider
* @ingroup allocators */
template<class T, class MemResProvider=MemResGlobal>
class Allocator : public detail::_AllocatorUtil<MemResProvider>
class Allocator : public detail::_AllocatorUtil<MemResProvider> // NOLINT(*-member-functions)
{
public:
@@ -225,7 +225,7 @@ public:
Allocator(Allocator const&) = default;
Allocator(Allocator &&) = default;
Allocator& operator= (Allocator const&) = default; // WTF? why? @see http://en.cppreference.com/w/cpp/memory/polymorphic_allocator
Allocator& operator= (Allocator const&) = default; // why? @see http://en.cppreference.com/w/cpp/memory/polymorphic_allocator
Allocator& operator= (Allocator &&) = default;
/** returns a default-constructed polymorphic allocator object
@@ -265,7 +265,7 @@ public:
/** @ingroup allocators */
template<class T, size_t N=16, size_t Alignment=alignof(T), class MemResProvider=MemResGlobal>
class SmallAllocator : public detail::_AllocatorUtil<MemResProvider>
class SmallAllocator : public detail::_AllocatorUtil<MemResProvider> // NOLINT(*-member-functions)
{
static_assert(Alignment >= alignof(T), "invalid alignment");

View File

@@ -6,11 +6,14 @@
# pragma clang diagnostic ignored "-Wold-style-cast"
#elif defined(__GNUC__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wuseless-cast"
# pragma GCC diagnostic ignored "-Wchar-subscripts"
# pragma GCC diagnostic ignored "-Wtype-limits"
# pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
// NOLINTBEGIN(bugprone-signed-char-misuse,cert-str34-c,hicpp-signed-bitwise)
namespace c4 {
namespace detail {
@@ -78,7 +81,7 @@ void base64_test_tables()
for(size_t i = 0; i < C4_COUNTOF(detail::base64_sextet_to_char_); ++i)
{
char s2c = base64_sextet_to_char_[i];
char c2s = base64_char_to_sextet_[(int)s2c];
char c2s = base64_char_to_sextet_[(unsigned)s2c];
C4_CHECK((size_t)c2s == i);
}
for(size_t i = 0; i < C4_COUNTOF(detail::base64_char_to_sextet_); ++i)
@@ -86,7 +89,7 @@ void base64_test_tables()
char c2s = base64_char_to_sextet_[i];
if(c2s == char(-1))
continue;
char s2c = base64_sextet_to_char_[(int)c2s];
char s2c = base64_sextet_to_char_[(unsigned)c2s];
C4_CHECK((size_t)s2c == i);
}
}
@@ -96,7 +99,7 @@ void base64_test_tables()
bool base64_valid(csubstr encoded)
{
if(encoded.len & 3u) // (encoded.len % 4u)
if((encoded.len & size_t(3u)) != size_t(0)) // (encoded.len % 4u)
return false;
for(const char c : encoded)
{
@@ -159,7 +162,7 @@ size_t base64_decode(csubstr encoded, blob data)
#define c4append_(c) { if(wpos < data.len) { data.buf[wpos] = static_cast<c4::byte>(c); } ++wpos; }
#define c4appendval_(c, shift)\
{\
C4_XASSERT(c >= 0);\
C4_XASSERT((c) >= 0);\
C4_XASSERT(size_t(c) < sizeof(detail::base64_char_to_sextet_));\
val |= static_cast<uint32_t>(detail::base64_char_to_sextet_[(c)]) << ((shift) * 6);\
}
@@ -214,6 +217,8 @@ size_t base64_decode(csubstr encoded, blob data)
} // namespace c4
// NOLINTEND(bugprone-signed-char-misuse,cert-str34-c,hicpp-signed-bitwise)
#ifdef __clang__
# pragma clang diagnostic pop
#elif defined(__GNUC__)

View File

@@ -99,31 +99,31 @@ bm2stream(Stream &s, Enum value, EnumOffsetType offst=EOFFS_PFX)
* buffer. This macro simplifies the code for bm2str().
* @todo improve performance by writing from the end and moving only once. */
#define _c4prependchars(code, num) \
if(str && (pos + num <= sz)) \
if(str && (pos + (num) <= sz)) \
{ \
/* move the current string to the right */ \
memmove(str + num, str, pos); \
memmove(str + (num), str, pos); \
/* now write in the beginning of the string */ \
code; \
} \
else if(str && sz) \
{ \
C4_ERROR("cannot write to string pos=%d num=%d sz=%d", \
(int)pos, (int)num, (int)sz); \
(int)pos, (int)(num), (int)sz); \
} \
pos += num
/* Execute `code` if the `num` of characters is available in the str
* buffer. This macro simplifies the code for bm2str(). */
#define _c4appendchars(code, num) \
if(str && (pos + num <= sz)) \
if(str && (pos + (num) <= sz)) \
{ \
code; \
} \
else if(str && sz) \
{ \
C4_ERROR("cannot write to string pos=%d num=%d sz=%d", \
(int)pos, (int)num, (int)sz); \
(int)pos, (int)(num), (int)sz); \
} \
pos += num

View File

@@ -18,6 +18,8 @@ template<class T> struct is_blob_type<blob_<T>> : std::integral_constant<bool, t
template<class T> struct is_blob_value_type : std::integral_constant<bool, (std::is_fundamental<T>::value || std::is_trivially_copyable<T>::value)> {};
} // namespace
// NOLINTBEGIN(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
template<class T>
struct blob_
{
@@ -37,23 +39,25 @@ public:
C4_ALWAYS_INLINE blob_& operator=(blob_ && that) noexcept = default;
C4_ALWAYS_INLINE blob_& operator=(blob_ const& that) noexcept = default;
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_<U> const& that) noexcept : buf(that.buf), len(that.len) {}
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_<U> && that) noexcept : buf(that.buf), len(that.len) {}
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_<U> && that) noexcept { buf = that.buf; len = that.len; }
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_<U> const& that) noexcept { buf = that.buf; len = that.len; }
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_<U> const& that) noexcept : buf(that.buf), len(that.len) {} // NOLINT
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_(blob_<U> && that) noexcept : buf(that.buf), len(that.len) {} // NOLINT
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_<U> && that) noexcept { buf = that.buf; len = that.len; } // NOLINT
template<class U, class=typename std::enable_if<std::is_const<T>::value && std::is_same<typename std::add_const<U>::type, T>::value, U>::type> C4_ALWAYS_INLINE blob_& operator=(blob_<U> const& that) noexcept { buf = that.buf; len = that.len; } // NOLINT
C4_ALWAYS_INLINE blob_(void *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(n) {}
C4_ALWAYS_INLINE blob_(void const *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(n) {}
C4_ALWAYS_INLINE blob_(void *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(n) {} // NOLINT
C4_ALWAYS_INLINE blob_(void const *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(n) {} // NOLINT
#define _C4_REQUIRE_BLOBTYPE(ty) class=typename std::enable_if<((!detail::is_blob_type<ty>::value) && (detail::is_blob_value_type<ty>::value)), T>::type
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U &var) noexcept : buf(reinterpret_cast<T*>(&var)), len(sizeof(U)) {}
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(sizeof(U) * n) { C4_ASSERT(is_aligned(ptr)); }
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_& operator= (U &var) noexcept { buf = reinterpret_cast<T*>(&var); len = sizeof(U); return *this; }
template<class U, size_t N, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U (&arr)[N]) noexcept : buf(reinterpret_cast<T*>(arr)), len(sizeof(U) * N) {}
template<class U, size_t N, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_& operator= (U (&arr)[N]) noexcept { buf = reinterpret_cast<T*>(arr); len = sizeof(U) * N; return *this; }
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U &var) noexcept : buf(reinterpret_cast<T*>(&var)), len(sizeof(U)) {} // NOLINT
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U *ptr, size_t n) noexcept : buf(reinterpret_cast<T*>(ptr)), len(sizeof(U) * n) { C4_ASSERT(is_aligned(ptr)); } // NOLINT
template<class U, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_& operator= (U &var) noexcept { buf = reinterpret_cast<T*>(&var); len = sizeof(U); return *this; } // NOLINT
template<class U, size_t N, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_(U (&arr)[N]) noexcept : buf(reinterpret_cast<T*>(arr)), len(sizeof(U) * N) {} // NOLINT
template<class U, size_t N, _C4_REQUIRE_BLOBTYPE(U)> C4_ALWAYS_INLINE blob_& operator= (U (&arr)[N]) noexcept { buf = reinterpret_cast<T*>(arr); len = sizeof(U) * N; return *this; } // NOLINT
#undef _C4_REQUIRE_BLOBTYPE
};
// NOLINTEND(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
/** an immutable binary blob */
using cblob = blob_<cbyte>;
/** a mutable binary blob */

View File

@@ -135,6 +135,7 @@
#define C4_NO_UBSAN_IOVRFLW
#endif
// NOLINTBEGIN(hicpp-signed-bitwise)
namespace c4 {
@@ -544,24 +545,25 @@ C4_CONSTEXPR14 C4_ALWAYS_INLINE unsigned digits_oct(T v_) noexcept
// TODO: is there a better way?
C4_STATIC_ASSERT(std::is_integral<T>::value);
C4_ASSERT(v_ >= 0);
using U = typename
std::conditional<sizeof(T) <= sizeof(unsigned),
unsigned,
typename std::make_unsigned<T>::type>::type;
U v = (U) v_; // safe because we require v_ >= 0
unsigned __n = 1;
const unsigned __b2 = 64u;
const unsigned __b3 = __b2 * 8u;
const unsigned long __b4 = __b3 * 8u;
using U = typename std::conditional<sizeof(T) <= sizeof(unsigned),
unsigned,
typename std::make_unsigned<T>::type>::type;
U v = (U) v_; // safe because we require v_ >= 0 // NOLINT
uint32_t __n = 1;
enum : U {
__b2 = 64u,
__b3 = 64u * 8u,
__b4 = 64u * 8u * 8u,
};
while(true)
{
if(v < 8u)
return __n;
if(v < __b2)
else if(v < __b2)
return __n + 1;
if(v < __b3)
else if(v < __b3)
return __n + 2;
if(v < __b4)
else if(v < __b4)
return __n + 3;
v /= (U) __b4;
__n += 4;
@@ -616,7 +618,7 @@ void write_dec_unchecked(substr buf, T v, unsigned digits_v) noexcept
{
T quo = v;
quo /= T(100);
const auto num = (v - quo * T(100)) << 1u;
const auto num = (v - quo * T(100)) << 1u; // NOLINT
v = quo;
buf.str[--digits_v] = detail::digits0099[num + 1];
buf.str[--digits_v] = detail::digits0099[num];
@@ -787,7 +789,7 @@ size_t write_num_digits(substr buf, T v, size_t num_digits) noexcept
else if(ret >= buf.len || num_digits > buf.len)
return num_digits;
C4_ASSERT(num_digits >= ret);
size_t delta = static_cast<size_t>(num_digits - ret);
size_t delta = static_cast<size_t>(num_digits - ret); // NOLINT
memmove(buf.str + delta, buf.str, ret);
memset(buf.str, '0', delta);
return num_digits;
@@ -1012,7 +1014,7 @@ C4_NO_INLINE size_t _itoa2buf(substr buf, I radix) noexcept
size_t pos = 0;
if(C4_LIKELY(buf.len > 0))
buf.str[pos++] = '-';
switch(radix)
switch(radix) // NOLINT(hicpp-multiway-paths-covered)
{
case I(10):
if(C4_UNLIKELY(buf.len < digits_type::maxdigits_dec))
@@ -1051,7 +1053,7 @@ C4_NO_INLINE size_t _itoa2buf(substr buf, I radix, size_t num_digits) noexcept
size_t needed_digits = 0;
if(C4_LIKELY(buf.len > 0))
buf.str[pos++] = '-';
switch(radix)
switch(radix) // NOLINT(hicpp-multiway-paths-covered)
{
case I(10):
// add 1 to account for -
@@ -1159,7 +1161,7 @@ C4_ALWAYS_INLINE size_t itoa(substr buf, T v, T radix) noexcept
++pos;
}
unsigned digits = 0;
switch(radix)
switch(radix) // NOLINT(hicpp-multiway-paths-covered)
{
case T(10):
digits = digits_dec(v);
@@ -1236,7 +1238,7 @@ C4_ALWAYS_INLINE size_t itoa(substr buf, T v, T radix, size_t num_digits) noexce
++pos;
}
unsigned total_digits = 0;
switch(radix)
switch(radix) // NOLINT(hicpp-multiway-paths-covered)
{
case T(10):
total_digits = digits_dec(v);
@@ -1321,7 +1323,7 @@ C4_ALWAYS_INLINE size_t utoa(substr buf, T v, T radix) noexcept
C4_STATIC_ASSERT(std::is_unsigned<T>::value);
C4_ASSERT(radix == 10 || radix == 16 || radix == 2 || radix == 8);
unsigned digits = 0;
switch(radix)
switch(radix) // NOLINT(hicpp-multiway-paths-covered)
{
case T(10):
digits = digits_dec(v);
@@ -1376,7 +1378,7 @@ C4_ALWAYS_INLINE size_t utoa(substr buf, T v, T radix, size_t num_digits) noexce
C4_STATIC_ASSERT(std::is_unsigned<T>::value);
C4_ASSERT(radix == 10 || radix == 16 || radix == 2 || radix == 8);
unsigned total_digits = 0;
switch(radix)
switch(radix) // NOLINT(hicpp-multiway-paths-covered)
{
case T(10):
total_digits = digits_dec(v);
@@ -1988,7 +1990,7 @@ C4_ALWAYS_INLINE bool scan_rhex(csubstr s, T *C4_RESTRICT val) noexcept
else if(c == 'p' || c == 'P')
{
++pos;
goto power; // no mantissa given, jump to power
goto power; // no mantissa given, jump to power // NOLINT
}
else
{
@@ -1998,7 +2000,7 @@ C4_ALWAYS_INLINE bool scan_rhex(csubstr s, T *C4_RESTRICT val) noexcept
// mantissa
{
// 0.0625 == 1/16 == value of first digit after the comma
for(T digit = T(0.0625); pos < s.len; ++pos, digit /= T(16))
for(T digit = T(0.0625); pos < s.len; ++pos, digit /= T(16)) // NOLINT
{
const char c = s.str[pos];
if(c >= '0' && c <= '9')
@@ -2010,7 +2012,7 @@ C4_ALWAYS_INLINE bool scan_rhex(csubstr s, T *C4_RESTRICT val) noexcept
else if(c == 'p' || c == 'P')
{
++pos;
goto power; // mantissa finished, jump to power
goto power; // mantissa finished, jump to power // NOLINT
}
else
{
@@ -2657,6 +2659,8 @@ inline size_t to_chars(substr buf, const char * C4_RESTRICT v) noexcept
} // namespace c4
// NOLINTEND(hicpp-signed-bitwise)
#ifdef _MSC_VER
# pragma warning(pop)
#endif

View File

@@ -9,7 +9,6 @@
#include "c4/compiler.hpp"
#include "c4/language.hpp"
#include "c4/error.hpp"
#include "c4/time.hpp"
#include "c4/types.hpp"
#endif /* _C4_COMMON_HPP_ */

View File

@@ -22,7 +22,7 @@
#endif
// mixed byte order (eg, PowerPC or ia64)
#define _C4EM 1111
#define _C4EM 1111 // NOLINT
#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
# define C4_CPU_X86_64

View File

@@ -60,7 +60,7 @@ inline void construct(U* ptr, Args&&... args)
new ((void*)ptr) U(std::forward<Args>(args)...);
}
template<class U, class I, class ...Args>
inline void construct_n(U* ptr, I n, Args&&... args)
inline void construct_n(U* ptr, I n, Args&&... args) // NOLINT
{
for(I i = 0; i < n; ++i)
{

View File

@@ -33,7 +33,7 @@ inline size_t dump(DumperFn &&dumpfn, substr buf, Arg const& a)
{
size_t sz = to_chars(buf, a); // need to serialize to the buffer
if(C4_LIKELY(sz <= buf.len))
dumpfn(buf.first(sz));
std::forward<DumperFn>(dumpfn)(buf.first(sz));
return sz;
}
@@ -49,7 +49,7 @@ template<class DumperFn>
inline size_t dump(DumperFn &&dumpfn, substr buf, csubstr a)
{
if(buf.len)
dumpfn(a); // dump directly, no need to serialize to the buffer
std::forward<DumperFn>(dumpfn)(a); // dump directly, no need to serialize to the buffer
return 0; // no space was used in the buffer
}
@@ -65,7 +65,7 @@ template<class DumperFn, size_t N>
inline size_t dump(DumperFn &&dumpfn, substr buf, const char (&a)[N])
{
if(buf.len)
dumpfn(csubstr(a)); // dump directly, no need to serialize to the buffer
std::forward<DumperFn>(dumpfn)(csubstr(a)); // dump directly, no need to serialize to the buffer
return 0; // no space was used in the buffer
}
@@ -93,14 +93,14 @@ struct DumpResults
/// @cond dev
// terminates the variadic recursion
template<class DumperFn>
size_t cat_dump(DumperFn &&, substr)
size_t cat_dump(DumperFn &&, substr) // NOLINT
{
return 0;
}
// terminates the variadic recursion
template<DumperPfn dumpfn>
size_t cat_dump(substr)
size_t cat_dump(substr) // NOLINT
{
return 0;
}
@@ -110,10 +110,10 @@ size_t cat_dump(substr)
template<class DumperFn, class Arg, class... Args>
size_t cat_dump(DumperFn &&dumpfn, substr buf, Arg const& C4_RESTRICT a, Args const& C4_RESTRICT ...more)
{
size_t size_for_a = dump(dumpfn, buf, a);
size_t size_for_a = dump(std::forward<DumperFn>(dumpfn), buf, a);
if(C4_UNLIKELY(size_for_a > buf.len))
buf = buf.first(0); // ensure no more calls
size_t size_for_more = cat_dump(dumpfn, buf, more...);
size_t size_for_more = cat_dump(std::forward<DumperFn>(dumpfn), buf, more...);
return size_for_more > size_for_a ? size_for_more : size_for_a;
}
@@ -156,7 +156,7 @@ DumpResults cat_dump_resume(size_t currarg, DumperFn &&dumpfn, DumpResults resul
{
if(C4_LIKELY(results.write_arg(currarg)))
{
size_t sz = dump(dumpfn, buf, a); // yield to the specialized function
size_t sz = dump(std::forward<DumperFn>(dumpfn), buf, a); // yield to the specialized function
if(currarg == results.lastok + 1 && sz <= buf.len)
results.lastok = currarg;
results.bufsize = sz > results.bufsize ? sz : results.bufsize;
@@ -174,8 +174,8 @@ DumpResults cat_dump_resume(size_t currarg, DumpResults results, substr buf, Arg
template<class DumperFn, class Arg, class... Args>
DumpResults cat_dump_resume(size_t currarg, DumperFn &&dumpfn, DumpResults results, substr buf, Arg const& C4_RESTRICT a, Args const& C4_RESTRICT ...more)
{
results = detail::cat_dump_resume(currarg, dumpfn, results, buf, a);
return detail::cat_dump_resume(currarg + 1u, dumpfn, results, buf, more...);
results = detail::cat_dump_resume(currarg, std::forward<DumperFn>(dumpfn), results, buf, a);
return detail::cat_dump_resume(currarg + 1u, std::forward<DumperFn>(dumpfn), results, buf, more...);
}
} // namespace detail
/// @endcond
@@ -194,7 +194,7 @@ C4_ALWAYS_INLINE DumpResults cat_dump_resume(DumperFn &&dumpfn, DumpResults resu
{
if(results.bufsize > buf.len)
return results;
return detail::cat_dump_resume(0u, dumpfn, results, buf, a, more...);
return detail::cat_dump_resume(0u, std::forward<DumperFn>(dumpfn), results, buf, a, more...);
}
template<DumperPfn dumpfn, class Arg, class... Args>
@@ -206,7 +206,7 @@ C4_ALWAYS_INLINE DumpResults cat_dump_resume(substr buf, Arg const& C4_RESTRICT
template<class DumperFn, class Arg, class... Args>
C4_ALWAYS_INLINE DumpResults cat_dump_resume(DumperFn &&dumpfn, substr buf, Arg const& C4_RESTRICT a, Args const& C4_RESTRICT ...more)
{
return detail::cat_dump_resume(0u, dumpfn, DumpResults{}, buf, a, more...);
return detail::cat_dump_resume(0u, std::forward<DumperFn>(dumpfn), DumpResults{}, buf, a, more...);
}
@@ -217,14 +217,14 @@ C4_ALWAYS_INLINE DumpResults cat_dump_resume(DumperFn &&dumpfn, substr buf, Arg
/// @cond dev
// terminate the recursion
template<class DumperFn, class Sep>
size_t catsep_dump(DumperFn &&, substr, Sep const& C4_RESTRICT)
size_t catsep_dump(DumperFn &&, substr, Sep const& C4_RESTRICT) // NOLINT
{
return 0;
}
// terminate the recursion
template<DumperPfn dumpfn, class Sep>
size_t catsep_dump(substr, Sep const& C4_RESTRICT)
size_t catsep_dump(substr, Sep const& C4_RESTRICT) // NOLINT
{
return 0;
}
@@ -234,17 +234,17 @@ size_t catsep_dump(substr, Sep const& C4_RESTRICT)
template<class DumperFn, class Sep, class Arg, class... Args>
size_t catsep_dump(DumperFn &&dumpfn, substr buf, Sep const& C4_RESTRICT sep, Arg const& C4_RESTRICT a, Args const& C4_RESTRICT ...more)
{
size_t sz = dump(dumpfn, buf, a);
size_t sz = dump(std::forward<DumperFn>(dumpfn), buf, a);
if(C4_UNLIKELY(sz > buf.len))
buf = buf.first(0); // ensure no more calls
if C4_IF_CONSTEXPR (sizeof...(more) > 0)
{
size_t szsep = dump(dumpfn, buf, sep);
size_t szsep = dump(std::forward<DumperFn>(dumpfn), buf, sep);
if(C4_UNLIKELY(szsep > buf.len))
buf = buf.first(0); // ensure no more calls
sz = sz > szsep ? sz : szsep;
}
size_t size_for_more = catsep_dump(dumpfn, buf, sep, more...);
size_t size_for_more = catsep_dump(std::forward<DumperFn>(dumpfn), buf, sep, more...);
return size_for_more > sz ? size_for_more : sz;
}
@@ -292,7 +292,7 @@ void catsep_dump_resume_(size_t currarg, DumperFn &&dumpfn, DumpResults *C4_REST
{
if(C4_LIKELY(results->write_arg(currarg)))
{
size_t sz = dump(dumpfn, *buf, a);
size_t sz = dump(std::forward<DumperFn>(dumpfn), *buf, a);
results->bufsize = sz > results->bufsize ? sz : results->bufsize;
if(C4_LIKELY(sz <= buf->len))
results->lastok = currarg;
@@ -310,7 +310,7 @@ C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, DumpResults *C4_RESTRIC
template<class DumperFn, class Sep, class Arg>
C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, DumperFn &&dumpfn, DumpResults *C4_RESTRICT results, substr *C4_RESTRICT buf, Sep const& C4_RESTRICT, Arg const& C4_RESTRICT a)
{
detail::catsep_dump_resume_(currarg, dumpfn, results, buf, a);
detail::catsep_dump_resume_(currarg, std::forward<DumperFn>(dumpfn), results, buf, a);
}
template<DumperPfn dumpfn, class Sep, class Arg, class... Args>
@@ -324,9 +324,9 @@ C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, DumpResults *C4_RESTRIC
template<class DumperFn, class Sep, class Arg, class... Args>
C4_ALWAYS_INLINE void catsep_dump_resume(size_t currarg, DumperFn &&dumpfn, DumpResults *C4_RESTRICT results, substr *C4_RESTRICT buf, Sep const& C4_RESTRICT sep, Arg const& C4_RESTRICT a, Args const& C4_RESTRICT ...more)
{
detail::catsep_dump_resume_(currarg , dumpfn, results, buf, a);
detail::catsep_dump_resume_(currarg + 1u, dumpfn, results, buf, sep);
detail::catsep_dump_resume (currarg + 2u, dumpfn, results, buf, sep, more...);
detail::catsep_dump_resume_(currarg , std::forward<DumperFn>(dumpfn), results, buf, a);
detail::catsep_dump_resume_(currarg + 1u, std::forward<DumperFn>(dumpfn), results, buf, sep);
detail::catsep_dump_resume (currarg + 2u, std::forward<DumperFn>(dumpfn), results, buf, sep, more...);
}
} // namespace detail
/// @endcond
@@ -342,7 +342,7 @@ C4_ALWAYS_INLINE DumpResults catsep_dump_resume(DumpResults results, substr buf,
template<class DumperFn, class Sep, class... Args>
C4_ALWAYS_INLINE DumpResults catsep_dump_resume(DumperFn &&dumpfn, DumpResults results, substr buf, Sep const& C4_RESTRICT sep, Args const& C4_RESTRICT ...more)
{
detail::catsep_dump_resume(0u, dumpfn, &results, &buf, sep, more...);
detail::catsep_dump_resume(0u, std::forward<DumperFn>(dumpfn), &results, &buf, sep, more...);
return results;
}
@@ -358,7 +358,7 @@ template<class DumperFn, class Sep, class... Args>
C4_ALWAYS_INLINE DumpResults catsep_dump_resume(DumperFn &&dumpfn, substr buf, Sep const& C4_RESTRICT sep, Args const& C4_RESTRICT ...more)
{
DumpResults results;
detail::catsep_dump_resume(0u, dumpfn, &results, &buf, sep, more...);
detail::catsep_dump_resume(0u, std::forward<DumperFn>(dumpfn), &results, &buf, sep, more...);
return results;
}
@@ -376,7 +376,7 @@ C4_ALWAYS_INLINE size_t format_dump(DumperFn &&dumpfn, substr buf, csubstr fmt)
// we can dump without using buf
// but we'll only dump if the buffer is ok
if(C4_LIKELY(buf.len > 0 && fmt.len))
dumpfn(fmt);
std::forward<DumperFn>(dumpfn)(fmt);
return 0u;
}
@@ -404,16 +404,16 @@ C4_NO_INLINE size_t format_dump(DumperFn &&dumpfn, substr buf, csubstr fmt, Arg
if(C4_UNLIKELY(pos == csubstr::npos))
{
if(C4_LIKELY(buf.len > 0 && fmt.len > 0))
dumpfn(fmt);
std::forward<DumperFn>(dumpfn)(fmt);
return 0u;
}
if(C4_LIKELY(buf.len > 0 && pos > 0))
dumpfn(fmt.first(pos)); // we can dump without using buf
std::forward<DumperFn>(dumpfn)(fmt.first(pos)); // we can dump without using buf
fmt = fmt.sub(pos + 2); // skip {} do this before assigning to pos again
pos = dump(dumpfn, buf, a);
pos = dump(std::forward<DumperFn>(dumpfn), buf, a);
if(C4_UNLIKELY(pos > buf.len))
buf.len = 0; // ensure no more calls to dump
size_t size_for_more = format_dump(dumpfn, buf, fmt, more...);
size_t size_for_more = format_dump(std::forward<DumperFn>(dumpfn), buf, fmt, more...);
return size_for_more > pos ? size_for_more : pos;
}
@@ -468,7 +468,7 @@ DumpResults format_dump_resume(size_t currarg, DumperFn &&dumpfn, DumpResults re
// but we'll only dump if the buffer is ok
if(C4_LIKELY(buf.len > 0))
{
dumpfn(fmt);
std::forward<DumperFn>(dumpfn)(fmt);
results.lastok = currarg;
}
return results;
@@ -529,27 +529,27 @@ DumpResults format_dump_resume(size_t currarg, DumperFn &&dumpfn, DumpResults re
if(C4_LIKELY(buf.len > 0))
{
results.lastok = currarg;
dumpfn(fmt);
std::forward<DumperFn>(dumpfn)(fmt);
}
return results;
}
if(C4_LIKELY(buf.len > 0))
{
results.lastok = currarg;
dumpfn(fmt.first(pos));
std::forward<DumperFn>(dumpfn)(fmt.first(pos));
}
}
fmt = fmt.sub(pos + 2);
if(C4_LIKELY(results.write_arg(currarg + 1)))
{
pos = dump(dumpfn, buf, a);
pos = dump(std::forward<DumperFn>(dumpfn), buf, a);
results.bufsize = pos > results.bufsize ? pos : results.bufsize;
if(C4_LIKELY(pos <= buf.len))
results.lastok = currarg + 1;
else
buf.len = 0;
}
return detail::format_dump_resume(currarg + 2u, dumpfn, results, buf, fmt, more...);
return detail::format_dump_resume(currarg + 2u, std::forward<DumperFn>(dumpfn), results, buf, fmt, more...);
}
} // namespace detail
@@ -563,7 +563,7 @@ C4_ALWAYS_INLINE DumpResults format_dump_resume(DumpResults results, substr buf,
template<class DumperFn, class... Args>
C4_ALWAYS_INLINE DumpResults format_dump_resume(DumperFn &&dumpfn, DumpResults results, substr buf, csubstr fmt, Args const& C4_RESTRICT ...more)
{
return detail::format_dump_resume(0u, dumpfn, results, buf, fmt, more...);
return detail::format_dump_resume(0u, std::forward<DumperFn>(dumpfn), results, buf, fmt, more...);
}
@@ -576,7 +576,7 @@ C4_ALWAYS_INLINE DumpResults format_dump_resume(substr buf, csubstr fmt, Args co
template<class DumperFn, class... Args>
C4_ALWAYS_INLINE DumpResults format_dump_resume(DumperFn &&dumpfn, substr buf, csubstr fmt, Args const& C4_RESTRICT ...more)
{
return detail::format_dump_resume(0u, dumpfn, DumpResults{}, buf, fmt, more...);
return detail::format_dump_resume(0u, std::forward<DumperFn>(dumpfn), DumpResults{}, buf, fmt, more...);
}
C4_SUPPRESS_WARNING_GCC_CLANG_POP

View File

@@ -77,7 +77,7 @@ public:
private:
Sym const* m_symbols;
size_t const m_num;
size_t const m_num; // NOLINT(*avoid-const*)
};

View File

@@ -4,9 +4,9 @@
#include <stdio.h>
#include <stdarg.h>
#define C4_LOGF_ERR(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
#define C4_LOGF_WARN(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
#define C4_LOGP(msg, ...) printf(msg)
#define C4_LOGF_ERR(...) (void)fprintf(stderr, __VA_ARGS__); (void)fflush(stderr)
#define C4_LOGF_WARN(...) (void)fprintf(stderr, __VA_ARGS__); (void)fflush(stderr)
#define C4_LOGP(msg, ...) (void)printf(msg)
#if defined(C4_XBOX) || (defined(C4_WIN) && defined(C4_MSVC))
# include "c4/windows.hpp"
@@ -41,6 +41,7 @@
# pragma GCC diagnostic ignored "-Wformat-nonliteral"
# pragma GCC diagnostic ignored "-Wold-style-cast"
#endif
// NOLINTBEGIN(*use-anonymous-namespace*,cert-dcl50-cpp)
//-----------------------------------------------------------------------------
@@ -82,7 +83,7 @@ void handle_error(srcloc where, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ilen = vsnprintf(buf, sizeof(buf), fmt, args); // ss.vprintf(fmt, args);
int ilen = vsnprintf(buf, sizeof(buf), fmt, args); // NOLINT(clang-analyzer-valist.Uninitialized)
va_end(args);
msglen = ilen >= 0 && ilen < (int)sizeof(buf) ? static_cast<size_t>(ilen) : sizeof(buf)-1;
}
@@ -131,7 +132,11 @@ void handle_warning(srcloc where, const char *fmt, ...)
va_list args;
char buf[1024];
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
int ret = vsnprintf(buf, sizeof(buf), fmt, args); // NOLINT(clang-analyzer-valist.Uninitialized)
if(ret+1 > (int)sizeof(buf))
buf[sizeof(buf) - 1] = '\0'; // truncate
else if(ret < 0)
buf[0] = '\0'; // output/format error
va_end(args);
C4_LOGF_WARN("\n");
#if defined(C4_ERROR_SHOWS_FILELINE) && defined(C4_ERROR_SHOWS_FUNC)
@@ -160,30 +165,21 @@ bool is_debugger_attached()
//! @see http://stackoverflow.com/questions/3596781/how-to-detect-if-the-current-process-is-being-run-by-gdb
//! (this answer: http://stackoverflow.com/a/24969863/3968589 )
char buf[1024] = "";
int status_fd = open("/proc/self/status", O_RDONLY);
int status_fd = open("/proc/self/status", O_RDONLY); // NOLINT
if (status_fd == -1)
return false;
ssize_t num_read = ::read(status_fd, buf, sizeof(buf));
if (num_read > 0)
{
return 0;
}
else
{
ssize_t num_read = ::read(status_fd, buf, sizeof(buf));
if (num_read > 0)
{
static const char TracerPid[] = "TracerPid:";
char *tracer_pid;
if(num_read < 1024)
{
buf[num_read] = 0;
}
tracer_pid = strstr(buf, TracerPid);
if (tracer_pid)
{
first_call_result = !!::atoi(tracer_pid + sizeof(TracerPid) - 1);
}
}
close(status_fd);
static const char TracerPid[] = "TracerPid:";
char *tracer_pid;
if(num_read < 1024)
buf[num_read] = 0;
tracer_pid = strstr(buf, TracerPid);
if(tracer_pid)
first_call_result = !!::atoi(tracer_pid + sizeof(TracerPid) - 1); // NOLINT
}
close(status_fd);
C4_SUPPRESS_WARNING_GCC_POP
}
return first_call_result;
@@ -229,6 +225,7 @@ bool is_debugger_attached()
} // namespace c4
// NOLINTEND(*use-anonymous-namespace*,cert-dcl50-cpp)
#ifdef __clang__
# pragma clang diagnostic pop

View File

@@ -114,17 +114,17 @@ namespace c4 {
typedef enum : uint32_t {
/** when an error happens and the debugger is attached, call C4_DEBUG_BREAK().
* Without effect otherwise. */
ON_ERROR_DEBUGBREAK = 0x01 << 0,
ON_ERROR_DEBUGBREAK = 0x01u << 0u,
/** when an error happens log a message. */
ON_ERROR_LOG = 0x01 << 1,
ON_ERROR_LOG = 0x01u << 1u,
/** when an error happens invoke a callback if it was set with
* set_error_callback(). */
ON_ERROR_CALLBACK = 0x01 << 2,
ON_ERROR_CALLBACK = 0x01u << 2u,
/** when an error happens call std::terminate(). */
ON_ERROR_ABORT = 0x01 << 3,
ON_ERROR_ABORT = 0x01u << 3u,
/** when an error happens and exceptions are enabled throw an exception.
* Without effect otherwise. */
ON_ERROR_THROW = 0x01 << 4,
ON_ERROR_THROW = 0x01u << 4u,
/** the default flags. */
ON_ERROR_DEFAULTS = ON_ERROR_DEBUGBREAK|ON_ERROR_LOG|ON_ERROR_CALLBACK|ON_ERROR_ABORT
} ErrorFlags_e;
@@ -140,7 +140,7 @@ C4CORE_EXPORT error_callback_type get_error_callback();
//-----------------------------------------------------------------------------
/** RAII class controling the error settings inside a scope. */
struct ScopedErrorSettings
struct ScopedErrorSettings // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
{
error_flags m_flags;
error_callback_type m_callback;

View File

@@ -19,7 +19,7 @@ size_t to_chars(substr buf, fmt::const_raw_wrapper r)
{
void * vptr = buf.str;
size_t space = buf.len;
auto ptr = (decltype(buf.str)) std::align(r.alignment, r.len, vptr, space);
char * ptr = (char*) std::align(r.alignment, r.len, vptr, space);
if(ptr == nullptr)
{
// if it was not possible to align, return a conservative estimate
@@ -42,7 +42,7 @@ bool from_chars(csubstr buf, fmt::raw_wrapper *r)
void * vptr = (void*)buf.str;
C4_SUPPRESS_WARNING_GCC_POP
size_t space = buf.len;
auto ptr = (decltype(buf.str)) std::align(r->alignment, r->len, vptr, space);
char * ptr = (char*) std::align(r->alignment, r->len, vptr, space);
C4_CHECK(ptr != nullptr);
C4_CHECK(ptr >= buf.begin() && ptr <= buf.end());
C4_SUPPRESS_WARNING_GCC_PUSH

View File

@@ -20,6 +20,7 @@
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wuseless-cast"
#endif
// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast,*avoid-goto*)
/** @defgroup doc_format_utils Format utilities
*
@@ -1047,6 +1048,7 @@ retry:
} // namespace c4
// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast,*avoid-goto*)
#ifdef _MSC_VER
# pragma warning(pop)
#elif defined(__clang__)

View File

@@ -38,7 +38,7 @@ public:
C4_CONSTEXPR14 void update(const void *const data, const size_t size) noexcept
{
auto cdata = static_cast<const unsigned char *>(data);
auto const* cdata = static_cast<const unsigned char *>(data);
auto acc = this->state_;
for(size_t i = 0; i < size; ++i)
{

View File

@@ -333,7 +333,7 @@ namespace detail {
#ifdef __GNUC__
# define C4_DONT_OPTIMIZE(var) c4::detail::dont_optimize(var)
template< class T >
C4_ALWAYS_INLINE void dont_optimize(T const& value) { asm volatile("" : : "g"(value) : "memory"); }
C4_ALWAYS_INLINE void dont_optimize(T const& value) { asm volatile("" : : "g"(value) : "memory"); } // NOLINT
#else
# define C4_DONT_OPTIMIZE(var) c4::detail::use_char_pointer(reinterpret_cast< const char* >(&var))
void use_char_pointer(char const volatile*);

View File

@@ -114,10 +114,10 @@ arealloc_pfn get_arealloc();
/** C++17-style memory_resource base class. See http://en.cppreference.com/w/cpp/experimental/memory_resource
* @ingroup memory_resources */
struct MemoryResource
struct MemoryResource // NOLINT(*-member-functions)
{
const char *name = nullptr;
virtual ~MemoryResource() {}
virtual ~MemoryResource() = default;
void* allocate(size_t sz, size_t alignment=alignof(max_align_t), void *hint=nullptr)
{
@@ -170,28 +170,27 @@ C4_ALWAYS_INLINE void set_memory_resource(MemoryResource* mr)
/** A c4::aalloc-based memory resource. Thread-safe if the implementation
* called by c4::aalloc() is safe.
* @ingroup memory_resources */
struct MemoryResourceMalloc : public MemoryResource
struct MemoryResourceMalloc : public MemoryResource // NOLINT(*-member-functions)
{
MemoryResourceMalloc() { name = "malloc"; }
virtual ~MemoryResourceMalloc() override {}
protected:
virtual void* do_allocate(size_t sz, size_t alignment, void *hint) override
void* do_allocate(size_t sz, size_t alignment, void *hint) override
{
C4_UNUSED(hint);
return c4::aalloc(sz, alignment);
}
virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) override
void do_deallocate(void* ptr, size_t sz, size_t alignment) override
{
C4_UNUSED(sz);
C4_UNUSED(alignment);
c4::afree(ptr);
}
virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override
void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override
{
return c4::arealloc(ptr, oldsz, newsz, alignment);
}
@@ -239,19 +238,19 @@ private:
protected:
virtual void* do_allocate(size_t sz, size_t alignment, void* hint) override
void* do_allocate(size_t sz, size_t alignment, void* hint) override
{
return m_local->allocate(sz, alignment, hint);
}
virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override
void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override
{
return m_local->reallocate(ptr, oldsz, newsz, alignment);
}
virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) override
void do_deallocate(void* ptr, size_t sz, size_t alignment) override
{
return m_local->deallocate(ptr, sz, alignment);
m_local->deallocate(ptr, sz, alignment);
}
};
@@ -273,7 +272,7 @@ public:
/** initialize with borrowed memory */
_MemoryResourceSingleChunk(void *mem, size_t sz) : _MemoryResourceSingleChunk() { acquire(mem, sz); }
virtual ~_MemoryResourceSingleChunk() override { release(); }
~_MemoryResourceSingleChunk() override { release(); }
public:
@@ -317,7 +316,7 @@ public:
* malloc/free take place.
*
* @ingroup memory_resources */
struct MemoryResourceLinear : public detail::_MemoryResourceSingleChunk
struct MemoryResourceLinear : public detail::_MemoryResourceSingleChunk // NOLINT(*-member-functions)
{
C4_NO_COPY_OR_MOVE(MemoryResourceLinear);
@@ -328,9 +327,9 @@ public:
protected:
virtual void* do_allocate(size_t sz, size_t alignment, void *hint) override;
virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) override;
virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override;
void* do_allocate(size_t sz, size_t alignment, void *hint) override;
void do_deallocate(void* ptr, size_t sz, size_t alignment) override;
void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override;
};
@@ -339,7 +338,7 @@ protected:
//-----------------------------------------------------------------------------
/** provides a stack-type malloc-based memory resource.
* @ingroup memory_resources */
struct MemoryResourceStack : public detail::_MemoryResourceSingleChunk
struct MemoryResourceStack : public detail::_MemoryResourceSingleChunk // NOLINT(*-member-functions)
{
C4_NO_COPY_OR_MOVE(MemoryResourceStack);
@@ -350,9 +349,9 @@ public:
protected:
virtual void* do_allocate(size_t sz, size_t alignment, void *hint) override;
virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) override;
virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override;
void* do_allocate(size_t sz, size_t alignment, void *hint) override;
void do_deallocate(void* ptr, size_t sz, size_t alignment) override;
void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override;
};
@@ -365,15 +364,10 @@ protected:
template<size_t N>
struct MemoryResourceLinearArr : public MemoryResourceLinear
{
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4324) // structure was padded due to alignment specifier
#endif
C4_SUPPRESS_WARNING_MSVC_WITH_PUSH(4324) // structure was padded due to alignment specifier
alignas(alignof(max_align_t)) char m_arr[N];
#ifdef _MSC_VER
#pragma warning(pop)
#endif
MemoryResourceLinearArr() : MemoryResourceLinear(m_arr, N) { name = "linear_arr"; }
C4_SUPPRESS_WARNING_MSVC_POP
MemoryResourceLinearArr() : MemoryResourceLinear(m_arr, N) { name = "linear_arr"; } // NOLINT
};
@@ -493,25 +487,25 @@ public:
protected:
MemoryResource *m_resource;
AllocationCounts m_counts;
MemoryResource *m_resource; // NOLINT
AllocationCounts m_counts; // NOLINT
protected:
virtual void* do_allocate(size_t sz, size_t alignment, void * /*hint*/) override
void* do_allocate(size_t sz, size_t alignment, void * /*hint*/) override
{
void *ptr = m_resource->allocate(sz, alignment);
m_counts.add_counts(ptr, sz);
return ptr;
}
virtual void do_deallocate(void* ptr, size_t sz, size_t alignment) override
void do_deallocate(void* ptr, size_t sz, size_t alignment) override
{
m_counts.rem_counts(ptr, sz);
m_resource->deallocate(ptr, sz, alignment);
}
virtual void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override
void* do_reallocate(void* ptr, size_t oldsz, size_t newsz, size_t alignment) override
{
m_counts.rem_counts(ptr, oldsz);
void* nptr = m_resource->reallocate(ptr, oldsz, newsz, alignment);
@@ -524,7 +518,7 @@ protected:
//-----------------------------------------------------------------------------
/** RAII class which binds a memory resource with a scope duration.
* @ingroup memory_resources */
struct ScopedMemoryResource
struct ScopedMemoryResource // NOLINT(*-member-functions)
{
MemoryResource *m_original;
@@ -545,7 +539,7 @@ struct ScopedMemoryResource
/** RAII class which counts allocations and frees inside a scope. Can
* optionally set also the memory resource to be used.
* @ingroup memory_resources */
struct ScopedMemoryResourceCounts
struct ScopedMemoryResourceCounts // NOLINT(*-member-functions)
{
MemoryResourceCounts mr;

View File

@@ -19,7 +19,7 @@ void mem_repeat(void* dest, void const* pattern, size_t pattern_size, size_t num
while(begin + 2*n < end)
{
::memcpy(begin + n, begin, n);
n <<= 1; // double n
n <<= 1u; // double n
}
// copy the missing part
if(begin + n < end)

View File

@@ -25,6 +25,8 @@
/** @file memory_util.hpp Some memory utilities. */
// NOLINTBEGIN(google-runtime-int)
namespace c4 {
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
@@ -696,8 +698,8 @@ struct tight_pair<First, Second, tpc_same_empty> : public First
C4_ALWAYS_INLINE C4_CONSTEXPR14 First & first () { return static_cast<First &>(*this); }
C4_ALWAYS_INLINE C4_CONSTEXPR14 First const& first () const { return static_cast<First const&>(*this); }
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return reinterpret_cast<Second &>(*this); }
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return reinterpret_cast<Second const&>(*this); }
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second & second() { return reinterpret_cast<Second &>(*this); } // NOLINT
C4_ALWAYS_INLINE C4_CONSTEXPR14 Second const& second() const { return reinterpret_cast<Second const&>(*this); } // NOLINT
};
template<class First, class Second>
@@ -775,4 +777,6 @@ C4_SUPPRESS_WARNING_GCC_CLANG_POP
} // namespace c4
// NOLINTEND(google-runtime-int)
#endif /* _C4_MEMORY_UTIL_HPP_ */

View File

@@ -12,6 +12,7 @@
namespace c4 {
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
// NOLINTBEGIN(misc-confusable-identifiers)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
@@ -200,7 +201,10 @@ public:
#undef _c4csz
};
//-----------------------------------------------------------------------------
// NOLINTBEGIN(*-redundant-inline*)
template<class T, class Il, class Ir, class _Impll, class _Implr>
inline constexpr bool operator==
(
@@ -268,13 +272,15 @@ inline constexpr bool operator>=
return ! (l < r);
}
// NOLINTEND(*-redundant-inline*)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/** A non-owning span of elements contiguously stored in memory. */
template<class T, class I=C4_SIZE_TYPE>
class span : public span_crtp<T, I, span<T, I>>
class span : public span_crtp<T, I, span<T, I>> // NOLINT(*-special-member-functions)
{
friend class span_crtp<T, I, span<T, I>>;
@@ -351,7 +357,7 @@ template<class T, class I=C4_SIZE_TYPE> using cspan = span<const T, I>;
*/
template<class T, class I=C4_SIZE_TYPE>
class spanrs : public span_crtp<T, I, spanrs<T, I>>
class spanrs : public span_crtp<T, I, spanrs<T, I>> // NOLINT(*-special-member-functions)
{
friend class span_crtp<T, I, spanrs<T, I>>;
@@ -434,7 +440,7 @@ template<class T, class I=C4_SIZE_TYPE> using cspanrs = spanrs<const T, I>;
* can always be recovered by calling original().
*/
template<class T, class I=C4_SIZE_TYPE>
class spanrsl : public span_crtp<T, I, spanrsl<T, I>>
class spanrsl : public span_crtp<T, I, spanrsl<T, I>> // NOLINT(*-special-member-functions)
{
friend class span_crtp<T, I, spanrsl<T, I>>;
@@ -512,6 +518,8 @@ public:
};
template<class T, class I=C4_SIZE_TYPE> using cspanrsl = spanrsl<const T, I>;
// NOLINTEND(misc-confusable-identifiers)
C4_SUPPRESS_WARNING_GCC_CLANG_POP
} // namespace c4

View File

@@ -24,7 +24,7 @@ C4_ALWAYS_INLINE c4::substr to_substr(std::string &s) noexcept
#error this function will have undefined behavior
#endif
// since c++11 it is legal to call s[s.size()].
return c4::substr(&s[0], s.size());
return c4::substr(&s[0], s.size()); // NOLINT(readability-container-data-pointer)
}
/** get a readonly view to an existing std::string.
@@ -38,7 +38,7 @@ C4_ALWAYS_INLINE c4::csubstr to_csubstr(std::string const& s) noexcept
#error this function will have undefined behavior
#endif
// since c++11 it is legal to call s[s.size()].
return c4::csubstr(&s[0], s.size());
return c4::csubstr(&s[0], s.size()); // NOLINT(readability-container-data-pointer)
}
//-----------------------------------------------------------------------------
@@ -87,7 +87,7 @@ inline bool from_chars(c4::csubstr buf, std::string * s)
if(buf.len)
{
C4_ASSERT(buf.str != nullptr);
memcpy(&(*s)[0], buf.str, buf.len);
memcpy(&(*s)[0], buf.str, buf.len); // NOLINT(readability-container-data-pointer)
}
return true;
}

View File

@@ -78,7 +78,7 @@ inline bool from_chars(c4::csubstr buf, std::vector<char, Alloc> * s)
// see https://github.com/biojppm/rapidyaml/pull/264#issuecomment-1262133637
if(buf.len > 0)
{
memcpy(&(*s)[0], buf.str, buf.len);
memcpy(&(*s)[0], buf.str, buf.len); // NOLINT(readability-container-data-pointer)
}
return true;
}

View File

@@ -5,6 +5,8 @@
#include <cstddef>
// NOLINTBEGIN(cert-dcl58-cpp)
// forward declarations for std::vector
#if defined(__GLIBCXX__) || defined(__GLIBCPP__) || defined(_MSC_VER)
#if defined(_MSC_VER)
@@ -63,4 +65,6 @@ template<class Alloc> bool from_chars(c4::csubstr buf, std::vector<char, Alloc>
} // namespace c4
// NOLINTEND(cert-dcl58-cpp)
#endif // _C4_STD_VECTOR_FWD_HPP_

View File

@@ -72,7 +72,7 @@ static inline void _do_reverse(C *C4_RESTRICT first, C *C4_RESTRICT last)
* @see @ref csubstr and @ref to_csubstr()
*/
template<class C>
struct C4CORE_EXPORT basic_substring
struct C4CORE_EXPORT basic_substring // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
{
public:
@@ -530,11 +530,11 @@ public:
/** @name Lookup methods */
/** @{ */
inline size_t find(const C c, size_t start_pos=0) const
size_t find(const C c, size_t start_pos=0) const
{
return first_of(c, start_pos);
}
inline size_t find(ro_substr pattern, size_t start_pos=0) const
size_t find(ro_substr pattern, size_t start_pos=0) const
{
C4_ASSERT(start_pos == npos || (start_pos >= 0 && start_pos <= len));
if(len < pattern.len) return npos;
@@ -561,7 +561,7 @@ public:
public:
/** count the number of occurrences of c */
inline size_t count(const C c, size_t pos=0) const
size_t count(const C c, size_t pos=0) const
{
C4_ASSERT(pos >= 0 && pos <= len);
size_t num = 0;
@@ -575,7 +575,7 @@ public:
}
/** count the number of occurrences of s */
inline size_t count(ro_substr c, size_t pos=0) const
size_t count(ro_substr c, size_t pos=0) const
{
C4_ASSERT(pos >= 0 && pos <= len);
size_t num = 0;
@@ -589,14 +589,14 @@ public:
}
/** get the substr consisting of the first occurrence of @p c after @p pos, or an empty substr if none occurs */
inline basic_substring select(const C c, size_t pos=0) const
basic_substring select(const C c, size_t pos=0) const
{
pos = find(c, pos);
return pos != npos ? sub(pos, 1) : basic_substring();
}
/** get the substr consisting of the first occurrence of @p pattern after @p pos, or an empty substr if none occurs */
inline basic_substring select(ro_substr pattern, size_t pos=0) const
basic_substring select(ro_substr pattern, size_t pos=0) const
{
pos = find(pattern, pos);
return pos != npos ? sub(pos, pattern.len) : basic_substring();
@@ -608,7 +608,7 @@ public:
{
size_t which;
size_t pos;
inline operator bool() const { return which != NONE && pos != npos; }
operator bool() const { return which != NONE && pos != npos; }
};
first_of_any_result first_of_any(ro_substr s0, ro_substr s1) const
@@ -1307,12 +1307,12 @@ public:
else if(c == '.')
{
++pos;
goto fractional_part_dec;
goto fractional_part_dec; // NOLINT
}
else if(c == 'e' || c == 'E')
{
++pos;
goto power_part_dec;
goto power_part_dec; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1341,7 +1341,7 @@ public:
else if(c == 'e' || c == 'E')
{
++pos;
goto power_part_dec;
goto power_part_dec; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1394,12 +1394,12 @@ public:
else if(c == '.')
{
++pos;
goto fractional_part_hex;
goto fractional_part_hex; // NOLINT
}
else if(c == 'p' || c == 'P')
{
++pos;
goto power_part_hex;
goto power_part_hex; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1428,7 +1428,7 @@ public:
else if(c == 'p' || c == 'P')
{
++pos;
goto power_part_hex;
goto power_part_hex; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1484,12 +1484,12 @@ public:
else if(c == '.')
{
++pos;
goto fractional_part_bin;
goto fractional_part_bin; // NOLINT
}
else if(c == 'p' || c == 'P')
{
++pos;
goto power_part_bin;
goto power_part_bin; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1518,7 +1518,7 @@ public:
else if(c == 'p' || c == 'P')
{
++pos;
goto power_part_bin;
goto power_part_bin; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1574,12 +1574,12 @@ public:
else if(c == '.')
{
++pos;
goto fractional_part_oct;
goto fractional_part_oct; // NOLINT
}
else if(c == 'p' || c == 'P')
{
++pos;
goto power_part_oct;
goto power_part_oct; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1608,7 +1608,7 @@ public:
else if(c == 'p' || c == 'P')
{
++pos;
goto power_part_oct;
goto power_part_oct; // NOLINT
}
else if(_is_delim_char(c))
{
@@ -1714,7 +1714,7 @@ private:
}
split_iterator_impl& operator++ () { _tick(); return *this; }
split_iterator_impl operator++ (int) { split_iterator_impl it = *this; _tick(); return it; }
split_iterator_impl operator++ (int) { split_iterator_impl it = *this; _tick(); return it; } // NOLINT
basic_substring& operator* () { return m_str; }
basic_substring* operator-> () { return &m_str; }
@@ -2069,7 +2069,7 @@ public:
C4_REQUIRE_RW(basic_substring) erase_range(size_t first, size_t last)
{
C4_ASSERT(first <= last);
return erase(first, static_cast<size_t>(last-first));
return erase(first, static_cast<size_t>(last-first)); // NOLINT
}
/** erase a part of the string.

View File

@@ -17,6 +17,8 @@
/** @defgroup types Type utilities */
// NOLINTBEGIN(bugprone-macro-parentheses)
namespace c4 {
/** @defgroup intrinsic_types Intrinsic types
@@ -114,17 +116,17 @@ using fastcref = typename std::conditional<c4::cref_uses_val<T>::value, T, T con
//--------------------------------------------------
/** Just what its name says. Useful sometimes as a default empty policy class. */
struct EmptyStruct
struct EmptyStruct // NOLINT
{
template<class... T> EmptyStruct(T && ...){}
template<class... T> EmptyStruct(T && ...){} // NOLINT
};
/** Just what its name says. Useful sometimes as a default policy class to
* be inherited from. */
struct EmptyStructVirtual
struct EmptyStructVirtual // NOLINT
{
virtual ~EmptyStructVirtual() = default;
template<class... T> EmptyStructVirtual(T && ...){}
template<class... T> EmptyStructVirtual(T && ...){} // NOLINT
};
@@ -159,7 +161,7 @@ struct Padded : public T
using T::T;
using T::operator=;
Padded(T const& val) : T(val) {}
Padded(T && val) : T(val) {}
Padded(T && val) : T(std::forward<T>(val)) {} // NOLINT
char ___c4padspace___[BytesToPadAtEnd];
};
#pragma pack(pop)
@@ -170,7 +172,7 @@ struct Padded<T, 0> : public T
using T::T;
using T::operator=;
Padded(T const& val) : T(val) {}
Padded(T && val) : T(val) {}
Padded(T && val) : T(std::forward<T>(val)) {} // NOLINT
};
/** make T have a size which is at least Min bytes */
@@ -500,4 +502,6 @@ using index_sequence_for = make_index_sequence<sizeof...(_Tp)>;
} // namespace c4
// NOLINTEND(bugprone-macro-parentheses)
#endif /* _C4_TYPES_HPP_ */

View File

@@ -16,23 +16,23 @@ size_t decode_code_point(uint8_t *C4_RESTRICT buf, size_t buflen, const uint32_t
}
else if(code <= UINT32_C(0x7ff))
{
buf[0] = (uint8_t)(UINT32_C(0xc0) | (code >> 6)); /* 110xxxxx */
buf[0] = (uint8_t)(UINT32_C(0xc0) | (code >> 6u)); /* 110xxxxx */
buf[1] = (uint8_t)(UINT32_C(0x80) | (code & UINT32_C(0x3f))); /* 10xxxxxx */
return 2u;
}
else if(code <= UINT32_C(0xffff))
{
buf[0] = (uint8_t)(UINT32_C(0xe0) | ((code >> 12))); /* 1110xxxx */
buf[1] = (uint8_t)(UINT32_C(0x80) | ((code >> 6) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[2] = (uint8_t)(UINT32_C(0x80) | ((code ) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[0] = (uint8_t)(UINT32_C(0xe0) | ((code >> 12u))); /* 1110xxxx */
buf[1] = (uint8_t)(UINT32_C(0x80) | ((code >> 6u) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[2] = (uint8_t)(UINT32_C(0x80) | ((code ) & UINT32_C(0x3f))); /* 10xxxxxx */
return 3u;
}
else if(code <= UINT32_C(0x10ffff))
{
buf[0] = (uint8_t)(UINT32_C(0xf0) | ((code >> 18))); /* 11110xxx */
buf[1] = (uint8_t)(UINT32_C(0x80) | ((code >> 12) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[2] = (uint8_t)(UINT32_C(0x80) | ((code >> 6) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[3] = (uint8_t)(UINT32_C(0x80) | ((code ) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[0] = (uint8_t)(UINT32_C(0xf0) | ((code >> 18u))); /* 11110xxx */
buf[1] = (uint8_t)(UINT32_C(0x80) | ((code >> 12u) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[2] = (uint8_t)(UINT32_C(0x80) | ((code >> 6u) & UINT32_C(0x3f))); /* 10xxxxxx */
buf[3] = (uint8_t)(UINT32_C(0x80) | ((code ) & UINT32_C(0x3f))); /* 10xxxxxx */
return 4u;
}
return 0;

View File

@@ -9,7 +9,7 @@
namespace c4 {
substr decode_code_point(substr out, csubstr code_point);
size_t decode_code_point(uint8_t *C4_RESTRICT buf, size_t buflen, const uint32_t code);
size_t decode_code_point(uint8_t *C4_RESTRICT buf, size_t buflen, uint32_t code);
} // namespace c4