From 1c31a85a43743d51b348dcee01d9725f6d10b95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fr=C3=B6jdh?= Date: Wed, 3 Dec 2025 12:14:35 +0100 Subject: [PATCH] added function to remove duplicates, preserve order of dbit --- slsDetectorSoftware/src/Module.cpp | 10 +++---- slsSupportLib/include/sls/container_utils.h | 28 ++++++++++++++++++ slsSupportLib/tests/test-container_utils.cpp | 31 +++++++++++++++++++- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index a47eda649..8cde3f072 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -2568,17 +2568,15 @@ std::vector Module::getReceiverDbitList() const { void Module::setReceiverDbitList(std::vector list) { LOG(logDEBUG1) << "Setting Receiver Dbit List"; - if (list.size() > 64) { - throw RuntimeError("Dbit list size cannot be greater than 64\n"); - } + for (auto &it : list) { if (it < 0 || it > 63) { throw RuntimeError("Dbit list value must be between 0 and 63\n"); } } - std::sort(begin(list), end(list)); - auto last = std::unique(begin(list), end(list)); - list.erase(last, list.end()); + auto r = stableRemoveDuplicates(list); + if(r) + LOG(logWARNING) << "Removed duplicated from receiver dbit list"; StaticVector arg = list; sendToReceiver(F_SET_RECEIVER_DBIT_LIST, arg, nullptr); diff --git a/slsSupportLib/include/sls/container_utils.h b/slsSupportLib/include/sls/container_utils.h index ab234994b..a3de80e40 100644 --- a/slsSupportLib/include/sls/container_utils.h +++ b/slsSupportLib/include/sls/container_utils.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -155,6 +156,10 @@ template bool hasDuplicates(Container c) { return pos != c.end(); // if we found something there are duplicates } +/** + * @brief Sorts the container and removes duplicated elements + * returns true if elements were removed otherwiese false + */ template typename std::enable_if::value, bool>::type removeDuplicates(T &c) { @@ -167,6 +172,29 @@ removeDuplicates(T &c) { return false; } +/** + * @brief Removed duplicated entries while preserving the oder + * returns true if elements were removed otherwiese false + */ +template +typename std::enable_if::value, bool>::type +stableRemoveDuplicates(T &c) { + auto containerSize = c.size(); + std::set seen; + c.erase( + std::remove_if(c.begin(), c.end(), + [&](const typename T::value_type& val) { + return !seen.insert(val).second; // erase if already seen + }), + c.end() + ); + if (c.size() != containerSize) { + return true; + } + return false; +} + + } // namespace sls #endif // CONTAINER_UTILS_H diff --git a/slsSupportLib/tests/test-container_utils.cpp b/slsSupportLib/tests/test-container_utils.cpp index d2db66c84..b43eaf814 100644 --- a/slsSupportLib/tests/test-container_utils.cpp +++ b/slsSupportLib/tests/test-container_utils.cpp @@ -153,13 +153,35 @@ TEST_CASE("check for duplicates in vector of pairs") { REQUIRE(hasDuplicates(vec) == true); } -TEST_CASE("remove duplicates from vector") { +TEST_CASE("sorts the vector and remove duplicates") { std::vector v{5, 6, 5, 3}; auto r = removeDuplicates(v); CHECK(r == true); // did indeed remove elements CHECK(v == std::vector{3, 5, 6}); } +TEST_CASE("remove duplicates but keep order") { + std::vector v{5, 6, 5, 3}; + auto r = stableRemoveDuplicates(v); + CHECK(r == true); // did indeed remove elements + CHECK(v == std::vector{5, 6, 3}); +} + +TEST_CASE("remove duplicates but keep order, all elements the same ") { + std::vector v{'c', 'c', 'c', 'c', 'c', 'c'}; + auto r = stableRemoveDuplicates(v); + CHECK(r == true); // did indeed remove elements + CHECK(v == std::vector{'c'}); +} + +TEST_CASE("remove duplicates but keep order, pattern ") { + std::vector v{8,1,2,8,8,3,2}; + auto r = stableRemoveDuplicates(v); + CHECK(r == true); // did indeed remove elements + CHECK(v == std::vector{8,1,2,3}); +} + + TEST_CASE("remove duplicated empty vector") { std::vector v; auto r = removeDuplicates(v); @@ -167,4 +189,11 @@ TEST_CASE("remove duplicated empty vector") { CHECK(v == std::vector{}); } +TEST_CASE("remove duplicated empty vector using stable version") { + std::vector v; + auto r = stableRemoveDuplicates(v); + CHECK(r == false); // no elements to remove + CHECK(v == std::vector{}); +} + } // namespace sls