1  // Pair implementation -*- C++ -*-
       2  
       3  // Copyright (C) 2001-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /*
      26   *
      27   * Copyright (c) 1994
      28   * Hewlett-Packard Company
      29   *
      30   * Permission to use, copy, modify, distribute and sell this software
      31   * and its documentation for any purpose is hereby granted without fee,
      32   * provided that the above copyright notice appear in all copies and
      33   * that both that copyright notice and this permission notice appear
      34   * in supporting documentation.  Hewlett-Packard Company makes no
      35   * representations about the suitability of this software for any
      36   * purpose.  It is provided "as is" without express or implied warranty.
      37   *
      38   *
      39   * Copyright (c) 1996,1997
      40   * Silicon Graphics Computer Systems, Inc.
      41   *
      42   * Permission to use, copy, modify, distribute and sell this software
      43   * and its documentation for any purpose is hereby granted without fee,
      44   * provided that the above copyright notice appear in all copies and
      45   * that both that copyright notice and this permission notice appear
      46   * in supporting documentation.  Silicon Graphics makes no
      47   * representations about the suitability of this software for any
      48   * purpose.  It is provided "as is" without express or implied warranty.
      49   */
      50  
      51  /** @file bits/stl_pair.h
      52   *  This is an internal header file, included by other library headers.
      53   *  Do not attempt to use it directly. @headername{utility}
      54   */
      55  
      56  #ifndef _STL_PAIR_H
      57  #define _STL_PAIR_H 1
      58  
      59  #if __cplusplus >= 201103L
      60  # include <type_traits>    // for std::__decay_and_strip
      61  # include <bits/move.h>    // for std::move / std::forward, and std::swap
      62  # include <bits/utility.h> // for std::tuple_element, std::tuple_size
      63  #endif
      64  #if __cplusplus >= 202002L
      65  # include <compare>
      66  # define __cpp_lib_constexpr_utility 201811L
      67  #endif
      68  
      69  namespace std _GLIBCXX_VISIBILITY(default)
      70  {
      71  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      72  
      73    /**
      74     *  @addtogroup utilities
      75     *  @{
      76     */
      77  
      78  #if __cplusplus >= 201103L
      79    /// Tag type for piecewise construction of std::pair objects.
      80    struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
      81  
      82    /// Tag for piecewise construction of std::pair objects.
      83    _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
      84      piecewise_construct_t();
      85  
      86    /// @cond undocumented
      87  
      88    // Forward declarations.
      89    template<typename...>
      90      class tuple;
      91  
      92    template<size_t...>
      93      struct _Index_tuple;
      94  
      95  #if ! __cpp_lib_concepts
      96    // Concept utility functions, reused in conditionally-explicit
      97    // constructors.
      98    // See PR 70437, don't look at is_constructible or
      99    // is_convertible if the types are the same to
     100    // avoid querying those properties for incomplete types.
     101    template <bool, typename _T1, typename _T2>
     102      struct _PCC
     103      {
     104        template <typename _U1, typename _U2>
     105        static constexpr bool _ConstructiblePair()
     106        {
     107  	return __and_<is_constructible<_T1, const _U1&>,
     108  		      is_constructible<_T2, const _U2&>>::value;
     109        }
     110  
     111        template <typename _U1, typename _U2>
     112        static constexpr bool _ImplicitlyConvertiblePair()
     113        {
     114  	return __and_<is_convertible<const _U1&, _T1>,
     115  		      is_convertible<const _U2&, _T2>>::value;
     116        }
     117  
     118        template <typename _U1, typename _U2>
     119        static constexpr bool _MoveConstructiblePair()
     120        {
     121  	return __and_<is_constructible<_T1, _U1&&>,
     122  		      is_constructible<_T2, _U2&&>>::value;
     123        }
     124  
     125        template <typename _U1, typename _U2>
     126        static constexpr bool _ImplicitlyMoveConvertiblePair()
     127        {
     128  	return __and_<is_convertible<_U1&&, _T1>,
     129  		      is_convertible<_U2&&, _T2>>::value;
     130        }
     131      };
     132  
     133    template <typename _T1, typename _T2>
     134      struct _PCC<false, _T1, _T2>
     135      {
     136        template <typename _U1, typename _U2>
     137        static constexpr bool _ConstructiblePair()
     138        {
     139  	return false;
     140        }
     141  
     142        template <typename _U1, typename _U2>
     143        static constexpr bool _ImplicitlyConvertiblePair()
     144        {
     145  	return false;
     146        }
     147  
     148        template <typename _U1, typename _U2>
     149        static constexpr bool _MoveConstructiblePair()
     150        {
     151  	return false;
     152        }
     153  
     154        template <typename _U1, typename _U2>
     155        static constexpr bool _ImplicitlyMoveConvertiblePair()
     156        {
     157  	return false;
     158        }
     159      };
     160  #endif // lib concepts
     161  #endif // C++11
     162  
     163    template<typename _U1, typename _U2> class __pair_base
     164    {
     165  #if __cplusplus >= 201103L && ! __cpp_lib_concepts
     166      template<typename _T1, typename _T2> friend struct pair;
     167      __pair_base() = default;
     168      ~__pair_base() = default;
     169      __pair_base(const __pair_base&) = default;
     170      __pair_base& operator=(const __pair_base&) = delete;
     171  #endif // C++11
     172    };
     173  
     174    /// @endcond
     175  
     176   /**
     177     *  @brief Struct holding two objects of arbitrary type.
     178     *
     179     *  @tparam _T1  Type of first object.
     180     *  @tparam _T2  Type of second object.
     181     *
     182     *  <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
     183     *
     184     * @headerfile utility
     185     */
     186    template<typename _T1, typename _T2>
     187      struct pair
     188      : public __pair_base<_T1, _T2>
     189      {
     190        typedef _T1 first_type;    ///< The type of the `first` member
     191        typedef _T2 second_type;   ///< The type of the `second` member
     192  
     193        _T1 first;                 ///< The first member
     194        _T2 second;                ///< The second member
     195  
     196  #if __cplusplus >= 201103L
     197        constexpr pair(const pair&) = default;	///< Copy constructor
     198        constexpr pair(pair&&) = default;		///< Move constructor
     199  
     200        template<typename... _Args1, typename... _Args2>
     201  	_GLIBCXX20_CONSTEXPR
     202  	pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
     203  
     204        /// Swap the first members and then the second members.
     205        _GLIBCXX20_CONSTEXPR void
     206        swap(pair& __p)
     207        noexcept(__and_<__is_nothrow_swappable<_T1>,
     208  		      __is_nothrow_swappable<_T2>>::value)
     209        {
     210  	using std::swap;
     211  	swap(first, __p.first);
     212  	swap(second, __p.second);
     213        }
     214  
     215  #if __cplusplus > 202002L
     216        // As an extension, we constrain the const swap member function in order
     217        // to continue accepting explicit instantiation of pairs whose elements
     218        // are not all const swappable.  Without this constraint, such an
     219        // explicit instantiation would also instantiate the ill-formed body of
     220        // this function and yield a hard error.  This constraint shouldn't
     221        // affect the behavior of valid programs.
     222        constexpr void
     223        swap(const pair& __p) const
     224        noexcept(__and_v<__is_nothrow_swappable<const _T1>,
     225  		       __is_nothrow_swappable<const _T2>>)
     226        requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
     227        {
     228  	using std::swap;
     229  	swap(first, __p.first);
     230  	swap(second, __p.second);
     231        }
     232  #endif // C++23
     233  
     234      private:
     235        template<typename... _Args1, size_t... _Indexes1,
     236  	       typename... _Args2, size_t... _Indexes2>
     237  	_GLIBCXX20_CONSTEXPR
     238  	pair(tuple<_Args1...>&, tuple<_Args2...>&,
     239  	     _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
     240      public:
     241  
     242  #if __cpp_lib_concepts
     243        // C++20 implementation using concepts, explicit(bool), fully constexpr.
     244  
     245        /// Default constructor
     246        constexpr
     247        explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
     248  			     __is_implicitly_default_constructible<_T2>>>())
     249        pair()
     250        requires is_default_constructible_v<_T1>
     251  	       && is_default_constructible_v<_T2>
     252        : first(), second()
     253        { }
     254  
     255      private:
     256  
     257        /// @cond undocumented
     258        template<typename _U1, typename _U2>
     259  	static constexpr bool
     260  	_S_constructible()
     261  	{
     262  	  if constexpr (is_constructible_v<_T1, _U1>)
     263  	    return is_constructible_v<_T2, _U2>;
     264  	  return false;
     265  	}
     266  
     267        template<typename _U1, typename _U2>
     268  	static constexpr bool
     269  	_S_nothrow_constructible()
     270  	{
     271  	  if constexpr (is_nothrow_constructible_v<_T1, _U1>)
     272  	    return is_nothrow_constructible_v<_T2, _U2>;
     273  	  return false;
     274  	}
     275  
     276        template<typename _U1, typename _U2>
     277  	static constexpr bool
     278  	_S_convertible()
     279  	{
     280  	  if constexpr (is_convertible_v<_U1, _T1>)
     281  	    return is_convertible_v<_U2, _T2>;
     282  	  return false;
     283  	}
     284  
     285        // True if construction from _U1 and _U2 would create a dangling ref.
     286        template<typename _U1, typename _U2>
     287  	static constexpr bool
     288  	_S_dangles()
     289  	{
     290  #if __has_builtin(__reference_constructs_from_temporary)
     291  	  if constexpr (__reference_constructs_from_temporary(_T1, _U1&&))
     292  	    return true;
     293  	  else
     294  	    return __reference_constructs_from_temporary(_T2, _U2&&);
     295  #else
     296  	  return false;
     297  #endif
     298  	}
     299        /// @endcond
     300  
     301      public:
     302  
     303        /// Constructor accepting lvalues of `first_type` and `second_type`
     304        constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
     305        pair(const _T1& __x, const _T2& __y)
     306        noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
     307        requires (_S_constructible<const _T1&, const _T2&>())
     308        : first(__x), second(__y)
     309        { }
     310  
     311        /// Constructor accepting two values of arbitrary types
     312        template<typename _U1, typename _U2>
     313  	requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
     314  	constexpr explicit(!_S_convertible<_U1, _U2>())
     315  	pair(_U1&& __x, _U2&& __y)
     316  	noexcept(_S_nothrow_constructible<_U1, _U2>())
     317  	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
     318  	{ }
     319  
     320        template<typename _U1, typename _U2>
     321  	requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
     322  	constexpr explicit(!_S_convertible<_U1, _U2>())
     323  	pair(_U1&&, _U2&&) = delete;
     324  
     325        /// Converting constructor from a const `pair<U1, U2>` lvalue
     326        template<typename _U1, typename _U2>
     327  	requires (_S_constructible<const _U1&, const _U2&>())
     328  	  && (!_S_dangles<_U1, _U2>())
     329  	constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
     330  	pair(const pair<_U1, _U2>& __p)
     331  	noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
     332  	: first(__p.first), second(__p.second)
     333  	{ }
     334  
     335        template<typename _U1, typename _U2>
     336  	requires (_S_constructible<const _U1&, const _U2&>())
     337  	      && (_S_dangles<const _U1&, const _U2&>())
     338  	constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
     339  	pair(const pair<_U1, _U2>&) = delete;
     340  
     341        /// Converting constructor from a non-const `pair<U1, U2>` rvalue
     342        template<typename _U1, typename _U2>
     343  	requires (_S_constructible<_U1, _U2>()) && (!_S_dangles<_U1, _U2>())
     344  	constexpr explicit(!_S_convertible<_U1, _U2>())
     345  	pair(pair<_U1, _U2>&& __p)
     346  	noexcept(_S_nothrow_constructible<_U1, _U2>())
     347  	: first(std::forward<_U1>(__p.first)),
     348  	  second(std::forward<_U2>(__p.second))
     349  	{ }
     350  
     351        template<typename _U1, typename _U2>
     352  	requires (_S_constructible<_U1, _U2>()) && (_S_dangles<_U1, _U2>())
     353  	constexpr explicit(!_S_convertible<_U1, _U2>())
     354  	pair(pair<_U1, _U2>&&) = delete;
     355  
     356  #if __cplusplus > 202002L
     357        /// Converting constructor from a non-const `pair<U1, U2>` lvalue
     358        template<typename _U1, typename _U2>
     359  	requires (_S_constructible<_U1&, _U2&>()) && (!_S_dangles<_U1&, _U2&>())
     360  	constexpr explicit(!_S_convertible<_U1&, _U2&>())
     361  	pair(pair<_U1, _U2>& __p)
     362  	noexcept(_S_nothrow_constructible<_U1&, _U2&>())
     363  	: first(__p.first), second(__p.second)
     364  	{ }
     365  
     366        template<typename _U1, typename _U2>
     367  	requires (_S_constructible<_U1&, _U2&>()) && (_S_dangles<_U1&, _U2&>())
     368  	constexpr explicit(!_S_convertible<_U1&, _U2&>())
     369  	pair(pair<_U1, _U2>&) = delete;
     370  
     371        /// Converting constructor from a const `pair<U1, U2>` rvalue
     372        template<typename _U1, typename _U2>
     373  	requires (_S_constructible<const _U1, const _U2>())
     374  	  && (!_S_dangles<const _U1, const _U2>())
     375  	constexpr explicit(!_S_convertible<const _U1, const _U2>())
     376  	pair(const pair<_U1, _U2>&& __p)
     377  	noexcept(_S_nothrow_constructible<const _U1, const _U2>())
     378  	: first(std::forward<const _U1>(__p.first)),
     379  	  second(std::forward<const _U2>(__p.second))
     380  	{ }
     381  
     382        template<typename _U1, typename _U2>
     383  	requires (_S_constructible<const _U1, const _U2>())
     384  	  && (_S_dangles<const _U1, const _U2>())
     385  	constexpr explicit(!_S_convertible<const _U1, const _U2>())
     386  	pair(const pair<_U1, _U2>&&) = delete;
     387  #endif // C++23
     388  
     389    private:
     390        /// @cond undocumented
     391        template<typename _U1, typename _U2>
     392  	static constexpr bool
     393  	_S_assignable()
     394  	{
     395  	  if constexpr (is_assignable_v<_T1&, _U1>)
     396  	    return is_assignable_v<_T2&, _U2>;
     397  	  return false;
     398  	}
     399  
     400        template<typename _U1, typename _U2>
     401  	static constexpr bool
     402  	_S_nothrow_assignable()
     403  	{
     404  	  if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
     405  	    return is_nothrow_assignable_v<_T2&, _U2>;
     406  	  return false;
     407  	}
     408        /// @endcond
     409  
     410    public:
     411  
     412        pair& operator=(const pair&) = delete;
     413  
     414        /// Copy assignment operator
     415        constexpr pair&
     416        operator=(const pair& __p)
     417        noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
     418        requires (_S_assignable<const _T1&, const _T2&>())
     419        {
     420  	first = __p.first;
     421  	second = __p.second;
     422  	return *this;
     423        }
     424  
     425        /// Move assignment operator
     426        constexpr pair&
     427        operator=(pair&& __p)
     428        noexcept(_S_nothrow_assignable<_T1, _T2>())
     429        requires (_S_assignable<_T1, _T2>())
     430        {
     431  	first = std::forward<first_type>(__p.first);
     432  	second = std::forward<second_type>(__p.second);
     433  	return *this;
     434        }
     435  
     436        /// Converting assignment from a const `pair<U1, U2>` lvalue
     437        template<typename _U1, typename _U2>
     438  	constexpr pair&
     439  	operator=(const pair<_U1, _U2>& __p)
     440  	noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
     441  	requires (_S_assignable<const _U1&, const _U2&>())
     442  	{
     443  	  first = __p.first;
     444  	  second = __p.second;
     445  	  return *this;
     446  	}
     447  
     448        /// Converting assignment from a non-const `pair<U1, U2>` rvalue
     449        template<typename _U1, typename _U2>
     450  	constexpr pair&
     451  	operator=(pair<_U1, _U2>&& __p)
     452  	noexcept(_S_nothrow_assignable<_U1, _U2>())
     453  	requires (_S_assignable<_U1, _U2>())
     454  	{
     455  	  first = std::forward<_U1>(__p.first);
     456  	  second = std::forward<_U2>(__p.second);
     457  	  return *this;
     458  	}
     459  
     460  #if __cplusplus > 202002L
     461        /// Copy assignment operator (const)
     462        constexpr const pair&
     463        operator=(const pair& __p) const
     464        requires is_copy_assignable_v<const first_type>
     465  	&& is_copy_assignable_v<const second_type>
     466        {
     467  	first = __p.first;
     468  	second = __p.second;
     469  	return *this;
     470        }
     471  
     472        /// Move assignment operator (const)
     473        constexpr const pair&
     474        operator=(pair&& __p) const
     475        requires is_assignable_v<const first_type&, first_type>
     476  	&& is_assignable_v<const second_type&, second_type>
     477        {
     478  	first = std::forward<first_type>(__p.first);
     479  	second = std::forward<second_type>(__p.second);
     480  	return *this;
     481        }
     482  
     483        /// Converting assignment from a const `pair<U1, U2>` lvalue
     484        template<typename _U1, typename _U2>
     485  	constexpr const pair&
     486  	operator=(const pair<_U1, _U2>& __p) const
     487  	requires is_assignable_v<const first_type&, const _U1&>
     488  	  && is_assignable_v<const second_type&, const _U2&>
     489  	{
     490  	  first = __p.first;
     491  	  second = __p.second;
     492  	  return *this;
     493  	}
     494  
     495        /// Converting assignment from a non-const `pair<U1, U2>` rvalue
     496        template<typename _U1, typename _U2>
     497  	constexpr const pair&
     498  	operator=(pair<_U1, _U2>&& __p) const
     499  	requires is_assignable_v<const first_type&, _U1>
     500  	  && is_assignable_v<const second_type&, _U2>
     501  	{
     502  	  first = std::forward<_U1>(__p.first);
     503  	  second = std::forward<_U2>(__p.second);
     504  	  return *this;
     505  	}
     506  #endif // C++23
     507  #else // !__cpp_lib_concepts
     508        // C++11/14/17 implementation using enable_if, partially constexpr.
     509  
     510        /// @cond undocumented
     511        // Error if construction from _U1 and _U2 would create a dangling ref.
     512  #if __has_builtin(__reference_constructs_from_temporary) \
     513        && defined _GLIBCXX_DEBUG
     514  # define __glibcxx_no_dangling_refs(_U1, _U2) \
     515    static_assert(!__reference_constructs_from_temporary(_T1, _U1) \
     516  	       && !__reference_constructs_from_temporary(_T2, _U2), \
     517  		"std::pair constructor creates a dangling reference")
     518  #else
     519  # define __glibcxx_no_dangling_refs(_U1, _U2)
     520  #endif
     521        /// @endcond
     522  
     523        /** The default constructor creates @c first and @c second using their
     524         *  respective default constructors.  */
     525        template <typename _U1 = _T1,
     526                  typename _U2 = _T2,
     527                  typename enable_if<__and_<
     528                                       __is_implicitly_default_constructible<_U1>,
     529                                       __is_implicitly_default_constructible<_U2>>
     530                                     ::value, bool>::type = true>
     531        constexpr pair()
     532        : first(), second() { }
     533  
     534        template <typename _U1 = _T1,
     535                  typename _U2 = _T2,
     536                  typename enable_if<__and_<
     537                         is_default_constructible<_U1>,
     538                         is_default_constructible<_U2>,
     539                         __not_<
     540                           __and_<__is_implicitly_default_constructible<_U1>,
     541                                  __is_implicitly_default_constructible<_U2>>>>
     542                                     ::value, bool>::type = false>
     543        explicit constexpr pair()
     544        : first(), second() { }
     545  
     546        // Shortcut for constraining the templates that don't take pairs.
     547        /// @cond undocumented
     548        using _PCCP = _PCC<true, _T1, _T2>;
     549        /// @endcond
     550  
     551        /// Construct from two const lvalues, allowing implicit conversions.
     552        template<typename _U1 = _T1, typename _U2=_T2, typename
     553  	       enable_if<_PCCP::template
     554  			   _ConstructiblePair<_U1, _U2>()
     555  	                 && _PCCP::template
     556  			   _ImplicitlyConvertiblePair<_U1, _U2>(),
     557                           bool>::type=true>
     558        constexpr pair(const _T1& __a, const _T2& __b)
     559        : first(__a), second(__b) { }
     560  
     561        /// Construct from two const lvalues, disallowing implicit conversions.
     562         template<typename _U1 = _T1, typename _U2=_T2, typename
     563  		enable_if<_PCCP::template
     564  			    _ConstructiblePair<_U1, _U2>()
     565  	                  && !_PCCP::template
     566  			    _ImplicitlyConvertiblePair<_U1, _U2>(),
     567                           bool>::type=false>
     568        explicit constexpr pair(const _T1& __a, const _T2& __b)
     569        : first(__a), second(__b) { }
     570  
     571        // Shortcut for constraining the templates that take pairs.
     572        /// @cond undocumented
     573        template <typename _U1, typename _U2>
     574          using _PCCFP = _PCC<!is_same<_T1, _U1>::value
     575  			    || !is_same<_T2, _U2>::value,
     576  			    _T1, _T2>;
     577        /// @endcond
     578  
     579        template<typename _U1, typename _U2, typename
     580  	       enable_if<_PCCFP<_U1, _U2>::template
     581  			   _ConstructiblePair<_U1, _U2>()
     582  	                 && _PCCFP<_U1, _U2>::template
     583  			   _ImplicitlyConvertiblePair<_U1, _U2>(),
     584  			  bool>::type=true>
     585  	constexpr pair(const pair<_U1, _U2>& __p)
     586  	: first(__p.first), second(__p.second)
     587  	{ __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
     588  
     589        template<typename _U1, typename _U2, typename
     590  	       enable_if<_PCCFP<_U1, _U2>::template
     591  			   _ConstructiblePair<_U1, _U2>()
     592  			 && !_PCCFP<_U1, _U2>::template
     593  			   _ImplicitlyConvertiblePair<_U1, _U2>(),
     594                           bool>::type=false>
     595  	explicit constexpr pair(const pair<_U1, _U2>& __p)
     596  	: first(__p.first), second(__p.second)
     597  	{ __glibcxx_no_dangling_refs(const _U1&, const _U2&); }
     598  
     599  #if _GLIBCXX_USE_DEPRECATED
     600  #if defined(__DEPRECATED)
     601  # define _GLIBCXX_DEPRECATED_PAIR_CTOR \
     602        __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
     603  				      "initialize std::pair of move-only " \
     604  				      "type and pointer")))
     605  #else
     606  # define _GLIBCXX_DEPRECATED_PAIR_CTOR
     607  #endif
     608  
     609      private:
     610        /// @cond undocumented
     611  
     612        // A type which can be constructed from literal zero, but not nullptr
     613        struct __zero_as_null_pointer_constant
     614        {
     615  	__zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
     616  	{ }
     617  	template<typename _Tp,
     618  		 typename = __enable_if_t<is_null_pointer<_Tp>::value>>
     619  	__zero_as_null_pointer_constant(_Tp) = delete;
     620        };
     621        /// @endcond
     622      public:
     623  
     624        // Deprecated extensions to DR 811.
     625        // These allow construction from an rvalue and a literal zero,
     626        // in cases where the standard says the zero should be deduced as int
     627        template<typename _U1,
     628  	       __enable_if_t<__and_<__not_<is_reference<_U1>>,
     629  				    is_pointer<_T2>,
     630  				    is_constructible<_T1, _U1>,
     631  				    __not_<is_constructible<_T1, const _U1&>>,
     632  				    is_convertible<_U1, _T1>>::value,
     633  			     bool> = true>
     634  	_GLIBCXX_DEPRECATED_PAIR_CTOR
     635  	constexpr
     636  	pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
     637  	: first(std::forward<_U1>(__x)), second(nullptr)
     638  	{ __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
     639  
     640        template<typename _U1,
     641  	       __enable_if_t<__and_<__not_<is_reference<_U1>>,
     642  				    is_pointer<_T2>,
     643  				    is_constructible<_T1, _U1>,
     644  				    __not_<is_constructible<_T1, const _U1&>>,
     645  				    __not_<is_convertible<_U1, _T1>>>::value,
     646  			     bool> = false>
     647  	_GLIBCXX_DEPRECATED_PAIR_CTOR
     648  	explicit constexpr
     649  	pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
     650  	: first(std::forward<_U1>(__x)), second(nullptr)
     651  	{ __glibcxx_no_dangling_refs(_U1&&, std::nullptr_t); }
     652  
     653        template<typename _U2,
     654  	       __enable_if_t<__and_<is_pointer<_T1>,
     655  				    __not_<is_reference<_U2>>,
     656  				    is_constructible<_T2, _U2>,
     657  				    __not_<is_constructible<_T2, const _U2&>>,
     658  				    is_convertible<_U2, _T2>>::value,
     659  			     bool> = true>
     660  	_GLIBCXX_DEPRECATED_PAIR_CTOR
     661  	constexpr
     662  	pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
     663  	: first(nullptr), second(std::forward<_U2>(__y))
     664  	{ __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
     665  
     666        template<typename _U2,
     667  	       __enable_if_t<__and_<is_pointer<_T1>,
     668  				    __not_<is_reference<_U2>>,
     669  				    is_constructible<_T2, _U2>,
     670  				    __not_<is_constructible<_T2, const _U2&>>,
     671  				    __not_<is_convertible<_U2, _T2>>>::value,
     672  			     bool> = false>
     673  	_GLIBCXX_DEPRECATED_PAIR_CTOR
     674  	explicit constexpr
     675  	pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
     676  	: first(nullptr), second(std::forward<_U2>(__y))
     677  	{ __glibcxx_no_dangling_refs(std::nullptr_t, _U2&&); }
     678  #undef _GLIBCXX_DEPRECATED_PAIR_CTOR
     679  #endif
     680  
     681        template<typename _U1, typename _U2, typename
     682  	       enable_if<_PCCP::template
     683  			   _MoveConstructiblePair<_U1, _U2>()
     684  			  && _PCCP::template
     685  			   _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     686                           bool>::type=true>
     687  	constexpr pair(_U1&& __x, _U2&& __y)
     688  	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
     689  	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
     690  
     691        template<typename _U1, typename _U2, typename
     692  	       enable_if<_PCCP::template
     693  			   _MoveConstructiblePair<_U1, _U2>()
     694  			  && !_PCCP::template
     695  			   _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     696                           bool>::type=false>
     697  	explicit constexpr pair(_U1&& __x, _U2&& __y)
     698  	: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
     699  	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
     700  
     701  
     702        template<typename _U1, typename _U2, typename
     703  	       enable_if<_PCCFP<_U1, _U2>::template
     704  			   _MoveConstructiblePair<_U1, _U2>()
     705  			  && _PCCFP<_U1, _U2>::template
     706  			   _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     707                           bool>::type=true>
     708  	constexpr pair(pair<_U1, _U2>&& __p)
     709  	: first(std::forward<_U1>(__p.first)),
     710  	  second(std::forward<_U2>(__p.second))
     711  	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
     712  
     713        template<typename _U1, typename _U2, typename
     714  	       enable_if<_PCCFP<_U1, _U2>::template
     715  			   _MoveConstructiblePair<_U1, _U2>()
     716  			  && !_PCCFP<_U1, _U2>::template
     717  			   _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     718                           bool>::type=false>
     719  	explicit constexpr pair(pair<_U1, _U2>&& __p)
     720  	: first(std::forward<_U1>(__p.first)),
     721  	  second(std::forward<_U2>(__p.second))
     722  	{ __glibcxx_no_dangling_refs(_U1&&, _U2&&); }
     723  
     724  #undef __glibcxx_no_dangling_refs
     725  
     726        pair&
     727        operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
     728  				       is_copy_assignable<_T2>>::value,
     729  				const pair&, const __nonesuch&> __p)
     730        {
     731  	first = __p.first;
     732  	second = __p.second;
     733  	return *this;
     734        }
     735  
     736        pair&
     737        operator=(__conditional_t<__and_<is_move_assignable<_T1>,
     738  				       is_move_assignable<_T2>>::value,
     739  				pair&&, __nonesuch&&> __p)
     740        noexcept(__and_<is_nothrow_move_assignable<_T1>,
     741  		      is_nothrow_move_assignable<_T2>>::value)
     742        {
     743  	first = std::forward<first_type>(__p.first);
     744  	second = std::forward<second_type>(__p.second);
     745  	return *this;
     746        }
     747  
     748        template<typename _U1, typename _U2>
     749  	typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
     750  				  is_assignable<_T2&, const _U2&>>::value,
     751  			   pair&>::type
     752  	operator=(const pair<_U1, _U2>& __p)
     753  	{
     754  	  first = __p.first;
     755  	  second = __p.second;
     756  	  return *this;
     757  	}
     758  
     759        template<typename _U1, typename _U2>
     760  	typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
     761  				  is_assignable<_T2&, _U2&&>>::value,
     762  			   pair&>::type
     763  	operator=(pair<_U1, _U2>&& __p)
     764  	{
     765  	  first = std::forward<_U1>(__p.first);
     766  	  second = std::forward<_U2>(__p.second);
     767  	  return *this;
     768  	}
     769  #endif // lib concepts
     770  #else
     771        // C++03 implementation
     772  
     773        // _GLIBCXX_RESOLVE_LIB_DEFECTS
     774        // 265.  std::pair::pair() effects overly restrictive
     775        /** The default constructor creates @c first and @c second using their
     776         *  respective default constructors.  */
     777        pair() : first(), second() { }
     778  
     779        /// Two objects may be passed to a `pair` constructor to be copied.
     780        pair(const _T1& __a, const _T2& __b)
     781        : first(__a), second(__b) { }
     782  
     783        /// Templated constructor to convert from other pairs.
     784        template<typename _U1, typename _U2>
     785  	pair(const pair<_U1, _U2>& __p)
     786  	: first(__p.first), second(__p.second)
     787  	{
     788  #if __has_builtin(__reference_constructs_from_temporary)
     789  #pragma GCC diagnostic push
     790  #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
     791  	  typedef int _DanglingCheck1[
     792  	    __reference_constructs_from_temporary(_T1, const _U1&) ? -1 : 1
     793  		      ];
     794  	  typedef int _DanglingCheck2[
     795  	    __reference_constructs_from_temporary(_T2, const _U2&) ? -1 : 1
     796  		      ];
     797  #pragma GCC diagnostic pop
     798  #endif
     799  	}
     800  #endif // C++11
     801      };
     802  
     803    /// @relates pair @{
     804  
     805  #if __cpp_deduction_guides >= 201606
     806    template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
     807  #endif
     808  
     809    /// Two pairs of the same type are equal iff their members are equal.
     810    template<typename _T1, typename _T2>
     811      inline _GLIBCXX_CONSTEXPR bool
     812      operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     813      { return __x.first == __y.first && __x.second == __y.second; }
     814  
     815  #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
     816    template<typename _T1, typename _T2>
     817      constexpr common_comparison_category_t<__detail::__synth3way_t<_T1>,
     818  					   __detail::__synth3way_t<_T2>>
     819      operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     820      {
     821        if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
     822  	return __c;
     823        return __detail::__synth3way(__x.second, __y.second);
     824      }
     825  #else
     826    /** Defines a lexicographical order for pairs.
     827     *
     828     * For two pairs of the same type, `P` is ordered before `Q` if
     829     * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
     830     * are equivalent (neither is less than the other) and `P.second` is less
     831     * than `Q.second`.
     832    */
     833    template<typename _T1, typename _T2>
     834      inline _GLIBCXX_CONSTEXPR bool
     835      operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     836      { return __x.first < __y.first
     837  	     || (!(__y.first < __x.first) && __x.second < __y.second); }
     838  
     839    /// Uses @c operator== to find the result.
     840    template<typename _T1, typename _T2>
     841      inline _GLIBCXX_CONSTEXPR bool
     842      operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     843      { return !(__x == __y); }
     844  
     845    /// Uses @c operator< to find the result.
     846    template<typename _T1, typename _T2>
     847      inline _GLIBCXX_CONSTEXPR bool
     848      operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     849      { return __y < __x; }
     850  
     851    /// Uses @c operator< to find the result.
     852    template<typename _T1, typename _T2>
     853      inline _GLIBCXX_CONSTEXPR bool
     854      operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     855      { return !(__y < __x); }
     856  
     857    /// Uses @c operator< to find the result.
     858    template<typename _T1, typename _T2>
     859      inline _GLIBCXX_CONSTEXPR bool
     860      operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     861      { return !(__x < __y); }
     862  #endif // !(three_way_comparison && concepts)
     863  
     864  #if __cplusplus >= 201103L
     865    /** Swap overload for pairs. Calls std::pair::swap().
     866     *
     867     * @note This std::swap overload is not declared in C++03 mode,
     868     * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
     869    */
     870    template<typename _T1, typename _T2>
     871      _GLIBCXX20_CONSTEXPR inline
     872  #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     873      // Constrained free swap overload, see p0185r1
     874      typename enable_if<__and_<__is_swappable<_T1>,
     875                                __is_swappable<_T2>>::value>::type
     876  #else
     877      void
     878  #endif
     879      swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
     880      noexcept(noexcept(__x.swap(__y)))
     881      { __x.swap(__y); }
     882  
     883  #if __cplusplus > 202002L
     884    template<typename _T1, typename _T2>
     885      requires is_swappable_v<const _T1> && is_swappable_v<const _T2>
     886      constexpr void
     887      swap(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     888      noexcept(noexcept(__x.swap(__y)))
     889      { __x.swap(__y); }
     890  #endif // C++23
     891  
     892  #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     893    template<typename _T1, typename _T2>
     894      typename enable_if<!__and_<__is_swappable<_T1>,
     895  			       __is_swappable<_T2>>::value>::type
     896      swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
     897  #endif
     898  #endif // __cplusplus >= 201103L
     899  
     900    /// @} relates pair
     901  
     902    /**
     903     *  @brief A convenience wrapper for creating a pair from two objects.
     904     *  @param  __x  The first object.
     905     *  @param  __y  The second object.
     906     *  @return   A newly-constructed pair<> object of the appropriate type.
     907     *
     908     *  The C++98 standard says the objects are passed by reference-to-const,
     909     *  but C++03 says they are passed by value (this was LWG issue #181).
     910     *
     911     *  Since C++11 they have been passed by forwarding reference and then
     912     *  forwarded to the new members of the pair. To create a pair with a
     913     *  member of reference type, pass a `reference_wrapper` to this function.
     914     */
     915    // _GLIBCXX_RESOLVE_LIB_DEFECTS
     916    // 181.  make_pair() unintended behavior
     917  #if __cplusplus >= 201103L
     918    // NB: DR 706.
     919    template<typename _T1, typename _T2>
     920      constexpr pair<typename __decay_and_strip<_T1>::__type,
     921                     typename __decay_and_strip<_T2>::__type>
     922      make_pair(_T1&& __x, _T2&& __y)
     923      {
     924        typedef typename __decay_and_strip<_T1>::__type __ds_type1;
     925        typedef typename __decay_and_strip<_T2>::__type __ds_type2;
     926        typedef pair<__ds_type1, __ds_type2> 	      __pair_type;
     927        return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
     928      }
     929  #else
     930    template<typename _T1, typename _T2>
     931      inline pair<_T1, _T2>
     932      make_pair(_T1 __x, _T2 __y)
     933      { return pair<_T1, _T2>(__x, __y); }
     934  #endif
     935  
     936    /// @}
     937  
     938  #if __cplusplus >= 201103L
     939    // Various functions which give std::pair a tuple-like interface.
     940  
     941    /// @cond undocumented
     942    template<typename _T1, typename _T2>
     943      struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
     944      { };
     945    /// @endcond
     946  
     947    /// Partial specialization for std::pair
     948    template<class _Tp1, class _Tp2>
     949      struct tuple_size<pair<_Tp1, _Tp2>>
     950      : public integral_constant<size_t, 2> { };
     951  
     952    /// Partial specialization for std::pair
     953    template<class _Tp1, class _Tp2>
     954      struct tuple_element<0, pair<_Tp1, _Tp2>>
     955      { typedef _Tp1 type; };
     956  
     957    /// Partial specialization for std::pair
     958    template<class _Tp1, class _Tp2>
     959      struct tuple_element<1, pair<_Tp1, _Tp2>>
     960      { typedef _Tp2 type; };
     961  
     962  #if __cplusplus >= 201703L
     963    template<typename _Tp1, typename _Tp2>
     964      inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
     965  
     966    template<typename _Tp1, typename _Tp2>
     967      inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
     968  
     969    template<typename _Tp>
     970      inline constexpr bool __is_pair = false;
     971  
     972    template<typename _Tp, typename _Up>
     973      inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
     974  #endif
     975  
     976    /// @cond undocumented
     977    template<size_t _Int>
     978      struct __pair_get;
     979  
     980    template<>
     981      struct __pair_get<0>
     982      {
     983        template<typename _Tp1, typename _Tp2>
     984  	static constexpr _Tp1&
     985  	__get(pair<_Tp1, _Tp2>& __pair) noexcept
     986  	{ return __pair.first; }
     987  
     988        template<typename _Tp1, typename _Tp2>
     989  	static constexpr _Tp1&&
     990  	__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
     991  	{ return std::forward<_Tp1>(__pair.first); }
     992  
     993        template<typename _Tp1, typename _Tp2>
     994  	static constexpr const _Tp1&
     995  	__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
     996  	{ return __pair.first; }
     997  
     998        template<typename _Tp1, typename _Tp2>
     999  	static constexpr const _Tp1&&
    1000  	__const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
    1001  	{ return std::forward<const _Tp1>(__pair.first); }
    1002      };
    1003  
    1004    template<>
    1005      struct __pair_get<1>
    1006      {
    1007        template<typename _Tp1, typename _Tp2>
    1008  	static constexpr _Tp2&
    1009  	__get(pair<_Tp1, _Tp2>& __pair) noexcept
    1010  	{ return __pair.second; }
    1011  
    1012        template<typename _Tp1, typename _Tp2>
    1013  	static constexpr _Tp2&&
    1014  	__move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
    1015  	{ return std::forward<_Tp2>(__pair.second); }
    1016  
    1017        template<typename _Tp1, typename _Tp2>
    1018  	static constexpr const _Tp2&
    1019  	__const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
    1020  	{ return __pair.second; }
    1021  
    1022        template<typename _Tp1, typename _Tp2>
    1023  	static constexpr const _Tp2&&
    1024  	__const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
    1025  	{ return std::forward<const _Tp2>(__pair.second); }
    1026      };
    1027    /// @endcond
    1028  
    1029    /** @{
    1030     * std::get overloads for accessing members of std::pair
    1031     */
    1032  
    1033    template<size_t _Int, class _Tp1, class _Tp2>
    1034      constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
    1035      get(pair<_Tp1, _Tp2>& __in) noexcept
    1036      { return __pair_get<_Int>::__get(__in); }
    1037  
    1038    template<size_t _Int, class _Tp1, class _Tp2>
    1039      constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
    1040      get(pair<_Tp1, _Tp2>&& __in) noexcept
    1041      { return __pair_get<_Int>::__move_get(std::move(__in)); }
    1042  
    1043    template<size_t _Int, class _Tp1, class _Tp2>
    1044      constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
    1045      get(const pair<_Tp1, _Tp2>& __in) noexcept
    1046      { return __pair_get<_Int>::__const_get(__in); }
    1047  
    1048    template<size_t _Int, class _Tp1, class _Tp2>
    1049      constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
    1050      get(const pair<_Tp1, _Tp2>&& __in) noexcept
    1051      { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
    1052  
    1053  #if __cplusplus >= 201402L
    1054  
    1055  #define __cpp_lib_tuples_by_type 201304L
    1056  
    1057    template <typename _Tp, typename _Up>
    1058      constexpr _Tp&
    1059      get(pair<_Tp, _Up>& __p) noexcept
    1060      { return __p.first; }
    1061  
    1062    template <typename _Tp, typename _Up>
    1063      constexpr const _Tp&
    1064      get(const pair<_Tp, _Up>& __p) noexcept
    1065      { return __p.first; }
    1066  
    1067    template <typename _Tp, typename _Up>
    1068      constexpr _Tp&&
    1069      get(pair<_Tp, _Up>&& __p) noexcept
    1070      { return std::move(__p.first); }
    1071  
    1072    template <typename _Tp, typename _Up>
    1073      constexpr const _Tp&&
    1074      get(const pair<_Tp, _Up>&& __p) noexcept
    1075      { return std::move(__p.first); }
    1076  
    1077    template <typename _Tp, typename _Up>
    1078      constexpr _Tp&
    1079      get(pair<_Up, _Tp>& __p) noexcept
    1080      { return __p.second; }
    1081  
    1082    template <typename _Tp, typename _Up>
    1083      constexpr const _Tp&
    1084      get(const pair<_Up, _Tp>& __p) noexcept
    1085      { return __p.second; }
    1086  
    1087    template <typename _Tp, typename _Up>
    1088      constexpr _Tp&&
    1089      get(pair<_Up, _Tp>&& __p) noexcept
    1090      { return std::move(__p.second); }
    1091  
    1092    template <typename _Tp, typename _Up>
    1093      constexpr const _Tp&&
    1094      get(const pair<_Up, _Tp>&& __p) noexcept
    1095      { return std::move(__p.second); }
    1096  
    1097  #if __cplusplus > 202002L
    1098    template<typename _T1, typename _T2, typename _U1, typename _U2,
    1099  	   template<typename> class _TQual, template<typename> class _UQual>
    1100      requires requires { typename pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
    1101  				      common_reference_t<_TQual<_T2>, _UQual<_U2>>>; }
    1102    struct basic_common_reference<pair<_T1, _T2>, pair<_U1, _U2>, _TQual, _UQual>
    1103    {
    1104      using type = pair<common_reference_t<_TQual<_T1>, _UQual<_U1>>,
    1105  		      common_reference_t<_TQual<_T2>, _UQual<_U2>>>;
    1106    };
    1107  
    1108    template<typename _T1, typename _T2, typename _U1, typename _U2>
    1109      requires requires { typename pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; }
    1110    struct common_type<pair<_T1, _T2>, pair<_U1, _U2>>
    1111    { using type = pair<common_type_t<_T1, _U1>, common_type_t<_T2, _U2>>; };
    1112  #endif // C++23
    1113  
    1114  #endif // C++14
    1115    /// @}
    1116  #endif // C++11
    1117  
    1118  _GLIBCXX_END_NAMESPACE_VERSION
    1119  } // namespace std
    1120  
    1121  #endif /* _STL_PAIR_H */