[libcxx-commits] [libcxx] [libc++][ranges] implement `ranges::elements_of` (PR #91414)
Xiaoyang Liu via libcxx-commits
libcxx-commits at lists.llvm.org
Wed May 8 10:22:24 PDT 2024
https://github.com/xiaoyang-sde updated https://github.com/llvm/llvm-project/pull/91414
>From 1807a424108f29e2cf73f8ac8b086a2f28f52939 Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Tue, 7 May 2024 17:58:02 -0700
Subject: [PATCH 1/5] [libc++][ranges] implement 'ranges::elements_of'
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__ranges/elements_of.h | 47 +++++++++++++++++++
libcxx/include/ranges | 5 ++
libcxx/modules/std/ranges.inc | 4 +-
.../range.elementsof/elements_of.pass.cpp | 39 +++++++++++++++
5 files changed, 95 insertions(+), 1 deletion(-)
create mode 100644 libcxx/include/__ranges/elements_of.h
create mode 100644 libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index fd7eb125e007b..b1f9be1dc3d7d 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -646,6 +646,7 @@ set(files
__ranges/data.h
__ranges/drop_view.h
__ranges/drop_while_view.h
+ __ranges/elements_of.h
__ranges/elements_view.h
__ranges/empty.h
__ranges/empty_view.h
diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h
new file mode 100644
index 0000000000000..727ba92666eb3
--- /dev/null
+++ b/libcxx/include/__ranges/elements_of.h
@@ -0,0 +1,47 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_ELEMENTS_OF_H
+#define _LIBCPP___RANGES_ELEMENTS_OF_H
+
+#include <__config>
+#include <__memory/allocator.h>
+#include <__ranges/concepts.h>
+#include <cstddef>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 23
+
+namespace ranges {
+
+template <range _Range, class _Allocator = allocator<byte>>
+struct elements_of {
+ _LIBCPP_NO_UNIQUE_ADDRESS _Range range;
+ _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator();
+};
+
+template <class _Range, class _Allocator = allocator<byte>>
+elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>;
+
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 23
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+#endif // _LIBCPP___RANGES_ELEMENTS_OF_H
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 07a525ed8641f..a8fbfc462bf0d 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -116,6 +116,10 @@ namespace std::ranges {
// [range.dangling], dangling iterator handling
struct dangling;
+ // [range.elementsof], class template elements_of
+ template<range R, class Allocator = allocator<byte>>
+ struct elements_of;
+
template<range R>
using borrowed_iterator_t = see below;
@@ -392,6 +396,7 @@ namespace std {
#include <__ranges/data.h>
#include <__ranges/drop_view.h>
#include <__ranges/drop_while_view.h>
+#include <__ranges/elements_of.h>
#include <__ranges/elements_view.h>
#include <__ranges/empty.h>
#include <__ranges/empty_view.h>
diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc
index 80f31c79a1a40..94f3defdcbc35 100644
--- a/libcxx/modules/std/ranges.inc
+++ b/libcxx/modules/std/ranges.inc
@@ -83,8 +83,10 @@ export namespace std {
// [range.dangling], dangling iterator handling
using std::ranges::dangling;
+#if _LIBCPP_STD_VER >= 23
// [range.elementsof], class template elements_of
- // using std::ranges::elements_of;
+ using std::ranges::elements_of;
+#endif
using std::ranges::borrowed_iterator_t;
diff --git a/libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp b/libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp
new file mode 100644
index 0000000000000..e1c2f91b96079
--- /dev/null
+++ b/libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// std::ranges::elements_of;
+
+#include <ranges>
+
+#include <vector>
+#include <concepts>
+
+constexpr bool test() {
+ {
+ auto elements_of = std::ranges::elements_of(std::vector<int>());
+ static_assert(
+ std::same_as<decltype(elements_of), std::ranges::elements_of<std::vector<int>&&, std::allocator<std::byte>>>);
+ static_assert(std::same_as<decltype(elements_of.range), std::vector<int>&&>);
+ static_assert(std::same_as<decltype(elements_of.allocator), std::allocator<std::byte>>);
+ }
+ {
+ auto elements_of = std::ranges::elements_of(std::vector<int>(), std::allocator<int>());
+ static_assert(
+ std::same_as<decltype(elements_of), std::ranges::elements_of<std::vector<int>&&, std::allocator<int>>>);
+ static_assert(std::same_as<decltype(elements_of.range), std::vector<int>&&>);
+ static_assert(std::same_as<decltype(elements_of.allocator), std::allocator<int>>);
+ }
+ return true;
+}
+
+int main() {
+ test();
+ static_assert(test());
+}
>From e14469bc4b829a7d40e8a445920d396ef08c5dda Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Tue, 7 May 2024 18:03:43 -0700
Subject: [PATCH 2/5] [libc++][ranges] implement 'ranges::elements_of'
---
libcxx/include/__ranges/elements_of.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h
index 727ba92666eb3..d7cb1937563c6 100644
--- a/libcxx/include/__ranges/elements_of.h
+++ b/libcxx/include/__ranges/elements_of.h
@@ -44,4 +44,5 @@ elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Alloc
_LIBCPP_END_NAMESPACE_STD
_LIBCPP_POP_MACROS
+
#endif // _LIBCPP___RANGES_ELEMENTS_OF_H
>From 85ca069a211767c13059a315803fb71c442540a5 Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Tue, 7 May 2024 18:04:53 -0700
Subject: [PATCH 3/5] [libc++][ranges] implement 'ranges::elements_of'
---
.../ranges/range.utility/range.elementsof/elements_of.pass.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp b/libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp
index e1c2f91b96079..378bcb0a2f13f 100644
--- a/libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp
+++ b/libcxx/test/std/ranges/range.utility/range.elementsof/elements_of.pass.cpp
@@ -12,8 +12,9 @@
#include <ranges>
-#include <vector>
#include <concepts>
+#include <memory>
+#include <vector>
constexpr bool test() {
{
>From b031c387baf12789a0da5268da2c92710087aac8 Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Tue, 7 May 2024 19:45:10 -0700
Subject: [PATCH 4/5] [libc++][ranges] implement 'ranges::elements_of'
---
libcxx/include/module.modulemap | 1 +
1 file changed, 1 insertion(+)
diff --git a/libcxx/include/module.modulemap b/libcxx/include/module.modulemap
index 2974d12500c4c..ee952c48c11d5 100644
--- a/libcxx/include/module.modulemap
+++ b/libcxx/include/module.modulemap
@@ -1699,6 +1699,7 @@ module std_private_ranges_dangling [system] { header "__ranges
module std_private_ranges_data [system] { header "__ranges/data.h" }
module std_private_ranges_drop_view [system] { header "__ranges/drop_view.h" }
module std_private_ranges_drop_while_view [system] { header "__ranges/drop_while_view.h" }
+module std_private_ranges_elements_of [system] { header "__ranges/elements_of.h" }
module std_private_ranges_elements_view [system] { header "__ranges/elements_view.h" }
module std_private_ranges_empty [system] { header "__ranges/empty.h" }
module std_private_ranges_empty_view [system] { header "__ranges/empty_view.h" }
>From 32b68f274244cc866d7edf5a83fffcb4ba0bec19 Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Wed, 8 May 2024 13:22:10 -0400
Subject: [PATCH 5/5] [libc++][ranges] implement 'ranges::elements_of'
---
libcxx/include/__ranges/elements_of.h | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h
index d7cb1937563c6..6219446a742a8 100644
--- a/libcxx/include/__ranges/elements_of.h
+++ b/libcxx/include/__ranges/elements_of.h
@@ -31,7 +31,11 @@ namespace ranges {
template <range _Range, class _Allocator = allocator<byte>>
struct elements_of {
_LIBCPP_NO_UNIQUE_ADDRESS _Range range;
- _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator();
+ _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator;
+
+ // This explicit constructor is required because AppleClang 15 hasn't implement P0960R3
+ explicit elements_of(_Range&& __range, _Allocator __allocator = _Allocator())
+ : range(std::move(__range)), allocator(std::move(__allocator)) {}
};
template <class _Range, class _Allocator = allocator<byte>>
More information about the libcxx-commits
mailing list