diff --git a/.clang-tidy b/.clang-tidy index 2e81039e16142d0498198397067b2dba8b0c9ebd..3b576049dc6f31873aaf67e2de2064ee896a071b 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -5,11 +5,48 @@ --- Checks: >- -*, + bugprone-*, + -bugprone-easily-swappable-parameters, + -bugprone-macro-parentheses, cert-*, clang-analyzer-core*, clang-analyzer-cplusplus*, - clang-analyzer-unix.MismatchedDeallocator, - misc-new-delete-overloads + clang-analyzer-security*, + clang-analyzer-unix.*, + cppcoreguidelines-*, + -cppcoreguidelines-avoid-c-arrays, + -cppcoreguidelines-avoid-const-or-ref-data-members, + -cppcoreguidelines-avoid-do-while, + -cppcoreguidelines-avoid-magic-numbers, + -cppcoreguidelines-macro-to-enum, + -cppcoreguidelines-macro-usage, + -cppcoreguidelines-no-malloc, + -cppcoreguidelines-non-private-member-variables-in-classes, + -cppcoreguidelines-owning-memory, + -cppcoreguidelines-pro-*, + -cppcoreguidelines-special-member-functions, + -cppcoreguidelines-use-default-member-init, + -cppcoreguidelines-virtual-class-destructor, + hicpp-*, + -hicpp-avoid-c-arrays, + -hicpp-named-parameter, + -hicpp-no-array-decay, + -hicpp-no-assembler, + -hicpp-no-malloc, + -hicpp-signed-bitwise, + -hicpp-special-member-functions, + -hicpp-use-auto, + misc-new-delete-overloads, + performance-*, + -performance-enum-size, + readability-*, + -readability-convert-member-functions-to-static, + -readability-identifier-length, + -readability-implicit-bool-conversion, + -readability-isolate-declaration, + -readability-magic-numbers, + -readability-named-parameter, + -readability-redundant-inline-specifier WarningsAsErrors: '*' HeaderFilterRegex: '(intrinsiccv|test)/.*' FormatStyle: google diff --git a/adapters/opencv/intrinsiccv_hal.cpp b/adapters/opencv/intrinsiccv_hal.cpp index d68c337bcdc88074910fa6dea591a5b82ed60861..f5a4cbf546a8efc1ff4a327a56bddc43b6ff44ae 100644 --- a/adapters/opencv/intrinsiccv_hal.cpp +++ b/adapters/opencv/intrinsiccv_hal.cpp @@ -304,7 +304,7 @@ int gaussian_blur(const uchar *src_data, size_t src_step, uchar *dst_data, intrinsiccv_filter_params_t params; params.channels = cn; - params.type_size = get_type_size(depth) * 2ul /* widening */; + params.type_size = get_type_size(depth) * 2UL /* widening */; intrinsiccv_rectangle_t image = { .width = static_cast(width), diff --git a/intrinsiccv/include/containers/stack.h b/intrinsiccv/include/containers/stack.h index 5ecf7956926f4ebdf8f34f8904ae19ccc8366499..58645446c1dea4ccbdb018ad7afc8ca544427f0f 100644 --- a/intrinsiccv/include/containers/stack.h +++ b/intrinsiccv/include/containers/stack.h @@ -24,6 +24,7 @@ class Stack final : public NonCopyable { using reference = value_type &; using const_reference = const value_type &; + // NOLINTBEGIN(cppcoreguidelines-prefer-member-initializer) explicit Stack() noexcept { current_block_ = Block::make_block(nullptr); // Note: push_back() first increments the back_ pointer. @@ -33,6 +34,7 @@ class Stack final : public NonCopyable { empty_back_ = back_min_; first_block_ = current_block_; } + // NOLINTEND(cppcoreguidelines-prefer-member-initializer) ~Stack() noexcept { Block *block = first_block_; @@ -76,7 +78,7 @@ class Stack final : public NonCopyable { // Granularity of blocks in bytes. Blocks are a multiple of this value in // size. It matches the smallest page size, therefore it should work well with // systems with larger page size too. - static constexpr size_t kBlockGranule = 2 * 4096; + static constexpr size_t kBlockGranule = 2 * 4096UL; static_assert(sizeof(T) <= sizeof(void *), "Current implementation is limited. Please improve it."); diff --git a/intrinsiccv/include/conversions/split.h b/intrinsiccv/include/conversions/split.h index 3f70fa9a71990ef51b8b6eafb8e5b9cb5273fcd8..d4a5e603c3051e251ff38f67adf8a111db80b8a7 100644 --- a/intrinsiccv/include/conversions/split.h +++ b/intrinsiccv/include/conversions/split.h @@ -12,8 +12,8 @@ namespace intrinsiccv { namespace neon { void split(const void *src_data, size_t src_stride, void **dst_data, - size_t *dst_strides, size_t width, size_t height, size_t channels, - size_t element_size); + const size_t *dst_strides, size_t width, size_t height, + size_t channels, size_t element_size); } // namespace neon diff --git a/intrinsiccv/include/dispatch.h b/intrinsiccv/include/dispatch.h index 43a248d9c1ad94f6e40ceb47a52a41b7281fdf46..441c2bb7db22f35149098387de86c17c426c82ac 100644 --- a/intrinsiccv/include/dispatch.h +++ b/intrinsiccv/include/dispatch.h @@ -32,7 +32,8 @@ static inline bool hwcaps_has_sve2(HwCaps hwcaps) { static inline bool hwcaps_has_sme2(HwCaps hwcaps) { // Actually checks for SME, not SME2, but this will be changed to check for // SME2 in future. - return hwcaps.hwcap2 & (1UL << 23); + const int kSMEBit = 23; + return hwcaps.hwcap2 & (1UL << kSMEBit); } struct IFuncImpls final { diff --git a/intrinsiccv/include/morphology/workspace.h b/intrinsiccv/include/morphology/workspace.h index b69353e8e76564f5a24e982e1196ba89bcb1e27e..b932fec9b46f930fc999fc7ea8676dc6324b890e 100644 --- a/intrinsiccv/include/morphology/workspace.h +++ b/intrinsiccv/include/morphology/workspace.h @@ -45,7 +45,7 @@ class MorphologyWorkspace final { size_t channels, size_t buffer_type_size) INTRINSICCV_STREAMING_COMPATIBLE { // These values are arbitrarily choosen. - const size_t rows_per_iteration = std::max(2 * kernel.height(), 32ul); + const size_t rows_per_iteration = std::max(2 * kernel.height(), 32UL); // To avoid load/store penalties. const size_t kAlignment = 16; @@ -54,7 +54,7 @@ class MorphologyWorkspace final { size_t wide_rows_width = margin.left() + rect.width() + margin.right(); size_t wide_rows_stride = wide_rows_width * channels; wide_rows_stride = __builtin_align_up(wide_rows_stride, kAlignment); - size_t wide_rows_height = 1ul; // There is only one wide row. + size_t wide_rows_height = 1UL; // There is only one wide row. size_t wide_rows_size = wide_rows_stride * wide_rows_height; wide_rows_size += kAlignment - 1; @@ -73,7 +73,7 @@ class MorphologyWorkspace final { size_t allocation_size = sizeof(MorphologyWorkspace) + indirect_row_storage_size + buffer_rows_size + wide_rows_size; - auto allocation = std::malloc(allocation_size); + void *allocation = std::malloc(allocation_size); auto workspace = MorphologyWorkspace::Pointer{ reinterpret_cast(allocation)}; if (!workspace) { @@ -84,12 +84,12 @@ class MorphologyWorkspace final { workspace->wide_rows_src_width_ = rect.width(); workspace->channels_ = channels; - auto buffer_rows_address = &workspace->data_[indirect_row_storage_size]; + auto *buffer_rows_address = &workspace->data_[indirect_row_storage_size]; buffer_rows_address = __builtin_align_up(buffer_rows_address, kAlignment); workspace->buffer_rows_offset_ = buffer_rows_address - &workspace->data_[0]; workspace->buffer_rows_stride_ = buffer_rows_stride; - auto wide_rows_address = + auto *wide_rows_address = &workspace->data_[indirect_row_storage_size + buffer_rows_size]; wide_rows_address += margin.left() * channels; wide_rows_address = __builtin_align_up(wide_rows_address, kAlignment); @@ -100,6 +100,8 @@ class MorphologyWorkspace final { return workspace; } + // This function is too complex, but disable the warning for now. + // NOLINTBEGIN(readability-function-cognitive-complexity) template void process(Rectangle rect, Rows src_rows, Rows dst_rows, Margin margin, @@ -196,7 +198,7 @@ class MorphologyWorkspace final { } // switch (border_type) // [Step 2] Process the preloaded data. - operation.process_horizontal(Rectangle{rect.width(), 1ul}, wide_rows, + operation.process_horizontal(Rectangle{rect.width(), 1UL}, wide_rows, db_indirect_rows.write_at().at(index)); } // for (...; index < horizontal_height; ...) @@ -255,7 +257,7 @@ class MorphologyWorkspace final { break; } // switch (border_type) - operation.process_horizontal(Rectangle{rect.width(), 1ul}, wide_rows, + operation.process_horizontal(Rectangle{rect.width(), 1UL}, wide_rows, db_indirect_rows.write_at().at(index)); } // for (...; index < horizontal_height; ...) @@ -267,6 +269,7 @@ class MorphologyWorkspace final { db_indirect_rows.swap(); } } + // NOLINTEND(readability-function-cognitive-complexity) private: // The number of wide rows to process in the next iteration. diff --git a/intrinsiccv/include/neon.h b/intrinsiccv/include/neon.h index a3983890bd56af18d8efaba25ecbc8c7d698647b..6f17e8e0ef2154fc39b63d20966e94af2e606c47 100644 --- a/intrinsiccv/include/neon.h +++ b/intrinsiccv/include/neon.h @@ -323,7 +323,7 @@ class SeparableFilter; // Driver for a separable 3x3 filter. template -class SeparableFilter { +class SeparableFilter { public: using SourceType = typename FilterType::SourceType; using BufferType = typename FilterType::BufferType; @@ -335,9 +335,9 @@ class SeparableFilter { using BorderInfoType = typename intrinsiccv::FixedBorderInfo3x3; using BorderOffsets = typename BorderInfoType::Offsets; - explicit SeparableFilter(FilterType filter) { filter_ = filter; } + explicit SeparableFilter(FilterType filter) : filter_{filter} {} - static constexpr Margin margin() { return Margin{1ul}; } + static constexpr Margin margin() { return Margin{1UL}; } void process_vertical(size_t width, Rows src_rows, Rows dst_rows, @@ -449,11 +449,11 @@ class SeparableFilter { } FilterType filter_; -}; // end of class SeparableFilter +}; // end of class SeparableFilter // Driver for a separable 5x5 filter. template -class SeparableFilter { +class SeparableFilter { public: using SourceType = typename FilterType::SourceType; using BufferType = typename FilterType::BufferType; @@ -465,9 +465,9 @@ class SeparableFilter { using BorderInfoType = typename intrinsiccv::FixedBorderInfo5x5; using BorderOffsets = typename BorderInfoType::Offsets; - explicit SeparableFilter(FilterType filter) { filter_ = filter; } + explicit SeparableFilter(FilterType filter) : filter_{filter} {} - static constexpr Margin margin() { return Margin{2ul}; } + static constexpr Margin margin() { return Margin{2UL}; } void process_vertical(size_t width, Rows src_rows, Rows dst_rows, @@ -567,15 +567,15 @@ class SeparableFilter { } FilterType filter_; -}; // end of class SeparableFilter +}; // end of class SeparableFilter // Shorthand for 3x3 separable filters driver type. template -using SeparableFilter3x3 = SeparableFilter; +using SeparableFilter3x3 = SeparableFilter; // Shorthand for 5x5 separable filters driver type. template -using SeparableFilter5x5 = SeparableFilter; +using SeparableFilter5x5 = SeparableFilter; } // namespace neon } // namespace intrinsiccv diff --git a/intrinsiccv/include/operations.h b/intrinsiccv/include/operations.h index fa15ea81cb96f30ada9177f3053959cff8671323..b806ddf47eaab7b8badd6b789b7d33f1c111a7c1 100644 --- a/intrinsiccv/include/operations.h +++ b/intrinsiccv/include/operations.h @@ -165,6 +165,7 @@ class RowBasedOperation : public OperationBase { // Instructs the loop logic to try to avoid the tail loop. void try_avoid_tail_loop() { try_avoid_tail_loop_ = true; } + // NOLINTBEGIN(cppcoreguidelines-avoid-goto, hicpp-avoid-goto) template void process_row(size_t length, ColumnTypes... columns) INTRINSICCV_STREAMING_COMPATIBLE { @@ -209,6 +210,7 @@ class RowBasedOperation : public OperationBase { // clang-format on } + // NOLINTEND(cppcoreguidelines-avoid-goto, hicpp-avoid-goto) private: // True if tail loop should be avoided at all costs. diff --git a/intrinsiccv/include/sve2.h b/intrinsiccv/include/sve2.h index be274b1937fee7c8d0d8a4ca2310ad8b70cc2bf9..543ab681ea5dc257cfb6e2e81c318eeff0e7115e 100644 --- a/intrinsiccv/include/sve2.h +++ b/intrinsiccv/include/sve2.h @@ -472,7 +472,7 @@ class SeparableFilter; // Driver for a separable 3x3 filter. template -class SeparableFilter { +class SeparableFilter { public: using SourceType = typename FilterType::SourceType; using BufferType = typename FilterType::BufferType; @@ -484,12 +484,11 @@ class SeparableFilter { using BorderInfoType = typename intrinsiccv::FixedBorderInfo3x3; using BorderOffsets = typename BorderInfoType::Offsets; - explicit SeparableFilter(FilterType filter) INTRINSICCV_STREAMING_COMPATIBLE { - filter_ = filter; - } + explicit SeparableFilter(FilterType filter) INTRINSICCV_STREAMING_COMPATIBLE + : filter_{filter} {} static constexpr Margin margin() INTRINSICCV_STREAMING_COMPATIBLE { - return Margin{1ul}; + return Margin{1UL}; } void process_vertical( @@ -604,11 +603,11 @@ class SeparableFilter { } FilterType filter_; -}; // end of class SeparableFilter +}; // end of class SeparableFilter // Driver for a separable 5x5 filter. template -class SeparableFilter { +class SeparableFilter { public: using SourceType = typename FilterType::SourceType; using BufferType = typename FilterType::BufferType; @@ -620,12 +619,11 @@ class SeparableFilter { using BorderInfoType = typename intrinsiccv::FixedBorderInfo5x5; using BorderOffsets = typename BorderInfoType::Offsets; - explicit SeparableFilter(FilterType filter) INTRINSICCV_STREAMING_COMPATIBLE { - filter_ = filter; - } + explicit SeparableFilter(FilterType filter) INTRINSICCV_STREAMING_COMPATIBLE + : filter_{filter} {} static constexpr Margin margin() INTRINSICCV_STREAMING_COMPATIBLE { - return Margin{2ul}; + return Margin{2UL}; } void process_vertical( @@ -758,15 +756,15 @@ class SeparableFilter { } FilterType filter_; -}; // end of class SeparableFilter +}; // end of class SeparableFilter // Shorthand for 3x3 separable filters driver type. template -using SeparableFilter3x3 = SeparableFilter; +using SeparableFilter3x3 = SeparableFilter; // Shorthand for 5x5 separable filters driver type. template -using SeparableFilter5x5 = SeparableFilter; +using SeparableFilter5x5 = SeparableFilter; } // namespace intrinsiccv::sve2 diff --git a/intrinsiccv/include/types.h b/intrinsiccv/include/types.h index a21bba91967ce7f98db3772be85b8bf36b0ff533..799a976ad80dca68b2aaebf09a22839d94cc325b 100644 --- a/intrinsiccv/include/types.h +++ b/intrinsiccv/include/types.h @@ -101,15 +101,14 @@ class Margin final { template class Border final { public: - explicit Border() INTRINSICCV_STREAMING_COMPATIBLE {} + Border() INTRINSICCV_STREAMING_COMPATIBLE = default; - explicit Border(double left, double top, double right, - double bottom) INTRINSICCV_STREAMING_COMPATIBLE { - left_ = saturating_cast(left); - top_ = saturating_cast(top); - right_ = saturating_cast(right); - bottom_ = saturating_cast(bottom); - } + Border(double left, double top, double right, + double bottom) INTRINSICCV_STREAMING_COMPATIBLE + : left_{saturating_cast(left)}, + top_{saturating_cast(top)}, + right_{saturating_cast(right)}, + bottom_{saturating_cast(bottom)} {} explicit Border(intrinsiccv_border_values_t border_values) INTRINSICCV_STREAMING_COMPATIBLE @@ -138,7 +137,7 @@ class Columns final { // Subscript operator to return an arbitrary column at an index. To account // for channel count use at() method. - T &operator[](ptrdiff_t index) INTRINSICCV_STREAMING_COMPATIBLE { + T &operator[](size_t index) INTRINSICCV_STREAMING_COMPATIBLE { return ptr_[index]; } @@ -159,15 +158,16 @@ class Columns final { return operator+=(1); } + // NOLINTBEGIN(hicpp-explicit-conversions) // Implicit conversion operator from Columns to Columns. [[nodiscard]] operator Columns() const INTRINSICCV_STREAMING_COMPATIBLE { return Columns{ptr_, channels()}; } + // NOLINTEND(hicpp-explicit-conversions) // Returns a new instance at a given column. - [[nodiscard]] Columns at(ptrdiff_t column) - INTRINSICCV_STREAMING_COMPATIBLE { + [[nodiscard]] Columns at(size_t column) INTRINSICCV_STREAMING_COMPATIBLE { return Columns{&ptr_[column * channels()], channels()}; } @@ -245,8 +245,11 @@ class RowBase { } protected: - // The default constructor creates an uninitialized instance. - RowBase() INTRINSICCV_STREAMING_COMPATIBLE {} + // TODO: default initialise members. + // NOLINTBEGIN(hicpp-member-init) + // The default constructor creates an uninitialized instance. + RowBase() INTRINSICCV_STREAMING_COMPATIBLE = default; + // NOLINTEND(hicpp-member-init) RowBase(size_t stride, size_t channels) INTRINSICCV_STREAMING_COMPATIBLE : stride_(stride), @@ -258,7 +261,9 @@ class RowBase { INTRINSICCV_STREAMING_COMPATIBLE { uintptr_t intptr = reinterpret_cast(ptr); intptr += stride; + // NOLINTBEGIN(performance-no-int-to-ptr) return reinterpret_cast

(intptr); + // NOLINTEND(performance-no-int-to-ptr) } // Subtracts a stride to a pointer, and returns the new pointer. @@ -267,7 +272,9 @@ class RowBase { INTRINSICCV_STREAMING_COMPATIBLE { uintptr_t intptr = reinterpret_cast(ptr); intptr -= stride; + // NOLINTBEGIN(performance-no-int-to-ptr) return reinterpret_cast

(intptr); + // NOLINTEND(performance-no-int-to-ptr) } private: @@ -321,12 +328,12 @@ class Rows final : public RowBase { // Subscript operator to return an arbitrary position within the current row. // To account for stride and channel count use at() method. - T &operator[](ptrdiff_t index) INTRINSICCV_STREAMING_COMPATIBLE { + T &operator[](size_t index) INTRINSICCV_STREAMING_COMPATIBLE { return ptr_[index]; } // Addition assignment operator to navigate among rows. - Rows &operator+=(ptrdiff_t diff) INTRINSICCV_STREAMING_COMPATIBLE { + Rows &operator+=(size_t diff) INTRINSICCV_STREAMING_COMPATIBLE { ptr_ = get_pointer_at(diff); return *this; } @@ -336,14 +343,16 @@ class Rows final : public RowBase { return operator+=(1); } + // NOLINTBEGIN(hicpp-explicit-conversions) // Returns a const variant of this instance. [[nodiscard]] operator Rows() INTRINSICCV_STREAMING_COMPATIBLE { return Rows{ptr_, stride(), channels()}; } + // NOLINTEND(hicpp-explicit-conversions) // Returns a new instance at a given row and column. - [[nodiscard]] Rows at(ptrdiff_t row, ptrdiff_t column = 0) - INTRINSICCV_STREAMING_COMPATIBLE { + [[nodiscard]] Rows at(size_t row, + size_t column = 0) INTRINSICCV_STREAMING_COMPATIBLE { return Rows{get_pointer_at(row, column), stride(), channels()}; } @@ -364,7 +373,7 @@ class Rows final : public RowBase { private: // Returns a column in a row at a given index taking stride and channels into // account. - [[nodiscard]] T *get_pointer_at(ptrdiff_t row, ptrdiff_t column = 0) + [[nodiscard]] T *get_pointer_at(size_t row, size_t column = 0) INTRINSICCV_STREAMING_COMPATIBLE { T *ptr = RowBase::add_stride(ptr_, row * stride()); return &ptr[column * channels()]; @@ -401,12 +410,12 @@ class IndirectRows : public RowBase { // Subscript operator to return a position within the current row. To account // for stride and channel count use at() method. - T &operator[](ptrdiff_t index) INTRINSICCV_STREAMING_COMPATIBLE { + T &operator[](size_t index) INTRINSICCV_STREAMING_COMPATIBLE { return ptr_storage_[0][index]; } // Addition assignment operator to navigate among rows. - IndirectRows &operator+=(ptrdiff_t diff) INTRINSICCV_STREAMING_COMPATIBLE { + IndirectRows &operator+=(size_t diff) INTRINSICCV_STREAMING_COMPATIBLE { ptr_storage_ += diff; return *this; } @@ -417,8 +426,8 @@ class IndirectRows : public RowBase { } // Returns a new instance at a given row and column. - [[nodiscard]] Rows at(ptrdiff_t row, ptrdiff_t column = 0) - INTRINSICCV_STREAMING_COMPATIBLE { + [[nodiscard]] Rows at(size_t row, + size_t column = 0) INTRINSICCV_STREAMING_COMPATIBLE { auto rows = Rows{ptr_storage_[row], stride(), channels()}; return rows.at(0, column); } @@ -492,7 +501,7 @@ class ParallelRows final : public RowBase { : ParallelRows(ptr, stride, 1) {} // Addition assignment operator to navigate among rows. - ParallelRows &operator+=(ptrdiff_t diff) INTRINSICCV_STREAMING_COMPATIBLE { + ParallelRows &operator+=(size_t diff) INTRINSICCV_STREAMING_COMPATIBLE { ptrs_[0] = RowBase::add_stride(ptrs_[0], diff * stride()); ptrs_[1] = RowBase::add_stride(ptrs_[1], diff * stride()); return *this; @@ -644,8 +653,8 @@ class RowsOverUniquePtr { protected: RowsOverUniquePtr(Rectangle rect, Margin margin) - : rect_{get_rectangle(rect, margin)} { - data_ = std::unique_ptr(new (std::nothrow) T[rect_.area()]); + : rect_{get_rectangle(rect, margin)}, + data_{std::unique_ptr(new(std::nothrow) T[rect_.area()])} { if (!data_) { // FIXME: add error handling __builtin_trap(); diff --git a/intrinsiccv/include/utils.h b/intrinsiccv/include/utils.h index 3d3591816fcdb6e215d7b1812f317e181f4ed40a..c50a0ced3961bf24c5d5ba519105f3a96380050a 100644 --- a/intrinsiccv/include/utils.h +++ b/intrinsiccv/include/utils.h @@ -21,7 +21,8 @@ template std::numeric_limits::max()) { return std::numeric_limits::max(); - } else if (value < 0) { + } + if (value < 0) { return 0; } diff --git a/intrinsiccv/include/workspace/borders.h b/intrinsiccv/include/workspace/borders.h index 066e117776906a527b83d4e54e56eb1bdb59258f..76fe2e2143ca544265ea2d84dff76a8b135178d7 100644 --- a/intrinsiccv/include/workspace/borders.h +++ b/intrinsiccv/include/workspace/borders.h @@ -15,18 +15,14 @@ class FixedBorderInfo; // Border offsets for 3x3 filters. template -class FixedBorderInfo final { +class FixedBorderInfo final { public: // Simple object holding read-only constant offsets. class Offsets final { public: - explicit Offsets() {} + Offsets() = default; - explicit Offsets(size_t o0, size_t o1, size_t o2) { - offsets_[0] = o0; - offsets_[1] = o1; - offsets_[2] = o2; - } + Offsets(size_t o0, size_t o1, size_t o2) : offsets_{o0, o1, o2} {} size_t c0() const { return offsets_[0]; } size_t c1() const { return offsets_[1]; } @@ -91,15 +87,15 @@ class FixedBorderInfo final { // Retuns offsets for rows or columns affected by any border. Offsets offsets_with_border(size_t row_or_column_index) const INTRINSICCV_STREAMING_COMPATIBLE { - if (row_or_column_index == 0u) { + if (row_or_column_index == 0U) { // Rows and columns have the same offsets. return offsets_with_left_border(row_or_column_index); - } else if (row_or_column_index == (height_ - 1u)) { + } + if (row_or_column_index == (height_ - 1U)) { // Rows and columns have the same offsets. return offsets_with_right_border(row_or_column_index); - } else { - return offsets_without_border(); } + return offsets_without_border(); } private: @@ -110,24 +106,21 @@ class FixedBorderInfo final { size_t height_; intrinsiccv_border_type_t border_type_; -}; // end of class FixedBorderInfo +}; // end of class FixedBorderInfo // Border offsets for 5x5 filters. template -class FixedBorderInfo final { +class FixedBorderInfo final { public: // Simple object holding read-only constant offsets. class Offsets final { public: - explicit Offsets() {} - - explicit Offsets(size_t o0, size_t o1, size_t o2, size_t o3, size_t o4) { - offsets_[0] = o0; - offsets_[1] = o1; - offsets_[2] = o2; - offsets_[3] = o3; - offsets_[4] = o4; - } + // NOLINTBEGIN(hicpp-member-init) + Offsets() = default; + // NOLINTEND(hicpp-member-init) + + Offsets(size_t o0, size_t o1, size_t o2, size_t o3, size_t o4) + : offsets_{o0, o1, o2, o3, o4} {} size_t c0() const { return offsets_[0]; } size_t c1() const { return offsets_[1]; } @@ -234,15 +227,15 @@ class FixedBorderInfo final { // Retuns offsets for rows or columns affected by any border. Offsets offsets_with_border(size_t row_or_column_index) const INTRINSICCV_STREAMING_COMPATIBLE { - if (row_or_column_index <= 1u) { + if (row_or_column_index <= 1U) { // Rows and columns have the same offsets. return offsets_with_left_border(row_or_column_index); - } else if (row_or_column_index >= (height_ - 2u)) { + } + if (row_or_column_index >= (height_ - 2U)) { // Rows and columns have the same offsets. return offsets_with_right_border(row_or_column_index); - } else { - return offsets_without_border(); } + return offsets_without_border(); } private: @@ -254,15 +247,15 @@ class FixedBorderInfo final { size_t height_; intrinsiccv_border_type_t border_type_; -}; // end of class FixedBorderInfo +}; // end of class FixedBorderInfo // Shorthand for 3x3 filter border type. template -using FixedBorderInfo3x3 = FixedBorderInfo; +using FixedBorderInfo3x3 = FixedBorderInfo; // Shorthand for 5x5 filter border type. template -using FixedBorderInfo5x5 = FixedBorderInfo; +using FixedBorderInfo5x5 = FixedBorderInfo; } // namespace intrinsiccv diff --git a/intrinsiccv/include/workspace/separable.h b/intrinsiccv/include/workspace/separable.h index f91625968b16c974142657ba354b2691900e1e38..f2e2925c60e21e25050c576b15ffe80e4aac3a35 100644 --- a/intrinsiccv/include/workspace/separable.h +++ b/intrinsiccv/include/workspace/separable.h @@ -70,7 +70,7 @@ class SeparableFilterWorkspaceDeleter { class SeparableFilterWorkspace final { public: // To avoid load/store penalties. - static constexpr size_t kAlignment = 16ul; + static constexpr size_t kAlignment = 16UL; // Shorthand for std::unique_ptr<> holding a workspace. using Pointer = std::unique_ptr(allocation)}; @@ -105,7 +105,7 @@ class SeparableFilterWorkspace final { return workspace; } - auto buffer_rows_address = &workspace->data_[0]; + auto *buffer_rows_address = &workspace->data_[0]; buffer_rows_address = __builtin_align_up(buffer_rows_address, kAlignment); workspace->buffer_rows_offset_ = buffer_rows_address - &workspace->data_[0]; workspace->buffer_rows_stride_ = buffer_rows_stride; diff --git a/intrinsiccv/src/analysis/canny_neon.cpp b/intrinsiccv/src/analysis/canny_neon.cpp index f3c1d2d9320179debaba895897d5cf8d3e4d70ec..200e1b41fb6ecd73366c3667602a742c6ba6f0f7 100644 --- a/intrinsiccv/src/analysis/canny_neon.cpp +++ b/intrinsiccv/src/analysis/canny_neon.cpp @@ -276,10 +276,10 @@ static void directional_masking(const int16_t *prev_rows, vreinterpretq_s8_s16(directions)); // Load indices which are used to create prev and next rows. - const int8x16_t lane_offsets = vld1q_s8(&indices[0 * kNumLanesS8]); - const int8x16_t prev_row_table = vld1q_s8(&indices[1 * kNumLanesS8]); - const int8x16_t next_row_table = vld1q_s8(&indices[2 * kNumLanesS8]); - const int8x16_t current_row_table = vld1q_s8(&indices[3 * kNumLanesS8]); + const int8x16_t lane_offsets = vld1q_s8(&indices[0UL * kNumLanesS8]); + const int8x16_t prev_row_table = vld1q_s8(&indices[1UL * kNumLanesS8]); + const int8x16_t next_row_table = vld1q_s8(&indices[2UL * kNumLanesS8]); + const int8x16_t current_row_table = vld1q_s8(&indices[3UL * kNumLanesS8]); // Temporary indexing and other vectors. int8x16_t tmp_indices_0, tmp_indices_1; @@ -287,9 +287,12 @@ static void directional_masking(const int16_t *prev_rows, // Load the previous row. int8x16x3_t prev_row; - prev_row.val[0] = vreinterpretq_s8_s16(vld1q_s16(&prev_rows[0 * kNumLanes])); - prev_row.val[1] = vreinterpretq_s8_s16(vld1q_s16(&prev_rows[1 * kNumLanes])); - prev_row.val[2] = vreinterpretq_s8_s16(vld1q_s16(&prev_rows[2 * kNumLanes])); + prev_row.val[0] = + vreinterpretq_s8_s16(vld1q_s16(&prev_rows[0UL * kNumLanes])); + prev_row.val[1] = + vreinterpretq_s8_s16(vld1q_s16(&prev_rows[1UL * kNumLanes])); + prev_row.val[2] = + vreinterpretq_s8_s16(vld1q_s16(&prev_rows[2UL * kNumLanes])); // 1.1 tmp_indices_0 = vqtbl1q_s8(prev_row_table, dir); @@ -300,9 +303,12 @@ static void directional_masking(const int16_t *prev_rows, // Load the next row. int8x16x3_t next_row; - next_row.val[0] = vreinterpretq_s8_s16(vld1q_s16(&next_rows[0 * kNumLanes])); - next_row.val[1] = vreinterpretq_s8_s16(vld1q_s16(&next_rows[1 * kNumLanes])); - next_row.val[2] = vreinterpretq_s8_s16(vld1q_s16(&next_rows[2 * kNumLanes])); + next_row.val[0] = + vreinterpretq_s8_s16(vld1q_s16(&next_rows[0UL * kNumLanes])); + next_row.val[1] = + vreinterpretq_s8_s16(vld1q_s16(&next_rows[1UL * kNumLanes])); + next_row.val[2] = + vreinterpretq_s8_s16(vld1q_s16(&next_rows[2UL * kNumLanes])); // 2.1 tmp_indices_0 = vqtbl1q_s8(next_row_table, dir); @@ -316,9 +322,12 @@ static void directional_masking(const int16_t *prev_rows, // Load the current row. int8x16x3_t curr_row; - curr_row.val[0] = vreinterpretq_s8_s16(vld1q_s16(&curr_rows[0 * kNumLanes])); - curr_row.val[1] = vreinterpretq_s8_s16(vld1q_s16(&curr_rows[1 * kNumLanes])); - curr_row.val[2] = vreinterpretq_s8_s16(vld1q_s16(&curr_rows[2 * kNumLanes])); + curr_row.val[0] = + vreinterpretq_s8_s16(vld1q_s16(&curr_rows[0UL * kNumLanes])); + curr_row.val[1] = + vreinterpretq_s8_s16(vld1q_s16(&curr_rows[1UL * kNumLanes])); + curr_row.val[2] = + vreinterpretq_s8_s16(vld1q_s16(&curr_rows[2UL * kNumLanes])); // 3.1 tmp_indices_0 = vqtbl1q_s8(current_row_table, dir); @@ -352,7 +361,7 @@ static void directional_masking(const int16_t *prev_rows, } static bool is_vect_len_memory_null(const int16_t *data) { - auto s64_data = reinterpret_cast(data); + const auto *s64_data = reinterpret_cast(data); return ((s64_data[0] | s64_data[1]) == 0); } @@ -438,7 +447,7 @@ static void handle_potentially_strong_pixel(StrongEdgeStack &strong_edge_pixels, static void perform_hysteresis(StrongEdgeStack &strong_edge_pixels, size_t stride) { while (!strong_edge_pixels.empty()) { - auto strong_pixel = strong_edge_pixels.back(); + auto *strong_pixel = strong_edge_pixels.back(); strong_edge_pixels.pop_back(); handle_potentially_strong_pixel(strong_edge_pixels, diff --git a/intrinsiccv/src/analysis/min_max_loc_neon.cpp b/intrinsiccv/src/analysis/min_max_loc_neon.cpp index 63e25c5b703ab4d05ed286d49e0a2bf5a8ca9877..a0040be6e73b887be3d2fb5b4f1a697c0ed1b4cb 100644 --- a/intrinsiccv/src/analysis/min_max_loc_neon.cpp +++ b/intrinsiccv/src/analysis/min_max_loc_neon.cpp @@ -106,6 +106,7 @@ class MinMaxLoc final : public UnrollTwice { using UnsignedVectorType = typename neon::VecTraits>::VectorType; + // NOLINTBEGIN(cppcoreguidelines-prefer-member-initializer) MinMaxLoc() { vmin_offsets_ = vmax_offsets_ = vmin_offsets_new_ = vmax_offsets_new_ = vdupq_n(ScalarType{0}); @@ -118,6 +119,7 @@ class MinMaxLoc final : public UnrollTwice { min_scalar_index_ = max_scalar_index_ = 0; running_index_ = 0; } + // NOLINTEND(cppcoreguidelines-prefer-member-initializer) void vector_path(VectorType src) { VectorType v_is_smaller = vcltq_u8(src, vmin_new_); diff --git a/intrinsiccv/src/arithmetics/add_abs_with_threshold_neon.cpp b/intrinsiccv/src/arithmetics/add_abs_with_threshold_neon.cpp index ace9f63810c5b918a5a1184f08218c7e7e111d1c..24fccea5b16cd564a80c16cb2b8fcc3767b3e07e 100644 --- a/intrinsiccv/src/arithmetics/add_abs_with_threshold_neon.cpp +++ b/intrinsiccv/src/arithmetics/add_abs_with_threshold_neon.cpp @@ -15,10 +15,8 @@ class AddAbsWithThreshold final : public UnrollOnce, public UnrollTwice { using VecTraits = neon::VecTraits; using VectorType = typename VecTraits::VectorType; - explicit AddAbsWithThreshold(ScalarType threshold) { - threshold_ = threshold; - threshold_vec_ = vdupq_n_s16(threshold); - } + explicit AddAbsWithThreshold(ScalarType threshold) + : threshold_{threshold}, threshold_vec_{vdupq_n_s16(threshold)} {} VectorType vector_path(VectorType src_a, VectorType src_b) { VectorType add_abs = vaddq_s16(vabsq_s16(src_a), vabsq_s16(src_b)); diff --git a/intrinsiccv/src/arithmetics/multiply_neon.cpp b/intrinsiccv/src/arithmetics/multiply_neon.cpp index 561013db4dfad28239cbc03b7a9f84ff4ca18a6d..7fc29a2391d410cc20e6f482a454c30b60da4d2e 100644 --- a/intrinsiccv/src/arithmetics/multiply_neon.cpp +++ b/intrinsiccv/src/arithmetics/multiply_neon.cpp @@ -16,7 +16,7 @@ class SaturatingMultiply final : public UnrollTwice { using VecTraits = neon::VecTraits; using VectorType = typename VecTraits::VectorType; - SaturatingMultiply(double scale = 1.0) : scale_{scale} {}; + explicit SaturatingMultiply(double scale = 1.0) : scale_{scale} {}; VectorType vector_path(VectorType src_a, VectorType src_b) { VectorType result; @@ -48,16 +48,14 @@ class SaturatingMultiply final : public UnrollTwice { return (src_a < 0 && src_b > 0) || (src_a > 0 && src_b < 0) ? std::numeric_limits::min() : std::numeric_limits::max(); - } else { - return result; } + return result; } if (__builtin_mul_overflow(src_a, src_b, &result)) { return std::numeric_limits::max(); - } else { - return result; } + return result; } private: diff --git a/intrinsiccv/src/arithmetics/multiply_sve2.cpp b/intrinsiccv/src/arithmetics/multiply_sve2.cpp index eb9090b43f1f443e5b7a96891fe0644bc9d878d5..94ed60a7102b1d4a471a790eb3ff16d0bcd4fc74 100644 --- a/intrinsiccv/src/arithmetics/multiply_sve2.cpp +++ b/intrinsiccv/src/arithmetics/multiply_sve2.cpp @@ -14,7 +14,7 @@ class SaturatingMultiply final : public UnrollTwice { using VecTraits = sve2::VecTraits; using VectorType = typename VecTraits::VectorType; - SaturatingMultiply(double scale = 1.0) : scale_{scale} {}; + explicit SaturatingMultiply(double scale = 1.0) : scale_{scale} {}; VectorType vector_path(ContextType ctx, VectorType src_a, VectorType src_b) { VectorType result; diff --git a/intrinsiccv/src/arithmetics/scale_neon.cpp b/intrinsiccv/src/arithmetics/scale_neon.cpp index c5af029253b89dd9cd61951574079bd4947632a2..c8c531d2115ebb494c960508ef86bb53729c7246 100644 --- a/intrinsiccv/src/arithmetics/scale_neon.cpp +++ b/intrinsiccv/src/arithmetics/scale_neon.cpp @@ -53,19 +53,17 @@ namespace intrinsiccv::neon { template class ScaleBase : public UnrollTwice { public: - ScaleBase(float scale, float shift) { - scale_ = scale; - shift_ = shift; - } + ScaleBase(float scale, float shift) : scale_{scale}, shift_{shift} {} protected: static constexpr ScalarType ScalarMax = std::numeric_limits::max(); inline ScalarType scale_value(ScalarType value) { int64_t v = lrintf(value * scale_ + shift_); - ScalarType res = static_cast( - static_cast(v) <= ScalarMax ? v : (v > 0 ? ScalarMax : 0)); - return res; + if (static_cast(v) <= ScalarMax) { + return static_cast(v); + } + return static_cast(v > 0 ? ScalarMax : 0); } private: @@ -127,10 +125,10 @@ class ScaleFloat final : public ScaleBase { using VecTraits = neon::VecTraits; using VectorType = typename VecTraits::VectorType; - ScaleFloat(float scale, float shift) : ScaleBase(scale, shift) { - vscale_ = vdupq_n_f32(scale); - vshift_ = vdupq_n_f32(shift); - } + ScaleFloat(float scale, float shift) + : ScaleBase(scale, shift), + vscale_{vdupq_n_f32(scale)}, + vshift_{vdupq_n_f32(shift)} {} VectorType vector_path(VectorType src) { // For scaling, uint8 values have to be converted to uint32 diff --git a/intrinsiccv/src/arithmetics/threshold_neon.cpp b/intrinsiccv/src/arithmetics/threshold_neon.cpp index 3f6a43ca08bf2b895f18c778c59849e6becfa230..ff3332a9a8a308cee48efdfb36f179b9b56bc46a 100644 --- a/intrinsiccv/src/arithmetics/threshold_neon.cpp +++ b/intrinsiccv/src/arithmetics/threshold_neon.cpp @@ -14,11 +14,11 @@ class BinaryThreshold final : public UnrollTwice { using VectorType = typename VecTraits::VectorType; BinaryThreshold(ScalarType threshold, ScalarType value) - : threshold_(threshold), value_(value) { - threshold_vect_ = vdupq_n_u8(threshold); - value_vect_ = vdupq_n_u8(value); - zero_vect_ = vdupq_n_u8(0); - } + : threshold_vect_{vdupq_n_u8(threshold)}, + value_vect_{vdupq_n_u8(value)}, + zero_vect_{vdupq_n_u8(0)}, + threshold_{threshold}, + value_{value} {} VectorType vector_path(VectorType src) { VectorType predicate = vcgtq_u8(src, threshold_vect_); diff --git a/intrinsiccv/src/arithmetics/transpose_neon.cpp b/intrinsiccv/src/arithmetics/transpose_neon.cpp index c70742078d530378a81cdf80e70601ea6bbd3d75..94d367ee800cadf63dd7b074c01905cefd0c4808 100644 --- a/intrinsiccv/src/arithmetics/transpose_neon.cpp +++ b/intrinsiccv/src/arithmetics/transpose_neon.cpp @@ -216,9 +216,8 @@ void transpose(const void *src, size_t src_stride, void *dst, size_t dst_stride, if (src_width != src_height) { // Inplace transpose only implemented if width and height are the same return; - } else { - inplace = true; } + inplace = true; } switch (element_size) { diff --git a/intrinsiccv/src/conversions/gray_to_rgb_neon.cpp b/intrinsiccv/src/conversions/gray_to_rgb_neon.cpp index 81ae9e55cd8c8d6f8291309373430e643cab4a7d..a6682412f9008f44539180c2ae1bd1cb440619f2 100644 --- a/intrinsiccv/src/conversions/gray_to_rgb_neon.cpp +++ b/intrinsiccv/src/conversions/gray_to_rgb_neon.cpp @@ -14,11 +14,11 @@ class GrayToRGB final : public UnrollTwice { using VecTraits = neon::VecTraits; using VectorType = typename VecTraits::VectorType; - GrayToRGB() { #if !INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE - indices_ = vld1q_u8_x3(kGrayToRGBTableIndices); + GrayToRGB() : indices_{vld1q_u8_x3(kGrayToRGBTableIndices)} {} +#else + GrayToRGB() = default; #endif - } void vector_path(VectorType src_vect, ScalarType *dst) { uint8x16x3_t dst_vect; @@ -56,14 +56,15 @@ class GrayToRGBA final : public UnrollTwice { using VecTraits = neon::VecTraits; using VectorType = typename VecTraits::VectorType; - GrayToRGBA() { #if INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE - alpha = vdupq_n_u8(0xff); + GrayToRGBA() : alpha_{vdupq_n_u8(0xff)} {} #else - indices_ = vld1q_u8_x4(kGrayToRGBATableIndices); + // NOLINTBEGIN(hicpp-member-init) + GrayToRGBA() : indices_{vld1q_u8_x4(kGrayToRGBATableIndices)} { src_and_alpha_.val[1] = vdupq_n_u8(0xff); -#endif } + // NOLINTEND(hicpp-member-init) +#endif void vector_path(VectorType src_vect, ScalarType *dst) { uint8x16x4_t dst_vect; @@ -71,7 +72,7 @@ class GrayToRGBA final : public UnrollTwice { dst_vect.val[0] = src_vect; dst_vect.val[1] = src_vect; dst_vect.val[2] = src_vect; - dst_vect.val[3] = alpha; + dst_vect.val[3] = alpha_; vst4q_u8(dst, dst_vect); #else src_and_alpha_.val[0] = src_vect; @@ -90,7 +91,7 @@ class GrayToRGBA final : public UnrollTwice { private: #if INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE - uint8x16_t alpha; + uint8x16_t alpha_; #else uint8x16x4_t indices_; uint8x16x2_t src_and_alpha_; diff --git a/intrinsiccv/src/conversions/merge_neon.cpp b/intrinsiccv/src/conversions/merge_neon.cpp index 395db8068e44161ccb43177a4dfd6ad4eb6afd8f..d88154355b0d6578ed8256820fde6fd0bb5312b0 100644 --- a/intrinsiccv/src/conversions/merge_neon.cpp +++ b/intrinsiccv/src/conversions/merge_neon.cpp @@ -68,7 +68,7 @@ class Merge3 final : public UnrollTwice { using Vector3Type = typename VecTraits::Vector3Type; #if !INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE - Merge3() { table_indices_ = vld1q_u8_x3(lookup_table()); } + Merge3() : table_indices_{vld1q_u8_x3(lookup_table())} {} #endif void vector_path(VectorType src_a, VectorType src_b, VectorType src_c, @@ -407,20 +407,24 @@ void merge(const void **srcs, const size_t *src_strides, void *dst, switch (element_size) { default: case sizeof(uint8_t): - return merge(srcs, src_strides, dst, dst_stride, width, height, - channels); + merge(srcs, src_strides, dst, dst_stride, width, height, + channels); + break; case sizeof(uint16_t): - return merge(srcs, src_strides, dst, dst_stride, width, height, - channels); + merge(srcs, src_strides, dst, dst_stride, width, height, + channels); + break; case sizeof(uint32_t): - return merge(srcs, src_strides, dst, dst_stride, width, height, - channels); + merge(srcs, src_strides, dst, dst_stride, width, height, + channels); + break; case sizeof(uint64_t): - return merge(srcs, src_strides, dst, dst_stride, width, height, - channels); + merge(srcs, src_strides, dst, dst_stride, width, height, + channels); + break; } } diff --git a/intrinsiccv/src/conversions/rgb_to_rgb_neon.cpp b/intrinsiccv/src/conversions/rgb_to_rgb_neon.cpp index a85cb7b893937024ff7de509b02216266395d463..137150b4a14fa2126889b94e00e0fd781b3cf7f0 100644 --- a/intrinsiccv/src/conversions/rgb_to_rgb_neon.cpp +++ b/intrinsiccv/src/conversions/rgb_to_rgb_neon.cpp @@ -13,11 +13,11 @@ class RGBToBGR final : public UnrollTwice { public: using VecTraits = neon::VecTraits; - RGBToBGR() { #if !INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE - indices_ = vld1q_u8_x3(kRGBToBGRTableIndices); + RGBToBGR() : indices_{vld1q_u8_x3(kRGBToBGRTableIndices)} {} +#else + RGBToBGR() = default; #endif - } void vector_path(const ScalarType *src, ScalarType *dst) { #if INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE diff --git a/intrinsiccv/src/conversions/split_neon.cpp b/intrinsiccv/src/conversions/split_neon.cpp index d125c549126e912420d17657939be7bca9020445..df7ec9bf3e56931eb5f1c601cae4254677fa8adc 100644 --- a/intrinsiccv/src/conversions/split_neon.cpp +++ b/intrinsiccv/src/conversions/split_neon.cpp @@ -57,7 +57,9 @@ class Split3 final : public UnrollTwice { using VectorType = typename VecTraits::VectorType; #if !INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE + // NOLINTBEGIN(hicpp-member-init) Split3() { Split3Init(); } +// NOLINTEND(hicpp-member-init) #endif #if INTRINSICCV_PREFER_INTERLEAVING_LOAD_STORE @@ -196,10 +198,8 @@ class Split4 final : public UnrollTwice { reinterpret_cast >(vsrc.val[2]), reinterpret_cast >(vsrc.val[3])); - dst0 = vuzp1q(reinterpret_cast(halfway_unzipped_1), - reinterpret_cast(halfway_unzipped_2)); - dst1 = vuzp2q(reinterpret_cast(halfway_unzipped_1), - reinterpret_cast(halfway_unzipped_2)); + dst0 = vuzp1q(halfway_unzipped_1, halfway_unzipped_2); + dst1 = vuzp2q(halfway_unzipped_1, halfway_unzipped_2); halfway_unzipped_1 = vuzp2q( reinterpret_cast >(vsrc.val[0]), @@ -208,10 +208,8 @@ class Split4 final : public UnrollTwice { reinterpret_cast >(vsrc.val[2]), reinterpret_cast >(vsrc.val[3])); - dst2 = vuzp1q(reinterpret_cast(halfway_unzipped_1), - reinterpret_cast(halfway_unzipped_2)); - dst3 = vuzp2q(reinterpret_cast(halfway_unzipped_1), - reinterpret_cast(halfway_unzipped_2)); + dst2 = vuzp1q(halfway_unzipped_1, halfway_unzipped_2); + dst3 = vuzp2q(halfway_unzipped_1, halfway_unzipped_2); } #endif @@ -256,11 +254,11 @@ class Split4 final : public UnrollTwice { template void split(const void *src_data, const size_t src_stride, void **dst_data, - size_t *dst_strides, size_t width, size_t height, size_t channels) { + const size_t *dst_strides, size_t width, size_t height, + size_t channels) { Rectangle rect{width, height}; - ScalarType *dst0, *dst1; - dst0 = reinterpret_cast(dst_data[0]); - dst1 = reinterpret_cast(dst_data[1]); + ScalarType *dst0 = reinterpret_cast(dst_data[0]), + *dst1 = reinterpret_cast(dst_data[1]); Rows src_rows{ const_cast(reinterpret_cast(src_data)), src_stride, channels}; @@ -272,47 +270,51 @@ void split(const void *src_data, const size_t src_stride, void **dst_data, apply_operation_by_rows(operation, rect, src_rows, dst_rows0, dst_rows1); } break; case 3: { - ScalarType *dst2; - dst2 = reinterpret_cast(dst_data[2]); + ScalarType *dst2 = reinterpret_cast(dst_data[2]); Rows dst_rows2{dst2, dst_strides[2]}; Split3 operation; apply_operation_by_rows(operation, rect, src_rows, dst_rows0, dst_rows1, dst_rows2); } break; case 4: { - ScalarType *dst2, *dst3; - dst2 = reinterpret_cast(dst_data[2]); - dst3 = reinterpret_cast(dst_data[3]); + ScalarType *dst2 = reinterpret_cast(dst_data[2]), + *dst3 = reinterpret_cast(dst_data[3]); Rows dst_rows2{dst2, dst_strides[2]}; Rows dst_rows3{dst3, dst_strides[3]}; Split4 operation; apply_operation_by_rows(operation, rect, src_rows, dst_rows0, dst_rows1, dst_rows2, dst_rows3); } break; + default: + __builtin_trap(); } } INTRINSICCV_TARGET_FN_ATTRS void split(const void *src_data, size_t src_stride, void **dst_data, - size_t *dst_strides, size_t width, size_t height, size_t channels, - size_t element_size) { + const size_t *dst_strides, size_t width, size_t height, + size_t channels, size_t element_size) { switch (element_size) { default: case sizeof(uint8_t): - return split(src_data, src_stride, dst_data, dst_strides, width, - height, channels); + split(src_data, src_stride, dst_data, dst_strides, width, height, + channels); + break; case sizeof(uint16_t): - return split(src_data, src_stride, dst_data, dst_strides, width, - height, channels); + split(src_data, src_stride, dst_data, dst_strides, width, + height, channels); + break; case sizeof(uint32_t): - return split(src_data, src_stride, dst_data, dst_strides, width, - height, channels); + split(src_data, src_stride, dst_data, dst_strides, width, + height, channels); + break; case sizeof(uint64_t): - return split(src_data, src_stride, dst_data, dst_strides, width, - height, channels); + split(src_data, src_stride, dst_data, dst_strides, width, + height, channels); + break; } } } // namespace intrinsiccv::neon diff --git a/intrinsiccv/src/conversions/yuv_to_rgb_neon.cpp b/intrinsiccv/src/conversions/yuv_to_rgb_neon.cpp index 79b34ff534f672c22706767602db4adeaea4ea4d..d62006dee0f4c1fe35fa29720098d561e3b24e2c 100644 --- a/intrinsiccv/src/conversions/yuv_to_rgb_neon.cpp +++ b/intrinsiccv/src/conversions/yuv_to_rgb_neon.cpp @@ -15,17 +15,19 @@ class YUVSpToRGBxOrBGRx final : public UnrollOnce { using ScalarType = VecTraits::ScalarType; using VectorType = VecTraits::VectorType; - YUVSpToRGBxOrBGRx(bool is_nv21) : is_nv21_(is_nv21) { - y_weight_ = vdupq_n_s32(kYWeight); - uv_weights_ = vld2_s32(kUVWeights); - // Both the rounding shift right constant and the -128 value are included. - r_base_ = vdupq_n_s32((1L << (kWeightScale - 1)) - - 128 * kUVWeights[kRVWeightIndex]); - g_base_ = vdupq_n_s32((1L << (kWeightScale - 1)) - - 128 * (kUVWeights[1] + kUVWeights[2])); - b_base_ = vdupq_n_s32((1L << (kWeightScale - 1)) - 128 * kUVWeights[3]); - de_interleave_indices_ = vld1q_s8_x4(kDeInterleaveTableIndices); - } + explicit YUVSpToRGBxOrBGRx(bool is_nv21) + : y_weight_{vdupq_n_s32(kYWeight)}, + uv_weights_{vld2_s32(kUVWeights)}, + // Both the rounding shift right constant and the -128 value are + // included. + r_base_{vdupq_n_s32(static_cast(1 << (kWeightScale - 1)) - + 128 * kUVWeights[kRVWeightIndex])}, + g_base_{vdupq_n_s32(static_cast(1 << (kWeightScale - 1)) - + 128 * (kUVWeights[1] + kUVWeights[2]))}, + b_base_{vdupq_n_s32(static_cast(1 << (kWeightScale - 1)) - + 128 * kUVWeights[3])}, + de_interleave_indices_{vld1q_s8_x4(kDeInterleaveTableIndices)}, + is_nv21_(is_nv21) {} // Returns the number of channels in the output image. static constexpr size_t output_channels() { @@ -207,7 +209,10 @@ class YUVSpToRGBxOrBGRx final : public UnrollOnce { const uint8_t *y_rows[2] = {y_row_0, y_row_1}; uint8_t *rgbx_rows[2] = {rgbx_row_0, rgbx_row_1}; + // These are set near the start of the first loop. + // NOLINTBEGIN(cppcoreguidelines-init-variables) int32_t u_m128, v_m128; + // NOLINTEND(cppcoreguidelines-init-variables) for (size_t index = 0; index < length; ++index) { disable_loop_vectorization(); diff --git a/intrinsiccv/src/conversions/yuv_to_rgb_sc.h b/intrinsiccv/src/conversions/yuv_to_rgb_sc.h index f36fafbd93dd081d0ee25393baa725a93cacbc5c..e81ac51e09ccb22a3a177e846ae6b5a395a2c832 100644 --- a/intrinsiccv/src/conversions/yuv_to_rgb_sc.h +++ b/intrinsiccv/src/conversions/yuv_to_rgb_sc.h @@ -19,7 +19,7 @@ class YUVSpToRGBxOrBGRx final { using ContextType = sve2::Context; using VecTraits = sve2::VecTraits; - YUVSpToRGBxOrBGRx(bool is_nv21) INTRINSICCV_STREAMING_COMPATIBLE + explicit YUVSpToRGBxOrBGRx(bool is_nv21) INTRINSICCV_STREAMING_COMPATIBLE : is_nv21_(is_nv21) {} // Returns the number of channels in the output image. @@ -36,12 +36,11 @@ class YUVSpToRGBxOrBGRx final { auto pg = ctx.predicate(); // Both the rounding shift right constant and the -128 value are included. - svint32_t r_base = svdup_s32((1L << (kWeightScale - 1)) - - 128 * kUVWeights[kRVWeightIndex]); - svint32_t g_base = svdup_s32((1L << (kWeightScale - 1)) - - 128 * (kUVWeights[1] + kUVWeights[2])); - svint32_t b_base = - svdup_s32((1L << (kWeightScale - 1)) - 128 * kUVWeights[3]); + constexpr int32_t kOffset = 1 << (kWeightScale - 1); + svint32_t r_base = svdup_s32(kOffset - 128 * kUVWeights[kRVWeightIndex]); + svint32_t g_base = + svdup_s32(kOffset - 128 * (kUVWeights[1] + kUVWeights[2])); + svint32_t b_base = svdup_s32(kOffset - 128 * kUVWeights[3]); // Load channels: y0 and y1 are two adjacent rows. svuint8_t y0 = svld1(pg, y_row_0); diff --git a/intrinsiccv/src/filters/gaussian_blur_api.cpp b/intrinsiccv/src/filters/gaussian_blur_api.cpp index 8d59c6ce5e94458626d6025da496a4fc0edcb65d..bd693eccf6075b3524b812948625bef7d923a78c 100644 --- a/intrinsiccv/src/filters/gaussian_blur_api.cpp +++ b/intrinsiccv/src/filters/gaussian_blur_api.cpp @@ -28,8 +28,12 @@ void INTRINSICCV_C_API(filter_release)(intrinsiccv_filter_params_t *params) { return; } + // Deliberately create and immediately destroy a unique_ptr to delete the + // workspace. + // NOLINTBEGIN(bugprone-unused-raii) SeparableFilterWorkspace::Pointer{ reinterpret_cast(params->workspace)}; + // NOLINTEND(bugprone-unused-raii) params->workspace = nullptr; } diff --git a/intrinsiccv/src/filters/gaussian_blur_neon.cpp b/intrinsiccv/src/filters/gaussian_blur_neon.cpp index 4e29acd38711dce598c43134cc32fbde8ea1ba94..7e8e24badbf908ddf4e5a9da96b96a728632b6ee 100644 --- a/intrinsiccv/src/filters/gaussian_blur_neon.cpp +++ b/intrinsiccv/src/filters/gaussian_blur_neon.cpp @@ -47,7 +47,7 @@ class DiscreteGaussianBlur { // Applies vertical filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2 ] * [ 1, 2, 1 ]T - void vertical_scalar_path(SourceType src[3], BufferType *dst) const { + void vertical_scalar_path(const SourceType src[3], BufferType *dst) const { dst[0] = src[0] + 2 * src[1] + src[2]; } @@ -65,7 +65,8 @@ class DiscreteGaussianBlur { // Applies horizontal filtering vector using scalar operations. // // DST = 1/16 * [ SRC0, SRC1, SRC2 ] * [ 1, 2, 1 ]T - void horizontal_scalar_path(BufferType src[3], DestinationType *dst) const { + void horizontal_scalar_path(const BufferType src[3], + DestinationType *dst) const { auto acc = src[0] + 2 * src[1] + src[2]; dst[0] = rounding_shift_right(acc, 4); } @@ -86,11 +87,10 @@ class DiscreteGaussianBlur { using BufferType = uint16_t; using DestinationType = uint8_t; - DiscreteGaussianBlur() { - const_6_u8_ = vmov_n_u8(6); - const_6_u16_ = vmovq_n_u16(6); - const_4_u16_ = vmovq_n_u16(4); - } + DiscreteGaussianBlur() + : const_6_u8_{vmov_n_u8(6)}, + const_6_u16_{vmovq_n_u16(6)}, + const_4_u16_{vmovq_n_u16(4)} {} // Applies vertical filtering vector using SIMD operations. // @@ -111,7 +111,7 @@ class DiscreteGaussianBlur { // Applies vertical filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2, SRC3, SRC4 ] * [ 1, 4, 6, 4, 1 ]T - void vertical_scalar_path(SourceType src[5], BufferType *dst) const { + void vertical_scalar_path(const SourceType src[5], BufferType *dst) const { dst[0] = src[0] + src[4] + 4 * (src[1] + src[3]) + 6 * src[2]; } @@ -130,7 +130,8 @@ class DiscreteGaussianBlur { // Applies horizontal filtering vector using scalar operations. // // DST = 1/256 * [ SRC0, SRC1, SRC2, SRC3, SRC4 ] * [ 1, 4, 6, 4, 1 ]T - void horizontal_scalar_path(BufferType src[5], DestinationType *dst) const { + void horizontal_scalar_path(const BufferType src[5], + DestinationType *dst) const { auto acc = src[0] + src[4] + 4 * (src[1] + src[3]) + 6 * src[2]; dst[0] = rounding_shift_right(acc, 8); } @@ -153,7 +154,7 @@ void discrete_gaussian_blur(const ScalarType *src, size_t src_stride, Rows src_rows{src, src_stride, channels}; Rows dst_rows{dst, dst_stride, channels}; - auto workspace = + auto *workspace = reinterpret_cast(params->workspace); GaussianBlurFilterType blur; diff --git a/intrinsiccv/src/filters/gaussian_blur_sc.h b/intrinsiccv/src/filters/gaussian_blur_sc.h index dbd83f763645d3e2bd1ad338b1994c67dd689a12..c31319deaac9e24629395b572903282c9172da0e 100644 --- a/intrinsiccv/src/filters/gaussian_blur_sc.h +++ b/intrinsiccv/src/filters/gaussian_blur_sc.h @@ -75,8 +75,8 @@ class DiscreteGaussianBlur { // Applies horizontal filtering vector using scalar operations. // // DST = 1/256 * [ SRC0, SRC1, SRC2, SRC3, SRC4 ] * [ 1, 4, 6, 4, 1 ]T - void horizontal_scalar_path(BufferType src[5], DestinationType *dst) const - INTRINSICCV_STREAMING_COMPATIBLE { + void horizontal_scalar_path(const BufferType src[5], DestinationType *dst) + const INTRINSICCV_STREAMING_COMPATIBLE { auto acc = src[0] + src[4] + 4 * (src[1] + src[3]) + 6 * src[2]; dst[0] = rounding_shift_right(acc, 8); } @@ -95,7 +95,7 @@ void discrete_gaussian_blur(const ScalarType *src, size_t src_stride, Rows src_rows{src, src_stride, channels}; Rows dst_rows{dst, dst_stride, channels}; - auto workspace = + auto *workspace = reinterpret_cast(params->workspace); GaussianBlurFilterType blur; diff --git a/intrinsiccv/src/filters/sobel_neon.cpp b/intrinsiccv/src/filters/sobel_neon.cpp index 820c2b0d86c750b98a2d46363e7b91598082cd74..8a6df5a30503a9ae343444262db8738e0d0a1fdc 100644 --- a/intrinsiccv/src/filters/sobel_neon.cpp +++ b/intrinsiccv/src/filters/sobel_neon.cpp @@ -44,8 +44,9 @@ class HorizontalSobel3x3 { // Applies vertical filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2 ] * [ 1, 2, 1 ]T - void vertical_scalar_path(SourceType src[3], BufferType *dst) const { - dst[0] = src[0] + 2 * src[1] + src[2]; + void vertical_scalar_path(const SourceType src[3], BufferType *dst) const { + // Explicitly narrow. Overflow is permitted. + dst[0] = static_cast(src[0] + 2 * src[1] + src[2]); } // Applies horizontal filtering vector using SIMD operations. @@ -58,8 +59,10 @@ class HorizontalSobel3x3 { // Applies horizontal filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2 ] * [ -1, 0, 1 ]T - void horizontal_scalar_path(BufferType src[3], DestinationType *dst) const { - dst[0] = src[2] - src[0]; + void horizontal_scalar_path(const BufferType src[3], + DestinationType *dst) const { + // Explicitly narrow. Overflow is permitted. + dst[0] = static_cast(src[2] - src[0]); } }; // end of class HorizontalSobel3x3 @@ -95,8 +98,9 @@ class VerticalSobel3x3 { // Applies vertical filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2 ] * [ -1, 0, 1 ]T - void vertical_scalar_path(SourceType src[3], BufferType *dst) const { - dst[0] = src[2] - src[0]; + void vertical_scalar_path(const SourceType src[3], BufferType *dst) const { + // Explicitly narrow. Overflow is permitted. + dst[0] = static_cast(src[2] - src[0]); } // Applies horizontal filtering vector using SIMD operations. @@ -111,8 +115,10 @@ class VerticalSobel3x3 { // Applies horizontal filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2 ] * [ 1, 2, 1 ]T - void horizontal_scalar_path(BufferType src[3], DestinationType *dst) const { - dst[0] = src[0] + 2 * src[1] + src[2]; + void horizontal_scalar_path(const BufferType src[3], + DestinationType *dst) const { + // Explicitly narrow. Overflow is permitted. + dst[0] = static_cast(src[0] + 2 * src[1] + src[2]); } }; // end of class VerticalSobel3x3 diff --git a/intrinsiccv/src/filters/sobel_sc.h b/intrinsiccv/src/filters/sobel_sc.h index d3c172f56c5c8a45878f0db20c3c0afaaea1322c..2273d232b979ca12616f250eb96b82c6cc531b09 100644 --- a/intrinsiccv/src/filters/sobel_sc.h +++ b/intrinsiccv/src/filters/sobel_sc.h @@ -57,9 +57,10 @@ class HorizontalSobel3x3 { // Applies horizontal filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2 ] * [ -1, 0, 1 ]T - void horizontal_scalar_path(BufferType src[3], DestinationType *dst) const - INTRINSICCV_STREAMING_COMPATIBLE { - dst[0] = src[2] - src[0]; + void horizontal_scalar_path(const BufferType src[3], DestinationType *dst) + const INTRINSICCV_STREAMING_COMPATIBLE { + // Explicitly narrow. Overflow is permitted. + dst[0] = static_cast(src[2] - src[0]); } }; // end of class HorizontalSobel3x3 @@ -109,9 +110,10 @@ class VerticalSobel3x3 { // Applies horizontal filtering vector using scalar operations. // // DST = [ SRC0, SRC1, SRC2 ] * [ 1, 2, 1 ]T - void horizontal_scalar_path(BufferType src[3], DestinationType *dst) const - INTRINSICCV_STREAMING_COMPATIBLE { - dst[0] = src[0] + 2 * src[1] + src[2]; + void horizontal_scalar_path(const BufferType src[3], DestinationType *dst) + const INTRINSICCV_STREAMING_COMPATIBLE { + // Explicitly narrow. Overflow is permitted. + dst[0] = static_cast(src[0] + 2 * src[1] + src[2]); } }; // end of class VerticalSobel3x3 diff --git a/intrinsiccv/src/morphology/morphology_api.cpp b/intrinsiccv/src/morphology/morphology_api.cpp index cd6cdbf89679e6dbd46bada8427e3c018a007bd8..086ad6a1817a8f553147b4e622b298c6a81f70c1 100644 --- a/intrinsiccv/src/morphology/morphology_api.cpp +++ b/intrinsiccv/src/morphology/morphology_api.cpp @@ -72,8 +72,12 @@ void INTRINSICCV_C_API(morphology_release)( return; } + // Deliberately create and immediately destroy a unique_ptr to delete the + // workspace. + // NOLINTBEGIN(bugprone-unused-raii) MorphologyWorkspace::Pointer{ reinterpret_cast(params->data)}; + // NOLINTEND(bugprone-unused-raii) params->data = nullptr; } diff --git a/intrinsiccv/src/morphology/morphology_neon.cpp b/intrinsiccv/src/morphology/morphology_neon.cpp index eab1d0b40cf2a7c593e9c680718806097b70eafd..a0850a8a708d2d166bd64479fc92a7d094de37e6 100644 --- a/intrinsiccv/src/morphology/morphology_neon.cpp +++ b/intrinsiccv/src/morphology/morphology_neon.cpp @@ -56,10 +56,7 @@ class VerticalOp final { void vector_path_4x(IndirectRows src_rows, Rows dst_rows, const size_t index, const size_t height) { - const ScalarType *src_row; - ScalarType *dst_row; - - src_row = &src_rows[index]; + const ScalarType *src_row = &src_rows[index]; auto first_row0 = vld1q(&src_row[0 * VecTraits::num_lanes()]); auto first_row1 = vld1q(&src_row[1 * VecTraits::num_lanes()]); auto first_row2 = vld1q(&src_row[2 * VecTraits::num_lanes()]); @@ -119,7 +116,7 @@ class VerticalOp final { acc3 = O::operation(acc3, first_row3); // Store the results. - dst_row = &dst_rows[index]; + ScalarType *dst_row = &dst_rows[index]; vst1q(&dst_row[0 * VecTraits::num_lanes()], acc0); vst1q(&dst_row[1 * VecTraits::num_lanes()], acc1); vst1q(&dst_row[2 * VecTraits::num_lanes()], acc2); @@ -153,10 +150,7 @@ class VerticalOp final { void vector_path_2x(IndirectRows src_rows, Rows dst_rows, const size_t index, const size_t height) { - const ScalarType *src_row; - ScalarType *dst_row; - - src_row = &src_rows[index]; + const ScalarType *src_row = &src_rows[index]; auto first_row0 = vld1q(&src_row[0]); auto first_row1 = vld1q(&src_row[VecTraits::num_lanes()]); ++src_rows; @@ -198,7 +192,7 @@ class VerticalOp final { acc1 = O::operation(acc1, first_row1); // Store the results. - dst_row = &dst_rows[index]; + ScalarType *dst_row = &dst_rows[index]; vst1q(&dst_row[0], acc0); vst1q(&dst_row[VecTraits::num_lanes()], acc1); @@ -353,7 +347,7 @@ class HorizontalOp final { private: void vector_path_4x(Rows src_rows, Rows dst_rows, const size_t index) { - auto src_row = &src_rows[index]; + const auto *src_row = &src_rows[index]; auto acc0 = vld1q(&src_row[0 * VecTraits::num_lanes()]); auto acc1 = vld1q(&src_row[1 * VecTraits::num_lanes()]); auto acc2 = vld1q(&src_row[2 * VecTraits::num_lanes()]); @@ -380,7 +374,7 @@ class HorizontalOp final { void vector_path_2x(Rows src_rows, Rows dst_rows, const size_t index) { - auto src_row = &src_rows[index]; + const auto *src_row = &src_rows[index]; auto acc0 = vld1q(&src_row[0]); auto acc1 = vld1q(&src_row[VecTraits::num_lanes()]); @@ -403,7 +397,7 @@ class HorizontalOp final { for (size_t width = 1; width < kernel_.width(); ++width) { // TODO: Check if EXT was any faster. - auto src_row = &src_rows[index + width * src_rows.channels()]; + const auto *src_row = &src_rows[index + width * src_rows.channels()]; acc = O::operation(acc, vld1q(&src_row[0])); } @@ -503,7 +497,7 @@ void dilate(const T *src, size_t src_stride, T *dst, size_t dst_stride, Margin margin{params->kernel, params->anchor}; Border border{params->border_values}; - auto workspace = reinterpret_cast(params->data); + auto *workspace = reinterpret_cast(params->data); Rows current_src_rows = src_rows; Rows current_dst_rows = dst_rows; @@ -553,7 +547,7 @@ void erode(const T *src, size_t src_stride, T *dst, size_t dst_stride, Margin margin{params->kernel, params->anchor}; Border border{params->border_values}; - auto workspace = reinterpret_cast(params->data); + auto *workspace = reinterpret_cast(params->data); Rows current_src_rows = src_rows; Rows current_dst_rows = dst_rows; diff --git a/intrinsiccv/src/morphology/morphology_sc.h b/intrinsiccv/src/morphology/morphology_sc.h index 1ca0201cd4e839a39ccf1eee19196f80271c6245..40112c02dc019bd9f4a029b82b831398767629ec 100644 --- a/intrinsiccv/src/morphology/morphology_sc.h +++ b/intrinsiccv/src/morphology/morphology_sc.h @@ -63,10 +63,7 @@ class VerticalOp final { void vector_path_4x(IndirectRows src_rows, Rows dst_rows, const size_t index, const size_t height) INTRINSICCV_STREAMING_COMPATIBLE { - const ScalarType *src_row; - ScalarType *dst_row; - - src_row = &src_rows[index]; + const ScalarType *src_row = &src_rows[index]; auto first_row0 = svld1(VecTraits::svptrue(), &src_row[0]); auto first_row1 = svld1_vnum(VecTraits::svptrue(), &src_row[0], 1); auto first_row2 = svld1_vnum(VecTraits::svptrue(), &src_row[0], 2); @@ -131,7 +128,7 @@ class VerticalOp final { acc3 = O::operation(VecTraits::svptrue(), acc3, first_row3); // Store the results. - dst_row = &dst_rows[index]; + ScalarType *dst_row = &dst_rows[index]; svst1(VecTraits::svptrue(), &dst_row[0], acc0); svst1_vnum(VecTraits::svptrue(), &dst_row[0], 1, acc1); svst1_vnum(VecTraits::svptrue(), &dst_row[0], 2, acc2); @@ -166,10 +163,7 @@ class VerticalOp final { void vector_path_2x(IndirectRows src_rows, Rows dst_rows, const size_t index, const size_t height) INTRINSICCV_STREAMING_COMPATIBLE { - const ScalarType *src_row; - ScalarType *dst_row; - - src_row = &src_rows[index]; + const ScalarType *src_row = &src_rows[index]; auto first_row0 = svld1(VecTraits::svptrue(), &src_row[0]); auto first_row1 = svld1_vnum(VecTraits::svptrue(), &src_row[0], 1); ++src_rows; @@ -214,7 +208,7 @@ class VerticalOp final { acc1 = O::operation(VecTraits::svptrue(), acc1, first_row1); // Store the results. - dst_row = &dst_rows[index]; + ScalarType *dst_row = &dst_rows[index]; svst1(VecTraits::svptrue(), &dst_row[0], acc0); svst1_vnum(VecTraits::svptrue(), &dst_row[0], 1, acc1); @@ -329,7 +323,7 @@ class HorizontalOp final { void vector_path_4x(Rows src_rows, Rows dst_rows, const size_t index) INTRINSICCV_STREAMING_COMPATIBLE { - auto src_row = &src_rows[index]; + const auto *src_row = &src_rows[index]; auto acc0 = svld1(VecTraits::svptrue(), &src_row[0]); auto acc1 = svld1_vnum(VecTraits::svptrue(), &src_row[0], 1); auto acc2 = svld1_vnum(VecTraits::svptrue(), &src_row[0], 2); @@ -357,7 +351,7 @@ class HorizontalOp final { void vector_path_2x(Rows src_rows, Rows dst_rows, const size_t index) INTRINSICCV_STREAMING_COMPATIBLE { - auto src_row = &src_rows[index]; + const auto *src_row = &src_rows[index]; auto acc0 = svld1(VecTraits::svptrue(), &src_row[0]); auto acc1 = svld1_vnum(VecTraits::svptrue(), &src_row[0], 1); @@ -380,7 +374,7 @@ class HorizontalOp final { auto acc = svld1(pg, &src_rows[index]); for (size_t width = 1; width < kernel_.width(); ++width) { - auto src_row = &src_rows[index + width * src_rows.channels()]; + const auto *src_row = &src_rows[index + width * src_rows.channels()]; acc = O::operation(pg, acc, svld1(pg, &src_row[0])); } @@ -465,7 +459,7 @@ static inline void dilate_sc(const T *src, size_t src_stride, T *dst, Margin margin{params->kernel, params->anchor}; Border border{params->border_values}; - auto workspace = reinterpret_cast(params->data); + auto *workspace = reinterpret_cast(params->data); Rows current_src_rows = src_rows; Rows current_dst_rows = dst_rows; @@ -519,7 +513,7 @@ static inline void erode_sc(const T *src, size_t src_stride, T *dst, Margin margin{params->kernel, params->anchor}; Border border{params->border_values}; - auto workspace = reinterpret_cast(params->data); + auto *workspace = reinterpret_cast(params->data); Rows current_src_rows = src_rows; Rows current_dst_rows = dst_rows; diff --git a/intrinsiccv/src/resize/resize_sc.h b/intrinsiccv/src/resize/resize_sc.h index 1e417114e5dd6ba7b4a56b5704f6c94e503a6fee..9c3834fa2794ec11aab3bbef40e4ea220c233913 100644 --- a/intrinsiccv/src/resize/resize_sc.h +++ b/intrinsiccv/src/resize/resize_sc.h @@ -48,7 +48,7 @@ static inline void process_parallel_rows( Rows dst_rows, size_t dst_width) INTRINSICCV_STREAMING_COMPATIBLE { using VecTraits = sve2::VecTraits; - const size_t size_mask = ~static_cast(1u); + const size_t size_mask = ~static_cast(1U); // Process rows up to the last even pixel index. LoopUnroll2{src_width & size_mask, VecTraits::num_lanes()} @@ -110,7 +110,7 @@ static inline void process_single_row( Rows dst_rows, size_t dst_width) INTRINSICCV_STREAMING_COMPATIBLE { using VecTraits = sve2::VecTraits; - const size_t size_mask = ~static_cast(1u); + const size_t size_mask = ~static_cast(1U); // Process rows up to the last even pixel index. LoopUnroll2{src_width & size_mask, VecTraits::num_lanes()} diff --git a/test/.clang-tidy b/test/.clang-tidy new file mode 100644 index 0000000000000000000000000000000000000000..d20fd7f7feb2eee6b90f49d61b84fce8aca235c1 --- /dev/null +++ b/test/.clang-tidy @@ -0,0 +1,14 @@ +# SPDX-FileCopyrightText: 2024 Arm Limited and/or its affiliates +# +# SPDX-License-Identifier: Apache-2.0 + +--- +# Modify default clang-tidy settings for test code. +# * GTEST macros have a lot of conditionals that means even trivial +# tests will exceed the cognitive complexity limit. +# * Using endl is fine in test code. +Checks: >- + -readability-function-cognitive-complexity, + -performance-avoid-endl +InheritParentConfig: true +... diff --git a/test/api/test_min_max.cpp b/test/api/test_min_max.cpp index 811a8493dee93d501d0d492f9964cfadcbf46a73..aa3306573afb0d9938ce1284d98e959e45a5225c 100644 --- a/test/api/test_min_max.cpp +++ b/test/api/test_min_max.cpp @@ -191,12 +191,20 @@ class MinMaxTest { void one_test_call(const ArrayType& source, ElementType* p_min, ElementType* p_max, ElementType expected_min, ElementType expected_max) { - if (p_min) *p_min = std::numeric_limits::max(); - if (p_max) *p_max = std::numeric_limits::min(); + if (p_min) { + *p_min = std::numeric_limits::max(); + } + if (p_max) { + *p_max = std::numeric_limits::min(); + } min_max()(source.data(), source.stride(), width(), height(), p_min, p_max); - if (p_min) EXPECT_EQ(*p_min, expected_min); - if (p_max) EXPECT_EQ(*p_max, expected_max); + if (p_min) { + EXPECT_EQ(*p_min, expected_min); + } + if (p_max) { + EXPECT_EQ(*p_max, expected_max); + } } public: @@ -229,12 +237,20 @@ class MinMaxLocTest : public MinMaxTest { void one_test_call(const ArrayType& source, size_t* p_min_offset, size_t* p_max_offset, size_t expected_min_offset, size_t expected_max_offset) { - if (p_min_offset) *p_min_offset = std::numeric_limits::max(); - if (p_max_offset) *p_max_offset = std::numeric_limits::max(); + if (p_min_offset) { + *p_min_offset = std::numeric_limits::max(); + } + if (p_max_offset) { + *p_max_offset = std::numeric_limits::max(); + } min_max_loc()(source.data(), source.stride(), width(), height(), p_min_offset, p_max_offset); - if (p_min_offset) EXPECT_EQ(*p_min_offset, expected_min_offset); - if (p_max_offset) EXPECT_EQ(*p_max_offset, expected_max_offset); + if (p_min_offset) { + EXPECT_EQ(*p_min_offset, expected_min_offset); + } + if (p_max_offset) { + EXPECT_EQ(*p_max_offset, expected_max_offset); + } } public: @@ -245,7 +261,7 @@ class MinMaxLocTest : public MinMaxTest { setup(source, testData); - size_t min_offset, max_offset; + size_t min_offset = 0, max_offset = 0; one_test_call(source, nullptr, nullptr, 0, 0); one_test_call(source, &min_offset, nullptr, testData.expected_min_offset, 0); diff --git a/test/api/test_rgb_and_gray.cpp b/test/api/test_rgb_and_gray.cpp index 6395cf3d0bd6508525a39698ac960fd9466e0a09..c38dc91806eee019bda999e3bcbf2d5969db4644 100644 --- a/test/api/test_rgb_and_gray.cpp +++ b/test/api/test_rgb_and_gray.cpp @@ -10,9 +10,8 @@ class GrayTest final { public: - GrayTest(bool hasAlpha) : hasAlpha_(hasAlpha) { - outChannels_ = hasAlpha_ ? 4 : 3; - } + explicit GrayTest(bool hasAlpha) + : hasAlpha_(hasAlpha), outChannels_{hasAlpha ? 4U : 3U} {} template void execute_test(F impl) { @@ -37,7 +36,7 @@ class GrayTest final { private: void calculate_expected(test::Array2D &src, - test::Array2D &expected) { + test::Array2D &expected) const { for (size_t vindex = 0; vindex < expected.height(); vindex++) { for (size_t hindex = 0; hindex < expected.width() / outChannels_; hindex++) { @@ -88,7 +87,7 @@ class ColourTest final { private: void calculate_expected(test::Array2D &src, - test::Array2D &expected) { + test::Array2D &expected) const { for (size_t vindex = 0; vindex < expected.height(); vindex++) { for (size_t hindex = 0; hindex < expected.width() / outChannels_; hindex++) { diff --git a/test/api/test_yuv_to_rgb.cpp b/test/api/test_yuv_to_rgb.cpp index 931695a9ab9e1be8c8230fcee9c9d9669f9a459e..d0c14332ed8ea1777259a4ca62573b1bfb24c4d9 100644 --- a/test/api/test_yuv_to_rgb.cpp +++ b/test/api/test_yuv_to_rgb.cpp @@ -64,7 +64,7 @@ class YuvTest final { void calculate_expected(test::Array2D &y_arr, test::Array2D &uv_arr, - test::Array2D &exp_arr, bool is_nv21) { + test::Array2D &exp_arr, bool is_nv21) const { for (size_t vindex = 0; vindex < exp_arr.height(); vindex++) { for (size_t hindex = 0; hindex < exp_arr.width() / channel_number_; hindex++) { diff --git a/test/framework/abstract.h b/test/framework/abstract.h index 15156e153117c69fb383900919c0b08541c05521..700ea98934109d12d4aa40730649ba9235237192 100644 --- a/test/framework/abstract.h +++ b/test/framework/abstract.h @@ -23,7 +23,7 @@ class TwoDimensional { virtual size_t height() const = 0; /// Returns the number of channels. - virtual size_t channels() const { return 1ul; } + virtual size_t channels() const { return 1UL; } /// Returns a pointer to a data element at a given row and column position, or /// nullptr if the requested position is invalid. diff --git a/test/framework/array.h b/test/framework/array.h index 4a566053a2bed828c86bfe67320d73eec98228e1..be1f75948288aa0559c8f2f2e6b0402ccc547681 100644 --- a/test/framework/array.h +++ b/test/framework/array.h @@ -47,17 +47,19 @@ class Array2D : public TwoDimensional { } /// Destructor checks that padding bytes are not overwritten. - ~Array2D() { check_padding(); } + ~Array2D() override { check_padding(); } /// Copy constructor. Array2D(const Array2D &other) { this->operator=(other); } /// Move constructor. - Array2D(Array2D &&other) { this->operator=(other); } + Array2D(Array2D &&other) noexcept { this->operator=(other); } /// Copy assignment operator. Array2D &operator=(const Array2D &other) { - if (this == &other) return *this; + if (this == &other) { + return *this; + } width_ = other.width_; height_ = other.height_; channels_ = other.channels_; @@ -74,8 +76,10 @@ class Array2D : public TwoDimensional { } /// Move assignment operator. - Array2D &operator=(Array2D &&other) { - if (this == &other) return *this; + Array2D &operator=(Array2D &&other) noexcept { + if (this == &other) { + return *this; + } data_ = std::move(other.data_); width_ = other.width_; height_ = other.height_; @@ -111,7 +115,9 @@ class Array2D : public TwoDimensional { for (size_t column = 0; column < width(); ++column) { std::optional optional_value = generator->next(); ASSERT_NE(optional_value, std::nullopt); - ptr[column] = optional_value.value(); + if (optional_value.has_value()) { + ptr[column] = optional_value.value(); + } } ptr = add_stride(ptr, 1); diff --git a/test/framework/operation.h b/test/framework/operation.h index d372f8dc2d05d58fe44be1f2b60318776660b5a0..91dcedf21547f26f4e1de09ce3dbee23e3bd3be9 100644 --- a/test/framework/operation.h +++ b/test/framework/operation.h @@ -24,7 +24,7 @@ class OperationTest { ElementType values[InputsSize + OutputsSize]; }; // end of struct Elements - virtual ~OperationTest() {} + virtual ~OperationTest() = default; /// Sets the number of padding bytes at the end of rows. OperationTest& with_padding( diff --git a/test/framework/test_array2d.cpp b/test/framework/test_array2d.cpp index adbeaa7cdeaf120b2aff9625b7ad4222bbc00b6c..84a83350e2e8fece5a40d1f4d701f410995a31ce 100644 --- a/test/framework/test_array2d.cpp +++ b/test/framework/test_array2d.cpp @@ -77,13 +77,15 @@ TEST(Array2D, MoveAssignment) { // This test is specifically to find out what happens to an object after it is // moved so disable this static analysis check. - // NOLINTBEGIN(clang-analyzer-cplusplus.Move) + // NOLINTBEGIN(clang-analyzer-cplusplus.Move, bugprone-use-after-move, + // hicpp-invalid-access-moved) EXPECT_EQ(array_1.width(), 0); EXPECT_EQ(array_1.height(), 0); EXPECT_EQ(array_1.channels(), 0); EXPECT_EQ(array_1.stride(), 0); EXPECT_FALSE(array_1.valid()); - // NOLINTEND(clang-analyzer-cplusplus.Move) + // NOLINTEND(clang-analyzer-cplusplus.Move, bugprone-use-after-move, + // hicpp-invalid-access-moved) } /// Tests that test::Array2D.at() works for set/get. diff --git a/test/framework/test_generator.cpp b/test/framework/test_generator.cpp index a46b036a683427fd77a3539069a8cee97dac66a7..fba3ac2a30e3b9a2ebdddf840749a94f2a30de9f 100644 --- a/test/framework/test_generator.cpp +++ b/test/framework/test_generator.cpp @@ -14,10 +14,10 @@ TEST(PseudoRandomNumberGenerator, Reset) { using ElementType = uint8_t; test::PseudoRandomNumberGenerator generator; - ElementType initial_value = generator.next().value(); + ElementType initial_value = generator.next().value_or(123); generator.next(); generator.reset(); - ElementType value = generator.next().value(); + ElementType value = generator.next().value_or(234); EXPECT_EQ(initial_value, value); } @@ -27,11 +27,11 @@ TEST(SequenceGenerator, Reset) { std::array array{1, 2, 3}; test::SequenceGenerator generator{array}; - EXPECT_EQ(generator.next().value(), 1); - EXPECT_EQ(generator.next().value(), 2); - EXPECT_EQ(generator.next().value(), 3); + EXPECT_EQ(generator.next().value_or(0), 1); + EXPECT_EQ(generator.next().value_or(0), 2); + EXPECT_EQ(generator.next().value_or(0), 3); EXPECT_EQ(generator.next(), std::nullopt); generator.reset(); - EXPECT_EQ(generator.next().value(), 1); + EXPECT_EQ(generator.next().value_or(0), 1); } diff --git a/test/framework/test_main.cpp b/test/framework/test_main.cpp index 2c88f42a2796598608e62c5312b39d5dd539041e..6c515a33d4e2998589becce3a33c30f07663b0ce 100644 --- a/test/framework/test_main.cpp +++ b/test/framework/test_main.cpp @@ -22,7 +22,7 @@ static void parse_arguments(int argc, char **argv) { static struct option long_options[] = { {"vector-length", required_argument, nullptr, 'v'}, {"seed", required_argument, nullptr, 's'}, - {0, 0, nullptr, 0} + {nullptr, 0, nullptr, 0} }; // clang-format on