On Wed, 21 Aug 2024 at 01:40, Patrick Palka <[email protected]> wrote:
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk and perhaps
> 14?
>
> -- >8 --
>
> This implements the changes of this C++26 paper as a DR against C++20.
>
> libstdc++-v3/ChangeLog:
>
> * include/bits/iterator_concepts.h (indirectly_unary_invocable):
> Relax as per P2997R1.
> (indirectly_regular_unary_invocable): Likewise.
> (indirect_unary_predicate): Likewise.
> (indirect_binary_predicate): Likewise.
> (indirect_equivalence_relation): Likewise.
> (indirect_strict_weak_order): Likewise.
> * version.def (ranges): Update value for C++26.
> * version.h: Regenerate.
> * testsuite/24_iterators/indirect_callable/p2997r1.cc: New test.
> * testsuite/std/ranges/version_c++23.cc: Restrict to C++23 mode.
> * testsuite/std/ranges/version_c++26.cc: New test.
Can we get rid of version_c++23.cc (and not add version_c++26.cc) and
just expand the check in std/ranges/synopsis.cc instead?
Currently it does:
#ifndef __cpp_lib_ranges
# error "Feature test macro for ranges is missing in <ranges>"
#elif __cpp_lib_ranges < 201911L
# error "Feature test macro for ranges has wrong value in <ranges>"
#endif
but that could be:
#ifndef __cpp_lib_ranges
# error "Feature test macro for ranges is missing in <ranges>"
#elif __cplusplus > 202302 && __cpp_lib_ranges < 202406L
# error "Feature test macro for ranges has wrong value in <ranges>"
#elif __cplusplus == 202302 && __cpp_lib_ranges < 202406L
# error "Feature test macro for ranges has wrong value in <ranges>"
#elif __cpp_lib_ranges < 201911L
# error "Feature test macro for ranges has wrong value in <ranges>"
#endif
or define EXPECTED_VALUE to the appropriate value for each __cplusplus
dialect, then have one test of __cpp_lib_ranges != EXPECTED_VALUE.
This looks fine apart from that quibble.
> ---
> libstdc++-v3/include/bits/iterator_concepts.h | 17 ++-------
> libstdc++-v3/include/bits/version.def | 5 +++
> libstdc++-v3/include/bits/version.h | 7 +++-
> .../24_iterators/indirect_callable/p2997r1.cc | 37 +++++++++++++++++++
> .../testsuite/std/ranges/version_c++23.cc | 2 +-
> .../testsuite/std/ranges/version_c++26.cc | 10 +++++
> 6 files changed, 63 insertions(+), 15 deletions(-)
> create mode 100644
> libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
> create mode 100644 libstdc++-v3/testsuite/std/ranges/version_c++26.cc
>
> diff --git a/libstdc++-v3/include/bits/iterator_concepts.h
> b/libstdc++-v3/include/bits/iterator_concepts.h
> index 9306b7bd194..d849ddc32fc 100644
> --- a/libstdc++-v3/include/bits/iterator_concepts.h
> +++ b/libstdc++-v3/include/bits/iterator_concepts.h
> @@ -724,7 +724,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> concept indirectly_unary_invocable = indirectly_readable<_Iter>
> && copy_constructible<_Fn> && invocable<_Fn&,
> __indirect_value_t<_Iter>>
> && invocable<_Fn&, iter_reference_t<_Iter>>
> - && invocable<_Fn&, iter_common_reference_t<_Iter>>
> && common_reference_with<invoke_result_t<_Fn&,
> __indirect_value_t<_Iter>>,
> invoke_result_t<_Fn&,
> iter_reference_t<_Iter>>>;
>
> @@ -733,15 +732,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> && copy_constructible<_Fn>
> && regular_invocable<_Fn&, __indirect_value_t<_Iter>>
> && regular_invocable<_Fn&, iter_reference_t<_Iter>>
> - && regular_invocable<_Fn&, iter_common_reference_t<_Iter>>
> && common_reference_with<invoke_result_t<_Fn&,
> __indirect_value_t<_Iter>>,
> invoke_result_t<_Fn&,
> iter_reference_t<_Iter>>>;
>
> template<typename _Fn, typename _Iter>
> concept indirect_unary_predicate = indirectly_readable<_Iter>
> && copy_constructible<_Fn> && predicate<_Fn&,
> __indirect_value_t<_Iter>>
> - && predicate<_Fn&, iter_reference_t<_Iter>>
> - && predicate<_Fn&, iter_common_reference_t<_Iter>>;
> + && predicate<_Fn&, iter_reference_t<_Iter>>;
>
> template<typename _Fn, typename _I1, typename _I2>
> concept indirect_binary_predicate
> @@ -750,9 +747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> && predicate<_Fn&, __indirect_value_t<_I1>, __indirect_value_t<_I2>>
> && predicate<_Fn&, __indirect_value_t<_I1>, iter_reference_t<_I2>>
> && predicate<_Fn&, iter_reference_t<_I1>, __indirect_value_t<_I2>>
> - && predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>
> - && predicate<_Fn&, iter_common_reference_t<_I1>,
> - iter_common_reference_t<_I2>>;
> + && predicate<_Fn&, iter_reference_t<_I1>, iter_reference_t<_I2>>;
>
> template<typename _Fn, typename _I1, typename _I2 = _I1>
> concept indirect_equivalence_relation
> @@ -762,9 +757,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> && equivalence_relation<_Fn&, __indirect_value_t<_I1>,
> iter_reference_t<_I2>>
> && equivalence_relation<_Fn&, iter_reference_t<_I1>,
> __indirect_value_t<_I2>>
> && equivalence_relation<_Fn&, iter_reference_t<_I1>,
> - iter_reference_t<_I2>>
> - && equivalence_relation<_Fn&, iter_common_reference_t<_I1>,
> - iter_common_reference_t<_I2>>;
> + iter_reference_t<_I2>>;
>
> template<typename _Fn, typename _I1, typename _I2 = _I1>
> concept indirect_strict_weak_order
> @@ -773,9 +766,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> && strict_weak_order<_Fn&, __indirect_value_t<_I1>,
> __indirect_value_t<_I2>>
> && strict_weak_order<_Fn&, __indirect_value_t<_I1>,
> iter_reference_t<_I2>>
> && strict_weak_order<_Fn&, iter_reference_t<_I1>,
> __indirect_value_t<_I2>>
> - && strict_weak_order<_Fn&, iter_reference_t<_I1>,
> iter_reference_t<_I2>>
> - && strict_weak_order<_Fn&, iter_common_reference_t<_I1>,
> - iter_common_reference_t<_I2>>;
> + && strict_weak_order<_Fn&, iter_reference_t<_I1>,
> iter_reference_t<_I2>>;
>
> template<typename _Fn, typename... _Is>
> requires (indirectly_readable<_Is> && ...)
> diff --git a/libstdc++-v3/include/bits/version.def
> b/libstdc++-v3/include/bits/version.def
> index ea82c6fa2ca..bd3af9cba99 100644
> --- a/libstdc++-v3/include/bits/version.def
> +++ b/libstdc++-v3/include/bits/version.def
> @@ -1071,6 +1071,11 @@ ftms = {
>
> ftms = {
> name = ranges;
> + values = {
> + v = 202406;
> + cxxmin = 26;
> + extra_cond = "__glibcxx_concepts";
> + };
> values = {
> v = 202302;
> cxxmin = 23;
> diff --git a/libstdc++-v3/include/bits/version.h
> b/libstdc++-v3/include/bits/version.h
> index 981f0b7caea..364e3a05f0e 100644
> --- a/libstdc++-v3/include/bits/version.h
> +++ b/libstdc++-v3/include/bits/version.h
> @@ -1204,7 +1204,12 @@
> #undef __glibcxx_want_shift
>
> #if !defined(__cpp_lib_ranges)
> -# if (__cplusplus >= 202100L) && (__glibcxx_concepts)
> +# if (__cplusplus > 202302L) && (__glibcxx_concepts)
> +# define __glibcxx_ranges 202406L
> +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges)
> +# define __cpp_lib_ranges 202406L
> +# endif
> +# elif (__cplusplus >= 202100L) && (__glibcxx_concepts)
> # define __glibcxx_ranges 202302L
> # if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges)
> # define __cpp_lib_ranges 202302L
> diff --git a/libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
> b/libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
> new file mode 100644
> index 00000000000..6a66b0f2a96
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/24_iterators/indirect_callable/p2997r1.cc
> @@ -0,0 +1,37 @@
> +// Test the example from P2997R1 "Removing the common reference requirement
> +// from the indirectly invocable concepts".
> +// { dg-do compile { target c++20 } }
> +
> +#include <algorithm>
> +#include <ranges>
> +
> +struct C {
> + auto f() -> void;
> +};
> +
> +struct Iterator {
> + using value_type = C;
> + using difference_type = std::ptrdiff_t;
> + using iterator_category = std::input_iterator_tag;
> +
> + auto operator*() const -> C&&;
> + auto operator++() -> Iterator&;
> + auto operator++(int) -> void;
> + auto operator==(Iterator const&) const -> bool;
> +};
> +
> +static_assert(std::input_iterator<Iterator>);
> +static_assert(std::same_as<std::iter_value_t<Iterator>, C>);
> +static_assert(std::same_as<std::iter_reference_t<Iterator>, C&&>);
> +
> +struct R {
> + auto begin() -> Iterator;
> + auto end() -> Iterator;
> +};
> +
> +static_assert(std::ranges::range<R>);
> +static_assert(std::same_as<std::ranges::range_reference_t<R>, C&&>);
> +
> +auto f(R r) -> void {
> + std::ranges::for_each(r, [](auto&& c){ c.f(); });
> +}
> diff --git a/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
> b/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
> index 01871156a75..b30874f9d1e 100644
> --- a/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
> +++ b/libstdc++-v3/testsuite/std/ranges/version_c++23.cc
> @@ -1,4 +1,4 @@
> -// { dg-do preprocess { target c++23 } }
> +// { dg-do preprocess { target c++23_only } }
> // { dg-add-options no_pch }
>
> #include <version>
> diff --git a/libstdc++-v3/testsuite/std/ranges/version_c++26.cc
> b/libstdc++-v3/testsuite/std/ranges/version_c++26.cc
> new file mode 100644
> index 00000000000..350ad0cc711
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/std/ranges/version_c++26.cc
> @@ -0,0 +1,10 @@
> +// { dg-do preprocess { target c++26_only } }
> +// { dg-add-options no_pch }
> +
> +#include <version>
> +
> +#if __STDC_HOSTED__
> +# if __cpp_lib_ranges != 202406L
> +# error "Feature-test macro __cpp_lib_ranges has wrong value in <version>"
> +# endif
> +#endif
> --
> 2.46.0.267.gbb9c16bd4f
>