[libcxx-commits] [libcxx] 162397f - [libc++] Replace stable_sort with sort in flat_map (#121431)

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jan 13 06:09:34 PST 2025


Author: Hui
Date: 2025-01-13T09:09:29-05:00
New Revision: 162397f98d04415eebe115cdcb01558932e5c802

URL: https://github.com/llvm/llvm-project/commit/162397f98d04415eebe115cdcb01558932e5c802
DIFF: https://github.com/llvm/llvm-project/commit/162397f98d04415eebe115cdcb01558932e5c802.diff

LOG: [libc++] Replace stable_sort with sort in flat_map (#121431)

Fixes #120788

Added: 
    

Modified: 
    libcxx/include/__flat_map/flat_map.h
    libcxx/include/module.modulemap

Removed: 
    libcxx/test/libcxx/containers/containers.adaptors/flat.map/container_stability.pass.cpp
    libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp
    libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_stability.pass.cpp


################################################################################
diff  --git a/libcxx/include/__flat_map/flat_map.h b/libcxx/include/__flat_map/flat_map.h
index 9fe84250b12043..ab53b7a285ca46 100644
--- a/libcxx/include/__flat_map/flat_map.h
+++ b/libcxx/include/__flat_map/flat_map.h
@@ -17,7 +17,7 @@
 #include <__algorithm/ranges_inplace_merge.h>
 #include <__algorithm/ranges_lower_bound.h>
 #include <__algorithm/ranges_partition_point.h>
-#include <__algorithm/ranges_stable_sort.h>
+#include <__algorithm/ranges_sort.h>
 #include <__algorithm/ranges_unique.h>
 #include <__algorithm/ranges_upper_bound.h>
 #include <__algorithm/remove_if.h>
@@ -853,9 +853,7 @@ class flat_map {
   // is no invariant state to preserve
   _LIBCPP_HIDE_FROM_ABI void __sort_and_unique() {
     auto __zv = ranges::views::zip(__containers_.keys, __containers_.values);
-    // To be consistent with std::map's behaviour, we use stable_sort instead of sort.
-    // As a result, if there are duplicated keys, the first value in the original order will be taken.
-    ranges::stable_sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); });
+    ranges::sort(__zv, __compare_, [](const auto& __p) -> decltype(auto) { return std::get<0>(__p); });
     auto __dup_start = ranges::unique(__zv, __key_equiv(__compare_)).begin();
     auto __dist      = ranges::distance(__zv.begin(), __dup_start);
     __containers_.keys.erase(__containers_.keys.begin() + __dist, __containers_.keys.end());
@@ -886,7 +884,7 @@ class flat_map {
         return __compare_(std::get<0>(__p1), std::get<0>(__p2));
       };
       if constexpr (!_WasSorted) {
-        ranges::stable_sort(__zv.begin() + __append_start_offset, __end, __compare_key);
+        ranges::sort(__zv.begin() + __append_start_offset, __end, __compare_key);
       } else {
         _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(
             __is_sorted_and_unique(__containers_.keys | ranges::views::drop(__append_start_offset)),

diff  --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 07ab5649ae45cb..6800f8b5626504 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -760,6 +760,8 @@ module std [system] {
     module ranges_sort {
       header "__algorithm/ranges_sort.h"
       export std.functional.ranges_operations
+      export std.algorithm.sort
+      export std.algorithm.make_projected
     }
     module ranges_stable_partition {
       header "__algorithm/ranges_stable_partition.h"

diff  --git a/libcxx/test/libcxx/containers/containers.adaptors/flat.map/container_stability.pass.cpp b/libcxx/test/libcxx/containers/containers.adaptors/flat.map/container_stability.pass.cpp
deleted file mode 100644
index 0d90c3250061ff..00000000000000
--- a/libcxx/test/libcxx/containers/containers.adaptors/flat.map/container_stability.pass.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-
-// <flat_map>
-
-// flat_map(key_container_type key_cont, mapped_container_type mapped_cont);
-//
-// libc++ uses stable_sort to ensure that flat_map's behavior matches map's,
-// in terms of which duplicate items are kept.
-// This tests a conforming extension.
-
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <flat_map>
-#include <random>
-#include <map>
-#include <vector>
-
-#include "test_macros.h"
-
-struct Mod256 {
-  bool operator()(int x, int y) const { return (x % 256) < (y % 256); }
-};
-
-int main(int, char**) {
-  std::mt19937 randomness;
-  std::vector<uint16_t> values;
-  std::vector<std::pair<uint16_t, uint16_t>> pairs;
-  for (int i = 0; i < 200; ++i) {
-    uint16_t r = randomness();
-    values.push_back(r);
-    pairs.emplace_back(r, r);
-  }
-
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs.begin(), pairs.end());
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(values, values);
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs.begin(), pairs.end());
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(values, values, Mod256());
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs.begin(), pairs.end());
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(values, values, std::allocator<int>());
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs.begin(), pairs.end());
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(values, values, Mod256(), std::allocator<int>());
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  return 0;
-}

diff  --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp
deleted file mode 100644
index 14189840ce6605..00000000000000
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.cons/iter_iter_stability.pass.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-
-// <flat_map>
-
-// template<class InputIterator>
-//   flat_map(InputIterator first, InputIterator last, const key_compare& comp = key_compare())
-//
-// libc++ uses stable_sort to ensure that flat_map's behavior matches map's,
-// in terms of which duplicate items are kept.
-// This tests a conforming extension.
-
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <flat_map>
-#include <random>
-#include <map>
-#include <vector>
-
-#include "test_macros.h"
-
-struct Mod256 {
-  bool operator()(int x, int y) const { return (x % 256) < (y % 256); }
-};
-
-int main(int, char**) {
-  std::mt19937 randomness;
-  std::pair<uint16_t, uint16_t> pairs[200];
-  for (auto& pair : pairs) {
-    pair = {uint16_t(randomness()), uint16_t(randomness())};
-  }
-
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs, pairs + 200);
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(pairs, pairs + 200);
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs, pairs + 200, std::allocator<int>());
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(pairs, pairs + 200, std::allocator<int>());
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs, pairs + 200, Mod256());
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(pairs, pairs + 200, Mod256());
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  {
-    std::map<uint16_t, uint16_t, Mod256> m(pairs, pairs + 200, Mod256(), std::allocator<int>());
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(pairs, pairs + 200, Mod256(), std::allocator<int>());
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-  return 0;
-}

diff  --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_stability.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_stability.pass.cpp
deleted file mode 100644
index fabcb1d216a78a..00000000000000
--- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/insert_range_stability.pass.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
-
-// <flat_map>
-
-// template<container-compatible-range<value_type> R>
-//   void insert_range(R&& rg);
-//
-// libc++ uses stable_sort to ensure that flat_map's behavior matches map's,
-// in terms of which duplicate items are kept.
-// This tests a conforming extension.
-
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <flat_map>
-#include <random>
-#include <ranges>
-#include <map>
-#include <vector>
-#include <utility>
-
-#include "test_macros.h"
-
-struct Mod256 {
-  bool operator()(int x, int y) const { return (x % 256) < (y % 256); }
-};
-
-int main(int, char**) {
-  {
-    std::mt19937 randomness;
-    std::pair<uint16_t, uint16_t> pairs[400];
-    for (int i = 0; i < 400; ++i) {
-      uint16_t r = randomness();
-      pairs[i]   = {r, r};
-    }
-
-    std::map<uint16_t, uint16_t, Mod256> m(pairs, pairs + 200);
-    std::flat_map<uint16_t, uint16_t, Mod256> fm(std::sorted_unique, m.begin(), m.end());
-    assert(std::ranges::equal(fm, m));
-
-    fm.insert_range(std::views::counted(pairs + 200, 200));
-    m.insert(pairs + 200, pairs + 400);
-    assert(fm.size() == m.size());
-    LIBCPP_ASSERT(std::ranges::equal(fm, m));
-  }
-
-  {
-    std::vector<std::pair<int, int>> v{{1, 2}, {1, 3}};
-    std::flat_map<int, int> m;
-    m.insert_range(v);
-    assert(m.size() == 1);
-    LIBCPP_ASSERT(m[1] == 2);
-  }
-  return 0;
-}


        


More information about the libcxx-commits mailing list