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

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jun 7 08:36:31 PDT 2025


https://github.com/huixie90 updated https://github.com/llvm/llvm-project/pull/137524

>From ea06468d651c3eb96706d25131835f3cc071a6e7 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 27 Apr 2025 16:41:18 +0100
Subject: [PATCH 1/5] [libc++] LWG 3987 provide iterator.range access from
 flat_{map,set}

---
 libcxx/include/flat_map                       |  9 +++
 libcxx/include/flat_set                       |  9 +++
 .../lwg3987.flat_map.pass copy.cpp            | 74 +++++++++++++++++++
 .../iterator.range/lwg3987.flat_set.pass.cpp  | 74 +++++++++++++++++++
 4 files changed, 166 insertions(+)
 create mode 100644 libcxx/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp
 create mode 100644 libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp

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/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp b/libcxx/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp
new file mode 100644
index 0000000000000..049edf00d4ff4
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp	
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: clang-modules-build
+
+// <flat_map>
+
+// 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: <flat_map>
+
+#include <flat_map>
+
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::flat_map<int, int> m{{1, 1}, {2, 2}};
+    const auto& cm = m;
+    assert(std::begin(m) == m.begin());
+    assert(std::begin(cm) == cm.begin());
+    assert(std::end(m) == m.end());
+    assert(std::end(cm) == cm.end());
+    assert(std::cbegin(m) == cm.begin());
+    assert(std::cbegin(cm) == cm.begin());
+    assert(std::cend(m) == cm.end());
+    assert(std::cend(cm) == cm.end());
+    assert(std::rbegin(m) == m.rbegin());
+    assert(std::rbegin(cm) == cm.rbegin());
+    assert(std::rend(m) == cm.rend());
+    assert(std::rend(cm) == cm.rend());
+    assert(std::crbegin(m) == cm.rbegin());
+    assert(std::crbegin(cm) == cm.rbegin());
+    assert(std::crend(m) == cm.rend());
+    assert(std::crend(cm) == cm.rend());
+    assert(std::size(cm) == cm.size());
+    assert(std::ssize(cm) == decltype(std::ssize(m))(m.size()));
+    assert(std::empty(cm) == cm.empty());
+  }
+  {
+    int a[] = {1, 2, 3};
+    assert(std::begin(a) == &a[0]);
+    assert(std::end(a) == &a[3]);
+    assert(std::rbegin(a) == std::reverse_iterator<int*>(std::end(a)));
+    assert(std::rend(a) == std::reverse_iterator<int*>(std::begin(a)));
+    assert(std::size(a) == 3);
+    assert(std::ssize(a) == 3);
+    assert(!std::empty(a));
+    assert(std::data(a) == &a[0]);
+  }
+  {
+    auto a = {1, 2, 3};
+    assert(std::rbegin(a) == std::reverse_iterator<const int*>(std::end(a)));
+    assert(std::rend(a) == std::reverse_iterator<const int*>(std::begin(a)));
+    assert(!std::empty(a));
+    assert(std::data(a) == &*std::begin(a));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
\ No newline at end of file
diff --git a/libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp b/libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp
new file mode 100644
index 0000000000000..d093af6eb8397
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp
@@ -0,0 +1,74 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// UNSUPPORTED: clang-modules-build
+
+// <flat_set>
+
+// 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: <flat_set>
+
+#include <flat_set>
+
+#include <cassert>
+
+#include "test_macros.h"
+
+constexpr bool test() {
+  {
+    std::flat_set<int> m{1, 2, 3};
+    const auto& cm = m;
+    assert(std::begin(m) == m.begin());
+    assert(std::begin(cm) == cm.begin());
+    assert(std::end(m) == m.end());
+    assert(std::end(cm) == cm.end());
+    assert(std::cbegin(m) == cm.begin());
+    assert(std::cbegin(cm) == cm.begin());
+    assert(std::cend(m) == cm.end());
+    assert(std::cend(cm) == cm.end());
+    assert(std::rbegin(m) == m.rbegin());
+    assert(std::rbegin(cm) == cm.rbegin());
+    assert(std::rend(m) == cm.rend());
+    assert(std::rend(cm) == cm.rend());
+    assert(std::crbegin(m) == cm.rbegin());
+    assert(std::crbegin(cm) == cm.rbegin());
+    assert(std::crend(m) == cm.rend());
+    assert(std::crend(cm) == cm.rend());
+    assert(std::size(cm) == cm.size());
+    assert(std::ssize(cm) == decltype(std::ssize(m))(m.size()));
+    assert(std::empty(cm) == cm.empty());
+  }
+  {
+    int a[] = {1, 2, 3};
+    assert(std::begin(a) == &a[0]);
+    assert(std::end(a) == &a[3]);
+    assert(std::rbegin(a) == std::reverse_iterator<int*>(std::end(a)));
+    assert(std::rend(a) == std::reverse_iterator<int*>(std::begin(a)));
+    assert(std::size(a) == 3);
+    assert(std::ssize(a) == 3);
+    assert(!std::empty(a));
+    assert(std::data(a) == &a[0]);
+  }
+  {
+    auto a = {1, 2, 3};
+    assert(std::rbegin(a) == std::reverse_iterator<const int*>(std::end(a)));
+    assert(std::rend(a) == std::reverse_iterator<const int*>(std::begin(a)));
+    assert(!std::empty(a));
+    assert(std::data(a) == &*std::begin(a));
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test();
+
+  return 0;
+}
\ No newline at end of file

>From 66ab265dfe6238fdc31975acc242d19b6ed081fd Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 4 May 2025 18:11:27 +0100
Subject: [PATCH 2/5] use python test

---
 .../test/std/iterator_range_operations.gen.py | 168 ++++++++++++++++++
 .../lwg3987.flat_map.pass copy.cpp            |  74 --------
 .../iterator.range/lwg3987.flat_set.pass.cpp  |  74 --------
 libcxx/test/std/lit.local.cfg                 |   5 +
 4 files changed, 173 insertions(+), 148 deletions(-)
 create mode 100644 libcxx/test/std/iterator_range_operations.gen.py
 delete mode 100644 libcxx/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp
 delete mode 100644 libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp
 create mode 100644 libcxx/test/std/lit.local.cfg

diff --git a/libcxx/test/std/iterator_range_operations.gen.py b/libcxx/test/std/iterator_range_operations.gen.py
new file mode 100644
index 0000000000000..1aad88780f426
--- /dev/null
+++ b/libcxx/test/std/iterator_range_operations.gen.py
@@ -0,0 +1,168 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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
+#
+# ===----------------------------------------------------------------------===##
+
+# Test that headers are not tripped up by the surrounding code defining various
+# alphabetic macros. Also ensure that we don't swallow the definition of user
+# provided macros (in other words, ensure that we push/pop correctly everywhere).
+
+# 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: clang-modules-build
+// UNSUPPORTED: c++03
+
+// Some of the functions' return type, reverse_iterator, is not exported from
+// these headers, so we need to include <iterator> explicitly, which defeats
+// the purpose of this test. So disable the test for clang modules.
+
+#include <{header}>
+#include <cassert>
+
+#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;
+}}
+
+"""
+    )
diff --git a/libcxx/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp b/libcxx/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp
deleted file mode 100644
index 049edf00d4ff4..0000000000000
--- a/libcxx/test/std/iterators/iterator.range/lwg3987.flat_map.pass copy.cpp	
+++ /dev/null
@@ -1,74 +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
-// UNSUPPORTED: clang-modules-build
-
-// <flat_map>
-
-// 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: <flat_map>
-
-#include <flat_map>
-
-#include <cassert>
-
-#include "test_macros.h"
-
-constexpr bool test() {
-  {
-    std::flat_map<int, int> m{{1, 1}, {2, 2}};
-    const auto& cm = m;
-    assert(std::begin(m) == m.begin());
-    assert(std::begin(cm) == cm.begin());
-    assert(std::end(m) == m.end());
-    assert(std::end(cm) == cm.end());
-    assert(std::cbegin(m) == cm.begin());
-    assert(std::cbegin(cm) == cm.begin());
-    assert(std::cend(m) == cm.end());
-    assert(std::cend(cm) == cm.end());
-    assert(std::rbegin(m) == m.rbegin());
-    assert(std::rbegin(cm) == cm.rbegin());
-    assert(std::rend(m) == cm.rend());
-    assert(std::rend(cm) == cm.rend());
-    assert(std::crbegin(m) == cm.rbegin());
-    assert(std::crbegin(cm) == cm.rbegin());
-    assert(std::crend(m) == cm.rend());
-    assert(std::crend(cm) == cm.rend());
-    assert(std::size(cm) == cm.size());
-    assert(std::ssize(cm) == decltype(std::ssize(m))(m.size()));
-    assert(std::empty(cm) == cm.empty());
-  }
-  {
-    int a[] = {1, 2, 3};
-    assert(std::begin(a) == &a[0]);
-    assert(std::end(a) == &a[3]);
-    assert(std::rbegin(a) == std::reverse_iterator<int*>(std::end(a)));
-    assert(std::rend(a) == std::reverse_iterator<int*>(std::begin(a)));
-    assert(std::size(a) == 3);
-    assert(std::ssize(a) == 3);
-    assert(!std::empty(a));
-    assert(std::data(a) == &a[0]);
-  }
-  {
-    auto a = {1, 2, 3};
-    assert(std::rbegin(a) == std::reverse_iterator<const int*>(std::end(a)));
-    assert(std::rend(a) == std::reverse_iterator<const int*>(std::begin(a)));
-    assert(!std::empty(a));
-    assert(std::data(a) == &*std::begin(a));
-  }
-
-  return true;
-}
-
-int main(int, char**) {
-  test();
-
-  return 0;
-}
\ No newline at end of file
diff --git a/libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp b/libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp
deleted file mode 100644
index d093af6eb8397..0000000000000
--- a/libcxx/test/std/iterators/iterator.range/lwg3987.flat_set.pass.cpp
+++ /dev/null
@@ -1,74 +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
-// UNSUPPORTED: clang-modules-build
-
-// <flat_set>
-
-// 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: <flat_set>
-
-#include <flat_set>
-
-#include <cassert>
-
-#include "test_macros.h"
-
-constexpr bool test() {
-  {
-    std::flat_set<int> m{1, 2, 3};
-    const auto& cm = m;
-    assert(std::begin(m) == m.begin());
-    assert(std::begin(cm) == cm.begin());
-    assert(std::end(m) == m.end());
-    assert(std::end(cm) == cm.end());
-    assert(std::cbegin(m) == cm.begin());
-    assert(std::cbegin(cm) == cm.begin());
-    assert(std::cend(m) == cm.end());
-    assert(std::cend(cm) == cm.end());
-    assert(std::rbegin(m) == m.rbegin());
-    assert(std::rbegin(cm) == cm.rbegin());
-    assert(std::rend(m) == cm.rend());
-    assert(std::rend(cm) == cm.rend());
-    assert(std::crbegin(m) == cm.rbegin());
-    assert(std::crbegin(cm) == cm.rbegin());
-    assert(std::crend(m) == cm.rend());
-    assert(std::crend(cm) == cm.rend());
-    assert(std::size(cm) == cm.size());
-    assert(std::ssize(cm) == decltype(std::ssize(m))(m.size()));
-    assert(std::empty(cm) == cm.empty());
-  }
-  {
-    int a[] = {1, 2, 3};
-    assert(std::begin(a) == &a[0]);
-    assert(std::end(a) == &a[3]);
-    assert(std::rbegin(a) == std::reverse_iterator<int*>(std::end(a)));
-    assert(std::rend(a) == std::reverse_iterator<int*>(std::begin(a)));
-    assert(std::size(a) == 3);
-    assert(std::ssize(a) == 3);
-    assert(!std::empty(a));
-    assert(std::data(a) == &a[0]);
-  }
-  {
-    auto a = {1, 2, 3};
-    assert(std::rbegin(a) == std::reverse_iterator<const int*>(std::end(a)));
-    assert(std::rend(a) == std::reverse_iterator<const int*>(std::begin(a)));
-    assert(!std::empty(a));
-    assert(std::data(a) == &*std::begin(a));
-  }
-
-  return true;
-}
-
-int main(int, char**) {
-  test();
-
-  return 0;
-}
\ No newline at end of file
diff --git a/libcxx/test/std/lit.local.cfg b/libcxx/test/std/lit.local.cfg
new file mode 100644
index 0000000000000..4467d8070cc70
--- /dev/null
+++ b/libcxx/test/std/lit.local.cfg
@@ -0,0 +1,5 @@
+# The tests in this directory need to run Python
+import shlex
+import sys
+
+config.substitutions.append(("%{python}", shlex.quote(sys.executable)))

>From 91e4bcc47f4e513b28ce16ecfc68fb0a5fa835fa Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 4 May 2025 18:12:49 +0100
Subject: [PATCH 3/5] comments

---
 libcxx/test/std/iterator_range_operations.gen.py | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libcxx/test/std/iterator_range_operations.gen.py b/libcxx/test/std/iterator_range_operations.gen.py
index 1aad88780f426..0b989f3973257 100644
--- a/libcxx/test/std/iterator_range_operations.gen.py
+++ b/libcxx/test/std/iterator_range_operations.gen.py
@@ -6,10 +6,6 @@
 #
 # ===----------------------------------------------------------------------===##
 
-# Test that headers are not tripped up by the surrounding code defining various
-# alphabetic macros. Also ensure that we don't swallow the definition of user
-# provided macros (in other words, ensure that we push/pop correctly everywhere).
-
 # 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>,

>From 7c8dbe9cdc0d6d2c154654e9b110f237074e324e Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sun, 4 May 2025 19:15:21 +0100
Subject: [PATCH 4/5] format

---
 .../test/std/iterator_range_operations.gen.py | 24 +++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/libcxx/test/std/iterator_range_operations.gen.py b/libcxx/test/std/iterator_range_operations.gen.py
index 0b989f3973257..88e84888d4ac9 100644
--- a/libcxx/test/std/iterator_range_operations.gen.py
+++ b/libcxx/test/std/iterator_range_operations.gen.py
@@ -24,8 +24,28 @@
     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"]))
+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(

>From 409e5c27b9a7e8f188d02ba0318aea8cb1248d69 Mon Sep 17 00:00:00 2001
From: Hui Xie <hui.xie1990 at gmail.com>
Date: Sat, 7 Jun 2025 16:36:11 +0100
Subject: [PATCH 5/5] review

---
 libcxx/include/module.modulemap.in               | 15 +++++++++++++++
 libcxx/test/configs/cmake-bridge.cfg.in          |  3 +++
 libcxx/test/libcxx/lit.local.cfg                 |  5 -----
 libcxx/test/std/iterator_range_operations.gen.py |  3 ++-
 libcxx/test/std/lit.local.cfg                    |  5 -----
 5 files changed, 20 insertions(+), 11 deletions(-)
 delete mode 100644 libcxx/test/libcxx/lit.local.cfg
 delete mode 100644 libcxx/test/std/lit.local.cfg

diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 7f625cefed1c2..2c44752ccb916 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -876,6 +876,7 @@ module std [system] {
 
     header "array"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module atomic {
@@ -1230,6 +1231,7 @@ module std [system] {
 
     header "deque"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module exception {
@@ -1305,6 +1307,7 @@ module std [system] {
 
     header "flat_map"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module flat_set {
@@ -1321,6 +1324,7 @@ module std [system] {
     export std.flat_map.sorted_unique
     export std.flat_map.sorted_equivalent
     export *
+    export std.iterator.reverse_iterator
   }
 
   module format {
@@ -1376,6 +1380,7 @@ module std [system] {
   module forward_list {
     header "forward_list"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module fstream {
@@ -1550,6 +1555,7 @@ module std [system] {
   module list {
     header "list"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module locale {
@@ -1592,6 +1598,7 @@ module std [system] {
     module fwd { header "__fwd/map.h" }
     header "map"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module mdspan {
@@ -1937,6 +1944,7 @@ module std [system] {
   module regex {
     header "regex"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module scoped_allocator {
@@ -1953,6 +1961,7 @@ module std [system] {
     module fwd { header "__fwd/set.h" }
     header "set"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module shared_mutex {
@@ -1970,6 +1979,7 @@ module std [system] {
 
     header "span"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module sstream {
@@ -2022,6 +2032,7 @@ module std [system] {
 
     header "string"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module string_view {
@@ -2029,6 +2040,7 @@ module std [system] {
 
     header "string_view"
     export *
+    export std.iterator.reverse_iterator
   }
 
   module strstream {
@@ -2110,11 +2122,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 {
@@ -2203,6 +2217,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/iterator_range_operations.gen.py b/libcxx/test/std/iterator_range_operations.gen.py
index 88e84888d4ac9..3d791e661c5a9 100644
--- a/libcxx/test/std/iterator_range_operations.gen.py
+++ b/libcxx/test/std/iterator_range_operations.gen.py
@@ -53,7 +53,7 @@
 //--- {header}.pass.cpp
 {lit_header_restrictions.get(header, '')}
 {lit_header_undeprecations.get(header, '')}
-// UNSUPPORTED: clang-modules-build
+// SUPPORTED: clang-modules-build
 // UNSUPPORTED: c++03
 
 // Some of the functions' return type, reverse_iterator, is not exported from
@@ -62,6 +62,7 @@
 
 #include <{header}>
 #include <cassert>
+#include <initializer_list>
 
 #include "test_macros.h"
 
diff --git a/libcxx/test/std/lit.local.cfg b/libcxx/test/std/lit.local.cfg
deleted file mode 100644
index 4467d8070cc70..0000000000000
--- a/libcxx/test/std/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)))



More information about the libcxx-commits mailing list