LCOV - code coverage report
Current view: top level - usr/include/c++/12/bits - stl_pair.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 13 13 100.0 %
Date: 2023-07-19 08:18:47 Functions: 0 0 -

          Line data    Source code
       1             : // Pair implementation -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2001-2022 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             :   template<typename _T1, typename _T2>
     185       24734 :     struct pair
     186             :     : public __pair_base<_T1, _T2>
     187             :     {
     188             :       typedef _T1 first_type;    ///< The type of the `first` member
     189             :       typedef _T2 second_type;   ///< The type of the `second` member
     190             : 
     191             :       _T1 first;                 ///< The first member
     192             :       _T2 second;                ///< The second member
     193             : 
     194             : #if __cplusplus >= 201103L
     195             :       constexpr pair(const pair&) = default;        ///< Copy constructor
     196             :       constexpr pair(pair&&) = default;         ///< Move constructor
     197             : 
     198             :       template<typename... _Args1, typename... _Args2>
     199             :         _GLIBCXX20_CONSTEXPR
     200             :         pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
     201             : 
     202             :       /// Swap the first members and then the second members.
     203             :       _GLIBCXX20_CONSTEXPR void
     204             :       swap(pair& __p)
     205             :       noexcept(__and_<__is_nothrow_swappable<_T1>,
     206             :                       __is_nothrow_swappable<_T2>>::value)
     207             :       {
     208             :         using std::swap;
     209             :         swap(first, __p.first);
     210             :         swap(second, __p.second);
     211             :       }
     212             : 
     213             :     private:
     214             :       template<typename... _Args1, size_t... _Indexes1,
     215             :                typename... _Args2, size_t... _Indexes2>
     216             :         _GLIBCXX20_CONSTEXPR
     217             :         pair(tuple<_Args1...>&, tuple<_Args2...>&,
     218             :              _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
     219             :     public:
     220             : 
     221             : #if __cpp_lib_concepts
     222             :       // C++20 implementation using concepts, explicit(bool), fully constexpr.
     223             : 
     224             :       /// Default constructor
     225             :       constexpr
     226             :       explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
     227             :                              __is_implicitly_default_constructible<_T2>>>())
     228             :       pair()
     229             :       requires is_default_constructible_v<_T1>
     230             :                && is_default_constructible_v<_T2>
     231             :       : first(), second()
     232             :       { }
     233             : 
     234             :     private:
     235             : 
     236             :       /// @cond undocumented
     237             :       template<typename _U1, typename _U2>
     238             :         static constexpr bool
     239             :         _S_constructible()
     240             :         {
     241             :           if constexpr (is_constructible_v<_T1, _U1>)
     242             :             return is_constructible_v<_T2, _U2>;
     243             :           return false;
     244             :         }
     245             : 
     246             :       template<typename _U1, typename _U2>
     247             :         static constexpr bool
     248             :         _S_nothrow_constructible()
     249             :         {
     250             :           if constexpr (is_nothrow_constructible_v<_T1, _U1>)
     251             :             return is_nothrow_constructible_v<_T2, _U2>;
     252             :           return false;
     253             :         }
     254             : 
     255             :       template<typename _U1, typename _U2>
     256             :         static constexpr bool
     257             :         _S_convertible()
     258             :         {
     259             :           if constexpr (is_convertible_v<_U1, _T1>)
     260             :             return is_convertible_v<_U2, _T2>;
     261             :           return false;
     262             :         }
     263             :       /// @endcond
     264             : 
     265             :     public:
     266             : 
     267             :       /// Constructor accepting lvalues of `first_type` and `second_type`
     268             :       constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
     269             :       pair(const _T1& __x, const _T2& __y)
     270             :       noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
     271             :       requires (_S_constructible<const _T1&, const _T2&>())
     272             :       : first(__x), second(__y)
     273             :       { }
     274             : 
     275             :       /// Constructor accepting two values of arbitrary types
     276             :       template<typename _U1, typename _U2>
     277             :         requires (_S_constructible<_U1, _U2>())
     278             :         constexpr explicit(!_S_convertible<_U1, _U2>())
     279             :         pair(_U1&& __x, _U2&& __y)
     280             :         noexcept(_S_nothrow_constructible<_U1, _U2>())
     281             :         : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
     282             :         { }
     283             : 
     284             :       /// Converting constructor from a `pair<U1, U2>` lvalue
     285             :       template<typename _U1, typename _U2>
     286             :         requires (_S_constructible<const _U1&, const _U2&>())
     287             :         constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
     288             :         pair(const pair<_U1, _U2>& __p)
     289             :         noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
     290             :         : first(__p.first), second(__p.second)
     291             :         { }
     292             : 
     293             :       /// Converting constructor from a `pair<U1, U2>` rvalue
     294             :       template<typename _U1, typename _U2>
     295             :         requires (_S_constructible<_U1, _U2>())
     296             :         constexpr explicit(!_S_convertible<_U1, _U2>())
     297             :         pair(pair<_U1, _U2>&& __p)
     298             :         noexcept(_S_nothrow_constructible<_U1, _U2>())
     299             :         : first(std::forward<_U1>(__p.first)),
     300             :           second(std::forward<_U2>(__p.second))
     301             :         { }
     302             : 
     303             :   private:
     304             :       /// @cond undocumented
     305             :       template<typename _U1, typename _U2>
     306             :         static constexpr bool
     307             :         _S_assignable()
     308             :         {
     309             :           if constexpr (is_assignable_v<_T1&, _U1>)
     310             :             return is_assignable_v<_T2&, _U2>;
     311             :           return false;
     312             :         }
     313             : 
     314             :       template<typename _U1, typename _U2>
     315             :         static constexpr bool
     316             :         _S_nothrow_assignable()
     317             :         {
     318             :           if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
     319             :             return is_nothrow_assignable_v<_T2&, _U2>;
     320             :           return false;
     321             :         }
     322             :       /// @endcond
     323             : 
     324             :   public:
     325             : 
     326             :       pair& operator=(const pair&) = delete;
     327             : 
     328             :       /// Copy assignment operator
     329             :       constexpr pair&
     330             :       operator=(const pair& __p)
     331             :       noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
     332             :       requires (_S_assignable<const _T1&, const _T2&>())
     333             :       {
     334             :         first = __p.first;
     335             :         second = __p.second;
     336             :         return *this;
     337             :       }
     338             : 
     339             :       /// Move assignment operator
     340             :       constexpr pair&
     341             :       operator=(pair&& __p)
     342             :       noexcept(_S_nothrow_assignable<_T1, _T2>())
     343             :       requires (_S_assignable<_T1, _T2>())
     344             :       {
     345             :         first = std::forward<first_type>(__p.first);
     346             :         second = std::forward<second_type>(__p.second);
     347             :         return *this;
     348             :       }
     349             : 
     350             :       /// Converting assignment from a `pair<U1, U2>` lvalue
     351             :       template<typename _U1, typename _U2>
     352             :         constexpr pair&
     353             :         operator=(const pair<_U1, _U2>& __p)
     354             :         noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
     355             :         requires (_S_assignable<const _U1&, const _U2&>())
     356             :         {
     357             :           first = __p.first;
     358             :           second = __p.second;
     359             :           return *this;
     360             :         }
     361             : 
     362             :       /// Converting assignment from a `pair<U1, U2>` rvalue
     363             :       template<typename _U1, typename _U2>
     364             :         constexpr pair&
     365             :         operator=(pair<_U1, _U2>&& __p)
     366             :         noexcept(_S_nothrow_assignable<_U1, _U2>())
     367             :         requires (_S_assignable<_U1, _U2>())
     368             :         {
     369             :           first = std::forward<_U1>(__p.first);
     370             :           second = std::forward<_U2>(__p.second);
     371             :           return *this;
     372             :         }
     373             : #else
     374             :       // C++11/14/17 implementation using enable_if, partially constexpr.
     375             : 
     376             :       /** The default constructor creates @c first and @c second using their
     377             :        *  respective default constructors.  */
     378             :       template <typename _U1 = _T1,
     379             :                 typename _U2 = _T2,
     380             :                 typename enable_if<__and_<
     381             :                                      __is_implicitly_default_constructible<_U1>,
     382             :                                      __is_implicitly_default_constructible<_U2>>
     383             :                                    ::value, bool>::type = true>
     384        3617 :       constexpr pair()
     385             :       : first(), second() { }
     386             : 
     387             :       template <typename _U1 = _T1,
     388             :                 typename _U2 = _T2,
     389             :                 typename enable_if<__and_<
     390             :                        is_default_constructible<_U1>,
     391             :                        is_default_constructible<_U2>,
     392             :                        __not_<
     393             :                          __and_<__is_implicitly_default_constructible<_U1>,
     394             :                                 __is_implicitly_default_constructible<_U2>>>>
     395             :                                    ::value, bool>::type = false>
     396             :       explicit constexpr pair()
     397             :       : first(), second() { }
     398             : 
     399             :       // Shortcut for constraining the templates that don't take pairs.
     400             :       /// @cond undocumented
     401             :       using _PCCP = _PCC<true, _T1, _T2>;
     402             :       /// @endcond
     403             : 
     404             :       /// Construct from two const lvalues, allowing implicit conversions.
     405             :       template<typename _U1 = _T1, typename _U2=_T2, typename
     406             :                enable_if<_PCCP::template
     407             :                            _ConstructiblePair<_U1, _U2>()
     408             :                          && _PCCP::template
     409             :                            _ImplicitlyConvertiblePair<_U1, _U2>(),
     410             :                          bool>::type=true>
     411       36157 :       constexpr pair(const _T1& __a, const _T2& __b)
     412             :       : first(__a), second(__b) { }
     413             : 
     414             :       /// Construct from two const lvalues, disallowing implicit conversions.
     415             :        template<typename _U1 = _T1, typename _U2=_T2, typename
     416             :                 enable_if<_PCCP::template
     417             :                             _ConstructiblePair<_U1, _U2>()
     418             :                           && !_PCCP::template
     419             :                             _ImplicitlyConvertiblePair<_U1, _U2>(),
     420             :                          bool>::type=false>
     421             :       explicit constexpr pair(const _T1& __a, const _T2& __b)
     422             :       : first(__a), second(__b) { }
     423             : 
     424             :       // Shortcut for constraining the templates that take pairs.
     425             :       /// @cond undocumented
     426             :       template <typename _U1, typename _U2>
     427             :         using _PCCFP = _PCC<!is_same<_T1, _U1>::value
     428             :                             || !is_same<_T2, _U2>::value,
     429             :                             _T1, _T2>;
     430             :       /// @endcond
     431             : 
     432             :       template<typename _U1, typename _U2, typename
     433             :                enable_if<_PCCFP<_U1, _U2>::template
     434             :                            _ConstructiblePair<_U1, _U2>()
     435             :                          && _PCCFP<_U1, _U2>::template
     436             :                            _ImplicitlyConvertiblePair<_U1, _U2>(),
     437             :                           bool>::type=true>
     438             :         constexpr pair(const pair<_U1, _U2>& __p)
     439             :         : first(__p.first), second(__p.second) { }
     440             : 
     441             :       template<typename _U1, typename _U2, typename
     442             :                enable_if<_PCCFP<_U1, _U2>::template
     443             :                            _ConstructiblePair<_U1, _U2>()
     444             :                          && !_PCCFP<_U1, _U2>::template
     445             :                            _ImplicitlyConvertiblePair<_U1, _U2>(),
     446             :                          bool>::type=false>
     447             :         explicit constexpr pair(const pair<_U1, _U2>& __p)
     448             :         : first(__p.first), second(__p.second) { }
     449             : 
     450             : #if _GLIBCXX_USE_DEPRECATED
     451             : #if defined(__DEPRECATED)
     452             : # define _GLIBCXX_DEPRECATED_PAIR_CTOR \
     453             :       __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
     454             :                                       "initialize std::pair of move-only " \
     455             :                                       "type and pointer")))
     456             : #else
     457             : # define _GLIBCXX_DEPRECATED_PAIR_CTOR
     458             : #endif
     459             : 
     460             :     private:
     461             :       /// @cond undocumented
     462             : 
     463             :       // A type which can be constructed from literal zero, but not nullptr
     464             :       struct __zero_as_null_pointer_constant
     465             :       {
     466             :         __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
     467             :         { }
     468             :         template<typename _Tp,
     469             :                  typename = __enable_if_t<is_null_pointer<_Tp>::value>>
     470             :         __zero_as_null_pointer_constant(_Tp) = delete;
     471             :       };
     472             :       /// @endcond
     473             :     public:
     474             : 
     475             :       // Deprecated extensions to DR 811.
     476             :       // These allow construction from an rvalue and a literal zero,
     477             :       // in cases where the standard says the zero should be deduced as int
     478             :       template<typename _U1,
     479             :                __enable_if_t<__and_<__not_<is_reference<_U1>>,
     480             :                                     is_pointer<_T2>,
     481             :                                     is_constructible<_T1, _U1>,
     482             :                                     __not_<is_constructible<_T1, const _U1&>>,
     483             :                                     is_convertible<_U1, _T1>>::value,
     484             :                              bool> = true>
     485             :         _GLIBCXX_DEPRECATED_PAIR_CTOR
     486             :         constexpr
     487             :         pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
     488             :         : first(std::forward<_U1>(__x)), second(nullptr) { }
     489             : 
     490             :       template<typename _U1,
     491             :                __enable_if_t<__and_<__not_<is_reference<_U1>>,
     492             :                                     is_pointer<_T2>,
     493             :                                     is_constructible<_T1, _U1>,
     494             :                                     __not_<is_constructible<_T1, const _U1&>>,
     495             :                                     __not_<is_convertible<_U1, _T1>>>::value,
     496             :                              bool> = false>
     497             :         _GLIBCXX_DEPRECATED_PAIR_CTOR
     498             :         explicit constexpr
     499             :         pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
     500             :         : first(std::forward<_U1>(__x)), second(nullptr) { }
     501             : 
     502             :       template<typename _U2,
     503             :                __enable_if_t<__and_<is_pointer<_T1>,
     504             :                                     __not_<is_reference<_U2>>,
     505             :                                     is_constructible<_T2, _U2>,
     506             :                                     __not_<is_constructible<_T2, const _U2&>>,
     507             :                                     is_convertible<_U2, _T2>>::value,
     508             :                              bool> = true>
     509             :         _GLIBCXX_DEPRECATED_PAIR_CTOR
     510             :         constexpr
     511             :         pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
     512             :         : first(nullptr), second(std::forward<_U2>(__y)) { }
     513             : 
     514             :       template<typename _U2,
     515             :                __enable_if_t<__and_<is_pointer<_T1>,
     516             :                                     __not_<is_reference<_U2>>,
     517             :                                     is_constructible<_T2, _U2>,
     518             :                                     __not_<is_constructible<_T2, const _U2&>>,
     519             :                                     __not_<is_convertible<_U2, _T2>>>::value,
     520             :                              bool> = false>
     521             :         _GLIBCXX_DEPRECATED_PAIR_CTOR
     522             :         explicit constexpr
     523             :         pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
     524             :         : first(nullptr), second(std::forward<_U2>(__y)) { }
     525             : #undef _GLIBCXX_DEPRECATED_PAIR_CTOR
     526             : #endif
     527             : 
     528             :       template<typename _U1, typename _U2, typename
     529             :                enable_if<_PCCP::template
     530             :                            _MoveConstructiblePair<_U1, _U2>()
     531             :                           && _PCCP::template
     532             :                            _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     533             :                          bool>::type=true>
     534  3926509541 :         constexpr pair(_U1&& __x, _U2&& __y)
     535  3926004809 :         : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
     536             : 
     537             :       template<typename _U1, typename _U2, typename
     538             :                enable_if<_PCCP::template
     539             :                            _MoveConstructiblePair<_U1, _U2>()
     540             :                           && !_PCCP::template
     541             :                            _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     542             :                          bool>::type=false>
     543             :         explicit constexpr pair(_U1&& __x, _U2&& __y)
     544             :         : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
     545             : 
     546             : 
     547             :       template<typename _U1, typename _U2, typename
     548             :                enable_if<_PCCFP<_U1, _U2>::template
     549             :                            _MoveConstructiblePair<_U1, _U2>()
     550             :                           && _PCCFP<_U1, _U2>::template
     551             :                            _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     552             :                          bool>::type=true>
     553      111633 :         constexpr pair(pair<_U1, _U2>&& __p)
     554             :         : first(std::forward<_U1>(__p.first)),
     555      111633 :           second(std::forward<_U2>(__p.second)) { }
     556             : 
     557             :       template<typename _U1, typename _U2, typename
     558             :                enable_if<_PCCFP<_U1, _U2>::template
     559             :                            _MoveConstructiblePair<_U1, _U2>()
     560             :                           && !_PCCFP<_U1, _U2>::template
     561             :                            _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
     562             :                          bool>::type=false>
     563             :         explicit constexpr pair(pair<_U1, _U2>&& __p)
     564             :         : first(std::forward<_U1>(__p.first)),
     565             :           second(std::forward<_U2>(__p.second)) { }
     566             : 
     567             :       pair&
     568  7821586700 :       operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
     569             :                                        is_copy_assignable<_T2>>::value,
     570             :                                 const pair&, const __nonesuch&> __p)
     571             :       {
     572  7821586700 :         first = __p.first;
     573  3910527755 :         second = __p.second;
     574             :         return *this;
     575             :       }
     576             : 
     577             :       pair&
     578             :       operator=(__conditional_t<__and_<is_move_assignable<_T1>,
     579             :                                        is_move_assignable<_T2>>::value,
     580             :                                 pair&&, __nonesuch&&> __p)
     581             :       noexcept(__and_<is_nothrow_move_assignable<_T1>,
     582             :                       is_nothrow_move_assignable<_T2>>::value)
     583             :       {
     584             :         first = std::forward<first_type>(__p.first);
     585             :         second = std::forward<second_type>(__p.second);
     586             :         return *this;
     587             :       }
     588             : 
     589             :       template<typename _U1, typename _U2>
     590             :         typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
     591             :                                   is_assignable<_T2&, const _U2&>>::value,
     592             :                            pair&>::type
     593             :         operator=(const pair<_U1, _U2>& __p)
     594             :         {
     595             :           first = __p.first;
     596             :           second = __p.second;
     597             :           return *this;
     598             :         }
     599             : 
     600             :       template<typename _U1, typename _U2>
     601             :         typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
     602             :                                   is_assignable<_T2&, _U2&&>>::value,
     603             :                            pair&>::type
     604             :         operator=(pair<_U1, _U2>&& __p)
     605             :         {
     606             :           first = std::forward<_U1>(__p.first);
     607             :           second = std::forward<_U2>(__p.second);
     608             :           return *this;
     609             :         }
     610             : #endif // lib concepts
     611             : #else
     612             :       // C++03 implementation
     613             : 
     614             :       // _GLIBCXX_RESOLVE_LIB_DEFECTS
     615             :       // 265.  std::pair::pair() effects overly restrictive
     616             :       /** The default constructor creates @c first and @c second using their
     617             :        *  respective default constructors.  */
     618             :       pair() : first(), second() { }
     619             : 
     620             :       /// Two objects may be passed to a `pair` constructor to be copied.
     621             :       pair(const _T1& __a, const _T2& __b)
     622             :       : first(__a), second(__b) { }
     623             : 
     624             :       /// Templated constructor to convert from other pairs.
     625             :       template<typename _U1, typename _U2>
     626             :         pair(const pair<_U1, _U2>& __p)
     627             :         : first(__p.first), second(__p.second) { }
     628             : #endif // C++11
     629             :     };
     630             : 
     631             :   /// @relates pair @{
     632             : 
     633             : #if __cpp_deduction_guides >= 201606
     634             :   template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
     635             : #endif
     636             : 
     637             :   /// Two pairs of the same type are equal iff their members are equal.
     638             :   template<typename _T1, typename _T2>
     639             :     inline _GLIBCXX_CONSTEXPR bool
     640             :     operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     641             :     { return __x.first == __y.first && __x.second == __y.second; }
     642             : 
     643             : #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
     644             :   template<typename _T1, typename _T2>
     645             :     constexpr common_comparison_category_t<__detail::__synth3way_t<_T1>,
     646             :                                            __detail::__synth3way_t<_T2>>
     647             :     operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     648             :     {
     649             :       if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
     650             :         return __c;
     651             :       return __detail::__synth3way(__x.second, __y.second);
     652             :     }
     653             : #else
     654             :   /** Defines a lexicographical order for pairs.
     655             :    *
     656             :    * For two pairs of the same type, `P` is ordered before `Q` if
     657             :    * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
     658             :    * are equivalent (neither is less than the other) and `P.second` is less
     659             :    * than `Q.second`.
     660             :   */
     661             :   template<typename _T1, typename _T2>
     662             :     inline _GLIBCXX_CONSTEXPR bool
     663             :     operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     664             :     { return __x.first < __y.first
     665             :              || (!(__y.first < __x.first) && __x.second < __y.second); }
     666             : 
     667             :   /// Uses @c operator== to find the result.
     668             :   template<typename _T1, typename _T2>
     669             :     inline _GLIBCXX_CONSTEXPR bool
     670             :     operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     671             :     { return !(__x == __y); }
     672             : 
     673             :   /// Uses @c operator< to find the result.
     674             :   template<typename _T1, typename _T2>
     675             :     inline _GLIBCXX_CONSTEXPR bool
     676             :     operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     677             :     { return __y < __x; }
     678             : 
     679             :   /// Uses @c operator< to find the result.
     680             :   template<typename _T1, typename _T2>
     681             :     inline _GLIBCXX_CONSTEXPR bool
     682             :     operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     683             :     { return !(__y < __x); }
     684             : 
     685             :   /// Uses @c operator< to find the result.
     686             :   template<typename _T1, typename _T2>
     687             :     inline _GLIBCXX_CONSTEXPR bool
     688             :     operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
     689             :     { return !(__x < __y); }
     690             : #endif // !(three_way_comparison && concepts)
     691             : 
     692             : #if __cplusplus >= 201103L
     693             :   /** Swap overload for pairs. Calls std::pair::swap().
     694             :    *
     695             :    * @note This std::swap overload is not declared in C++03 mode,
     696             :    * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
     697             :   */
     698             :   template<typename _T1, typename _T2>
     699             :     _GLIBCXX20_CONSTEXPR inline
     700             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     701             :     // Constrained free swap overload, see p0185r1
     702             :     typename enable_if<__and_<__is_swappable<_T1>,
     703             :                               __is_swappable<_T2>>::value>::type
     704             : #else
     705             :     void
     706             : #endif
     707             :     swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
     708             :     noexcept(noexcept(__x.swap(__y)))
     709             :     { __x.swap(__y); }
     710             : 
     711             : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
     712             :   template<typename _T1, typename _T2>
     713             :     typename enable_if<!__and_<__is_swappable<_T1>,
     714             :                                __is_swappable<_T2>>::value>::type
     715             :     swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
     716             : #endif
     717             : #endif // __cplusplus >= 201103L
     718             : 
     719             :   /// @} relates pair
     720             : 
     721             :   /**
     722             :    *  @brief A convenience wrapper for creating a pair from two objects.
     723             :    *  @param  __x  The first object.
     724             :    *  @param  __y  The second object.
     725             :    *  @return   A newly-constructed pair<> object of the appropriate type.
     726             :    *
     727             :    *  The C++98 standard says the objects are passed by reference-to-const,
     728             :    *  but C++03 says they are passed by value (this was LWG issue #181).
     729             :    *
     730             :    *  Since C++11 they have been passed by forwarding reference and then
     731             :    *  forwarded to the new members of the pair. To create a pair with a
     732             :    *  member of reference type, pass a `reference_wrapper` to this function.
     733             :    */
     734             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     735             :   // 181.  make_pair() unintended behavior
     736             : #if __cplusplus >= 201103L
     737             :   // NB: DR 706.
     738             :   template<typename _T1, typename _T2>
     739             :     constexpr pair<typename __decay_and_strip<_T1>::__type,
     740             :                    typename __decay_and_strip<_T2>::__type>
     741     1026809 :     make_pair(_T1&& __x, _T2&& __y)
     742             :     {
     743             :       typedef typename __decay_and_strip<_T1>::__type __ds_type1;
     744             :       typedef typename __decay_and_strip<_T2>::__type __ds_type2;
     745             :       typedef pair<__ds_type1, __ds_type2>              __pair_type;
     746     1026809 :       return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
     747             :     }
     748             : #else
     749             :   template<typename _T1, typename _T2>
     750             :     inline pair<_T1, _T2>
     751             :     make_pair(_T1 __x, _T2 __y)
     752             :     { return pair<_T1, _T2>(__x, __y); }
     753             : #endif
     754             : 
     755             :   /// @}
     756             : 
     757             : #if __cplusplus >= 201103L
     758             :   // Various functions which give std::pair a tuple-like interface.
     759             : 
     760             :   template<typename _T1, typename _T2>
     761             :     struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
     762             :     { };
     763             : 
     764             :   /// Partial specialization for std::pair
     765             :   template<class _Tp1, class _Tp2>
     766             :     struct tuple_size<pair<_Tp1, _Tp2>>
     767             :     : public integral_constant<size_t, 2> { };
     768             : 
     769             :   /// Partial specialization for std::pair
     770             :   template<class _Tp1, class _Tp2>
     771             :     struct tuple_element<0, pair<_Tp1, _Tp2>>
     772             :     { typedef _Tp1 type; };
     773             : 
     774             :   /// Partial specialization for std::pair
     775             :   template<class _Tp1, class _Tp2>
     776             :     struct tuple_element<1, pair<_Tp1, _Tp2>>
     777             :     { typedef _Tp2 type; };
     778             : 
     779             : #if __cplusplus >= 201703L
     780             :   template<typename _Tp1, typename _Tp2>
     781             :     inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
     782             : 
     783             :   template<typename _Tp1, typename _Tp2>
     784             :     inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
     785             : 
     786             :   template<typename _Tp>
     787             :     inline constexpr bool __is_pair = false;
     788             : 
     789             :   template<typename _Tp, typename _Up>
     790             :     inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
     791             : 
     792             :   template<typename _Tp, typename _Up>
     793             :     inline constexpr bool __is_pair<const pair<_Tp, _Up>> = true;
     794             : #endif
     795             : 
     796             :   /// @cond undocumented
     797             :   template<size_t _Int>
     798             :     struct __pair_get;
     799             : 
     800             :   template<>
     801             :     struct __pair_get<0>
     802             :     {
     803             :       template<typename _Tp1, typename _Tp2>
     804             :         static constexpr _Tp1&
     805             :         __get(pair<_Tp1, _Tp2>& __pair) noexcept
     806             :         { return __pair.first; }
     807             : 
     808             :       template<typename _Tp1, typename _Tp2>
     809             :         static constexpr _Tp1&&
     810             :         __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
     811             :         { return std::forward<_Tp1>(__pair.first); }
     812             : 
     813             :       template<typename _Tp1, typename _Tp2>
     814             :         static constexpr const _Tp1&
     815             :         __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
     816             :         { return __pair.first; }
     817             : 
     818             :       template<typename _Tp1, typename _Tp2>
     819             :         static constexpr const _Tp1&&
     820             :         __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
     821             :         { return std::forward<const _Tp1>(__pair.first); }
     822             :     };
     823             : 
     824             :   template<>
     825             :     struct __pair_get<1>
     826             :     {
     827             :       template<typename _Tp1, typename _Tp2>
     828             :         static constexpr _Tp2&
     829             :         __get(pair<_Tp1, _Tp2>& __pair) noexcept
     830             :         { return __pair.second; }
     831             : 
     832             :       template<typename _Tp1, typename _Tp2>
     833             :         static constexpr _Tp2&&
     834             :         __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
     835             :         { return std::forward<_Tp2>(__pair.second); }
     836             : 
     837             :       template<typename _Tp1, typename _Tp2>
     838             :         static constexpr const _Tp2&
     839             :         __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
     840             :         { return __pair.second; }
     841             : 
     842             :       template<typename _Tp1, typename _Tp2>
     843             :         static constexpr const _Tp2&&
     844             :         __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
     845             :         { return std::forward<const _Tp2>(__pair.second); }
     846             :     };
     847             :   /// @endcond
     848             : 
     849             :   /** @{
     850             :    * std::get overloads for accessing members of std::pair
     851             :    */
     852             : 
     853             :   template<size_t _Int, class _Tp1, class _Tp2>
     854             :     constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
     855             :     get(pair<_Tp1, _Tp2>& __in) noexcept
     856             :     { return __pair_get<_Int>::__get(__in); }
     857             : 
     858             :   template<size_t _Int, class _Tp1, class _Tp2>
     859             :     constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
     860             :     get(pair<_Tp1, _Tp2>&& __in) noexcept
     861       24807 :     { return __pair_get<_Int>::__move_get(std::move(__in)); }
     862             : 
     863             :   template<size_t _Int, class _Tp1, class _Tp2>
     864             :     constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
     865             :     get(const pair<_Tp1, _Tp2>& __in) noexcept
     866             :     { return __pair_get<_Int>::__const_get(__in); }
     867             : 
     868             :   template<size_t _Int, class _Tp1, class _Tp2>
     869             :     constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
     870             :     get(const pair<_Tp1, _Tp2>&& __in) noexcept
     871             :     { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
     872             : 
     873             : #if __cplusplus >= 201402L
     874             : 
     875             : #define __cpp_lib_tuples_by_type 201304L
     876             : 
     877             :   template <typename _Tp, typename _Up>
     878             :     constexpr _Tp&
     879             :     get(pair<_Tp, _Up>& __p) noexcept
     880             :     { return __p.first; }
     881             : 
     882             :   template <typename _Tp, typename _Up>
     883             :     constexpr const _Tp&
     884             :     get(const pair<_Tp, _Up>& __p) noexcept
     885             :     { return __p.first; }
     886             : 
     887             :   template <typename _Tp, typename _Up>
     888             :     constexpr _Tp&&
     889             :     get(pair<_Tp, _Up>&& __p) noexcept
     890             :     { return std::move(__p.first); }
     891             : 
     892             :   template <typename _Tp, typename _Up>
     893             :     constexpr const _Tp&&
     894             :     get(const pair<_Tp, _Up>&& __p) noexcept
     895             :     { return std::move(__p.first); }
     896             : 
     897             :   template <typename _Tp, typename _Up>
     898             :     constexpr _Tp&
     899             :     get(pair<_Up, _Tp>& __p) noexcept
     900             :     { return __p.second; }
     901             : 
     902             :   template <typename _Tp, typename _Up>
     903             :     constexpr const _Tp&
     904             :     get(const pair<_Up, _Tp>& __p) noexcept
     905             :     { return __p.second; }
     906             : 
     907             :   template <typename _Tp, typename _Up>
     908             :     constexpr _Tp&&
     909             :     get(pair<_Up, _Tp>&& __p) noexcept
     910             :     { return std::move(__p.second); }
     911             : 
     912             :   template <typename _Tp, typename _Up>
     913             :     constexpr const _Tp&&
     914             :     get(const pair<_Up, _Tp>&& __p) noexcept
     915             :     { return std::move(__p.second); }
     916             : 
     917             : #endif // C++14
     918             :   /// @}
     919             : #endif // C++11
     920             : 
     921             : _GLIBCXX_END_NAMESPACE_VERSION
     922             : } // namespace std
     923             : 
     924             : #endif /* _STL_PAIR_H */

Generated by: LCOV version 1.16