[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