These functions are forward declared in bits/stl_pair.h and defining
them using qualified name guarantees that signatures are matching.

The deleted get<I>(const tuple<...>&) overloads for N > tuple_size is moved to
bits/stl_pair.h, so the candidate set is the same regardless if tuple
is included.

libstdc++-v3/ChangeLog:

        * include/bits/stl_pair.h (std::get(const tuple<...>&)): Moved
        from...
        * include/std/tuple (std::get<_Int>): Move deleted overload for out
        of bounds index to bits/stl_pair.h. Qualify remaining definitions.
        * include/std/array (std::get<_Int>): Qualify definitions.
        * include/std/complex (std::get<_Int>): Qualify definitions.
---
As discussed, this is worth doing as it would detect mismatches and
prevent problesm like PR128657.

Testing on x86_64 and powerpc64-le. OK for trunk when all tests
passes?

 libstdc++-v3/include/bits/stl_pair.h | 16 +++++++++++-----
 libstdc++-v3/include/std/array       |  8 ++++----
 libstdc++-v3/include/std/complex     |  9 +++++----
 libstdc++-v3/include/std/tuple       | 16 +++++-----------
 4 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/libstdc++-v3/include/bits/stl_pair.h 
b/libstdc++-v3/include/bits/stl_pair.h
index ccff8691206..645e394520c 100644
--- a/libstdc++-v3/include/bits/stl_pair.h
+++ b/libstdc++-v3/include/bits/stl_pair.h
@@ -133,6 +133,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
     get(const tuple<_Elements...>&& __t) noexcept;
 
+  /// @cond undocumented
+  // Deleted overload chosen for invalid indices.
+  template<size_t __i, typename... _Elements>
+    constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
+    get(const tuple<_Elements...>&) = delete;
+  /// @endcond
+
   template<size_t _Int, typename _Tp, size_t _Nm>
     constexpr _Tp&
     get(array<_Tp, _Nm>&) noexcept;
@@ -1284,25 +1291,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<size_t _Int, class _Tp1, class _Tp2>
     constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
-    get(pair<_Tp1, _Tp2>& __in) noexcept
+    ::std::get(pair<_Tp1, _Tp2>& __in) noexcept
     { return __pair_get<_Int>::__get(__in); }
 
   template<size_t _Int, class _Tp1, class _Tp2>
     constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
-    get(pair<_Tp1, _Tp2>&& __in) noexcept
+    ::std::get(pair<_Tp1, _Tp2>&& __in) noexcept
     { return __pair_get<_Int>::__move_get(std::move(__in)); }
 
   template<size_t _Int, class _Tp1, class _Tp2>
     constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
-    get(const pair<_Tp1, _Tp2>& __in) noexcept
+    ::std::get(const pair<_Tp1, _Tp2>& __in) noexcept
     { return __pair_get<_Int>::__const_get(__in); }
 
   template<size_t _Int, class _Tp1, class _Tp2>
     constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
-    get(const pair<_Tp1, _Tp2>&& __in) noexcept
+    ::std::get(const pair<_Tp1, _Tp2>&& __in) noexcept
     { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
 
-
 #ifdef __glibcxx_tuples_by_type // C++ >= 14
   template <typename _Tp, typename _Up>
     constexpr _Tp&
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 5d3edbea649..77a3ce12154 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -392,7 +392,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     [[__nodiscard__]]
     constexpr _Tp&
-    get(array<_Tp, _Nm>& __arr) noexcept
+    ::std::get(array<_Tp, _Nm>& __arr) noexcept
     {
       static_assert(_Int < _Nm, "array index is within bounds");
       return __arr._M_elems[_Int];
@@ -401,7 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     [[__nodiscard__]]
     constexpr _Tp&&
-    get(array<_Tp, _Nm>&& __arr) noexcept
+    ::std::get(array<_Tp, _Nm>&& __arr) noexcept
     {
       static_assert(_Int < _Nm, "array index is within bounds");
       return std::move(std::get<_Int>(__arr));
@@ -410,7 +410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     [[__nodiscard__]]
     constexpr const _Tp&
-    get(const array<_Tp, _Nm>& __arr) noexcept
+    ::std::get(const array<_Tp, _Nm>& __arr) noexcept
     {
       static_assert(_Int < _Nm, "array index is within bounds");
       return __arr._M_elems[_Int];
@@ -419,7 +419,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<std::size_t _Int, typename _Tp, std::size_t _Nm>
     [[__nodiscard__]]
     constexpr const _Tp&&
-    get(const array<_Tp, _Nm>&& __arr) noexcept
+    ::std::get(const array<_Tp, _Nm>&& __arr) noexcept
     {
       static_assert(_Int < _Nm, "array index is within bounds");
       return std::move(std::get<_Int>(__arr));
diff --git a/libstdc++-v3/include/std/complex b/libstdc++-v3/include/std/complex
index 1be1c7abfb6..c1ea392af4c 100644
--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -638,10 +638,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
 
 #if __glibcxx_tuple_like >= 202311L // >= C++26
+  // Forward declared in bits/stl_pair.h
   template<size_t _Int, typename _Tp>
     [[nodiscard,__gnu__::__always_inline__]]
     constexpr _Tp&
-    get(complex<_Tp>& __z) noexcept
+    ::std::get(complex<_Tp>& __z) noexcept
     {
       static_assert(_Int < 2);
       return __z.__get_part(_Int);
@@ -650,7 +651,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<size_t _Int, typename _Tp>
     [[nodiscard,__gnu__::__always_inline__]]
     constexpr _Tp&&
-    get(complex<_Tp>&& __z) noexcept
+    ::std::get(complex<_Tp>&& __z) noexcept
     {
       static_assert(_Int < 2);
       return std::move(__z.__get_part(_Int));
@@ -659,7 +660,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<size_t _Int, typename _Tp>
     [[nodiscard,__gnu__::__always_inline__]]
     constexpr const _Tp&
-    get(const complex<_Tp>& __z) noexcept
+    ::std::get(const complex<_Tp>& __z) noexcept
     {
       static_assert(_Int < 2);
       return __z.__get_part(_Int);
@@ -668,7 +669,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<size_t _Int, typename _Tp>
     [[nodiscard,__gnu__::__always_inline__]]
     constexpr const _Tp&&
-    get(const complex<_Tp>&& __z) noexcept
+    ::std::get(const complex<_Tp>&& __z) noexcept
     {
       static_assert(_Int < 2);
       return std::move(__z.__get_part(_Int));
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index d73cefcbca8..4e28c3920b0 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -2462,22 +2462,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __enable_if_t<(__i >= sizeof...(_Types))>
     __get_helper(const tuple<_Types...>&) = delete;
 
+  // Declared in bits/stl_pair.h
   /// Return a reference to the ith element of a tuple.
   template<size_t __i, typename... _Elements>
     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
-    get(tuple<_Elements...>& __t) noexcept
+    ::std::get(tuple<_Elements...>& __t) noexcept
     { return std::__get_helper<__i>(__t); }
 
   /// Return a const reference to the ith element of a const tuple.
   template<size_t __i, typename... _Elements>
     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
-    get(const tuple<_Elements...>& __t) noexcept
+    ::std::get(const tuple<_Elements...>& __t) noexcept
     { return std::__get_helper<__i>(__t); }
 
   /// Return an rvalue reference to the ith element of a tuple rvalue.
   template<size_t __i, typename... _Elements>
     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
-    get(tuple<_Elements...>&& __t) noexcept
+    ::std::get(tuple<_Elements...>&& __t) noexcept
     {
       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
       return std::forward<__element_type>(std::__get_helper<__i>(__t));
@@ -2486,19 +2487,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// Return a const rvalue reference to the ith element of a const tuple 
rvalue.
   template<size_t __i, typename... _Elements>
     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
-    get(const tuple<_Elements...>&& __t) noexcept
+    ::std::get(const tuple<_Elements...>&& __t) noexcept
     {
       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
       return std::forward<const __element_type>(std::__get_helper<__i>(__t));
     }
 
-  /// @cond undocumented
-  // Deleted overload chosen for invalid indices.
-  template<size_t __i, typename... _Elements>
-    constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
-    get(const tuple<_Elements...>&) = delete;
-  /// @endcond
-
 #ifdef __cpp_lib_tuples_by_type // C++ >= 14
   /// Return a reference to the unique element of type _Tp of a tuple.
   template <typename _Tp, typename... _Types>
-- 
2.56.1

Reply via email to