[libcxx-commits] [libcxx] [libc++][ranges] P2609R3: Relaxing Ranges Just A Smidge (PR #101715)
A. Jiang via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 27 20:25:41 PDT 2024
https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/101715
>From cc39cf1feec8cec50f6e59085c4b2680f58851b1 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 3 Aug 2024 00:29:17 +0800
Subject: [PATCH 1/6] Implement the major part of P2609R3
---
libcxx/include/__iterator/concepts.h | 58 ++++++++++++++++++++-------
libcxx/include/__iterator/projected.h | 8 ++++
2 files changed, 51 insertions(+), 15 deletions(-)
diff --git a/libcxx/include/__iterator/concepts.h b/libcxx/include/__iterator/concepts.h
index 0a4878308d55f0..be2890bee49284 100644
--- a/libcxx/include/__iterator/concepts.h
+++ b/libcxx/include/__iterator/concepts.h
@@ -35,6 +35,7 @@
#include <__type_traits/add_pointer.h>
#include <__type_traits/common_reference.h>
#include <__type_traits/is_pointer.h>
+#include <__type_traits/is_primary_template.h>
#include <__type_traits/is_reference.h>
#include <__type_traits/remove_cv.h>
#include <__type_traits/remove_cvref.h>
@@ -64,8 +65,33 @@ concept __indirectly_readable_impl =
template <class _In>
concept indirectly_readable = __indirectly_readable_impl<remove_cvref_t<_In>>;
+template <class _Tp>
+using __projected_iterator_t = typename _Tp::__projected_iterator;
+
+template <class _Tp>
+using __projected_projection_t = typename _Tp::__projected_projection;
+
+template <class _Tp>
+concept __specialization_of_projected = requires {
+ typename __projected_iterator_t<_Tp>;
+ typename __projected_projection_t<_Tp>;
+} && __is_primary_template<_Tp>::value;
+
+template <class _Tp>
+struct __indirect_value_t_impl {
+ using type = iter_value_t<_Tp>&;
+};
+template <__specialization_of_projected _Tp>
+struct __indirect_value_t_impl<_Tp> {
+ using type = invoke_result_t<__projected_projection_t<_Tp>&,
+ typename __indirect_value_t_impl<__projected_iterator_t<_Tp>>::type>;
+};
+
+template <indirectly_readable _Tp>
+using __indirect_value_t = typename __indirect_value_t_impl<_Tp>::type;
+
template <indirectly_readable _Tp>
-using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, iter_value_t<_Tp>&>;
+using iter_common_reference_t = common_reference_t<iter_reference_t<_Tp>, __indirect_value_t<_Tp>>;
// [iterator.concept.writable]
template <class _Out, class _Tp>
@@ -176,43 +202,45 @@ concept __has_arrow = input_iterator<_Ip> && (is_pointer_v<_Ip> || requires(_Ip
// [indirectcallable.indirectinvocable]
template <class _Fp, class _It>
concept indirectly_unary_invocable =
- indirectly_readable<_It> && copy_constructible<_Fp> && invocable<_Fp&, iter_value_t<_It>&> &&
+ indirectly_readable<_It> && copy_constructible<_Fp> && invocable<_Fp&, __indirect_value_t<_It>> &&
invocable<_Fp&, iter_reference_t<_It>> &&
- common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>;
+ common_reference_with< invoke_result_t<_Fp&, __indirect_value_t<_It>>,
+ invoke_result_t<_Fp&, iter_reference_t<_It>>>;
template <class _Fp, class _It>
concept indirectly_regular_unary_invocable =
- indirectly_readable<_It> && copy_constructible<_Fp> && regular_invocable<_Fp&, iter_value_t<_It>&> &&
+ indirectly_readable<_It> && copy_constructible<_Fp> && regular_invocable<_Fp&, __indirect_value_t<_It>> &&
regular_invocable<_Fp&, iter_reference_t<_It>> &&
- common_reference_with< invoke_result_t<_Fp&, iter_value_t<_It>&>, invoke_result_t<_Fp&, iter_reference_t<_It>>>;
+ common_reference_with< invoke_result_t<_Fp&, __indirect_value_t<_It>>,
+ invoke_result_t<_Fp&, iter_reference_t<_It>>>;
template <class _Fp, class _It>
concept indirect_unary_predicate =
- indirectly_readable<_It> && copy_constructible<_Fp> && predicate<_Fp&, iter_value_t<_It>&> &&
+ indirectly_readable<_It> && copy_constructible<_Fp> && predicate<_Fp&, __indirect_value_t<_It>> &&
predicate<_Fp&, iter_reference_t<_It>>;
template <class _Fp, class _It1, class _It2>
concept indirect_binary_predicate =
indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> &&
- predicate<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
- predicate<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
- predicate<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
+ predicate<_Fp&, __indirect_value_t<_It1>, __indirect_value_t<_It2>> &&
+ predicate<_Fp&, __indirect_value_t<_It1>, iter_reference_t<_It2>> &&
+ predicate<_Fp&, iter_reference_t<_It1>, __indirect_value_t<_It2>> &&
predicate<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>;
template <class _Fp, class _It1, class _It2 = _It1>
concept indirect_equivalence_relation =
indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> &&
- equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
- equivalence_relation<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
- equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
+ equivalence_relation<_Fp&, __indirect_value_t<_It1>, __indirect_value_t<_It2>> &&
+ equivalence_relation<_Fp&, __indirect_value_t<_It1>, iter_reference_t<_It2>> &&
+ equivalence_relation<_Fp&, iter_reference_t<_It1>, __indirect_value_t<_It2>> &&
equivalence_relation<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>;
template <class _Fp, class _It1, class _It2 = _It1>
concept indirect_strict_weak_order =
indirectly_readable<_It1> && indirectly_readable<_It2> && copy_constructible<_Fp> &&
- strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_value_t<_It2>&> &&
- strict_weak_order<_Fp&, iter_value_t<_It1>&, iter_reference_t<_It2>> &&
- strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_value_t<_It2>&> &&
+ strict_weak_order<_Fp&, __indirect_value_t<_It1>, __indirect_value_t<_It2>> &&
+ strict_weak_order<_Fp&, __indirect_value_t<_It1>, iter_reference_t<_It2>> &&
+ strict_weak_order<_Fp&, iter_reference_t<_It1>, __indirect_value_t<_It2>> &&
strict_weak_order<_Fp&, iter_reference_t<_It1>, iter_reference_t<_It2>>;
template <class _Fp, class... _Its>
diff --git a/libcxx/include/__iterator/projected.h b/libcxx/include/__iterator/projected.h
index 463d07b0d33c2d..1c560ec0550011 100644
--- a/libcxx/include/__iterator/projected.h
+++ b/libcxx/include/__iterator/projected.h
@@ -26,6 +26,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <class _It, class _Proj>
struct __projected_impl {
struct __type {
+ using __primary_template = __type;
+ using __projected_iterator = _It;
+ using __projected_projection = _Proj;
+
using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>;
indirect_result_t<_Proj&, _It> operator*() const; // not defined
};
@@ -34,6 +38,10 @@ struct __projected_impl {
template <weakly_incrementable _It, class _Proj>
struct __projected_impl<_It, _Proj> {
struct __type {
+ using __primary_template = __type;
+ using __projected_iterator = _It;
+ using __projected_projection = _Proj;
+
using value_type = remove_cvref_t<indirect_result_t<_Proj&, _It>>;
using difference_type = iter_difference_t<_It>;
indirect_result_t<_Proj&, _It> operator*() const; // not defined
>From 6098b44e34a7fbe3d9b6ec19d3564ea557ecb432 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 3 Aug 2024 00:30:30 +0800
Subject: [PATCH 2/6] Test coverage for P2609R3
Co-authored-by: Jakub Mazurkiewicz <mazkuba3 at gmail.com>
---
.../indirect.value.t.compile.pass.cpp | 75 +++++++++++++++++++
1 file changed, 75 insertions(+)
create mode 100644 libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.compile.pass.cpp
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.compile.pass.cpp
new file mode 100644
index 00000000000000..7a903c781d6881
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.compile.pass.cpp
@@ -0,0 +1,75 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+// template<indirectly_readable T>
+// using indirect-value-t = see below; // exposition only
+
+#include <algorithm>
+#include <memory>
+#include <ranges>
+#include <utility>
+#include <vector>
+
+void test() {
+ auto ints = std::views::iota(0, 5);
+ auto unique_ptr_maker = []<std::movable T>(T v) { return std::make_unique<T>(std::move(v)); };
+
+ using iota_iter = std::ranges::iterator_t<decltype(ints)>;
+ using unique_ptr_projection = decltype(unique_ptr_maker);
+ using projected_iter = std::projected<iota_iter, unique_ptr_projection>;
+
+ { // Check std::indirectly_unary_invocable
+ auto consume = [](auto) {};
+ static_assert(std::indirectly_unary_invocable<decltype(consume), projected_iter>);
+
+ std::ranges::for_each(ints, consume, unique_ptr_maker);
+ std::ranges::for_each(ints.begin(), ints.end(), consume, unique_ptr_maker);
+ }
+
+ { // Check std::indirectly_regular_unary_invocable
+ static_assert(std::indirectly_regular_unary_invocable<decltype([](auto) {}), projected_iter>);
+ using check_wellformedness [[maybe_unused]] = std::projected<projected_iter, unique_ptr_projection>;
+ }
+
+ { // Check std::indirect_unary_predicate
+ auto unary_pred = [](auto) { return false; };
+ static_assert(std::indirect_unary_predicate<decltype(unary_pred), projected_iter>);
+
+ (void)std::ranges::find_if(ints, unary_pred, unique_ptr_maker);
+ (void)std::ranges::find_if(ints.begin(), ints.end(), unary_pred, unique_ptr_maker);
+ (void)std::ranges::count_if(ints, unary_pred, unique_ptr_maker);
+ (void)std::ranges::count_if(ints.begin(), ints.end(), unary_pred, unique_ptr_maker);
+ }
+
+ { // Check std::indirect_binary_predicate
+ auto binary_pred = [](auto, auto) { return false; };
+ static_assert(std::indirect_binary_predicate<decltype(binary_pred), projected_iter, projected_iter>);
+
+ (void)std::ranges::adjacent_find(ints, binary_pred, unique_ptr_maker);
+ (void)std::ranges::adjacent_find(ints.begin(), ints.end(), binary_pred, unique_ptr_maker);
+ }
+
+ { // Check std::indirect_equivalence_relation
+ auto rel = [](auto, auto) { return false; };
+ static_assert(std::indirect_equivalence_relation<decltype(rel), projected_iter>);
+
+ std::vector<int> out;
+ (void)std::ranges::unique_copy(ints, std::back_inserter(out), rel, unique_ptr_maker);
+ (void)std::ranges::unique_copy(ints.begin(), ints.end(), std::back_inserter(out), rel, unique_ptr_maker);
+ }
+
+ { // Check std::indirect_strict_weak_order
+ auto rel = [](auto x, auto y) { return x < y; };
+ static_assert(std::indirect_strict_weak_order<decltype(rel), projected_iter>);
+
+ (void)std::ranges::is_sorted_until(ints, rel, unique_ptr_maker);
+ (void)std::ranges::is_sorted_until(ints.begin(), ints.end(), rel, unique_ptr_maker);
+ }
+}
>From 377730bcfbf233cdefb036bc257f0152096d9ade Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 3 Aug 2024 00:42:24 +0800
Subject: [PATCH 3/6] Adjust feature-test macro `__cpp_lib_ranges`
In C++20 mode the value should be 202110L because
- 202202L covers `range_adaptor_closure` (P2387R3), and
- 202207L covers move-only types in range adaptors (P2494R2).
And of these changes are only available since C++23 mode.
In C++23 mode the value should be 202406L because
- 202211L covers removing poison overloads (P2602R2),
- 202302L covers relaxing projected value types (P2609R3), and
- 202406L covers removing requirements on iter_common_reference_t (P2997R1).
And all of these changes are already or being implemented.
---
libcxx/docs/FeatureTestMacroTable.rst | 4 +++-
libcxx/include/version | 7 +++++--
.../algorithm.version.compile.pass.cpp | 15 ++++++++-------
.../functional.version.compile.pass.cpp | 15 ++++++++-------
.../iterator.version.compile.pass.cpp | 15 ++++++++-------
.../memory.version.compile.pass.cpp | 15 ++++++++-------
.../ranges.version.compile.pass.cpp | 15 ++++++++-------
.../version.version.compile.pass.cpp | 15 ++++++++-------
.../generate_feature_test_macro_components.py | 5 ++---
9 files changed, 58 insertions(+), 48 deletions(-)
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index a1506e115fe70f..7e6666f9abd916 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -266,7 +266,7 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_polymorphic_allocator`` ``201902L``
---------------------------------------------------------- -----------------
- ``__cpp_lib_ranges`` ``202207L``
+ ``__cpp_lib_ranges`` ``202110L``
---------------------------------------------------------- -----------------
``__cpp_lib_remove_cvref`` ``201711L``
---------------------------------------------------------- -----------------
@@ -350,6 +350,8 @@ Status
---------------------------------------------------------- -----------------
``__cpp_lib_print`` ``202207L``
---------------------------------------------------------- -----------------
+ ``__cpp_lib_ranges`` ``202406L``
+ ---------------------------------------------------------- -----------------
``__cpp_lib_ranges_as_const`` *unimplemented*
---------------------------------------------------------- -----------------
``__cpp_lib_ranges_as_rvalue`` ``202207L``
diff --git a/libcxx/include/version b/libcxx/include/version
index fe64343eafbc9c..abd2ffe2c08be1 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -182,8 +182,9 @@ __cpp_lib_philox_engine 202406L <random>
__cpp_lib_polymorphic_allocator 201902L <memory_resource>
__cpp_lib_print 202207L <ostream> <print>
__cpp_lib_quoted_string_io 201304L <iomanip>
-__cpp_lib_ranges 202207L <algorithm> <functional> <iterator>
+__cpp_lib_ranges 202406L <algorithm> <functional> <iterator>
<memory> <ranges>
+ 202110L // C++20
__cpp_lib_ranges_as_const 202207L <ranges>
__cpp_lib_ranges_as_rvalue 202207L <ranges>
__cpp_lib_ranges_chunk 202202L <ranges>
@@ -428,7 +429,7 @@ __cpp_lib_void_t 201411L <type_traits>
# if _LIBCPP_AVAILABILITY_HAS_PMR
# define __cpp_lib_polymorphic_allocator 201902L
# endif
-# define __cpp_lib_ranges 202207L
+# define __cpp_lib_ranges 202110L
# define __cpp_lib_remove_cvref 201711L
# if !defined(_LIBCPP_HAS_NO_THREADS) && _LIBCPP_AVAILABILITY_HAS_SYNC
# define __cpp_lib_semaphore 201907L
@@ -480,6 +481,8 @@ __cpp_lib_void_t 201411L <type_traits>
# define __cpp_lib_optional 202110L
# define __cpp_lib_out_ptr 202106L
# define __cpp_lib_print 202207L
+# undef __cpp_lib_ranges
+# define __cpp_lib_ranges 202406L
// # define __cpp_lib_ranges_as_const 202207L
# define __cpp_lib_ranges_as_rvalue 202207L
// # define __cpp_lib_ranges_chunk 202202L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
index ded80060632419..42ccbfceb8d77a 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/algorithm.version.compile.pass.cpp
@@ -21,7 +21,8 @@
__cpp_lib_default_template_type_for_algorithm_values 202403L [C++26]
__cpp_lib_freestanding_algorithm 202311L [C++26]
__cpp_lib_parallel_algorithm 201603L [C++17]
- __cpp_lib_ranges 202207L [C++20]
+ __cpp_lib_ranges 202110L [C++20]
+ 202406L [C++23]
__cpp_lib_ranges_contains 202207L [C++23]
__cpp_lib_ranges_find_last 202207L [C++23]
__cpp_lib_ranges_starts_ends_with 202106L [C++23]
@@ -244,8 +245,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++20"
+# if __cpp_lib_ranges != 202110L
+# error "__cpp_lib_ranges should have the value 202110L in c++20"
# endif
# ifdef __cpp_lib_ranges_contains
@@ -321,8 +322,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++23"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++23"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++23"
# endif
# ifndef __cpp_lib_ranges_contains
@@ -425,8 +426,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++26"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++26"
# endif
# ifndef __cpp_lib_ranges_contains
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
index 27e76e5b2b05a3..8ea19345903630 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/functional.version.compile.pass.cpp
@@ -27,7 +27,8 @@
__cpp_lib_invoke_r 202106L [C++23]
__cpp_lib_move_only_function 202110L [C++23]
__cpp_lib_not_fn 201603L [C++17]
- __cpp_lib_ranges 202207L [C++20]
+ __cpp_lib_ranges 202110L [C++20]
+ 202406L [C++23]
__cpp_lib_reference_wrapper 202403L [C++26]
__cpp_lib_result_of_sfinae 201210L [C++14]
__cpp_lib_transparent_operators 201210L [C++14]
@@ -305,8 +306,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++20"
+# if __cpp_lib_ranges != 202110L
+# error "__cpp_lib_ranges should have the value 202110L in c++20"
# endif
# ifdef __cpp_lib_reference_wrapper
@@ -409,8 +410,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++23"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++23"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++23"
# endif
# ifdef __cpp_lib_reference_wrapper
@@ -531,8 +532,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++26"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++26"
# endif
# ifndef __cpp_lib_reference_wrapper
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
index 700907ce9bb071..a756d10fcc375d 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/iterator.version.compile.pass.cpp
@@ -23,7 +23,8 @@
__cpp_lib_move_iterator_concept 202207L [C++20]
__cpp_lib_nonmember_container_access 201411L [C++17]
__cpp_lib_null_iterators 201304L [C++14]
- __cpp_lib_ranges 202207L [C++20]
+ __cpp_lib_ranges 202110L [C++20]
+ 202406L [C++23]
__cpp_lib_ssize 201902L [C++20]
*/
@@ -197,8 +198,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++20"
+# if __cpp_lib_ranges != 202110L
+# error "__cpp_lib_ranges should have the value 202110L in c++20"
# endif
# ifndef __cpp_lib_ssize
@@ -255,8 +256,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++23"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++23"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++23"
# endif
# ifndef __cpp_lib_ssize
@@ -313,8 +314,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++26"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++26"
# endif
# ifndef __cpp_lib_ssize
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
index aa1170658b103a..315058f7f46370 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.compile.pass.cpp
@@ -28,7 +28,8 @@
__cpp_lib_make_unique 201304L [C++14]
__cpp_lib_out_ptr 202106L [C++23]
202311L [C++26]
- __cpp_lib_ranges 202207L [C++20]
+ __cpp_lib_ranges 202110L [C++20]
+ 202406L [C++23]
__cpp_lib_raw_memory_algorithms 201606L [C++17]
__cpp_lib_shared_ptr_arrays 201611L [C++17]
201707L [C++20]
@@ -364,8 +365,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++20"
+# if __cpp_lib_ranges != 202110L
+# error "__cpp_lib_ranges should have the value 202110L in c++20"
# endif
# ifndef __cpp_lib_raw_memory_algorithms
@@ -495,8 +496,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++23"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++23"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++23"
# endif
# ifndef __cpp_lib_raw_memory_algorithms
@@ -626,8 +627,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++26"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++26"
# endif
# ifndef __cpp_lib_raw_memory_algorithms
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
index 30feacd796d8e1..8493505ef0236d 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
@@ -17,7 +17,8 @@
/* Constant Value
__cpp_lib_default_template_type_for_algorithm_values 202403L [C++26]
- __cpp_lib_ranges 202207L [C++20]
+ __cpp_lib_ranges 202110L [C++20]
+ 202406L [C++23]
__cpp_lib_ranges_as_const 202207L [C++23]
__cpp_lib_ranges_as_rvalue 202207L [C++23]
__cpp_lib_ranges_chunk 202202L [C++23]
@@ -192,8 +193,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++20"
+# if __cpp_lib_ranges != 202110L
+# error "__cpp_lib_ranges should have the value 202110L in c++20"
# endif
# ifdef __cpp_lib_ranges_as_const
@@ -245,8 +246,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++23"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++23"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++23"
# endif
# if !defined(_LIBCPP_VERSION)
@@ -364,8 +365,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++26"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++26"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index b8bad696f1bae0..239d108fc34088 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -166,7 +166,8 @@
__cpp_lib_polymorphic_allocator 201902L [C++20]
__cpp_lib_print 202207L [C++23]
__cpp_lib_quoted_string_io 201304L [C++14]
- __cpp_lib_ranges 202207L [C++20]
+ __cpp_lib_ranges 202110L [C++20]
+ 202406L [C++23]
__cpp_lib_ranges_as_const 202207L [C++23]
__cpp_lib_ranges_as_rvalue 202207L [C++23]
__cpp_lib_ranges_chunk 202202L [C++23]
@@ -4131,8 +4132,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++20"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++20"
+# if __cpp_lib_ranges != 202110L
+# error "__cpp_lib_ranges should have the value 202110L in c++20"
# endif
# ifdef __cpp_lib_ranges_as_const
@@ -5619,8 +5620,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++23"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++23"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++23"
# endif
# if !defined(_LIBCPP_VERSION)
@@ -7470,8 +7471,8 @@
# ifndef __cpp_lib_ranges
# error "__cpp_lib_ranges should be defined in c++26"
# endif
-# if __cpp_lib_ranges != 202207L
-# error "__cpp_lib_ranges should have the value 202207L in c++26"
+# if __cpp_lib_ranges != 202406L
+# error "__cpp_lib_ranges should have the value 202406L in c++26"
# endif
# if !defined(_LIBCPP_VERSION)
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 6c42748002aee3..0022be190b7c8d 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -991,9 +991,8 @@ def add_version_header(tc):
{
"name": "__cpp_lib_ranges",
"values": {
- "c++20": 202207,
- # "c++23": 202302, # Relaxing Ranges Just A Smidge
- # "c++26": 202406, # P2997R1 Removing the common reference requirement from the indirectly invocable concepts (already implemented as a DR)
+ "c++20": 202110, # P2415R2 What is a view?
+ "c++23": 202406, # P2997R1 Removing the common reference requirement from the indirectly invocable concepts (implemented as a DR against C++20)
},
"headers": ["algorithm", "functional", "iterator", "memory", "ranges"],
},
>From e460d7d2aff02f19f74b21d237ba3f64259d5642 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 3 Aug 2024 00:43:21 +0800
Subject: [PATCH 4/6] Add release notes
---
libcxx/docs/ReleaseNotes/20.rst | 2 ++
libcxx/docs/Status/Cxx23.rst | 1 +
libcxx/docs/Status/Cxx23Papers.csv | 2 +-
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index 960fdd7ce05626..c05f22cbc4a9c5 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -38,6 +38,8 @@ What's New in Libc++ 20.0.0?
Implemented Papers
------------------
+- P2609R3 - Relaxing Ranges Just A Smidge
+
- TODO
diff --git a/libcxx/docs/Status/Cxx23.rst b/libcxx/docs/Status/Cxx23.rst
index 23d30c8128d71e..5c85f6ec82c8ba 100644
--- a/libcxx/docs/Status/Cxx23.rst
+++ b/libcxx/docs/Status/Cxx23.rst
@@ -46,6 +46,7 @@ Paper Status
.. [#note-P2520R0] P2520R0: Libc++ implemented this paper as a DR in C++20 as well.
.. [#note-P2711R1] P2711R1: ``join_with_view`` hasn't been done yet since this type isn't implemented yet.
.. [#note-P2770R0] P2770R0: ``join_with_view`` hasn't been done yet since this type isn't implemented yet.
+ .. [#note-P2609R3] This paper is applied as DR against C++20. (MSVC STL does the same.)
.. [#note-P2693R1] P2693R1: The formatter for ``std::thread::id`` is implemented.
The formatter for ``stacktrace`` is not implemented, since ``stacktrace`` is
not implemented yet.
diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv
index da498629ca5dd4..1d7f50421784c1 100644
--- a/libcxx/docs/Status/Cxx23Papers.csv
+++ b/libcxx/docs/Status/Cxx23Papers.csv
@@ -107,7 +107,7 @@
"`P2770R0 <https://wg21.link/P2770R0>`__","Stashing stashing ``iterators`` for proper flattening","February 2023","|Partial| [#note-P2770R0]_","","|ranges|"
"`P2164R9 <https://wg21.link/P2164R9>`__","``views::enumerate``","February 2023","","","|ranges|"
"`P2711R1 <https://wg21.link/P2711R1>`__","Making multi-param constructors of ``views`` ``explicit``","February 2023","|In Progress| [#note-P2711R1]_","","|ranges|"
-"`P2609R3 <https://wg21.link/P2609R3>`__","Relaxing Ranges Just A Smidge","February 2023","","","|ranges|"
+"`P2609R3 <https://wg21.link/P2609R3>`__","Relaxing Ranges Just A Smidge","February 2023","|Complete| [#note-P2609R3]_","20.0","|ranges|"
"`P2713R1 <https://wg21.link/P2713R1>`__","Escaping improvements in ``std::format``","February 2023","|Complete|","19.0","|format|"
"`P2675R1 <https://wg21.link/P2675R1>`__","``format``'s width estimation is too approximate and not forward compatible","February 2023","|Complete|","17.0","|format|"
"`P2572R1 <https://wg21.link/P2572R1>`__","``std::format`` fill character allowances","February 2023","|Complete|","17.0","|format|"
>From 2d8791a3c6816997028915fcc630b820d2acda10 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 24 Aug 2024 18:40:02 +0800
Subject: [PATCH 5/6] Add Github link to 20.rst
---
libcxx/docs/ReleaseNotes/20.rst | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst
index 7159d89ba5c871..5db6a9058d6e30 100644
--- a/libcxx/docs/ReleaseNotes/20.rst
+++ b/libcxx/docs/ReleaseNotes/20.rst
@@ -38,9 +38,7 @@ What's New in Libc++ 20.0.0?
Implemented Papers
------------------
-- P2609R3 - Relaxing Ranges Just A Smidge
-
-- TODO
+- P2609R3 - Relaxing Ranges Just A Smidge (`Github <https://github.com/llvm/llvm-project/issues/105253>`__)
Improvements and New Features
>From ff841c89568695e102b4fbaf79f51fce11e70a90 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Wed, 28 Aug 2024 11:24:39 +0800
Subject: [PATCH 6/6] Run the test (also in constant evaluation since C++23)
---
...ile.pass.cpp => indirect.value.t.pass.cpp} | 33 +++++++++++++------
1 file changed, 23 insertions(+), 10 deletions(-)
rename libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/{indirect.value.t.compile.pass.cpp => indirect.value.t.pass.cpp} (71%)
diff --git a/libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.compile.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.pass.cpp
similarity index 71%
rename from libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.compile.pass.cpp
rename to libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.pass.cpp
index 7a903c781d6881..f278643d1a0913 100644
--- a/libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.compile.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/indirectcallable.traits/indirect.value.t.pass.cpp
@@ -11,13 +11,17 @@
// template<indirectly_readable T>
// using indirect-value-t = see below; // exposition only
+#include <cassert>
+
#include <algorithm>
#include <memory>
#include <ranges>
#include <utility>
#include <vector>
-void test() {
+#include "test_macros.h"
+
+TEST_CONSTEXPR_CXX23 void test() {
auto ints = std::views::iota(0, 5);
auto unique_ptr_maker = []<std::movable T>(T v) { return std::make_unique<T>(std::move(v)); };
@@ -42,18 +46,18 @@ void test() {
auto unary_pred = [](auto) { return false; };
static_assert(std::indirect_unary_predicate<decltype(unary_pred), projected_iter>);
- (void)std::ranges::find_if(ints, unary_pred, unique_ptr_maker);
- (void)std::ranges::find_if(ints.begin(), ints.end(), unary_pred, unique_ptr_maker);
- (void)std::ranges::count_if(ints, unary_pred, unique_ptr_maker);
- (void)std::ranges::count_if(ints.begin(), ints.end(), unary_pred, unique_ptr_maker);
+ assert(std::ranges::find_if(ints, unary_pred, unique_ptr_maker) == ints.end());
+ assert(std::ranges::find_if(ints.begin(), ints.end(), unary_pred, unique_ptr_maker) == ints.end());
+ assert(std::ranges::count_if(ints, unary_pred, unique_ptr_maker) == 0);
+ assert(std::ranges::count_if(ints.begin(), ints.end(), unary_pred, unique_ptr_maker) == 0);
}
{ // Check std::indirect_binary_predicate
auto binary_pred = [](auto, auto) { return false; };
static_assert(std::indirect_binary_predicate<decltype(binary_pred), projected_iter, projected_iter>);
- (void)std::ranges::adjacent_find(ints, binary_pred, unique_ptr_maker);
- (void)std::ranges::adjacent_find(ints.begin(), ints.end(), binary_pred, unique_ptr_maker);
+ assert(std::ranges::adjacent_find(ints, binary_pred, unique_ptr_maker) == ints.end());
+ assert(std::ranges::adjacent_find(ints.begin(), ints.end(), binary_pred, unique_ptr_maker) == ints.end());
}
{ // Check std::indirect_equivalence_relation
@@ -66,10 +70,19 @@ void test() {
}
{ // Check std::indirect_strict_weak_order
- auto rel = [](auto x, auto y) { return x < y; };
+ auto rel = [](auto x, auto y) { return *x < *y; };
static_assert(std::indirect_strict_weak_order<decltype(rel), projected_iter>);
- (void)std::ranges::is_sorted_until(ints, rel, unique_ptr_maker);
- (void)std::ranges::is_sorted_until(ints.begin(), ints.end(), rel, unique_ptr_maker);
+ assert(std::ranges::is_sorted_until(ints, rel, unique_ptr_maker) == ints.end());
+ assert(std::ranges::is_sorted_until(ints.begin(), ints.end(), rel, unique_ptr_maker) == ints.end());
}
}
+
+#if TEST_STD_VER >= 23
+static_assert((test(), true));
+#endif
+
+int main(int, char**) {
+ test();
+ return 0;
+}
More information about the libcxx-commits
mailing list