[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
Sun Apr 27 08:42:28 PDT 2025


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

None

>From 532b44a56118cdb85bfc032ee827833cc6db372a 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] [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



More information about the libcxx-commits mailing list