Warning: This file is not a C or C++ file. It does not have highlighting.

1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef _LIBCPP___CXX03___UTILITY_PAIR_H
10#define _LIBCPP___CXX03___UTILITY_PAIR_H
11
12#include <__cxx03/__config>
13#include <__cxx03/__fwd/array.h>
14#include <__cxx03/__fwd/pair.h>
15#include <__cxx03/__fwd/tuple.h>
16#include <__cxx03/__tuple/sfinae_helpers.h>
17#include <__cxx03/__tuple/tuple_element.h>
18#include <__cxx03/__tuple/tuple_indices.h>
19#include <__cxx03/__tuple/tuple_like_no_subrange.h>
20#include <__cxx03/__tuple/tuple_size.h>
21#include <__cxx03/__type_traits/common_type.h>
22#include <__cxx03/__type_traits/conditional.h>
23#include <__cxx03/__type_traits/decay.h>
24#include <__cxx03/__type_traits/integral_constant.h>
25#include <__cxx03/__type_traits/is_assignable.h>
26#include <__cxx03/__type_traits/is_constructible.h>
27#include <__cxx03/__type_traits/is_convertible.h>
28#include <__cxx03/__type_traits/is_implicitly_default_constructible.h>
29#include <__cxx03/__type_traits/is_nothrow_assignable.h>
30#include <__cxx03/__type_traits/is_nothrow_constructible.h>
31#include <__cxx03/__type_traits/is_reference.h>
32#include <__cxx03/__type_traits/is_same.h>
33#include <__cxx03/__type_traits/is_swappable.h>
34#include <__cxx03/__type_traits/is_trivially_relocatable.h>
35#include <__cxx03/__type_traits/nat.h>
36#include <__cxx03/__type_traits/remove_cvref.h>
37#include <__cxx03/__type_traits/unwrap_ref.h>
38#include <__cxx03/__utility/declval.h>
39#include <__cxx03/__utility/forward.h>
40#include <__cxx03/__utility/move.h>
41#include <__cxx03/__utility/piecewise_construct.h>
42#include <__cxx03/cstddef>
43
44#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
45# pragma GCC system_header
46#endif
47
48_LIBCPP_PUSH_MACROS
49#include <__cxx03/__undef_macros>
50
51_LIBCPP_BEGIN_NAMESPACE_STD
52
53template <class, class>
54struct __non_trivially_copyable_base {
55 _LIBCPP_HIDE_FROM_ABI __non_trivially_copyable_base() _NOEXCEPT {}
56 _LIBCPP_HIDE_FROM_ABI __non_trivially_copyable_base(__non_trivially_copyable_base const&) _NOEXCEPT {}
57};
58
59template <class _T1, class _T2>
60struct _LIBCPP_TEMPLATE_VIS pair
61#if defined(_LIBCPP_DEPRECATED_ABI_DISABLE_PAIR_TRIVIAL_COPY_CTOR)
62 : private __non_trivially_copyable_base<_T1, _T2>
63#endif
64{
65 using first_type = _T1;
66 using second_type = _T2;
67
68 _T1 first;
69 _T2 second;
70
71 using __trivially_relocatable =
72 __conditional_t<__libcpp_is_trivially_relocatable<_T1>::value && __libcpp_is_trivially_relocatable<_T2>::value,
73 pair,
74 void>;
75
76 _LIBCPP_HIDE_FROM_ABI pair(pair const&) = default;
77 _LIBCPP_HIDE_FROM_ABI pair(pair&&) = default;
78
79 // When we are requested for pair to be trivially copyable by the ABI macro, we use defaulted members
80 // if it is both legal to do it (i.e. no references) and we have a way to actually implement it, which requires
81 // the __enable_if__ attribute before C++20.
82#ifdef _LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR
83 // FIXME: This should really just be a static constexpr variable. It's in a struct to avoid gdb printing the value
84 // when printing a pair
85 struct __has_defaulted_members {
86 static const bool value = !is_reference<first_type>::value && !is_reference<second_type>::value;
87 };
88# if __has_attribute(__enable_if__)
89 _LIBCPP_HIDE_FROM_ABI pair& operator=(const pair&)
90 __attribute__((__enable_if__(__has_defaulted_members::value, ""))) = default;
91
92 _LIBCPP_HIDE_FROM_ABI pair& operator=(pair&&)
93 __attribute__((__enable_if__(__has_defaulted_members::value, ""))) = default;
94# else
95# error "_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR isn't supported with this compiler"
96# endif
97#else
98 struct __has_defaulted_members {
99 static const bool value = false;
100 };
101#endif // defined(_LIBCPP_ABI_TRIVIALLY_COPYABLE_PAIR) && __has_attribute(__enable_if__)
102
103 _LIBCPP_HIDE_FROM_ABI pair() : first(), second() {}
104
105 _LIBCPP_HIDE_FROM_ABI pair(_T1 const& __t1, _T2 const& __t2) : first(__t1), second(__t2) {}
106
107 template <class _U1, class _U2>
108 _LIBCPP_HIDE_FROM_ABI pair(const pair<_U1, _U2>& __p) : first(__p.first), second(__p.second) {}
109
110 _LIBCPP_HIDE_FROM_ABI pair& operator=(pair const& __p) {
111 first = __p.first;
112 second = __p.second;
113 return *this;
114 }
115
116 // Extension: This is provided in C++03 because it allows properly handling the
117 // assignment to a pair containing references, which would be a hard
118 // error otherwise.
119 template <
120 class _U1,
121 class _U2,
122 __enable_if_t<is_assignable<first_type&, _U1 const&>::value && is_assignable<second_type&, _U2 const&>::value,
123 int> = 0>
124 _LIBCPP_HIDE_FROM_ABI pair& operator=(pair<_U1, _U2> const& __p) {
125 first = __p.first;
126 second = __p.second;
127 return *this;
128 }
129
130 _LIBCPP_HIDE_FROM_ABI void swap(pair& __p) {
131 using std::swap;
132 swap(first, __p.first);
133 swap(second, __p.second);
134 }
135};
136
137// [pairs.spec], specialized algorithms
138
139template <class _T1, class _T2, class _U1, class _U2>
140inline _LIBCPP_HIDE_FROM_ABI bool operator==(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
141 return __x.first == __y.first && __x.second == __y.second;
142}
143
144template <class _T1, class _T2, class _U1, class _U2>
145inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
146 return !(__x == __y);
147}
148
149template <class _T1, class _T2, class _U1, class _U2>
150inline _LIBCPP_HIDE_FROM_ABI bool operator<(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
151 return __x.first < __y.first || (!(__y.first < __x.first) && __x.second < __y.second);
152}
153
154template <class _T1, class _T2, class _U1, class _U2>
155inline _LIBCPP_HIDE_FROM_ABI bool operator>(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
156 return __y < __x;
157}
158
159template <class _T1, class _T2, class _U1, class _U2>
160inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
161 return !(__x < __y);
162}
163
164template <class _T1, class _T2, class _U1, class _U2>
165inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const pair<_T1, _T2>& __x, const pair<_U1, _U2>& __y) {
166 return !(__y < __x);
167}
168
169template <class _T1, class _T2, __enable_if_t<__is_swappable_v<_T1> && __is_swappable_v<_T2>, int> = 0>
170inline _LIBCPP_HIDE_FROM_ABI void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) {
171 __x.swap(__y);
172}
173
174template <class _T1, class _T2>
175inline _LIBCPP_HIDE_FROM_ABI pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>
176make_pair(_T1&& __t1, _T2&& __t2) {
177 return pair<typename __unwrap_ref_decay<_T1>::type, typename __unwrap_ref_decay<_T2>::type>(
178 std::forward<_T1>(__t1), std::forward<_T2>(__t2));
179}
180
181template <class _T1, class _T2>
182struct _LIBCPP_TEMPLATE_VIS tuple_size<pair<_T1, _T2> > : public integral_constant<size_t, 2> {};
183
184template <size_t _Ip, class _T1, class _T2>
185struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, pair<_T1, _T2> > {
186 static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::pair<T1, T2>>");
187};
188
189template <class _T1, class _T2>
190struct _LIBCPP_TEMPLATE_VIS tuple_element<0, pair<_T1, _T2> > {
191 using type _LIBCPP_NODEBUG = _T1;
192};
193
194template <class _T1, class _T2>
195struct _LIBCPP_TEMPLATE_VIS tuple_element<1, pair<_T1, _T2> > {
196 using type _LIBCPP_NODEBUG = _T2;
197};
198
199template <size_t _Ip>
200struct __get_pair;
201
202template <>
203struct __get_pair<0> {
204 template <class _T1, class _T2>
205 static _LIBCPP_HIDE_FROM_ABI _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {
206 return __p.first;
207 }
208
209 template <class _T1, class _T2>
210 static _LIBCPP_HIDE_FROM_ABI const _T1& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
211 return __p.first;
212 }
213
214 template <class _T1, class _T2>
215 static _LIBCPP_HIDE_FROM_ABI _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
216 return std::forward<_T1>(__p.first);
217 }
218
219 template <class _T1, class _T2>
220 static _LIBCPP_HIDE_FROM_ABI const _T1&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
221 return std::forward<const _T1>(__p.first);
222 }
223};
224
225template <>
226struct __get_pair<1> {
227 template <class _T1, class _T2>
228 static _LIBCPP_HIDE_FROM_ABI _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {
229 return __p.second;
230 }
231
232 template <class _T1, class _T2>
233 static _LIBCPP_HIDE_FROM_ABI const _T2& get(const pair<_T1, _T2>& __p) _NOEXCEPT {
234 return __p.second;
235 }
236
237 template <class _T1, class _T2>
238 static _LIBCPP_HIDE_FROM_ABI _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
239 return std::forward<_T2>(__p.second);
240 }
241
242 template <class _T1, class _T2>
243 static _LIBCPP_HIDE_FROM_ABI const _T2&& get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
244 return std::forward<const _T2>(__p.second);
245 }
246};
247
248template <size_t _Ip, class _T1, class _T2>
249inline _LIBCPP_HIDE_FROM_ABI typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(pair<_T1, _T2>& __p) _NOEXCEPT {
250 return __get_pair<_Ip>::get(__p);
251}
252
253template <size_t _Ip, class _T1, class _T2>
254inline _LIBCPP_HIDE_FROM_ABI const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
255get(const pair<_T1, _T2>& __p) _NOEXCEPT {
256 return __get_pair<_Ip>::get(__p);
257}
258
259template <size_t _Ip, class _T1, class _T2>
260inline _LIBCPP_HIDE_FROM_ABI typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {
261 return __get_pair<_Ip>::get(std::move(__p));
262}
263
264template <size_t _Ip, class _T1, class _T2>
265inline _LIBCPP_HIDE_FROM_ABI const typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
266get(const pair<_T1, _T2>&& __p) _NOEXCEPT {
267 return __get_pair<_Ip>::get(std::move(__p));
268}
269
270_LIBCPP_END_NAMESPACE_STD
271
272_LIBCPP_POP_MACROS
273
274#endif // _LIBCPP___CXX03___UTILITY_PAIR_H
275

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of libcxx/include/__cxx03/__utility/pair.h