From 1807a424108f29e2cf73f8ac8b086a2f28f52939 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Tue, 7 May 2024 17:58:02 -0700 Subject: [PATCH 01/27] [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 + +#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 > +struct elements_of { + _LIBCPP_NO_UNIQUE_ADDRESS _Range range; + _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); +}; + +template > +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> + struct elements_of; + template 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 + +#include +#include + +constexpr bool test() { + { + auto elements_of = std::ranges::elements_of(std::vector()); + static_assert( + std::same_as&&, std::allocator>>); + static_assert(std::same_as&&>); + static_assert(std::same_as>); + } + { + auto elements_of = std::ranges::elements_of(std::vector(), std::allocator()); + static_assert( + std::same_as&&, std::allocator>>); + static_assert(std::same_as&&>); + static_assert(std::same_as>); + } + return true; +} + +int main() { + test(); + static_assert(test()); +} From e14469bc4b829a7d40e8a445920d396ef08c5dda Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Tue, 7 May 2024 18:03:43 -0700 Subject: [PATCH 02/27] [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 Date: Tue, 7 May 2024 18:04:53 -0700 Subject: [PATCH 03/27] [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 -#include #include +#include +#include constexpr bool test() { { From b031c387baf12789a0da5268da2c92710087aac8 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Tue, 7 May 2024 19:45:10 -0700 Subject: [PATCH 04/27] [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 Date: Wed, 8 May 2024 13:22:10 -0400 Subject: [PATCH 05/27] [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 > 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 > From 8e3560904d1cc79d014acba31eb2586edd71869d Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Wed, 8 May 2024 13:36:27 -0400 Subject: [PATCH 06/27] [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 6219446a742a8..043bcb918a692 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -13,6 +13,7 @@ #include <__config> #include <__memory/allocator.h> #include <__ranges/concepts.h> +#include <__utility/move.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) From 162ce8ab091420ff39031aad4260843ac8df6391 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Wed, 8 May 2024 16:36:47 -0400 Subject: [PATCH 07/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index 043bcb918a692..93020c93d5f7b 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -35,7 +35,7 @@ struct elements_of { _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()) + _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range __range, _Allocator __allocator = _Allocator()) : range(std::move(__range)), allocator(std::move(__allocator)) {} }; From 9dd983d4ccd1ac0e1b5a74340212d6013309cf2d Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Wed, 8 May 2024 16:51:32 -0400 Subject: [PATCH 08/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index 93020c93d5f7b..edce0af345f37 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -35,8 +35,8 @@ struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator; // This explicit constructor is required because AppleClang 15 hasn't implement P0960R3 - _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range __range, _Allocator __allocator = _Allocator()) - : range(std::move(__range)), allocator(std::move(__allocator)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range __range, _Allocator __alloc = _Allocator()) + : range(std::move(__range)), allocator(std::move(__alloc)) {} }; template > From 8291917ab08f32b609b7c2711ce63de9b649051b Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Tue, 14 May 2024 12:49:39 -0400 Subject: [PATCH 09/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index edce0af345f37..f446d3c12d67e 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -40,6 +40,8 @@ struct elements_of { }; template > +// This explicit constraint is required because AppleClang 15 might not deduce the correct type for `_Range` without it + requires range<_Range&&> elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>; } // namespace ranges From b741665949ed7fc8b58b757ae22499b7bff0aba7 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Sun, 28 Jul 2024 22:10:33 +0800 Subject: [PATCH 10/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 6 ++- .../range.elementsof/elements_of.pass.cpp | 48 +++++++++++++------ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index f446d3c12d67e..1b8f916589505 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -32,16 +32,20 @@ namespace ranges { template > struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Range range; - _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator; + _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); +# if defined(_LIBCPP_COMPILER_CLANG_BASED) && _LIBCPP_CLANG_VER < 1600 // This explicit constructor is required because AppleClang 15 hasn't implement P0960R3 _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range __range, _Allocator __alloc = _Allocator()) : range(std::move(__range)), allocator(std::move(__alloc)) {} +# endif }; template > +# if defined(_LIBCPP_COMPILER_CLANG_BASED) && _LIBCPP_CLANG_VER < 1600 // This explicit constraint is required because AppleClang 15 might not deduce the correct type for `_Range` without it requires range<_Range&&> +# endif elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>; } // namespace ranges 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 378bcb0a2f13f..8bdb4f7992ae2 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 @@ -16,25 +16,43 @@ #include #include +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_iterators.h" + +template +constexpr bool test_range() { + std::same_as>> decltype(auto) elements_of = + std::ranges::elements_of(Range()); + [[maybe_unused]] std::same_as decltype(auto) elements_of_range = std::move(elements_of.range); + [[maybe_unused]] std::same_as> decltype(auto) elements_of_allocator = elements_of.allocator; + return true; +} + +template +constexpr bool test_range_with_allocator() { + std::same_as< std::ranges::elements_of< Range&&, Allocator >> decltype(auto) elements_of = + std::ranges::elements_of(Range(), Allocator()); + [[maybe_unused]] std::same_as decltype(auto) elements_of_range = std::move(elements_of.range); + [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; + return true; +} + constexpr bool test() { - { - auto elements_of = std::ranges::elements_of(std::vector()); - static_assert( - std::same_as&&, std::allocator>>); - static_assert(std::same_as&&>); - static_assert(std::same_as>); - } - { - auto elements_of = std::ranges::elements_of(std::vector(), std::allocator()); - static_assert( - std::same_as&&, std::allocator>>); - static_assert(std::same_as&&>); - static_assert(std::same_as>); - } + types::for_each(types::type_list, min_allocator, test_allocator>{}, + [] { + types::for_each(types::type_list>{}, [] { + test_range(); + test_range_with_allocator(); + }); + }); + return true; } -int main() { +int main(int, char**) { test(); static_assert(test()); + + return 0; } From 07a62fe1e65a3c5c147acc9088f26a36faffa57e Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 12:50:36 -0400 Subject: [PATCH 11/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 4 ++-- libcxx/test/libcxx/transitive_includes/cxx03.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx11.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx14.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx17.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx20.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx23.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx26.csv | 1 + 8 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index 1b8f916589505..b2a93e9d55340 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -35,7 +35,7 @@ struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); # if defined(_LIBCPP_COMPILER_CLANG_BASED) && _LIBCPP_CLANG_VER < 1600 - // This explicit constructor is required because AppleClang 15 hasn't implement P0960R3 + // This explicit constructor is required because AppleClang 15 hasn't implemented P0960R3. _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range __range, _Allocator __alloc = _Allocator()) : range(std::move(__range)), allocator(std::move(__alloc)) {} # endif @@ -43,7 +43,7 @@ struct elements_of { template > # if defined(_LIBCPP_COMPILER_CLANG_BASED) && _LIBCPP_CLANG_VER < 1600 -// This explicit constraint is required because AppleClang 15 might not deduce the correct type for `_Range` without it +// This explicit constraint is required because AppleClang 15 might not deduce the correct type for `_Range` without it. requires range<_Range&&> # endif elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>; diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv index fd2cd7f1c2d96..f0efe06a01cd1 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -671,6 +671,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits +ranges new ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv index 04122fd0f4571..64a4954730d97 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -676,6 +676,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits +ranges new ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv index 42c742bead0c1..bc56918cb638b 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -679,6 +679,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits +ranges new ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv index bc0659127d4bf..29791eb0b56e3 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -680,6 +680,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits +ranges new ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv index fed0944f0219c..70470de2106e7 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -687,6 +687,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits +ranges new ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv index 53f99384a7f57..117a87b66a2cd 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -464,6 +464,7 @@ ranges cwchar ranges initializer_list ranges iterator ranges limits +ranges new ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv index 53f99384a7f57..117a87b66a2cd 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -464,6 +464,7 @@ ranges cwchar ranges initializer_list ranges iterator ranges limits +ranges new ranges optional ranges span ranges tuple From 74bd1855a16977ffd2e93619fa0e0cdfe83762d3 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 12:55:24 -0400 Subject: [PATCH 12/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index b2a93e9d55340..f23e8dd4a15e5 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -34,7 +34,7 @@ struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Range range; _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); -# if defined(_LIBCPP_COMPILER_CLANG_BASED) && _LIBCPP_CLANG_VER < 1600 +# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 // This explicit constructor is required because AppleClang 15 hasn't implemented P0960R3. _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range __range, _Allocator __alloc = _Allocator()) : range(std::move(__range)), allocator(std::move(__alloc)) {} @@ -42,7 +42,7 @@ struct elements_of { }; template > -# if defined(_LIBCPP_COMPILER_CLANG_BASED) && _LIBCPP_CLANG_VER < 1600 +# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 // This explicit constraint is required because AppleClang 15 might not deduce the correct type for `_Range` without it. requires range<_Range&&> # endif From 5e37e03d58d03a739942a0354646f057312be35f Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 14:04:15 -0400 Subject: [PATCH 13/27] [libc++][ranges] implement 'ranges::elements_of' --- .../range.elementsof/ctad.compile.pass.cpp | 49 ++++++++++++++ .../range.elementsof/elements_of.pass.cpp | 66 ++++++++++++++----- 2 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp diff --git a/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp new file mode 100644 index 0000000000000..3a679b521f75e --- /dev/null +++ b/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// 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 + +#include + +#include "min_allocator.h" +#include "test_allocator.h" +#include "test_iterators.h" + +template +struct Range { + Iterator begin() const; + sentinel_wrapper end() const; +}; + +constexpr bool test() { + types::for_each( + types::type_list, min_allocator, test_allocator>{}, + [] { + types::for_each(types::cpp20_input_iterator_list{}, [] { + Range r; + static_assert(std::same_as&, std::allocator>>); + static_assert(std::same_as())), + std::ranges::elements_of&&, std::allocator>>); + + Allocator a; + static_assert(std::same_as&, Allocator>>); + static_assert(std::same_as(), Allocator())), + std::ranges::elements_of&&, Allocator>>); + }); + }); + + return true; +} + +static_assert(test()); 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 8bdb4f7992ae2..8c6a8f98058c8 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,7 +12,6 @@ #include -#include #include #include @@ -20,30 +19,63 @@ #include "test_allocator.h" #include "test_iterators.h" -template +template +struct Range { + using Sentinel = sentinel_wrapper; + + Iterator begin() { return Iterator(data.data()); } + + sentinel_wrapper end() { return Sentinel(Iterator(data.data() + data.size())); } + + std::vector data = {0, 1, 2, 3}; +}; + +template constexpr bool test_range() { - std::same_as>> decltype(auto) elements_of = - std::ranges::elements_of(Range()); - [[maybe_unused]] std::same_as decltype(auto) elements_of_range = std::move(elements_of.range); - [[maybe_unused]] std::same_as> decltype(auto) elements_of_allocator = elements_of.allocator; - return true; -} + Range r; + + using elements_of_t = std::ranges::elements_of; + { + // constructor + std::same_as decltype(auto) elements_of = std::ranges::elements_of(r, Allocator()); + [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; + [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; + } + { + // designated initializer + std::same_as decltype(auto) elements_of = std::ranges::elements_of{ + .range = r, + .allocator = Allocator(), + }; + [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; + [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; + } + { + // copy constructor + std::same_as decltype(auto) elements_of_1 = std::ranges::elements_of(r, Allocator()); + std::same_as auto elements_of_2 = elements_of_1; + [[maybe_unused]] std::same_as decltype(auto) elements_of_1_range = elements_of_1.range; + [[maybe_unused]] std::same_as decltype(auto) elements_of_2_range = elements_of_2.range; + [[maybe_unused]] std::same_as decltype(auto) elements_of_2_allocator = elements_of_2.allocator; + } -template -constexpr bool test_range_with_allocator() { - std::same_as< std::ranges::elements_of< Range&&, Allocator >> decltype(auto) elements_of = - std::ranges::elements_of(Range(), Allocator()); - [[maybe_unused]] std::same_as decltype(auto) elements_of_range = std::move(elements_of.range); - [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; + using elements_of_r_t = std::ranges::elements_of; + { + // move constructor + std::same_as decltype(auto) elements_of_1 = std::ranges::elements_of(std::move(r), Allocator()); + std::same_as auto elements_of_2 = std::move(elements_of_1); + [[maybe_unused]] std::same_as decltype(auto) elements_of_1_range = std::move(elements_of_1.range); + [[maybe_unused]] std::same_as decltype(auto) elements_of_2_range = std::move(elements_of_2.range); + [[maybe_unused]] std::same_as decltype(auto) elements_of_2_allocator = elements_of_2.allocator; + } return true; } constexpr bool test() { types::for_each(types::type_list, min_allocator, test_allocator>{}, [] { - types::for_each(types::type_list>{}, [] { - test_range(); - test_range_with_allocator(); + types::for_each(types::cpp20_input_iterator_list{}, [] { + test_range, Allocator>(); }); }); From cd3b4cd40ee16c41e7c3f5070e7fde13c1373c84 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 14:09:12 -0400 Subject: [PATCH 14/27] [libc++][ranges] implement 'ranges::elements_of' --- .../range.elementsof/elements_of.pass.cpp | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) 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 8c6a8f98058c8..945d9dd67a34a 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 @@ -13,6 +13,7 @@ #include #include +#include #include #include "min_allocator.h" @@ -23,11 +24,12 @@ template struct Range { using Sentinel = sentinel_wrapper; - Iterator begin() { return Iterator(data.data()); } + Iterator begin() { return Iterator(data_.data()); } - sentinel_wrapper end() { return Sentinel(Iterator(data.data() + data.size())); } + sentinel_wrapper end() { return Sentinel(Iterator(data_.data() + data_.size())); } - std::vector data = {0, 1, 2, 3}; +private: + std::vector data_ = {0, 1, 2, 3}; }; template @@ -39,6 +41,9 @@ constexpr bool test_range() { // constructor std::same_as decltype(auto) elements_of = std::ranges::elements_of(r, Allocator()); [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; + if (!std::is_constant_evaluated()) { + assert(std::ranges::distance(elements_of_range) == 4); + } [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; } { @@ -47,7 +52,10 @@ constexpr bool test_range() { .range = r, .allocator = Allocator(), }; - [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; + [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; + if (!std::is_constant_evaluated()) { + assert(std::ranges::distance(elements_of_range) == 4); + } [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; } { @@ -56,6 +64,10 @@ constexpr bool test_range() { std::same_as auto elements_of_2 = elements_of_1; [[maybe_unused]] std::same_as decltype(auto) elements_of_1_range = elements_of_1.range; [[maybe_unused]] std::same_as decltype(auto) elements_of_2_range = elements_of_2.range; + if (!std::is_constant_evaluated()) { + assert(std::ranges::distance(elements_of_1_range) == 4); + assert(std::ranges::distance(elements_of_2_range) == 4); + } [[maybe_unused]] std::same_as decltype(auto) elements_of_2_allocator = elements_of_2.allocator; } @@ -64,8 +76,12 @@ constexpr bool test_range() { // move constructor std::same_as decltype(auto) elements_of_1 = std::ranges::elements_of(std::move(r), Allocator()); std::same_as auto elements_of_2 = std::move(elements_of_1); - [[maybe_unused]] std::same_as decltype(auto) elements_of_1_range = std::move(elements_of_1.range); - [[maybe_unused]] std::same_as decltype(auto) elements_of_2_range = std::move(elements_of_2.range); + [[maybe_unused]] std::same_as decltype(auto) elements_of_1_range = std::move(elements_of_1.range); + [[maybe_unused]] std::same_as decltype(auto) elements_of_2_range = std::move(elements_of_2.range); + if (!std::is_constant_evaluated()) { + assert(std::ranges::distance(elements_of_1_range) == 4); + assert(std::ranges::distance(elements_of_2_range) == 4); + } [[maybe_unused]] std::same_as decltype(auto) elements_of_2_allocator = elements_of_2.allocator; } return true; From bfb0e2511fb6d0d83178fb9f90a4a00f9b1dd0df Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 14:18:39 -0400 Subject: [PATCH 15/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/test/libcxx/transitive_includes/cxx03.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv index f0efe06a01cd1..fd2cd7f1c2d96 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -671,7 +671,6 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits -ranges new ranges optional ranges span ranges tuple From aacbc6b65346b18b1e2cd065387d42aebb800868 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 15:42:24 -0400 Subject: [PATCH 16/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/test/libcxx/transitive_includes/cxx11.csv | 2 +- libcxx/test/libcxx/transitive_includes/cxx14.csv | 2 +- libcxx/test/libcxx/transitive_includes/cxx17.csv | 2 +- libcxx/test/libcxx/transitive_includes/cxx20.csv | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv index 64a4954730d97..1d4dea0b18ba6 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -676,7 +676,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits -ranges new + ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv index bc56918cb638b..72f55701ee1b3 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -679,7 +679,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits -ranges new + ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv index 29791eb0b56e3..2591484084da5 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -680,7 +680,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits -ranges new + ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv index 70470de2106e7..8d832cdacf993 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -687,7 +687,7 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits -ranges new + ranges optional ranges span ranges tuple From ffc970083fa5b3e4950dfb2479d9d625ddfd29db Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 15:43:08 -0400 Subject: [PATCH 17/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/test/libcxx/transitive_includes/cxx11.csv | 1 - libcxx/test/libcxx/transitive_includes/cxx14.csv | 1 - libcxx/test/libcxx/transitive_includes/cxx17.csv | 1 - libcxx/test/libcxx/transitive_includes/cxx20.csv | 1 - 4 files changed, 4 deletions(-) diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv index 1d4dea0b18ba6..04122fd0f4571 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -676,7 +676,6 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits - ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv index 72f55701ee1b3..42c742bead0c1 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -679,7 +679,6 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits - ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv index 2591484084da5..bc0659127d4bf 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -680,7 +680,6 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits - ranges optional ranges span ranges tuple diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv index 8d832cdacf993..fed0944f0219c 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -687,7 +687,6 @@ ranges initializer_list ranges iosfwd ranges iterator ranges limits - ranges optional ranges span ranges tuple From 4c72a3a27463672b1eac3582836851778634ce02 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 23:46:16 -0400 Subject: [PATCH 18/27] [libc++][ranges] implement 'ranges::elements_of' --- .../range.elementsof/elements_of.pass.cpp | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) 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 945d9dd67a34a..13ce4cbea964d 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 @@ -48,15 +48,21 @@ constexpr bool test_range() { } { // designated initializer - std::same_as decltype(auto) elements_of = std::ranges::elements_of{ - .range = r, - .allocator = Allocator(), - }; - [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; - if (!std::is_constant_evaluated()) { - assert(std::ranges::distance(elements_of_range) == 4); + + // AppleClang 15 hasn't implemented P0960R3, so `std::ranges::elements_of` requires a + // user-defined constructor, making it non-aggregate and therefore incompatible with designated + // initializers. + if constexpr (std::is_aggregate_v) { + std::same_as decltype(auto) elements_of = std::ranges::elements_of{ + .range = r, + .allocator = Allocator(), + }; + [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; + if (!std::is_constant_evaluated()) { + assert(std::ranges::distance(elements_of_range) == 4); + } + [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; } - [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; } { // copy constructor From c2df436f696ba4494ce676436d7022c2cf222604 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 8 Aug 2024 23:52:09 -0400 Subject: [PATCH 19/27] [libc++][ranges] implement 'ranges::elements_of' --- .../ranges/range.utility/range.elementsof/elements_of.pass.cpp | 2 +- 1 file changed, 1 insertion(+), 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 13ce4cbea964d..38392383029d0 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 @@ -48,7 +48,7 @@ constexpr bool test_range() { } { // designated initializer - + // AppleClang 15 hasn't implemented P0960R3, so `std::ranges::elements_of` requires a // user-defined constructor, making it non-aggregate and therefore incompatible with designated // initializers. From 5884764de738c8cc30de3d967b662033c6e8f476 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Fri, 9 Aug 2024 00:31:52 -0400 Subject: [PATCH 20/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 34 +++++++++++++++++---------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index f23e8dd4a15e5..f6e1218cd998a 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -17,7 +17,7 @@ #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -# pragma GCC system_header +#pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -29,24 +29,32 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -template > -struct elements_of { +template > struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Range range; _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); -# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 - // This explicit constructor is required because AppleClang 15 hasn't implemented P0960R3. - _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range __range, _Allocator __alloc = _Allocator()) - : range(std::move(__range)), allocator(std::move(__alloc)) {} -# endif +#if defined(_LIBCPP_COMPILER_CLANG_BASED) && \ + defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 + // This explicit constructor is required because AppleClang 15 hasn't + // implemented P0960R3. + template > + _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of( + _Range2 &&Range, _Allocator2 &&Alloc = _Allocator()) + : range(std::forward<_Range2>(Range)), + allocator(std::forward<_Allocator2>(Alloc)) {} +#endif }; template > -# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 -// This explicit constraint is required because AppleClang 15 might not deduce the correct type for `_Range` without it. - requires range<_Range&&> -# endif -elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>; +#if defined(_LIBCPP_COMPILER_CLANG_BASED) && \ + defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 +// This explicit constraint is required because AppleClang 15 might not deduce +// the correct type for `_Range` without it. + requires range<_Range &&> +#endif +elements_of(_Range &&, + _Allocator = _Allocator()) -> elements_of<_Range &&, _Allocator>; } // namespace ranges From 752d590e4f8dd8ab28ba30129dfbd614654121a1 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Fri, 9 Aug 2024 02:37:21 -0400 Subject: [PATCH 21/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 31 +++++++++++---------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index f6e1218cd998a..bb79adeed538c 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -13,11 +13,11 @@ #include <__config> #include <__memory/allocator.h> #include <__ranges/concepts.h> -#include <__utility/move.h> +#include <__utility/forward.h> #include #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) -#pragma GCC system_header +# pragma GCC system_header #endif _LIBCPP_PUSH_MACROS @@ -29,32 +29,27 @@ _LIBCPP_BEGIN_NAMESPACE_STD namespace ranges { -template > struct elements_of { +template > +struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Range range; _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); -#if defined(_LIBCPP_COMPILER_CLANG_BASED) && \ - defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 +# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 // This explicit constructor is required because AppleClang 15 hasn't // implemented P0960R3. - template > - _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of( - _Range2 &&Range, _Allocator2 &&Alloc = _Allocator()) - : range(std::forward<_Range2>(Range)), - allocator(std::forward<_Allocator2>(Alloc)) {} -#endif + template > + _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range2&& Range, _Allocator2&& Alloc = _Allocator()) + : range(std::forward<_Range2>(Range)), allocator(std::forward<_Allocator2>(Alloc)) {} +# endif }; template > -#if defined(_LIBCPP_COMPILER_CLANG_BASED) && \ - defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 +# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 // This explicit constraint is required because AppleClang 15 might not deduce // the correct type for `_Range` without it. - requires range<_Range &&> -#endif -elements_of(_Range &&, - _Allocator = _Allocator()) -> elements_of<_Range &&, _Allocator>; + requires range<_Range&&> +# endif +elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>; } // namespace ranges From 93c65aa6c7fc7117fb153ca32c3e84c62e2a0051 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Mon, 12 Aug 2024 21:37:53 -0400 Subject: [PATCH 22/27] [libc++][ranges] implement 'ranges::elements_of' --- .../ranges/range.utility/range.elementsof/elements_of.pass.cpp | 1 + 1 file changed, 1 insertion(+) 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 38392383029d0..090a0dd50c778 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,6 +12,7 @@ #include +#include #include #include #include From 94b9c2c31884c5ed15bcf7044f2979d0eb6cce7a Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Sun, 18 Aug 2024 15:52:22 -0400 Subject: [PATCH 23/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index bb79adeed538c..fd918c3df0233 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -34,7 +34,7 @@ struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Range range; _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); -# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 +# if !defined(__cpp_aggregate_paren_init) // This explicit constructor is required because AppleClang 15 hasn't // implemented P0960R3. template > From 06f28a1a0f3a60fcb2ead8f700bd2d3bb4c3296b Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Tue, 27 Aug 2024 21:31:36 -0400 Subject: [PATCH 24/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 2 +- .../range.elementsof/ctad.compile.pass.cpp | 10 +++++++ .../range.elementsof/elements_of.pass.cpp | 28 +++++++++---------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index fd918c3df0233..f414a662907a9 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -37,7 +37,7 @@ struct elements_of { # if !defined(__cpp_aggregate_paren_init) // This explicit constructor is required because AppleClang 15 hasn't // implemented P0960R3. - template > + template > _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range2&& Range, _Allocator2&& Alloc = _Allocator()) : range(std::forward<_Range2>(Range)), allocator(std::forward<_Allocator2>(Alloc)) {} # endif diff --git a/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp index 3a679b521f75e..0f9204a07118e 100644 --- a/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp @@ -40,6 +40,16 @@ constexpr bool test() { std::ranges::elements_of&, Allocator>>); static_assert(std::same_as(), Allocator())), std::ranges::elements_of&&, Allocator>>); + +// AppleClang 15 hasn't implemented P0960R3 and P1816R0 +#if defined(__cpp_aggregate_paren_init) && __cpp_aggregate_paren_init >= 201902L && defined(__cpp_deduction_guides) && \ + __cpp_deduction_guides >= 201907L + static_assert(std::same_as&, Allocator>>); + static_assert( + std::same_as(), .allocator = Allocator()}), + std::ranges::elements_of&&, Allocator>>); +#endif }); }); 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 090a0dd50c778..f18a3bc8c61bc 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 @@ -48,22 +48,20 @@ constexpr bool test_range() { [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; } { - // designated initializer - - // AppleClang 15 hasn't implemented P0960R3, so `std::ranges::elements_of` requires a - // user-defined constructor, making it non-aggregate and therefore incompatible with designated - // initializers. - if constexpr (std::is_aggregate_v) { - std::same_as decltype(auto) elements_of = std::ranges::elements_of{ - .range = r, - .allocator = Allocator(), - }; - [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; - if (!std::is_constant_evaluated()) { - assert(std::ranges::distance(elements_of_range) == 4); - } - [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; +// designated initializer +// AppleClang 15 hasn't implemented P0960R3 and P1816R0 +#if defined(__cpp_aggregate_paren_init) && __cpp_aggregate_paren_init >= 201902L && defined(__cpp_deduction_guides) && \ + __cpp_deduction_guides >= 201907L + std::same_as decltype(auto) elements_of = std::ranges::elements_of{ + .range = r, + .allocator = Allocator(), + }; + [[maybe_unused]] std::same_as decltype(auto) elements_of_range = elements_of.range; + if (!std::is_constant_evaluated()) { + assert(std::ranges::distance(elements_of_range) == 4); } + [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; +#endif } { // copy constructor From ea82cce5f0702b2138b17901d716ff88525aad0d Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Thu, 17 Oct 2024 00:30:54 -0400 Subject: [PATCH 25/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 4 ++-- .../range.utility/range.elementsof/elements_of.pass.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index f414a662907a9..415565e813f39 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -38,8 +38,8 @@ struct elements_of { // This explicit constructor is required because AppleClang 15 hasn't // implemented P0960R3. template > - _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range2&& Range, _Allocator2&& Alloc = _Allocator()) - : range(std::forward<_Range2>(Range)), allocator(std::forward<_Allocator2>(Alloc)) {} + _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range2&& __range, _Allocator2&& __alloc = _Allocator()) + : range(std::forward<_Range2>(__range)), allocator(std::forward<_Allocator2>(__alloc)) {} # endif }; 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 f18a3bc8c61bc..5f63f090f45ff 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 @@ -27,7 +27,7 @@ struct Range { Iterator begin() { return Iterator(data_.data()); } - sentinel_wrapper end() { return Sentinel(Iterator(data_.data() + data_.size())); } + Sentinel end() { return Sentinel(Iterator(data_.data() + data_.size())); } private: std::vector data_ = {0, 1, 2, 3}; From 5ca60028e46828fe50715994f58f0b6b23563575 Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Sun, 10 Nov 2024 13:03:11 -0500 Subject: [PATCH 26/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/include/__ranges/elements_of.h | 13 ------------- .../range.elementsof/ctad.compile.pass.cpp | 4 ---- .../range.elementsof/elements_of.pass.cpp | 6 +----- 3 files changed, 1 insertion(+), 22 deletions(-) diff --git a/libcxx/include/__ranges/elements_of.h b/libcxx/include/__ranges/elements_of.h index 415565e813f39..668bd23d0ff7f 100644 --- a/libcxx/include/__ranges/elements_of.h +++ b/libcxx/include/__ranges/elements_of.h @@ -33,22 +33,9 @@ template > struct elements_of { _LIBCPP_NO_UNIQUE_ADDRESS _Range range; _LIBCPP_NO_UNIQUE_ADDRESS _Allocator allocator = _Allocator(); - -# if !defined(__cpp_aggregate_paren_init) - // This explicit constructor is required because AppleClang 15 hasn't - // implemented P0960R3. - template > - _LIBCPP_HIDE_FROM_ABI explicit constexpr elements_of(_Range2&& __range, _Allocator2&& __alloc = _Allocator()) - : range(std::forward<_Range2>(__range)), allocator(std::forward<_Allocator2>(__alloc)) {} -# endif }; template > -# if defined(_LIBCPP_COMPILER_CLANG_BASED) && defined(_LIBCPP_APPLE_CLANG_VER) && _LIBCPP_APPLE_CLANG_VER < 1600 -// This explicit constraint is required because AppleClang 15 might not deduce -// the correct type for `_Range` without it. - requires range<_Range&&> -# endif elements_of(_Range&&, _Allocator = _Allocator()) -> elements_of<_Range&&, _Allocator>; } // namespace ranges diff --git a/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp index 0f9204a07118e..5e7eeb831ba77 100644 --- a/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.utility/range.elementsof/ctad.compile.pass.cpp @@ -41,15 +41,11 @@ constexpr bool test() { static_assert(std::same_as(), Allocator())), std::ranges::elements_of&&, Allocator>>); -// AppleClang 15 hasn't implemented P0960R3 and P1816R0 -#if defined(__cpp_aggregate_paren_init) && __cpp_aggregate_paren_init >= 201902L && defined(__cpp_deduction_guides) && \ - __cpp_deduction_guides >= 201907L static_assert(std::same_as&, Allocator>>); static_assert( std::same_as(), .allocator = Allocator()}), std::ranges::elements_of&&, Allocator>>); -#endif }); }); 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 5f63f090f45ff..e7bf9098881ab 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 @@ -48,10 +48,7 @@ constexpr bool test_range() { [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; } { -// designated initializer -// AppleClang 15 hasn't implemented P0960R3 and P1816R0 -#if defined(__cpp_aggregate_paren_init) && __cpp_aggregate_paren_init >= 201902L && defined(__cpp_deduction_guides) && \ - __cpp_deduction_guides >= 201907L + // designated initializer std::same_as decltype(auto) elements_of = std::ranges::elements_of{ .range = r, .allocator = Allocator(), @@ -61,7 +58,6 @@ constexpr bool test_range() { assert(std::ranges::distance(elements_of_range) == 4); } [[maybe_unused]] std::same_as decltype(auto) elements_of_allocator = elements_of.allocator; -#endif } { // copy constructor From 2e11e4359bb8606668c37542db5668d134269ffc Mon Sep 17 00:00:00 2001 From: Xiaoyang Liu Date: Sun, 10 Nov 2024 15:43:17 -0500 Subject: [PATCH 27/27] [libc++][ranges] implement 'ranges::elements_of' --- libcxx/test/libcxx/transitive_includes/cxx23.csv | 1 + libcxx/test/libcxx/transitive_includes/cxx26.csv | 1 + 2 files changed, 2 insertions(+) diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv index 854ad1b5df6f1..143949088a50a 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -882,6 +882,7 @@ random version ranges cctype ranges compare ranges concepts +ranges cstddef ranges cstdint ranges cstdio ranges cstring diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv index ba2faaee5e375..4cd7f6df79e57 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -881,6 +881,7 @@ random version ranges cctype ranges compare ranges concepts +ranges cstddef ranges cstdint ranges cstdio ranges cstring