123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924 |
- // Pair implementation -*- C++ -*-
- // Copyright (C) 2001-2022 Free Software Foundation, Inc.
- //
- // This file is part of the GNU ISO C++ Library. This library is free
- // software; you can redistribute it and/or modify it under the
- // terms of the GNU General Public License as published by the
- // Free Software Foundation; either version 3, or (at your option)
- // any later version.
- // This library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // Under Section 7 of GPL version 3, you are granted additional
- // permissions described in the GCC Runtime Library Exception, version
- // 3.1, as published by the Free Software Foundation.
- // You should have received a copy of the GNU General Public License and
- // a copy of the GCC Runtime Library Exception along with this program;
- // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- // <http://www.gnu.org/licenses/>.
- /*
- *
- * Copyright (c) 1994
- * Hewlett-Packard Company
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Hewlett-Packard Company makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- *
- *
- * Copyright (c) 1996,1997
- * Silicon Graphics Computer Systems, Inc.
- *
- * Permission to use, copy, modify, distribute and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation. Silicon Graphics makes no
- * representations about the suitability of this software for any
- * purpose. It is provided "as is" without express or implied warranty.
- */
- /** @file bits/stl_pair.h
- * This is an internal header file, included by other library headers.
- * Do not attempt to use it directly. @headername{utility}
- */
- #ifndef _STL_PAIR_H
- #define _STL_PAIR_H 1
- #if __cplusplus >= 201103L
- # include <type_traits> // for std::__decay_and_strip
- # include <bits/move.h> // for std::move / std::forward, and std::swap
- # include <bits/utility.h> // for std::tuple_element, std::tuple_size
- #endif
- #if __cplusplus >= 202002L
- # include <compare>
- # define __cpp_lib_constexpr_utility 201811L
- #endif
- namespace std _GLIBCXX_VISIBILITY(default)
- {
- _GLIBCXX_BEGIN_NAMESPACE_VERSION
- /**
- * @addtogroup utilities
- * @{
- */
- #if __cplusplus >= 201103L
- /// Tag type for piecewise construction of std::pair objects.
- struct piecewise_construct_t { explicit piecewise_construct_t() = default; };
- /// Tag for piecewise construction of std::pair objects.
- _GLIBCXX17_INLINE constexpr piecewise_construct_t piecewise_construct =
- piecewise_construct_t();
- /// @cond undocumented
- // Forward declarations.
- template<typename...>
- class tuple;
- template<size_t...>
- struct _Index_tuple;
- #if ! __cpp_lib_concepts
- // Concept utility functions, reused in conditionally-explicit
- // constructors.
- // See PR 70437, don't look at is_constructible or
- // is_convertible if the types are the same to
- // avoid querying those properties for incomplete types.
- template <bool, typename _T1, typename _T2>
- struct _PCC
- {
- template <typename _U1, typename _U2>
- static constexpr bool _ConstructiblePair()
- {
- return __and_<is_constructible<_T1, const _U1&>,
- is_constructible<_T2, const _U2&>>::value;
- }
- template <typename _U1, typename _U2>
- static constexpr bool _ImplicitlyConvertiblePair()
- {
- return __and_<is_convertible<const _U1&, _T1>,
- is_convertible<const _U2&, _T2>>::value;
- }
- template <typename _U1, typename _U2>
- static constexpr bool _MoveConstructiblePair()
- {
- return __and_<is_constructible<_T1, _U1&&>,
- is_constructible<_T2, _U2&&>>::value;
- }
- template <typename _U1, typename _U2>
- static constexpr bool _ImplicitlyMoveConvertiblePair()
- {
- return __and_<is_convertible<_U1&&, _T1>,
- is_convertible<_U2&&, _T2>>::value;
- }
- };
- template <typename _T1, typename _T2>
- struct _PCC<false, _T1, _T2>
- {
- template <typename _U1, typename _U2>
- static constexpr bool _ConstructiblePair()
- {
- return false;
- }
- template <typename _U1, typename _U2>
- static constexpr bool _ImplicitlyConvertiblePair()
- {
- return false;
- }
- template <typename _U1, typename _U2>
- static constexpr bool _MoveConstructiblePair()
- {
- return false;
- }
- template <typename _U1, typename _U2>
- static constexpr bool _ImplicitlyMoveConvertiblePair()
- {
- return false;
- }
- };
- #endif // lib concepts
- #endif // C++11
- template<typename _U1, typename _U2> class __pair_base
- {
- #if __cplusplus >= 201103L && ! __cpp_lib_concepts
- template<typename _T1, typename _T2> friend struct pair;
- __pair_base() = default;
- ~__pair_base() = default;
- __pair_base(const __pair_base&) = default;
- __pair_base& operator=(const __pair_base&) = delete;
- #endif // C++11
- };
- /// @endcond
- /**
- * @brief Struct holding two objects of arbitrary type.
- *
- * @tparam _T1 Type of first object.
- * @tparam _T2 Type of second object.
- *
- * <https://gcc.gnu.org/onlinedocs/libstdc++/manual/utilities.html>
- */
- template<typename _T1, typename _T2>
- struct pair
- : public __pair_base<_T1, _T2>
- {
- typedef _T1 first_type; ///< The type of the `first` member
- typedef _T2 second_type; ///< The type of the `second` member
- _T1 first; ///< The first member
- _T2 second; ///< The second member
- #if __cplusplus >= 201103L
- constexpr pair(const pair&) = default; ///< Copy constructor
- constexpr pair(pair&&) = default; ///< Move constructor
- template<typename... _Args1, typename... _Args2>
- _GLIBCXX20_CONSTEXPR
- pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
- /// Swap the first members and then the second members.
- _GLIBCXX20_CONSTEXPR void
- swap(pair& __p)
- noexcept(__and_<__is_nothrow_swappable<_T1>,
- __is_nothrow_swappable<_T2>>::value)
- {
- using std::swap;
- swap(first, __p.first);
- swap(second, __p.second);
- }
- private:
- template<typename... _Args1, size_t... _Indexes1,
- typename... _Args2, size_t... _Indexes2>
- _GLIBCXX20_CONSTEXPR
- pair(tuple<_Args1...>&, tuple<_Args2...>&,
- _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
- public:
- #if __cpp_lib_concepts
- // C++20 implementation using concepts, explicit(bool), fully constexpr.
- /// Default constructor
- constexpr
- explicit(__not_<__and_<__is_implicitly_default_constructible<_T1>,
- __is_implicitly_default_constructible<_T2>>>())
- pair()
- requires is_default_constructible_v<_T1>
- && is_default_constructible_v<_T2>
- : first(), second()
- { }
- private:
- /// @cond undocumented
- template<typename _U1, typename _U2>
- static constexpr bool
- _S_constructible()
- {
- if constexpr (is_constructible_v<_T1, _U1>)
- return is_constructible_v<_T2, _U2>;
- return false;
- }
- template<typename _U1, typename _U2>
- static constexpr bool
- _S_nothrow_constructible()
- {
- if constexpr (is_nothrow_constructible_v<_T1, _U1>)
- return is_nothrow_constructible_v<_T2, _U2>;
- return false;
- }
- template<typename _U1, typename _U2>
- static constexpr bool
- _S_convertible()
- {
- if constexpr (is_convertible_v<_U1, _T1>)
- return is_convertible_v<_U2, _T2>;
- return false;
- }
- /// @endcond
- public:
- /// Constructor accepting lvalues of `first_type` and `second_type`
- constexpr explicit(!_S_convertible<const _T1&, const _T2&>())
- pair(const _T1& __x, const _T2& __y)
- noexcept(_S_nothrow_constructible<const _T1&, const _T2&>())
- requires (_S_constructible<const _T1&, const _T2&>())
- : first(__x), second(__y)
- { }
- /// Constructor accepting two values of arbitrary types
- template<typename _U1, typename _U2>
- requires (_S_constructible<_U1, _U2>())
- constexpr explicit(!_S_convertible<_U1, _U2>())
- pair(_U1&& __x, _U2&& __y)
- noexcept(_S_nothrow_constructible<_U1, _U2>())
- : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y))
- { }
- /// Converting constructor from a `pair<U1, U2>` lvalue
- template<typename _U1, typename _U2>
- requires (_S_constructible<const _U1&, const _U2&>())
- constexpr explicit(!_S_convertible<const _U1&, const _U2&>())
- pair(const pair<_U1, _U2>& __p)
- noexcept(_S_nothrow_constructible<const _U1&, const _U2&>())
- : first(__p.first), second(__p.second)
- { }
- /// Converting constructor from a `pair<U1, U2>` rvalue
- template<typename _U1, typename _U2>
- requires (_S_constructible<_U1, _U2>())
- constexpr explicit(!_S_convertible<_U1, _U2>())
- pair(pair<_U1, _U2>&& __p)
- noexcept(_S_nothrow_constructible<_U1, _U2>())
- : first(std::forward<_U1>(__p.first)),
- second(std::forward<_U2>(__p.second))
- { }
- private:
- /// @cond undocumented
- template<typename _U1, typename _U2>
- static constexpr bool
- _S_assignable()
- {
- if constexpr (is_assignable_v<_T1&, _U1>)
- return is_assignable_v<_T2&, _U2>;
- return false;
- }
- template<typename _U1, typename _U2>
- static constexpr bool
- _S_nothrow_assignable()
- {
- if constexpr (is_nothrow_assignable_v<_T1&, _U1>)
- return is_nothrow_assignable_v<_T2&, _U2>;
- return false;
- }
- /// @endcond
- public:
- pair& operator=(const pair&) = delete;
- /// Copy assignment operator
- constexpr pair&
- operator=(const pair& __p)
- noexcept(_S_nothrow_assignable<const _T1&, const _T2&>())
- requires (_S_assignable<const _T1&, const _T2&>())
- {
- first = __p.first;
- second = __p.second;
- return *this;
- }
- /// Move assignment operator
- constexpr pair&
- operator=(pair&& __p)
- noexcept(_S_nothrow_assignable<_T1, _T2>())
- requires (_S_assignable<_T1, _T2>())
- {
- first = std::forward<first_type>(__p.first);
- second = std::forward<second_type>(__p.second);
- return *this;
- }
- /// Converting assignment from a `pair<U1, U2>` lvalue
- template<typename _U1, typename _U2>
- constexpr pair&
- operator=(const pair<_U1, _U2>& __p)
- noexcept(_S_nothrow_assignable<const _U1&, const _U2&>())
- requires (_S_assignable<const _U1&, const _U2&>())
- {
- first = __p.first;
- second = __p.second;
- return *this;
- }
- /// Converting assignment from a `pair<U1, U2>` rvalue
- template<typename _U1, typename _U2>
- constexpr pair&
- operator=(pair<_U1, _U2>&& __p)
- noexcept(_S_nothrow_assignable<_U1, _U2>())
- requires (_S_assignable<_U1, _U2>())
- {
- first = std::forward<_U1>(__p.first);
- second = std::forward<_U2>(__p.second);
- return *this;
- }
- #else
- // C++11/14/17 implementation using enable_if, partially constexpr.
- /** The default constructor creates @c first and @c second using their
- * respective default constructors. */
- template <typename _U1 = _T1,
- typename _U2 = _T2,
- typename enable_if<__and_<
- __is_implicitly_default_constructible<_U1>,
- __is_implicitly_default_constructible<_U2>>
- ::value, bool>::type = true>
- constexpr pair()
- : first(), second() { }
- template <typename _U1 = _T1,
- typename _U2 = _T2,
- typename enable_if<__and_<
- is_default_constructible<_U1>,
- is_default_constructible<_U2>,
- __not_<
- __and_<__is_implicitly_default_constructible<_U1>,
- __is_implicitly_default_constructible<_U2>>>>
- ::value, bool>::type = false>
- explicit constexpr pair()
- : first(), second() { }
- // Shortcut for constraining the templates that don't take pairs.
- /// @cond undocumented
- using _PCCP = _PCC<true, _T1, _T2>;
- /// @endcond
- /// Construct from two const lvalues, allowing implicit conversions.
- template<typename _U1 = _T1, typename _U2=_T2, typename
- enable_if<_PCCP::template
- _ConstructiblePair<_U1, _U2>()
- && _PCCP::template
- _ImplicitlyConvertiblePair<_U1, _U2>(),
- bool>::type=true>
- constexpr pair(const _T1& __a, const _T2& __b)
- : first(__a), second(__b) { }
- /// Construct from two const lvalues, disallowing implicit conversions.
- template<typename _U1 = _T1, typename _U2=_T2, typename
- enable_if<_PCCP::template
- _ConstructiblePair<_U1, _U2>()
- && !_PCCP::template
- _ImplicitlyConvertiblePair<_U1, _U2>(),
- bool>::type=false>
- explicit constexpr pair(const _T1& __a, const _T2& __b)
- : first(__a), second(__b) { }
- // Shortcut for constraining the templates that take pairs.
- /// @cond undocumented
- template <typename _U1, typename _U2>
- using _PCCFP = _PCC<!is_same<_T1, _U1>::value
- || !is_same<_T2, _U2>::value,
- _T1, _T2>;
- /// @endcond
- template<typename _U1, typename _U2, typename
- enable_if<_PCCFP<_U1, _U2>::template
- _ConstructiblePair<_U1, _U2>()
- && _PCCFP<_U1, _U2>::template
- _ImplicitlyConvertiblePair<_U1, _U2>(),
- bool>::type=true>
- constexpr pair(const pair<_U1, _U2>& __p)
- : first(__p.first), second(__p.second) { }
- template<typename _U1, typename _U2, typename
- enable_if<_PCCFP<_U1, _U2>::template
- _ConstructiblePair<_U1, _U2>()
- && !_PCCFP<_U1, _U2>::template
- _ImplicitlyConvertiblePair<_U1, _U2>(),
- bool>::type=false>
- explicit constexpr pair(const pair<_U1, _U2>& __p)
- : first(__p.first), second(__p.second) { }
- #if _GLIBCXX_USE_DEPRECATED
- #if defined(__DEPRECATED)
- # define _GLIBCXX_DEPRECATED_PAIR_CTOR \
- __attribute__ ((__deprecated__ ("use 'nullptr' instead of '0' to " \
- "initialize std::pair of move-only " \
- "type and pointer")))
- #else
- # define _GLIBCXX_DEPRECATED_PAIR_CTOR
- #endif
- private:
- /// @cond undocumented
- // A type which can be constructed from literal zero, but not nullptr
- struct __zero_as_null_pointer_constant
- {
- __zero_as_null_pointer_constant(int __zero_as_null_pointer_constant::*)
- { }
- template<typename _Tp,
- typename = __enable_if_t<is_null_pointer<_Tp>::value>>
- __zero_as_null_pointer_constant(_Tp) = delete;
- };
- /// @endcond
- public:
- // Deprecated extensions to DR 811.
- // These allow construction from an rvalue and a literal zero,
- // in cases where the standard says the zero should be deduced as int
- template<typename _U1,
- __enable_if_t<__and_<__not_<is_reference<_U1>>,
- is_pointer<_T2>,
- is_constructible<_T1, _U1>,
- __not_<is_constructible<_T1, const _U1&>>,
- is_convertible<_U1, _T1>>::value,
- bool> = true>
- _GLIBCXX_DEPRECATED_PAIR_CTOR
- constexpr
- pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
- : first(std::forward<_U1>(__x)), second(nullptr) { }
- template<typename _U1,
- __enable_if_t<__and_<__not_<is_reference<_U1>>,
- is_pointer<_T2>,
- is_constructible<_T1, _U1>,
- __not_<is_constructible<_T1, const _U1&>>,
- __not_<is_convertible<_U1, _T1>>>::value,
- bool> = false>
- _GLIBCXX_DEPRECATED_PAIR_CTOR
- explicit constexpr
- pair(_U1&& __x, __zero_as_null_pointer_constant, ...)
- : first(std::forward<_U1>(__x)), second(nullptr) { }
- template<typename _U2,
- __enable_if_t<__and_<is_pointer<_T1>,
- __not_<is_reference<_U2>>,
- is_constructible<_T2, _U2>,
- __not_<is_constructible<_T2, const _U2&>>,
- is_convertible<_U2, _T2>>::value,
- bool> = true>
- _GLIBCXX_DEPRECATED_PAIR_CTOR
- constexpr
- pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
- : first(nullptr), second(std::forward<_U2>(__y)) { }
- template<typename _U2,
- __enable_if_t<__and_<is_pointer<_T1>,
- __not_<is_reference<_U2>>,
- is_constructible<_T2, _U2>,
- __not_<is_constructible<_T2, const _U2&>>,
- __not_<is_convertible<_U2, _T2>>>::value,
- bool> = false>
- _GLIBCXX_DEPRECATED_PAIR_CTOR
- explicit constexpr
- pair(__zero_as_null_pointer_constant, _U2&& __y, ...)
- : first(nullptr), second(std::forward<_U2>(__y)) { }
- #undef _GLIBCXX_DEPRECATED_PAIR_CTOR
- #endif
- template<typename _U1, typename _U2, typename
- enable_if<_PCCP::template
- _MoveConstructiblePair<_U1, _U2>()
- && _PCCP::template
- _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
- bool>::type=true>
- constexpr pair(_U1&& __x, _U2&& __y)
- : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
- template<typename _U1, typename _U2, typename
- enable_if<_PCCP::template
- _MoveConstructiblePair<_U1, _U2>()
- && !_PCCP::template
- _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
- bool>::type=false>
- explicit constexpr pair(_U1&& __x, _U2&& __y)
- : first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
- template<typename _U1, typename _U2, typename
- enable_if<_PCCFP<_U1, _U2>::template
- _MoveConstructiblePair<_U1, _U2>()
- && _PCCFP<_U1, _U2>::template
- _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
- bool>::type=true>
- constexpr pair(pair<_U1, _U2>&& __p)
- : first(std::forward<_U1>(__p.first)),
- second(std::forward<_U2>(__p.second)) { }
- template<typename _U1, typename _U2, typename
- enable_if<_PCCFP<_U1, _U2>::template
- _MoveConstructiblePair<_U1, _U2>()
- && !_PCCFP<_U1, _U2>::template
- _ImplicitlyMoveConvertiblePair<_U1, _U2>(),
- bool>::type=false>
- explicit constexpr pair(pair<_U1, _U2>&& __p)
- : first(std::forward<_U1>(__p.first)),
- second(std::forward<_U2>(__p.second)) { }
- pair&
- operator=(__conditional_t<__and_<is_copy_assignable<_T1>,
- is_copy_assignable<_T2>>::value,
- const pair&, const __nonesuch&> __p)
- {
- first = __p.first;
- second = __p.second;
- return *this;
- }
- pair&
- operator=(__conditional_t<__and_<is_move_assignable<_T1>,
- is_move_assignable<_T2>>::value,
- pair&&, __nonesuch&&> __p)
- noexcept(__and_<is_nothrow_move_assignable<_T1>,
- is_nothrow_move_assignable<_T2>>::value)
- {
- first = std::forward<first_type>(__p.first);
- second = std::forward<second_type>(__p.second);
- return *this;
- }
- template<typename _U1, typename _U2>
- typename enable_if<__and_<is_assignable<_T1&, const _U1&>,
- is_assignable<_T2&, const _U2&>>::value,
- pair&>::type
- operator=(const pair<_U1, _U2>& __p)
- {
- first = __p.first;
- second = __p.second;
- return *this;
- }
- template<typename _U1, typename _U2>
- typename enable_if<__and_<is_assignable<_T1&, _U1&&>,
- is_assignable<_T2&, _U2&&>>::value,
- pair&>::type
- operator=(pair<_U1, _U2>&& __p)
- {
- first = std::forward<_U1>(__p.first);
- second = std::forward<_U2>(__p.second);
- return *this;
- }
- #endif // lib concepts
- #else
- // C++03 implementation
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 265. std::pair::pair() effects overly restrictive
- /** The default constructor creates @c first and @c second using their
- * respective default constructors. */
- pair() : first(), second() { }
- /// Two objects may be passed to a `pair` constructor to be copied.
- pair(const _T1& __a, const _T2& __b)
- : first(__a), second(__b) { }
- /// Templated constructor to convert from other pairs.
- template<typename _U1, typename _U2>
- pair(const pair<_U1, _U2>& __p)
- : first(__p.first), second(__p.second) { }
- #endif // C++11
- };
- /// @relates pair @{
- #if __cpp_deduction_guides >= 201606
- template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
- #endif
- /// Two pairs of the same type are equal iff their members are equal.
- template<typename _T1, typename _T2>
- inline _GLIBCXX_CONSTEXPR bool
- operator==(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
- { return __x.first == __y.first && __x.second == __y.second; }
- #if __cpp_lib_three_way_comparison && __cpp_lib_concepts
- template<typename _T1, typename _T2>
- constexpr common_comparison_category_t<__detail::__synth3way_t<_T1>,
- __detail::__synth3way_t<_T2>>
- operator<=>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
- {
- if (auto __c = __detail::__synth3way(__x.first, __y.first); __c != 0)
- return __c;
- return __detail::__synth3way(__x.second, __y.second);
- }
- #else
- /** Defines a lexicographical order for pairs.
- *
- * For two pairs of the same type, `P` is ordered before `Q` if
- * `P.first` is less than `Q.first`, or if `P.first` and `Q.first`
- * are equivalent (neither is less than the other) and `P.second` is less
- * than `Q.second`.
- */
- template<typename _T1, typename _T2>
- inline _GLIBCXX_CONSTEXPR bool
- operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
- { return __x.first < __y.first
- || (!(__y.first < __x.first) && __x.second < __y.second); }
- /// Uses @c operator== to find the result.
- template<typename _T1, typename _T2>
- inline _GLIBCXX_CONSTEXPR bool
- operator!=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
- { return !(__x == __y); }
- /// Uses @c operator< to find the result.
- template<typename _T1, typename _T2>
- inline _GLIBCXX_CONSTEXPR bool
- operator>(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
- { return __y < __x; }
- /// Uses @c operator< to find the result.
- template<typename _T1, typename _T2>
- inline _GLIBCXX_CONSTEXPR bool
- operator<=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
- { return !(__y < __x); }
- /// Uses @c operator< to find the result.
- template<typename _T1, typename _T2>
- inline _GLIBCXX_CONSTEXPR bool
- operator>=(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
- { return !(__x < __y); }
- #endif // !(three_way_comparison && concepts)
- #if __cplusplus >= 201103L
- /** Swap overload for pairs. Calls std::pair::swap().
- *
- * @note This std::swap overload is not declared in C++03 mode,
- * which has performance implications, e.g. see https://gcc.gnu.org/PR38466
- */
- template<typename _T1, typename _T2>
- _GLIBCXX20_CONSTEXPR inline
- #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
- // Constrained free swap overload, see p0185r1
- typename enable_if<__and_<__is_swappable<_T1>,
- __is_swappable<_T2>>::value>::type
- #else
- void
- #endif
- swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y)
- noexcept(noexcept(__x.swap(__y)))
- { __x.swap(__y); }
- #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
- template<typename _T1, typename _T2>
- typename enable_if<!__and_<__is_swappable<_T1>,
- __is_swappable<_T2>>::value>::type
- swap(pair<_T1, _T2>&, pair<_T1, _T2>&) = delete;
- #endif
- #endif // __cplusplus >= 201103L
- /// @} relates pair
- /**
- * @brief A convenience wrapper for creating a pair from two objects.
- * @param __x The first object.
- * @param __y The second object.
- * @return A newly-constructed pair<> object of the appropriate type.
- *
- * The C++98 standard says the objects are passed by reference-to-const,
- * but C++03 says they are passed by value (this was LWG issue #181).
- *
- * Since C++11 they have been passed by forwarding reference and then
- * forwarded to the new members of the pair. To create a pair with a
- * member of reference type, pass a `reference_wrapper` to this function.
- */
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 181. make_pair() unintended behavior
- #if __cplusplus >= 201103L
- // NB: DR 706.
- template<typename _T1, typename _T2>
- constexpr pair<typename __decay_and_strip<_T1>::__type,
- typename __decay_and_strip<_T2>::__type>
- make_pair(_T1&& __x, _T2&& __y)
- {
- typedef typename __decay_and_strip<_T1>::__type __ds_type1;
- typedef typename __decay_and_strip<_T2>::__type __ds_type2;
- typedef pair<__ds_type1, __ds_type2> __pair_type;
- return __pair_type(std::forward<_T1>(__x), std::forward<_T2>(__y));
- }
- #else
- template<typename _T1, typename _T2>
- inline pair<_T1, _T2>
- make_pair(_T1 __x, _T2 __y)
- { return pair<_T1, _T2>(__x, __y); }
- #endif
- /// @}
- #if __cplusplus >= 201103L
- // Various functions which give std::pair a tuple-like interface.
- template<typename _T1, typename _T2>
- struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
- { };
- /// Partial specialization for std::pair
- template<class _Tp1, class _Tp2>
- struct tuple_size<pair<_Tp1, _Tp2>>
- : public integral_constant<size_t, 2> { };
- /// Partial specialization for std::pair
- template<class _Tp1, class _Tp2>
- struct tuple_element<0, pair<_Tp1, _Tp2>>
- { typedef _Tp1 type; };
- /// Partial specialization for std::pair
- template<class _Tp1, class _Tp2>
- struct tuple_element<1, pair<_Tp1, _Tp2>>
- { typedef _Tp2 type; };
- #if __cplusplus >= 201703L
- template<typename _Tp1, typename _Tp2>
- inline constexpr size_t tuple_size_v<pair<_Tp1, _Tp2>> = 2;
- template<typename _Tp1, typename _Tp2>
- inline constexpr size_t tuple_size_v<const pair<_Tp1, _Tp2>> = 2;
- template<typename _Tp>
- inline constexpr bool __is_pair = false;
- template<typename _Tp, typename _Up>
- inline constexpr bool __is_pair<pair<_Tp, _Up>> = true;
- template<typename _Tp, typename _Up>
- inline constexpr bool __is_pair<const pair<_Tp, _Up>> = true;
- #endif
- /// @cond undocumented
- template<size_t _Int>
- struct __pair_get;
- template<>
- struct __pair_get<0>
- {
- template<typename _Tp1, typename _Tp2>
- static constexpr _Tp1&
- __get(pair<_Tp1, _Tp2>& __pair) noexcept
- { return __pair.first; }
- template<typename _Tp1, typename _Tp2>
- static constexpr _Tp1&&
- __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
- { return std::forward<_Tp1>(__pair.first); }
- template<typename _Tp1, typename _Tp2>
- static constexpr const _Tp1&
- __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
- { return __pair.first; }
- template<typename _Tp1, typename _Tp2>
- static constexpr const _Tp1&&
- __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
- { return std::forward<const _Tp1>(__pair.first); }
- };
- template<>
- struct __pair_get<1>
- {
- template<typename _Tp1, typename _Tp2>
- static constexpr _Tp2&
- __get(pair<_Tp1, _Tp2>& __pair) noexcept
- { return __pair.second; }
- template<typename _Tp1, typename _Tp2>
- static constexpr _Tp2&&
- __move_get(pair<_Tp1, _Tp2>&& __pair) noexcept
- { return std::forward<_Tp2>(__pair.second); }
- template<typename _Tp1, typename _Tp2>
- static constexpr const _Tp2&
- __const_get(const pair<_Tp1, _Tp2>& __pair) noexcept
- { return __pair.second; }
- template<typename _Tp1, typename _Tp2>
- static constexpr const _Tp2&&
- __const_move_get(const pair<_Tp1, _Tp2>&& __pair) noexcept
- { return std::forward<const _Tp2>(__pair.second); }
- };
- /// @endcond
- /** @{
- * std::get overloads for accessing members of std::pair
- */
- template<size_t _Int, class _Tp1, class _Tp2>
- constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
- get(pair<_Tp1, _Tp2>& __in) noexcept
- { return __pair_get<_Int>::__get(__in); }
- template<size_t _Int, class _Tp1, class _Tp2>
- constexpr typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
- get(pair<_Tp1, _Tp2>&& __in) noexcept
- { return __pair_get<_Int>::__move_get(std::move(__in)); }
- template<size_t _Int, class _Tp1, class _Tp2>
- constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&
- get(const pair<_Tp1, _Tp2>& __in) noexcept
- { return __pair_get<_Int>::__const_get(__in); }
- template<size_t _Int, class _Tp1, class _Tp2>
- constexpr const typename tuple_element<_Int, pair<_Tp1, _Tp2>>::type&&
- get(const pair<_Tp1, _Tp2>&& __in) noexcept
- { return __pair_get<_Int>::__const_move_get(std::move(__in)); }
- #if __cplusplus >= 201402L
- #define __cpp_lib_tuples_by_type 201304L
- template <typename _Tp, typename _Up>
- constexpr _Tp&
- get(pair<_Tp, _Up>& __p) noexcept
- { return __p.first; }
- template <typename _Tp, typename _Up>
- constexpr const _Tp&
- get(const pair<_Tp, _Up>& __p) noexcept
- { return __p.first; }
- template <typename _Tp, typename _Up>
- constexpr _Tp&&
- get(pair<_Tp, _Up>&& __p) noexcept
- { return std::move(__p.first); }
- template <typename _Tp, typename _Up>
- constexpr const _Tp&&
- get(const pair<_Tp, _Up>&& __p) noexcept
- { return std::move(__p.first); }
- template <typename _Tp, typename _Up>
- constexpr _Tp&
- get(pair<_Up, _Tp>& __p) noexcept
- { return __p.second; }
- template <typename _Tp, typename _Up>
- constexpr const _Tp&
- get(const pair<_Up, _Tp>& __p) noexcept
- { return __p.second; }
- template <typename _Tp, typename _Up>
- constexpr _Tp&&
- get(pair<_Up, _Tp>&& __p) noexcept
- { return std::move(__p.second); }
- template <typename _Tp, typename _Up>
- constexpr const _Tp&&
- get(const pair<_Up, _Tp>&& __p) noexcept
- { return std::move(__p.second); }
- #endif // C++14
- /// @}
- #endif // C++11
- _GLIBCXX_END_NAMESPACE_VERSION
- } // namespace std
- #endif /* _STL_PAIR_H */
|