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

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Jun 6 10:31:57 PDT 2025


================
@@ -0,0 +1,184 @@
+# ===----------------------------------------------------------------------===##
+#
+# 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: 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**)  {{
+  {{
----------------
ldionne wrote:

Since the Standard says (emphasis mine):

>  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

I'm not certain whether they actually mean that the function can be called at runtime without additional includes. As you pointed out, would it be conforming to only provide a forward declaration of these functions?

Depending on the answer to this question, we can either leave the runtime tests in (and that means these headers effectively have to *define* `reverse_iterator`), or we can turn them into something like

```
requires (Container c) {
  { std::begin(c) };
  { std::rbegin(c) };
  // etc...
}
```

@frederick-vs-ja Do you have an opinion on the interpretation of the word **available** here? If we're too unsure, we should probably ask on the LWG reflector or open a LWG issue.

I'd argue that if a forward-declaration is conforming, this requirement from the Standard isn't very useful for end users.

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


More information about the libcxx-commits mailing list