libstdc++: Fix missing change to views::pairwise from P2165R4 [PR121956]

Message ID 20250916151900.2680715-1-jwakely@redhat.com
State Committed
Commit 0c762f79a9e7bbd8d8fc5e639d53e43d9e331299
Headers
Series libstdc++: Fix missing change to views::pairwise from P2165R4 [PR121956] |

Commit Message

Jonathan Wakely Sept. 16, 2025, 3:18 p.m. UTC
  ranges::adjacent_view::_Iterator::value_type should have been changed by
r14-8710-g65b4cba9d6a9ff to always produce std::tuple, even for the
N == 2 views::pairwise specialization.

libstdc++-v3/ChangeLog:

	PR libstdc++/121956
	* include/std/ranges (adjacent_view::_Iterator::value_type):
	Always define as std::tuple<T, N>, not std::pair<T, T>.
	* testsuite/std/ranges/adaptors/adjacent/1.cc: Check value type
	of views::pairwise.
---

Tested powerpc64le-linux.

 libstdc++-v3/include/std/ranges                     |  4 +---
 .../testsuite/std/ranges/adaptors/adjacent/1.cc     | 13 +++++++++++++
 2 files changed, 14 insertions(+), 3 deletions(-)
  

Comments

Patrick Palka Sept. 16, 2025, 4:15 p.m. UTC | #1
On Tue, 16 Sep 2025, Jonathan Wakely wrote:

> ranges::adjacent_view::_Iterator::value_type should have been changed by
> r14-8710-g65b4cba9d6a9ff to always produce std::tuple, even for the
> N == 2 views::pairwise specialization.

LGTM. I missed this part of P2165R4 because it didn't use the
__tuple_or_pair helper

> 
> libstdc++-v3/ChangeLog:
> 
> 	PR libstdc++/121956
> 	* include/std/ranges (adjacent_view::_Iterator::value_type):
> 	Always define as std::tuple<T, N>, not std::pair<T, T>.
> 	* testsuite/std/ranges/adaptors/adjacent/1.cc: Check value type
> 	of views::pairwise.
> ---
> 
> Tested powerpc64le-linux.
> 
>  libstdc++-v3/include/std/ranges                     |  4 +---
>  .../testsuite/std/ranges/adaptors/adjacent/1.cc     | 13 +++++++++++++
>  2 files changed, 14 insertions(+), 3 deletions(-)
> 
> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
> index 6c64f4c36213..fd290ea362cc 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -5460,9 +5460,7 @@ namespace views::__adaptor
>    public:
>      using iterator_category = input_iterator_tag;
>      using iterator_concept = decltype(_S_iter_concept());
> -    using value_type = conditional_t<_Nm == 2,
> -				     pair<range_value_t<_Base>, range_value_t<_Base>>,
> -				     __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
> +    using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
>      using difference_type = range_difference_t<_Base>;
>  
>      _Iterator() = default;
> diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
> index 085cd4a8c54c..0a5c67f56140 100644
> --- a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
> +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
> @@ -114,6 +114,18 @@ test04()
>    return true;
>  }
>  
> +constexpr bool
> +test05()
> +{
> +  // PR libstdc++/121956
> +  int a[2]{};
> +  __gnu_test::test_random_access_range r(a);
> +  auto v = r | views::pairwise;
> +  static_assert( std::is_same_v<ranges::range_value_t<decltype(v)>,
> +				std::tuple<int, int>> );
> +  return true;
> +}
> +
>  int
>  main()
>  {
> @@ -121,4 +133,5 @@ main()
>    static_assert(test02());
>    static_assert(test03());
>    static_assert(test04());
> +  static_assert(test05());
>  }
> -- 
> 2.51.0
> 
>
  
Jonathan Wakely Sept. 16, 2025, 4:43 p.m. UTC | #2
On Tue, 16 Sept 2025 at 17:15, Patrick Palka <ppalka@redhat.com> wrote:
>
> On Tue, 16 Sep 2025, Jonathan Wakely wrote:
>
> > ranges::adjacent_view::_Iterator::value_type should have been changed by
> > r14-8710-g65b4cba9d6a9ff to always produce std::tuple, even for the
> > N == 2 views::pairwise specialization.
>
> LGTM. I missed this part of P2165R4 because it didn't use the
> __tuple_or_pair helper

Yeah, I figured.

It's a pity that GCC 14 and 15 use std::pair here, but changing it
would be an ABI change, so it's probably best to not do that on the
release branches.
  

Patch

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 6c64f4c36213..fd290ea362cc 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -5460,9 +5460,7 @@  namespace views::__adaptor
   public:
     using iterator_category = input_iterator_tag;
     using iterator_concept = decltype(_S_iter_concept());
-    using value_type = conditional_t<_Nm == 2,
-				     pair<range_value_t<_Base>, range_value_t<_Base>>,
-				     __detail::__repeated_tuple<range_value_t<_Base>, _Nm>>;
+    using value_type = __detail::__repeated_tuple<range_value_t<_Base>, _Nm>;
     using difference_type = range_difference_t<_Base>;
 
     _Iterator() = default;
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
index 085cd4a8c54c..0a5c67f56140 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/adjacent/1.cc
@@ -114,6 +114,18 @@  test04()
   return true;
 }
 
+constexpr bool
+test05()
+{
+  // PR libstdc++/121956
+  int a[2]{};
+  __gnu_test::test_random_access_range r(a);
+  auto v = r | views::pairwise;
+  static_assert( std::is_same_v<ranges::range_value_t<decltype(v)>,
+				std::tuple<int, int>> );
+  return true;
+}
+
 int
 main()
 {
@@ -121,4 +133,5 @@  main()
   static_assert(test02());
   static_assert(test03());
   static_assert(test04());
+  static_assert(test05());
 }