Skip to content

Commit

Permalink
Fix static-analysis issues: apply hidden friend pattern to binary ope…
Browse files Browse the repository at this point in the history
…rators
  • Loading branch information
egorodet committed Dec 28, 2024
1 parent 6d02e75 commit 592b68c
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 179 deletions.
11 changes: 6 additions & 5 deletions Apps/07-ParallelRendering/ParallelRenderingApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,12 @@ constexpr char const* g_app_variant_name = "Root Constants";
constexpr char const* g_app_variant_name = "Buffer Views";
#endif

bool ParallelRenderingApp::Settings::operator==(const Settings& other) const noexcept
bool operator==(const ParallelRenderingApp::Settings& left,
const ParallelRenderingApp::Settings& right) noexcept
{
META_FUNCTION_TASK();
return std::tie(cubes_grid_size, render_thread_count, parallel_rendering_enabled) ==
std::tie(other.cubes_grid_size, other.render_thread_count, other.parallel_rendering_enabled);
return std::tie(left.cubes_grid_size, left.render_thread_count, left.parallel_rendering_enabled) ==
std::tie(right.cubes_grid_size, right.render_thread_count, right.parallel_rendering_enabled);
}

uint32_t ParallelRenderingApp::Settings::GetTotalCubesCount() const noexcept
Expand Down Expand Up @@ -219,7 +220,7 @@ void ParallelRenderingApp::Init()
frame.cubes_uniform_argument_binding_ptrs[0] = &frame.cubes_program_bindings[0].Get({ rhi::ShaderType::All, "g_uniforms" });
frame.cubes_program_bindings[0].SetName(fmt::format("Cube 0 Bindings {}", frame.index));
#else
const Data::Size uniform_data_size = MeshBuffers::GetUniformSize();
static const Data::Size uniform_data_size = MeshBuffers::GetUniformSize();
frame.cubes_array.program_bindings_per_instance.resize(cubes_count);
frame.cubes_array.program_bindings_per_instance[0] = render_state_settings.program.CreateBindings({
{
Expand All @@ -245,7 +246,7 @@ void ParallelRenderingApp::Init()
cube_program_bindings.SetName(fmt::format("Cube {} Bindings {}", cube_index, frame.index));
}
#else
[&frame, &cube_array_buffers, uniform_data_size](const uint32_t cube_index)
[&frame, &cube_array_buffers](const uint32_t cube_index)
{
rhi::ProgramBindings& cube_program_bindings = frame.cubes_array.program_bindings_per_instance[cube_index];
cube_program_bindings = rhi::ProgramBindings(frame.cubes_array.program_bindings_per_instance[0], {
Expand Down
9 changes: 4 additions & 5 deletions Apps/07-ParallelRendering/ParallelRenderingApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class ParallelRenderingApp final // NOSONAR - destructor required
uint32_t render_thread_count = std::thread::hardware_concurrency();
bool parallel_rendering_enabled = true;

bool operator==(const Settings& other) const noexcept;
friend bool operator==(const Settings& left, const Settings& right) noexcept;

uint32_t GetTotalCubesCount() const noexcept;
uint32_t GetActiveRenderThreadCount() const noexcept;
Expand All @@ -92,10 +92,6 @@ class ParallelRenderingApp final // NOSONAR - destructor required
const Settings& GetSettings() const noexcept { return m_settings; }
void SetSettings(const Settings& settings);

protected:
// IContextCallback override
void OnContextReleased(rhi::IContext& context) override;

private:
struct CubeParameters
{
Expand All @@ -114,6 +110,9 @@ class ParallelRenderingApp final // NOSONAR - destructor required
const std::vector<rhi::ProgramBindings>& program_bindings_per_instance,
uint32_t begin_instance_index, const uint32_t end_instance_index) const;

// IContextCallback override
void OnContextReleased(rhi::IContext& context) override;

Settings m_settings;
gfx::Camera m_camera;
rhi::RenderState m_render_state;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,14 @@ class AlignedAllocator
return size_type(-1) / sizeof(value_type);
}

bool operator!=(const AlignedAllocator<T, N>& other) const
friend bool operator!=(const AlignedAllocator& left,
const AlignedAllocator& right)
{
return !(*this == other);
return !(left == right);
}

bool operator==(const AlignedAllocator<T, N>&) const
friend bool operator==(const AlignedAllocator&,
const AlignedAllocator&)
{
return true;
}
Expand Down
42 changes: 21 additions & 21 deletions Modules/Data/RangeSet/Include/Methane/Data/Range.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,46 +50,46 @@ class Range
: Range(*init.begin(), *(init.begin() + 1))
{ }

[[nodiscard]] bool operator==(const Range<ScalarT>& other) const noexcept { return m_start == other.m_start && m_end == other.m_end; }
[[nodiscard]] bool operator!=(const Range<ScalarT>& other) const noexcept { return !operator==(other); }
[[nodiscard]] bool operator< (const Range<ScalarT>& other) const noexcept { return m_end <= other.m_start; }
[[nodiscard]] bool operator> (const Range<ScalarT>& other) const noexcept { return m_start > other.end; }

[[nodiscard]] ScalarT GetStart() const noexcept { return m_start; }
[[nodiscard]] ScalarT GetEnd() const noexcept { return m_end; }
[[nodiscard]] ScalarT GetMin() const noexcept { return m_start; }
[[nodiscard]] ScalarT GetMax() const noexcept { return m_end; }
[[nodiscard]] ScalarT GetLength() const noexcept { return m_end - m_start; }
[[nodiscard]] bool IsEmpty() const noexcept { return m_start == m_end; }
[[nodiscard]] friend bool operator==(const Range& left, const Range& right) noexcept { return left.m_start == right.m_start && left.m_end == right.m_end; }
[[nodiscard]] friend bool operator!=(const Range& left, const Range& right) noexcept { return !(left == right); }
[[nodiscard]] friend bool operator< (const Range& left, const Range& right) noexcept { return left.m_end <= right.m_start; }
[[nodiscard]] friend bool operator> (const Range& left, const Range& right) noexcept { return left.m_start > right.m_end; }

[[nodiscard]] ScalarT GetStart() const noexcept { return m_start; }
[[nodiscard]] ScalarT GetEnd() const noexcept { return m_end; }
[[nodiscard]] ScalarT GetMin() const noexcept { return m_start; }
[[nodiscard]] ScalarT GetMax() const noexcept { return m_end; }
[[nodiscard]] ScalarT GetLength() const noexcept { return m_end - m_start; }
[[nodiscard]] bool IsEmpty() const noexcept { return m_start == m_end; }

[[nodiscard]] bool IsAdjacent(const Range& other) const noexcept { return m_start == other.m_end || other.m_start == m_end; }
[[nodiscard]] bool IsOverlapping(const Range& other) const noexcept { return m_start < other.m_end && other.m_start < m_end; }
[[nodiscard]] bool IsMergeable(const Range& other) const noexcept { return m_start <= other.m_end && other.m_start <= m_end; }
[[nodiscard]] bool Contains(const Range& other) const noexcept { return m_start <= other.m_start && other.m_end <= m_end; }

[[nodiscard]]
Range operator+(const Range& other) const // merge
friend Range operator+(const Range& left, const Range& right) // merge
{
META_FUNCTION_TASK();
META_CHECK_DESCR(other, IsMergeable(other), "can not merge ranges which are not overlapping or adjacent");
return Range(std::min(m_start, other.m_start), std::max(m_end, other.m_end));
META_CHECK_DESCR(right, left.IsMergeable(right), "can not merge ranges which are not overlapping or adjacent");
return Range(std::min(left.m_start, right.m_start), std::max(left.m_end, right.m_end));
}

[[nodiscard]]
Range operator%(const Range& other) const // intersect
friend Range operator%(const Range& left, const Range& right) // intersect
{
META_FUNCTION_TASK();
META_CHECK_DESCR(other, IsMergeable(other), "can not intersect ranges which are not overlapping or adjacent");
return Range(std::max(m_start, other.m_start), std::min(m_end, other.m_end));
META_CHECK_DESCR(right, left.IsMergeable(right), "can not intersect ranges which are not overlapping or adjacent");
return Range(std::max(left.m_start, right.m_start), std::min(left.m_end, right.m_end));
}

[[nodiscard]]
Range operator-(const Range& other) const // subtract
friend Range operator-(const Range& left, const Range& right) // subtract
{
META_FUNCTION_TASK();
META_CHECK_DESCR(other, IsOverlapping(other), "can not subtract ranges which are not overlapping");
META_CHECK_DESCR(other, !Contains(other) && !other.Contains(*this), "can not subtract ranges containing one another");
return (m_start <= other.m_start) ? Range(m_start, other.m_start) : Range(other.m_end, m_end);
META_CHECK_DESCR(right, left.IsOverlapping(right), "can not subtract ranges which are not overlapping");
META_CHECK_DESCR(right, !left.Contains(right) && !right.Contains(left), "can not subtract ranges containing one another");
return (left.m_start <= right.m_start) ? Range(left.m_start, right.m_start) : Range(right.m_end, left.m_end);
}

[[nodiscard]] explicit operator bool() const noexcept { return !IsEmpty(); }
Expand Down
61 changes: 31 additions & 30 deletions Modules/Data/Types/Include/Methane/Data/Point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,109 +134,110 @@ class Point // NOSONAR - class has more than 35 methods
}
}

[[nodiscard]] bool operator==(const PointType& other) const noexcept
[[nodiscard]] friend bool operator==(const PointType& left, const PointType& right) noexcept
{
#if defined(__APPLE__) && defined(__x86_64__)
// FIXME: workaround for HLSL++ issue (https://github.com/redorav/hlslpp/issues/61):
// Integer vector comparison is working incorrectly on Intel based Macs with MacOS >= 11
return AsArray() == other.AsArray();
return left.AsArray() == right.AsArray();
#else
return hlslpp::all(m_vector == other.AsVector());
return hlslpp::all(left.m_vector == right.AsVector());
#endif
}

[[nodiscard]] bool operator<(const PointType& other) const noexcept
[[nodiscard]] friend bool operator<(const PointType& left, const PointType& right) noexcept
{
#if defined(__APPLE__) && defined(__x86_64__)
// FIXME: workaround for HLSL++ issue (https://github.com/redorav/hlslpp/issues/61):
// Integer vector comparison is working incorrectly on Intel based Macs with MacOS >= 11
for(size_t i = 0; i < size; ++i)
if ((*this)[i] >= other[i])
if (left[i] >= right[i])
return false;
return true;
#else
return hlslpp::all(m_vector < other.AsVector());
return hlslpp::all(left.m_vector < right.AsVector());
#endif
}

[[nodiscard]] bool operator>(const PointType& other) const noexcept
[[nodiscard]] friend bool operator>(const PointType& left, const PointType& right) noexcept
{
#if defined(__APPLE__) && defined(__x86_64__)
// FIXME: workaround for HLSL++ issue (https://github.com/redorav/hlslpp/issues/61):
// Integer vector comparison is working incorrectly on Intel based Macs with MacOS >= 11
for(size_t i = 0; i < size; ++i)
if ((*this)[i] <= other[i])
if (left[i] <= right[i])
return false;
return true;
#else
return hlslpp::all(m_vector > other.AsVector());
return hlslpp::all(left.m_vector > right.AsVector());
#endif
}

bool operator!=(const PointType& other) const noexcept { return !operator==(other); }
bool operator<=(const PointType& other) const noexcept { return hlslpp::all(m_vector <= other.AsVector()); }
bool operator>=(const PointType& other) const noexcept { return hlslpp::all(m_vector >= other.AsVector()); }
friend bool operator!=(const PointType& left, const PointType& right) noexcept { return !(left == right); }
friend bool operator<=(const PointType& left, const PointType& right) noexcept { return hlslpp::all(left.m_vector <= right.AsVector()); }
friend bool operator>=(const PointType& left, const PointType& right) noexcept { return hlslpp::all(left.m_vector >= right.AsVector()); }

friend PointType operator+(const PointType& left, const PointType& right) noexcept { return PointType(left.m_vector + right.AsVector()); }
friend PointType operator-(const PointType& left, const PointType& right) noexcept { return PointType(left.m_vector - right.AsVector()); }

PointType operator+(const PointType& other) const noexcept { return PointType(m_vector + other.AsVector()); }
PointType operator-(const PointType& other) const noexcept { return PointType(m_vector - other.AsVector()); }
PointType& operator+=(const PointType& other) noexcept { m_vector += other.AsVector(); return *this; }
PointType& operator-=(const PointType& other) noexcept { m_vector -= other.AsVector(); return *this; }

template<typename M>
std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator*(M multiplier) const noexcept
friend std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator*(const PointType& point, M multiplier) noexcept
{
if constexpr (std::is_same_v<T, M>)
return PointType(m_vector * multiplier);
return PointType(point.m_vector * multiplier);
else
{
if constexpr (std::is_floating_point_v<M>)
return PointType(Point<M, size>(*this) * multiplier);
return PointType(Point<M, size>(point) * multiplier);
else
return PointType(m_vector * static_cast<T>(multiplier));
return PointType(point.m_vector * static_cast<T>(multiplier));
}
}

template<typename M>
std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator/(M divisor) const noexcept
friend std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator/(const PointType& point, M divisor) noexcept
{
if constexpr (std::is_same_v<T, M>)
return PointType(m_vector / divisor);
return PointType(point.m_vector / divisor);
else
{
if constexpr (std::is_floating_point_v<M>)
return PointType(Point<M, size>(*this) / divisor);
return PointType(Point<M, size>(point) / divisor);
else
return PointType(m_vector / static_cast<T>(divisor));
return PointType(point.m_vector / static_cast<T>(divisor));
}
}

template<typename M>
std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator*(const Point<M, size>& multiplier) const noexcept
friend std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator*(const PointType& point, const Point<M, size>& multiplier) noexcept
{
if constexpr (std::is_same_v<T, M>)
return PointType(m_vector * multiplier.AsVector());
return PointType(point.m_vector * multiplier.AsVector());
else
{
if constexpr (std::is_floating_point_v<M>)
{
return PointType(Point<M, size>(static_cast<Point<M, size>>(*this).AsVector() * multiplier.AsVector()));
return PointType(Point<M, size>(static_cast<Point<M, size>>(point).AsVector() * multiplier.AsVector()));
}
else
return PointType(m_vector * static_cast<PointType>(multiplier).AsVector());
return PointType(point.m_vector * static_cast<PointType>(multiplier).AsVector());
}
}

template<typename M>
std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator/(const Point<M, size>& divisor) const noexcept
friend std::enable_if_t<std::is_arithmetic_v<M>, PointType> operator/(const PointType& point, const Point<M, size>& divisor) noexcept
{
if constexpr (std::is_same_v<T, M>)
return PointType(m_vector / divisor.AsVector());
return PointType(point.m_vector / divisor.AsVector());
else
{
if constexpr (std::is_floating_point_v<M>)
return PointType(Point<M, size>(static_cast<Point<M, size>>(*this).AsVector() / divisor.AsVector()));
return PointType(Point<M, size>(static_cast<Point<M, size>>(point).AsVector() / divisor.AsVector()));
else
return PointType(m_vector / static_cast<PointType>(divisor).AsVector());
return PointType(point.m_vector / static_cast<PointType>(divisor).AsVector());
}
}

Expand Down
Loading

0 comments on commit 592b68c

Please sign in to comment.