From 4a14e382d52d1b67acf8594649f825740def7d4f Mon Sep 17 00:00:00 2001 From: Ralph Sennhauser Date: Mon, 28 Jul 2025 18:47:09 +0200 Subject: [PATCH] Replace deprecated std::is_pod std::is_pod is deprecated in C++20 and as such triggers -Wdeprecated-declarations when built with C++20, "is_standard_layout && is_trivial" is the equivalent, so migrate to that. While at it replace runtime dispatch with compile time and reduce the required trait for memcpy to what is really needed. Signed-off-by: Ralph Sennhauser --- source/network/StunClient.cpp | 4 +- source/simulation2/helpers/Grid.h | 91 +++++++++++++------------------ 2 files changed, 40 insertions(+), 55 deletions(-) diff --git a/source/network/StunClient.cpp b/source/network/StunClient.cpp index 6c2fd38e8b..9d3ce821d5 100644 --- a/source/network/StunClient.cpp +++ b/source/network/StunClient.cpp @@ -88,7 +88,7 @@ ENetAddress m_PublicAddress; template void AddToBuffer(std::vector& buffer, const T value) { - static_assert(std::is_pod_v, "T must be POD"); + static_assert(std::is_standard_layout_v && std::is_trivial_v, "T must be POD"); buffer.reserve(buffer.size() + n); // std::byte* can alias anything so this is legal. const std::byte* ptr = reinterpret_cast(&value); @@ -107,7 +107,7 @@ void AddToBuffer(std::vector& buffer, const T value) template bool GetFromBuffer(const std::vector& buffer, u32& offset, T& result) { - static_assert(std::is_pod_v, "T must be POD"); + static_assert(std::is_standard_layout_v && std::is_trivial_v, "T must be POD"); if (offset + n > buffer.size()) return false; diff --git a/source/simulation2/helpers/Grid.h b/source/simulation2/helpers/Grid.h index 0bf07300e0..a330a02a2c 100644 --- a/source/simulation2/helpers/Grid.h +++ b/source/simulation2/helpers/Grid.h @@ -46,23 +46,6 @@ template class Grid { friend struct SerializeHelper>; -protected: - // Tag-dispatching internal utilities for convenience. - struct default_type{}; - struct is_pod { operator default_type() { return default_type{}; }}; - struct is_container { operator default_type() { return default_type{}; }}; - - // helper to detect value_type - template struct has_value_type : std::false_type { }; - template struct has_value_type (), 0)> : std::true_type { }; - - template using if_ = typename std::conditional::type; - - template - using dispatch = if_< std::is_pod, is_pod, - if_, is_container, - default_type>>; - public: Grid() : m_W(0), m_H(0), m_Data(NULL) { @@ -82,9 +65,6 @@ public: public: // Ensure that o and this are the same size before calling. - void copy_data(T* o, default_type) { std::copy(o, o + m_H*m_W, &m_Data[0]); } - void copy_data(T* o, is_pod) { memcpy(m_Data, o, m_W*m_H*sizeof(T)); } - Grid& operator=(const Grid& g) { if (this == &g) @@ -92,7 +72,10 @@ public: if (m_W == g.m_W && m_H == g.m_H) { - copy_data(g.m_Data, dispatch{}); + if constexpr (std::is_trivially_copyable_v) + memcpy(m_Data, g.m_Data, m_W*m_H*sizeof(T)); + else + std::copy(g.m_Data, g.m_Data + m_H*m_W, &m_Data[0]); return *this; } @@ -102,7 +85,10 @@ public: if (g.m_Data) { m_Data = new T[m_W * m_H]; - copy_data(g.m_Data, dispatch{}); + if constexpr (std::is_trivially_copyable_v) + memcpy(m_Data, g.m_Data, m_W*m_H*sizeof(T)); + else + std::copy(g.m_Data, g.m_Data + m_H*m_W, &m_Data[0]); } return *this; } @@ -120,15 +106,16 @@ public: } // Ensure that o and this are the same size before calling. - bool compare_data(T* o, default_type) const { return std::equal(&m_Data[0], &m_Data[m_W*m_H], o); } - bool compare_data(T* o, is_pod) const { return memcmp(m_Data, o, m_W*m_H*sizeof(T)) == 0; } bool operator==(const Grid& g) const { if (!compare_sizes(&g)) return false; - return compare_data(g.m_Data, dispatch{}); + if constexpr (std::is_standard_layout_v && std::is_trivial_v) + return memcmp(m_Data, g.m_Data, m_W*m_H*sizeof(T)) == 0; + else + return std::equal(&m_Data[0], &m_Data[m_W*m_H], g.m_Data); } bool operator!=(const Grid& g) const { return !(*this==g); } @@ -140,41 +127,39 @@ public: u16 width() const { return m_W; }; u16 height() const { return m_H; }; - - bool _any_set_in_square(int, int, int, int, default_type) const - { - static_assert(!std::is_same::value, "Not implemented."); - return false; // Fix warnings. - } - bool _any_set_in_square(int i0, int j0, int i1, int j1, is_pod) const - { -#if GRID_BOUNDS_DEBUG - ENSURE(i0 >= 0 && j0 >= 0 && i1 <= m_W && j1 <= m_H); -#endif - for (int j = j0; j < j1; ++j) - { - int sum = 0; - for (int i = i0; i < i1; ++i) - sum += m_Data[j*m_W + i]; - if (sum > 0) - return true; - } - return false; - } - bool any_set_in_square(int i0, int j0, int i1, int j1) const { - return _any_set_in_square(i0, j0, i1, j1, dispatch{}); + if constexpr (std::is_standard_layout_v && std::is_trivial_v) + { +#if GRID_BOUNDS_DEBUG + ENSURE(i0 >= 0 && j0 >= 0 && i1 <= m_W && j1 <= m_H); +#endif + for (int j = j0; j < j1; ++j) + { + int sum = 0; + for (int i = i0; i < i1; ++i) + sum += m_Data[j*m_W + i]; + if (sum > 0) + return true; + } + return false; + } + else + { + static_assert(!std::is_same::value, "Not implemented."); + return false; // Fix warnings. + } } - void reset_data(default_type) { std::fill(&m_Data[0], &m_Data[m_H*m_W], T{}); } - void reset_data(is_pod) { memset(m_Data, 0, m_W*m_H*sizeof(T)); } - // Reset the data to its default-constructed value (usually 0), not changing size. void reset() { - if (m_Data) - reset_data(dispatch{}); + if (m_Data) { + if constexpr (std::is_standard_layout_v && std::is_trivial_v) + memset(m_Data, 0, m_W*m_H*sizeof(T)); + else + std::fill(&m_Data[0], &m_Data[m_H*m_W], T{}); + } } // Clear the grid setting the size to 0 and freeing any data.