[libcxx-commits] [libcxx] 13f7a1f - [libc++] LWG 3987 provide iterator.range access from flat_{map, set} (#137524)

via libcxx-commits libcxx-commits at lists.llvm.org
Sun Jul 6 04:25:21 PDT 2025


Author: Hui
Date: 2025-07-06T12:25:18+01:00
New Revision: 13f7a1fb59044d56fca7a8c231505248d35f3d42

URL: https://github.com/llvm/llvm-project/commit/13f7a1fb59044d56fca7a8c231505248d35f3d42
DIFF: https://github.com/llvm/llvm-project/commit/13f7a1fb59044d56fca7a8c231505248d35f3d42.diff

LOG: [libc++] LWG 3987 provide iterator.range access from flat_{map,set} (#137524)

fixes #105309

Added: 
    libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py

Modified: 
    libcxx/include/flat_map
    libcxx/include/flat_set
    libcxx/include/module.modulemap.in
    libcxx/test/configs/cmake-bridge.cfg.in

Removed: 
    libcxx/test/libcxx/lit.local.cfg


################################################################################
diff  --git a/libcxx/include/flat_map b/libcxx/include/flat_map
index 2552450081734..eea9896165f06 100644
--- a/libcxx/include/flat_map
+++ b/libcxx/include/flat_map
@@ -72,6 +72,15 @@ namespace std {
 #  include <version>
 
 // standard required includes
+
+// [iterator.range]
+#  include <__iterator/access.h>
+#  include <__iterator/data.h>
+#  include <__iterator/empty.h>
+#  include <__iterator/reverse_access.h>
+#  include <__iterator/size.h>
+
+// [flat.map.syn]
 #  include <compare>
 #  include <initializer_list>
 

diff  --git a/libcxx/include/flat_set b/libcxx/include/flat_set
index ebbb3a0247f3e..66041a42b79cf 100644
--- a/libcxx/include/flat_set
+++ b/libcxx/include/flat_set
@@ -65,6 +65,15 @@ namespace std {
 #  include <version>
 
 // standard required includes
+
+// [iterator.range]
+#  include <__iterator/access.h>
+#  include <__iterator/data.h>
+#  include <__iterator/empty.h>
+#  include <__iterator/reverse_access.h>
+#  include <__iterator/size.h>
+
+// [flat.set.syn]
 #  include <compare>
 #  include <initializer_list>
 

diff  --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 12fe65a3d3812..45b9c72a05b82 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -868,6 +868,7 @@ module std [system] {
 
     header "array"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module atomic {
@@ -1225,6 +1226,7 @@ module std [system] {
 
     header "deque"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module exception {
@@ -1301,6 +1303,7 @@ module std [system] {
     header "flat_map"
     export *
     export std.algorithm.ranges_sort
+    export std.iterator.reverse_iterator
     export std.ranges.zip_view
     export std.tuple
   }
@@ -1320,6 +1323,7 @@ module std [system] {
     export std.flat_map.sorted_equivalent
     export *
     export std.algorithm.ranges_sort
+    export std.iterator.reverse_iterator
     export std.ranges.zip_view
     export std.tuple
   }
@@ -1377,6 +1381,7 @@ module std [system] {
   module forward_list {
     header "forward_list"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module fstream {
@@ -1552,6 +1557,7 @@ module std [system] {
   module list {
     header "list"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module locale {
@@ -1603,6 +1609,7 @@ module std [system] {
     module fwd { header "__fwd/map.h" }
     header "map"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module mdspan {
@@ -1949,6 +1956,7 @@ module std [system] {
   module regex {
     header "regex"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module scoped_allocator {
@@ -1965,6 +1973,7 @@ module std [system] {
     module fwd { header "__fwd/set.h" }
     header "set"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module shared_mutex {
@@ -1982,6 +1991,7 @@ module std [system] {
 
     header "span"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module sstream {
@@ -2034,6 +2044,7 @@ module std [system] {
 
     header "string"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module string_view {
@@ -2041,6 +2052,7 @@ module std [system] {
 
     header "string_view"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module strstream {
@@ -2122,11 +2134,13 @@ module std [system] {
   module unordered_map {
     header "unordered_map"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module unordered_set {
     header "unordered_set"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module utility {
@@ -2215,6 +2229,7 @@ module std [system] {
     }
 
     header "vector"
+    export std.iterator.reverse_iterator
     export *
   }
 

diff  --git a/libcxx/test/configs/cmake-bridge.cfg.in b/libcxx/test/configs/cmake-bridge.cfg.in
index d7d588669032d..20b7c1e9bc357 100644
--- a/libcxx/test/configs/cmake-bridge.cfg.in
+++ b/libcxx/test/configs/cmake-bridge.cfg.in
@@ -12,6 +12,8 @@
 #
 
 import os, site
+import shlex
+import sys
 site.addsitedir(os.path.join('@LIBCXX_SOURCE_DIR@', 'utils'))
 import libcxx.test.format
 
@@ -32,3 +34,4 @@ config.substitutions.append(('%{lib-dir}', '@LIBCXX_TESTING_INSTALL_PREFIX@/@LIB
 config.substitutions.append(('%{module-dir}', '@LIBCXX_TESTING_INSTALL_PREFIX@/@LIBCXX_INSTALL_MODULES_DIR@'))
 config.substitutions.append(('%{test-tools-dir}', '@LIBCXX_TEST_TOOLS_PATH@'))
 config.substitutions.append(('%{benchmark_flags}', '-I @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/include -L @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/lib -L @LIBCXX_BINARY_DIR@/test/benchmarks/google-benchmark/lib64 -l benchmark'))
+config.substitutions.append(("%{python}", shlex.quote(sys.executable)))

diff  --git a/libcxx/test/libcxx/lit.local.cfg b/libcxx/test/libcxx/lit.local.cfg
deleted file mode 100644
index 4467d8070cc70..0000000000000
--- a/libcxx/test/libcxx/lit.local.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-# The tests in this directory need to run Python
-import shlex
-import sys
-
-config.substitutions.append(("%{python}", shlex.quote(sys.executable)))

diff  --git a/libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py b/libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py
new file mode 100644
index 0000000000000..46290b1ed52a0
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.range/mandatory_inclusions.gen.py
@@ -0,0 +1,180 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# In addition to being available via inclusion of the <iterator> header,
+# the function templates in [iterator.range] are available when any of the following
+# headers are included: <array>, <deque>, <flat_map>, <flat_set>, <forward_list>,
+# <list>, <map>, <regex>, <set>, <span>, <string>, <string_view>, <unordered_map>,
+# <unordered_set>, <vector>.
+
+# RUN: %{python} %s %{libcxx-dir}/utils
+# END.
+
+import sys
+
+sys.path.append(sys.argv[1])
+from libcxx.header_information import (
+    lit_header_restrictions,
+    lit_header_undeprecations,
+    Header,
+)
+
+headers = list(
+    map(
+        Header,
+        [
+            "array",
+            "deque",
+            "flat_map",
+            "flat_set",
+            "forward_list",
+            "list",
+            "map",
+            "regex",
+            "set",
+            "span",
+            "string",
+            "string_view",
+            "unordered_map",
+            "unordered_set",
+            "vector",
+        ],
+    )
+)
+
+for header in headers:
+    print(
+        f"""\
+//--- {header}.pass.cpp
+{lit_header_restrictions.get(header, '')}
+{lit_header_undeprecations.get(header, '')}
+// UNSUPPORTED: c++03
+
+#include <{header}>
+#include <cassert>
+#include <initializer_list>
+
+#include "test_macros.h"
+
+struct Container {{
+  int a[3] = {{1, 2, 3}};
+
+  int* begin() {{ return &a[0]; }}
+  const int* begin() const {{ return &a[0]; }}
+  int* rbegin() {{ return &a[2]; }}
+  const int* rbegin() const {{ return &a[2]; }}
+  int* end() {{ return &a[3]; }}
+  const int* end() const {{ return &a[3]; }}
+  int* rend() {{ return (&a[0]) - 1; }}
+  const int* rend() const {{ return (&a[0]) - 1; }}
+  std::size_t size() const {{ return 3; }}
+  bool empty() const {{ return false; }}
+  int* data() {{return &a[0]; }}
+  const int* data() const {{ return &a[0]; }}
+}};
+
+int main(int, char**)  {{
+  {{
+    Container c;
+    const auto& cc = c;
+    assert(std::begin(c) == c.begin());
+    assert(std::begin(cc) == cc.begin());
+    assert(std::end(c) == c.end());
+    assert(std::end(cc) == cc.end());
+#if TEST_STD_VER >= 14
+    assert(std::cbegin(c) == cc.begin());
+    assert(std::cbegin(cc) == cc.begin());
+    assert(std::cend(c) == cc.end());
+    assert(std::cend(cc) == cc.end());
+    assert(std::rbegin(c) == c.rbegin());
+    assert(std::rbegin(cc) == cc.rbegin());
+    assert(std::rend(c) == cc.rend());
+    assert(std::rend(cc) == cc.rend());
+    assert(std::crbegin(c) == cc.rbegin());
+    assert(std::crbegin(cc) == cc.rbegin());
+    assert(std::crend(c) == cc.rend());
+    assert(std::crend(cc) == cc.rend());
+#endif
+#if TEST_STD_VER >= 17
+    assert(std::data(c) == c.data());
+    assert(std::data(cc) == cc.data());
+    assert(std::size(cc) == cc.size());
+    assert(std::empty(cc) == cc.empty());
+#endif
+#if TEST_STD_VER >= 20
+    assert(std::ssize(cc) == 3);
+#endif
+  }}
+  {{
+    int a[]        = {{1, 2, 3}};
+    const auto& ca = a;
+    assert(std::begin(a) == &a[0]);
+    assert(std::begin(ca) == &ca[0]);
+    assert(std::end(a) == &a[3]);
+    assert(std::end(ca) == &ca[3]);
+#if TEST_STD_VER >= 14
+    assert(std::cbegin(a) == &a[0]);
+    assert(std::cbegin(ca) == &ca[0]);
+    assert(std::cend(a) == &a[3]);
+    assert(std::cend(ca) == &ca[3]);
+    assert(std::rbegin(a) == std::reverse_iterator<int*>(std::end(a)));
+    assert(std::rbegin(ca) == std::reverse_iterator<const int*>(std::end(ca)));
+    assert(std::rend(a) == std::reverse_iterator<int*>(std::begin(a)));
+    assert(std::rend(ca) == std::reverse_iterator<const int*>(std::begin(ca)));
+    assert(std::crbegin(a) == std::reverse_iterator<const int*>(std::end(a)));
+    assert(std::crbegin(ca) == std::reverse_iterator<const int*>(std::end(ca)));
+    assert(std::crend(a) == std::reverse_iterator<const int*>(std::begin(a)));
+    assert(std::crend(ca) == std::reverse_iterator<const int*>(std::begin(ca)));
+#endif
+#if TEST_STD_VER >= 17
+    assert(std::size(ca) == 3);
+    assert(!std::empty(ca));
+    assert(std::data(a) == &a[0]);
+    assert(std::data(ca) == &ca[0]);
+#endif
+#if TEST_STD_VER >= 20
+    assert(std::ssize(ca) == 3);
+#endif
+  }}
+  {{
+    auto il         = {{1, 2, 3}};
+    const auto& cil = il;
+    assert(std::begin(il) == il.begin());
+    assert(std::begin(cil) == cil.begin());
+    assert(std::end(il) == il.end());
+    assert(std::end(cil) == cil.end());
+#if TEST_STD_VER >= 14
+    assert(std::cbegin(il) == cil.begin());
+    assert(std::cbegin(cil) == cil.begin());
+    assert(std::cend(il) == cil.end());
+    assert(std::cend(cil) == cil.end());
+    assert(std::rbegin(il) == std::reverse_iterator<const int*>(std::end(il)));
+    assert(std::rbegin(cil) == std::reverse_iterator<const int*>(std::end(il)));
+    assert(std::rend(il) == std::reverse_iterator<const int*>(std::begin(il)));
+    assert(std::rend(cil) == std::reverse_iterator<const int*>(std::begin(il)));
+    assert(std::crbegin(il) == std::reverse_iterator<const int*>(std::end(il)));
+    assert(std::crbegin(cil) == std::reverse_iterator<const int*>(std::end(il)));
+    assert(std::crend(il) == std::reverse_iterator<const int*>(std::begin(il)));
+    assert(std::crend(cil) == std::reverse_iterator<const int*>(std::begin(il)));
+#endif
+#if TEST_STD_VER >= 17
+    assert(std::size(cil) == 3);
+    assert(!std::empty(cil));
+    assert(std::data(il) == &*std::begin(il));
+    assert(std::data(cil) == &*std::begin(il));
+#endif
+#if TEST_STD_VER >= 20
+    assert(std::ssize(cil) == 3);
+#endif
+  }}
+
+  return 0;
+}}
+
+"""
+    )


        


More information about the libcxx-commits mailing list