From 642e6369d5a74000c4c6eea30e663e3c2e417bea Mon Sep 17 00:00:00 2001 From: selsta Date: Sat, 9 May 2026 20:09:12 +0200 Subject: [PATCH] epee: avoid memcpy in rolling median move --- contrib/epee/include/rolling_median.h | 42 ++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/contrib/epee/include/rolling_median.h b/contrib/epee/include/rolling_median.h index a666303a9..a88bdbf65 100644 --- a/contrib/epee/include/rolling_median.h +++ b/contrib/epee/include/rolling_median.h @@ -36,6 +36,7 @@ #include "misc_language.h" +#include #include #include @@ -47,6 +48,9 @@ namespace misc_utils template struct rolling_median_t { + static_assert(std::is_trivially_copyable_v, + "rolling_median_t requires trivially copyable Item"); + private: Item* data; //circular queue of values int* pos; //index into `heap` for each value @@ -124,6 +128,27 @@ private: return i == 0; } + void consume_from(rolling_median_t& m) noexcept + { + data = m.data; + pos = m.pos; + heap = m.heap; + N = m.N; + idx = m.idx; + minCt = m.minCt; + maxCt = m.maxCt; + sz = m.sz; + + m.data = nullptr; + m.pos = nullptr; + m.heap = nullptr; + m.N = 0; + m.idx = 0; + m.minCt = 0; + m.maxCt = 0; + m.sz = 0; + } + protected: rolling_median_t &operator=(const rolling_median_t&) = delete; @@ -152,16 +177,19 @@ public: sz = other.sz; } - rolling_median_t(rolling_median_t &&m) + rolling_median_t(rolling_median_t &&m) noexcept { - memcpy(this, &m, sizeof(rolling_median_t)); - m.data = NULL; + consume_from(m); } - rolling_median_t &operator=(rolling_median_t &&m) + + rolling_median_t &operator=(rolling_median_t &&m) noexcept { - free(data); - memcpy(this, &m, sizeof(rolling_median_t)); - m.data = NULL; + if (this != &m) + { + free(data); + consume_from(m); + } + return *this; }