Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
pair.hpp
Go to the documentation of this file.
1// Copyright 2026, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_PAIR_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_PAIR_HPP_
7
8// parasoft-begin-suppress CERT_CPP-DCL58-a-2 "Part of a standard library implementation"
9// parasoft-begin-suppress AUTOSAR-A17_6_1-a-2 "Part of a standard library implementation"
10
11// IWYU pragma: private, include <utility>
12// IWYU pragma: friend "stdlib_detail/.*"
13
14#include "arene/base/constraints.hpp"
15#include "arene/base/type_traits/comparison_traits.hpp"
16#include "arene/base/type_traits/is_swappable.hpp"
17#include "arene/base/type_traits/unwrap_reference.hpp"
18#include "stdlib/include/stdlib_detail/conditional.hpp"
19#include "stdlib/include/stdlib_detail/cstddef.hpp"
20#include "stdlib/include/stdlib_detail/enable_if.hpp"
21#include "stdlib/include/stdlib_detail/forward.hpp"
22#include "stdlib/include/stdlib_detail/integer_sequence.hpp"
23#include "stdlib/include/stdlib_detail/integral_constant.hpp"
24#include "stdlib/include/stdlib_detail/is_assignable.hpp"
25#include "stdlib/include/stdlib_detail/is_constructible.hpp"
26#include "stdlib/include/stdlib_detail/is_convertible.hpp"
27#include "stdlib/include/stdlib_detail/is_copy_constructible.hpp"
28#include "stdlib/include/stdlib_detail/is_default_constructible.hpp"
29#include "stdlib/include/stdlib_detail/is_same.hpp"
30#include "stdlib/include/stdlib_detail/move.hpp"
31#include "stdlib/include/stdlib_detail/swap.hpp"
32#include "stdlib/include/stdlib_detail/tuple_element.hpp"
33#include "stdlib/include/stdlib_detail/tuple_fwd.hpp"
34#include "stdlib/include/stdlib_detail/tuple_size.hpp"
35
36namespace std {
37
38/// @brief Tag type for piecewise construction
40
41/// @brief Tag constant for piecewise construction
43
44// parasoft-begin-suppress AUTOSAR-A12_1_5-a "False positive: delegating constructors would not reduce duplication"
45/// @brief A simple data structure to hold two values.
46/// @tparam T1 The type of the first value
47/// @tparam T2 The type of the second value
48template <typename T1, typename T2>
49class pair {
50 // parasoft-end-suppress AUTOSAR-A12_1_5-a
51 public:
52 /// @brief The type of the first value
53 using first_type = T1;
54 /// @brief The type of the second value
55 using second_type = T2;
56
57 // parasoft-begin-suppress AUTOSAR-M11_0_1-a "This is part of the C++14 standard API"
58 /// @brief The first value
59 first_type first;
60 /// @brief The second value
61 second_type second;
62 // parasoft-end-suppress AUTOSAR-M11_0_1-a
63
64 private:
65 /// @brief Check if the memberwise copy constructor should be explicit
66 /// @tparam Arg1 The type of the initializer for first argument
67 /// @tparam Arg2 The type of the initializer for second argument
68 template <typename Arg1, typename Arg2>
69 static constexpr auto
70 memberwise_copy_constructor_is_explicit{!is_convertible_v<Arg1 const&, Arg1> || !is_convertible_v<Arg2 const&, Arg2>};
71
72 /// @brief Check if the memberwise forward constructor should be explicit
73 /// @tparam Arg1 The type of the initializer for first argument
74 /// @tparam Arg2 The type of the initializer for second argument
75 template <typename Arg1, typename Arg2>
76 static constexpr auto
77 memberwise_forward_constructor_is_explicit{!is_convertible_v<Arg1&&, first_type> || !is_convertible_v<Arg2&&, second_type>};
78
79 /// @brief Check if the copy constructor should be explicit
80 /// @tparam Arg1 The type of the initializer for first argument
81 /// @tparam Arg2 The type of the initializer for second argument
82 template <typename Arg1, typename Arg2>
83 static constexpr auto
84 copy_constructor_is_explicit{!is_convertible_v<Arg1 const&, first_type> || !is_convertible_v<Arg2 const&, second_type>};
85
86 /// @brief Check if the move constructor should be explicit
87 /// @tparam Arg1 The type of the initializer for first argument
88 /// @tparam Arg2 The type of the initializer for second argument
89 template <typename Arg1, typename Arg2>
90 static constexpr auto
91 move_constructor_is_explicit{!is_convertible_v<Arg1&&, first_type> || !is_convertible_v<Arg2&&, second_type>};
92
93 public:
94 // parasoft-begin-suppress AUTOSAR-A12_7_1-a "False positive: Not equivalent, ensures members are value-initialized"
95 /// @brief Default construct a @c pair, with the @c first and @c second members value-initialized.
96 ///
97 /// This is disabled if either @c T1 or @c T2 is not default-constructible
98 /// @tparam CheckType1 Template parameter used for checking constraints on @c T1
99 /// @tparam CheckType2 Template parameter used for checking constraints on @c T2
100 template <
101 typename CheckType1 = T1,
102 typename CheckType2 = T2,
103 arene::base::constraints<
104 enable_if_t<is_default_constructible_v<CheckType1>>,
105 enable_if_t<is_default_constructible_v<CheckType2>>> = nullptr>
106 constexpr pair() noexcept(is_nothrow_default_constructible_v<T1> && is_nothrow_default_constructible_v<T2>)
107 : first{},
108 second{} {}
109 // parasoft-end-suppress AUTOSAR-A12_7_1-a
110
111 // parasoft-begin-suppress AUTOSAR-A13_3_1-a "This is part of the C++14 standard API"
112 /// @brief Construct a @c pair from specified values for the two data members.
113 ///
114 /// This is disabled if either @c T1 or @c T2 is not copy-constructible
115 /// @tparam CheckType1 Template parameter used for checking constraints on @c T1
116 /// @tparam CheckType2 Template parameter used for checking constraints on @c T2
117 /// @param val1 The value to use to initialize @c first
118 /// @param val2 The value to use to initialize @c second
119 ///
120 /// @note The constructor is explicit if and only if <tt> is_convertible<const first_type&, first_type>::value </tt>
121 /// is false or <tt> is_convertible<const second_type&, second_type>::value </tt> is false.
122 template <
123 typename CheckType1 = T1,
124 typename CheckType2 = T2,
125 arene::base::constraints<
126 enable_if_t<is_copy_constructible_v<CheckType1>>,
127 enable_if_t<is_copy_constructible_v<CheckType2>>,
128 enable_if_t<memberwise_copy_constructor_is_explicit<CheckType1, CheckType2>>> = nullptr>
129 explicit constexpr pair(
130 first_type const& val1,
131 second_type const& val2
132 ) noexcept(is_nothrow_copy_constructible_v<T1> && is_nothrow_copy_constructible_v<T2>)
133 : first(val1),
134 second(val2) {}
135 // parasoft-end-suppress AUTOSAR-A13_3_1-a
136
137 // parasoft-begin-suppress AUTOSAR-A13_3_1-a "This is part of the C++14 standard API"
138 /// @brief Construct a @c pair from specified values for the two data members.
139 ///
140 /// This is disabled if either @c T1 or @c T2 is not copy-constructible
141 /// @tparam CheckType1 Template parameter used for checking constraints on @c T1
142 /// @tparam CheckType2 Template parameter used for checking constraints on @c T2
143 /// @param val1 The value to use to initialize @c first
144 /// @param val2 The value to use to initialize @c second
145 ///
146 /// @note The constructor is explicit if and only if <tt> is_convertible<const first_type&, first_type>::value </tt>
147 /// is false or <tt> is_convertible<const second_type&, second_type>::value </tt> is false.
148 template <
149 typename CheckType1 = T1,
150 typename CheckType2 = T2,
151 arene::base::constraints<
152 enable_if_t<is_copy_constructible_v<CheckType1>>,
153 enable_if_t<is_copy_constructible_v<CheckType2>>,
154 enable_if_t<!memberwise_copy_constructor_is_explicit<CheckType1, CheckType2>>> = nullptr>
155 constexpr pair(
156 first_type const& val1,
157 second_type const& val2
158 ) noexcept(is_nothrow_copy_constructible_v<T1> && is_nothrow_copy_constructible_v<T2>)
159 : first(val1),
160 second(val2) {}
161 // parasoft-end-suppress AUTOSAR-A13_3_1-a
162
163 /// @brief Construct a @c pair from specified values for the two data members using perfect forwarding.
164 ///
165 /// This is disabled if either @c T1 or @c T2 is not constructible from the corresponding initializer.
166 /// @tparam Arg1 The type of the initializer for @c first
167 /// @tparam Arg2 The type of the initializer for @c second
168 /// @param val1 The value to use to initialize @c first
169 /// @param val2 The value to use to initialize @c second
170 ///
171 /// @note The constructor is explicit if and only if <tt> is_convertible<Arg1&&, first_type>::value </tt> is false or
172 /// <tt> is_convertible<Arg2&&, second_type>::value </tt> is false.
173 template <
174 typename Arg1,
175 typename Arg2,
176 arene::base::constraints<
177 enable_if_t<is_constructible_v<T1, Arg1&&>>,
178 enable_if_t<is_constructible_v<T2, Arg2&&>>,
179 enable_if_t<memberwise_forward_constructor_is_explicit<Arg1, Arg2>>> = nullptr>
180 explicit constexpr pair(
181 Arg1&& val1,
182 Arg2&& val2
183 ) noexcept(is_nothrow_constructible_v<T1, Arg1&&> && is_nothrow_constructible_v<T2, Arg2&&>)
184 : first(std::forward<Arg1>(val1)),
185 second(std::forward<Arg2>(val2)) {}
186
187 /// @brief Construct a @c pair from specified values for the two data members using perfect forwarding.
188 ///
189 /// This is disabled if either @c T1 or @c T2 is not constructible from the corresponding initializer.
190 /// @tparam Arg1 The type of the initializer for @c first
191 /// @tparam Arg2 The type of the initializer for @c second
192 /// @param val1 The value to use to initialize @c first
193 /// @param val2 The value to use to initialize @c second
194 ///
195 /// @note The constructor is explicit if and only if <tt> is_convertible<Arg1&&, first_type>::value </tt> is false or
196 /// <tt> is_convertible<Arg2&&, second_type>::value </tt> is false.
197 template <
198 typename Arg1,
199 typename Arg2,
200 arene::base::constraints<
201 enable_if_t<is_constructible_v<T1, Arg1&&>>,
202 enable_if_t<is_constructible_v<T2, Arg2&&>>,
203 enable_if_t<!memberwise_forward_constructor_is_explicit<Arg1, Arg2>>> = nullptr>
204 constexpr pair(
205 Arg1&& val1,
206 Arg2&& val2
207 ) noexcept(is_nothrow_constructible_v<T1, Arg1&&> && is_nothrow_constructible_v<T2, Arg2&&>)
208 : first(std::forward<Arg1>(val1)),
209 second(std::forward<Arg2>(val2)) {}
210
211 /// @brief Copy a @c pair from another pair with potentially different value types
212 ///
213 /// This is disabled if either @c T1 or @c T2 is not constructible from the corresponding initializer.
214 /// @tparam Arg1 The type of @c first in the source pair
215 /// @tparam Arg2 The type of @c second in the source pair
216 /// @param other The pair to initialize from
217 ///
218 /// @note The constructor is explicit if and only if <tt> is_convertible<const Arg1&, first_type>::value </tt> is
219 /// false or <tt> is_convertible<const Arg2&, second_type>::value </tt> is false.
220 template <
221 typename Arg1,
222 typename Arg2,
223 arene::base::constraints<
224 enable_if_t<is_constructible_v<T1, Arg1 const&>>,
225 enable_if_t<is_constructible_v<T2, Arg2 const&>>,
226 enable_if_t<copy_constructor_is_explicit<Arg1, Arg2>>> = nullptr>
227 explicit constexpr pair(pair<Arg1, Arg2> const& other
228 ) noexcept(is_nothrow_constructible_v<T1, Arg1 const&> && is_nothrow_constructible_v<T2, Arg2 const&>)
229 : pair(other.first, other.second) {}
230
231 /// @brief Copy a @c pair from another pair with potentially different value types
232 ///
233 /// This is disabled if either @c T1 or @c T2 is not constructible from the corresponding initializer.
234 /// @tparam Arg1 The type of @c first in the source pair
235 /// @tparam Arg2 The type of @c second in the source pair
236 /// @param other The pair to initialize from
237 ///
238 /// @note The constructor is explicit if and only if <tt> is_convertible<const Arg1&, first_type>::value </tt> is
239 /// false or <tt> is_convertible<const Arg2&, second_type>::value </tt> is false.
240 template <
241 typename Arg1,
242 typename Arg2,
243 arene::base::constraints<
244 enable_if_t<is_constructible_v<T1, Arg1 const&>>,
245 enable_if_t<is_constructible_v<T2, Arg2 const&>>,
246 enable_if_t<!copy_constructor_is_explicit<Arg1, Arg2>>> = nullptr>
247 // NOLINTNEXTLINE(hicpp-explicit-conversions)
248 constexpr pair(pair<Arg1, Arg2> const& other
249 ) noexcept(is_nothrow_constructible_v<T1, Arg1 const&> && is_nothrow_constructible_v<T2, Arg2 const&>)
250 : pair(other.first, other.second) {}
251
252 // parasoft-begin-suppress AUTOSAR-A8_4_6-a "False positive: Fields are forwarded"
253 // parasoft-begin-suppress AUTOSAR-A8_4_5-a "False positive: Fields are forwarded"
254 // parasoft-begin-suppress AUTOSAR-A12_8_4-a "False positive: Fields are forwarded"
255 // parasoft-begin-suppress AUTOSAR-A18_9_2-a "False positive: Forwarding fields"
256 /// @brief Move-construct a @c pair from another pair with potentially different value types
257 ///
258 /// This is disabled if either @c T1 or @c T2 is not constructible from the corresponding initializer.
259 /// @tparam Arg1 The type of @c first in the source pair
260 /// @tparam Arg2 The type of @c second in the source pair
261 /// @param other The pair to initialize from
262 ///
263 /// @note The constructor is explicit if and only if <tt> is_convertible<Arg1&&, first_type>::value </tt> is false or
264 /// <tt> is_convertible<Arg2&&, second_type>::value </tt> is false.
265 template <
266 typename Arg1,
267 typename Arg2,
268 arene::base::constraints<
269 enable_if_t<is_constructible_v<T1, Arg1&&>>,
270 enable_if_t<is_constructible_v<T2, Arg2&&>>,
271 enable_if_t<move_constructor_is_explicit<Arg1, Arg2>>> = nullptr>
272 explicit constexpr pair(pair<Arg1, Arg2>&& other
273 ) noexcept(is_nothrow_constructible_v<T1, Arg1&&> && is_nothrow_constructible_v<T2, Arg2&&>)
274 : first(std::forward<Arg1>(other.first)),
275 second(std::forward<Arg2>(other.second)) {}
276 // parasoft-end-suppress AUTOSAR-A18_9_2-a
277 // parasoft-end-suppress AUTOSAR-A8_4_6-a
278 // parasoft-end-suppress AUTOSAR-A8_4_5-a
279 // parasoft-end-suppress AUTOSAR-A12_8_4-a
280
281 // parasoft-begin-suppress AUTOSAR-A8_4_6-a "False positive: Fields are forwarded"
282 // parasoft-begin-suppress AUTOSAR-A8_4_5-a "False positive: Fields are forwarded"
283 // parasoft-begin-suppress AUTOSAR-A12_8_4-a "False positive: Fields are forwarded"
284 // parasoft-begin-suppress AUTOSAR-A18_9_2-a "False positive: Forwarding fields"
285 /// @brief Move-construct a @c pair from another pair with potentially different value types
286 ///
287 /// This is disabled if either @c T1 or @c T2 is not constructible from the corresponding initializer.
288 /// @tparam Arg1 The type of @c first in the source pair
289 /// @tparam Arg2 The type of @c second in the source pair
290 /// @param other The pair to initialize from
291 ///
292 /// @note The constructor is explicit if and only if <tt> is_convertible<Arg1&&, first_type>::value </tt> is false or
293 /// <tt> is_convertible<Arg2&&, second_type>::value </tt> is false.
294 template <
295 typename Arg1,
296 typename Arg2,
297 arene::base::constraints<
298 enable_if_t<is_constructible_v<T1, Arg1&&>>,
299 enable_if_t<is_constructible_v<T2, Arg2&&>>,
300 enable_if_t<!move_constructor_is_explicit<Arg1, Arg2>>> = nullptr>
301 // NOLINTNEXTLINE(hicpp-explicit-conversions)
302 constexpr pair(pair<Arg1, Arg2>&& other
303 ) noexcept(is_nothrow_constructible_v<T1, Arg1&&> && is_nothrow_constructible_v<T2, Arg2&&>)
304 : first(std::forward<Arg1>(other.first)),
305 second(std::forward<Arg2>(other.second)) {}
306 // parasoft-end-suppress AUTOSAR-A18_9_2-a
307 // parasoft-end-suppress AUTOSAR-A8_4_6-a
308 // parasoft-end-suppress AUTOSAR-A8_4_5-a
309 // parasoft-end-suppress AUTOSAR-A12_8_4-a
310
311 private:
312 // parasoft-begin-suppress AUTOSAR-A0_1_4-a "False positive: The parameters are used"
313 // parasoft-begin-suppress AUTOSAR-A2_7_3-b "False positive: The parameters are documented with @brief"
314 // parasoft-begin-suppress AUTOSAR-A18_9_2-a "The type stored in the tuple is defined to be forwarded."
315 /// @brief Helper constructor for piecewise construction
316 /// @tparam Args1 The types of arguments in the tuple for constructing @c first
317 /// @tparam Args2 The types of arguments in the tuple for constructing @c second
318 /// @tparam I1 Indices for the first tuple arguments
319 /// @tparam I2 Indices for the second tuple arguments
320 /// @param first_args Tuple containing arguments to construct @c first
321 /// @param second_args Tuple containing arguments to construct @c second
322 template <typename... Args1, typename... Args2, size_t... I1, size_t... I2>
323 pair(tuple<Args1...>& first_args,index_sequence<I1...>, tuple<Args2...>& second_args, //
324 index_sequence<I2...>) //
325 noexcept(is_nothrow_constructible_v<T1, Args1&&...> && is_nothrow_constructible_v<T2, Args2&&...>)
326 : first{std::forward<Args1>(get<I1>(first_args))...},
327 second{std::forward<Args2>(get<I2>(second_args))...} {}
328 // parasoft-end-suppress AUTOSAR-A18_9_2-a
329 // parasoft-end-suppress AUTOSAR-A2_7_3-b
330 // parasoft-end-suppress AUTOSAR-A0_1_4-a
331
332 public:
333 // parasoft-begin-suppress CERT_C-EXP37-a "False positive: The rule does not mention naming all parameters"
334 /// @brief Construct a @c pair using piecewise construction from tuples of arguments
335 ///
336 /// This constructor allows constructing each element from a tuple of arguments using perfect forwarding.
337 /// This is disabled if either @c T1 is not constructible from @c Args1&&... or @c T2 is not constructible from @c
338 /// Args2&&...
339 /// @tparam Args1 The types of arguments in the tuple for constructing @c first
340 /// @tparam Args2 The types of arguments in the tuple for constructing @c second
341 /// @param first_args Tuple containing arguments to construct @c first
342 /// @param second_args Tuple containing arguments to construct @c second
343 template <
344 typename... Args1,
345 typename... Args2,
346 arene::base::constraints<
347 enable_if_t<is_constructible_v<T1, Args1&&...>>,
348 enable_if_t<is_constructible_v<T2, Args2&&...>>> = nullptr>
349 pair(
350 piecewise_construct_t,
351 tuple<Args1...> first_args,
352 tuple<Args2...> second_args
353 ) noexcept(is_nothrow_constructible_v<T1, Args1&&...> && is_nothrow_constructible_v<T2, Args2&&...>)
354 : pair{first_args, index_sequence_for<Args1...>{}, second_args, index_sequence_for<Args2...>{}} {}
355 // parasoft-end-suppress CERT_C-EXP37-a
356
357 /// @brief Copy-assign a @c pair from another pair with different value types
358 ///
359 /// This is disabled if either @c T1 or @c T2 is not assignable from the corresponding initializer.
360 /// @tparam Arg1 The type of @c first in the source pair
361 /// @tparam Arg2 The type of @c second in the source pair
362 /// @param other The pair to copy from
363 /// @return @c *this
364 template <
365 typename Arg1,
366 typename Arg2,
367 arene::base::constraints<
368 enable_if_t<!is_same_v<T1, Arg1> || !is_same_v<T2, Arg2>>,
369 enable_if_t<is_assignable_v<T1&, Arg1 const&>>,
370 enable_if_t<is_assignable_v<T2&, Arg2 const&>>> = nullptr>
371 auto operator=(pair<Arg1, Arg2> const& other
372 ) noexcept(is_nothrow_assignable_v<T1&, Arg1 const&> && is_nothrow_assignable_v<T2&, Arg2 const&>) -> pair& {
373 first = other.first;
374 second = other.second;
375 return *this;
376 }
377
378 // parasoft-begin-suppress AUTOSAR-A8_4_6-a "False positive: Fields are forwarded"
379 // parasoft-begin-suppress AUTOSAR-A8_4_5-a "False positive: Fields are forwarded"
380 // parasoft-begin-suppress AUTOSAR-A12_8_4-a "False positive: Fields are forwarded"
381 // parasoft-begin-suppress AUTOSAR-A18_9_2-a "False positive: Forwarding fields"
382 /// @brief Move-assign a @c pair from another pair with different value types
383 ///
384 /// This is disabled if either @c T1 or @c T2 is not assignable from the corresponding initializer.
385 /// @tparam Arg1 The type of @c first in the source pair
386 /// @tparam Arg2 The type of @c second in the source pair
387 /// @param other The pair to move from
388 /// @return @c *this
389 template <
390 typename Arg1,
391 typename Arg2,
392 arene::base::constraints<
393 enable_if_t<!is_same_v<T1, Arg1> || !is_same_v<T2, Arg2>>,
394 enable_if_t<is_assignable_v<T1&, Arg1&&>>,
395 enable_if_t<is_assignable_v<T2&, Arg2&&>>> = nullptr>
396 auto operator=(pair<Arg1, Arg2>&& other
397 ) noexcept(is_nothrow_assignable_v<T1&, Arg1&&> && is_nothrow_assignable_v<T2&, Arg2&&>) -> pair& {
398 first = std::forward<Arg1>(other.first);
399 second = std::forward<Arg2>(other.second);
400 return *this;
401 }
402 // parasoft-end-suppress AUTOSAR-A18_9_2-a
403 // parasoft-end-suppress AUTOSAR-A8_4_6-a
404 // parasoft-end-suppress AUTOSAR-A8_4_5-a
405 // parasoft-end-suppress AUTOSAR-A12_8_4-a
406
407 // parasoft-begin-suppress AUTOSAR-A2_10_1-d "False positive: identifier 'swap' does not hide anything"
408 /// @brief Swap a @c pair with another instance of the same type. Swaps @c first with @c other.first and swaps @c
409 /// second with @c other.second
410 ///
411 /// This is disabled if either @c T1 or @c T2 is not swappable
412 /// @param other The pair to swap with
413 template <
414 typename CheckType1 = T1,
415 typename CheckType2 = T2,
416 arene::base::constraints<
417 enable_if_t<arene::base::is_swappable_v<CheckType1>>,
418 enable_if_t<arene::base::is_swappable_v<CheckType2>>> = nullptr>
419 void swap(pair& other
420 ) noexcept(arene::base::is_nothrow_swappable_v<CheckType1> && arene::base::is_nothrow_swappable_v<CheckType2>) {
421 using std::swap;
422 swap(first, other.first);
423 swap(second, other.second);
424 }
425};
426// parasoft-end-suppress AUTOSAR-A2_10_1-d
427
428// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Conditionally noexcept based on underlying comparison"
429// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: Inline function for use in multiple translation units"
430/// @brief Swap a @c pair with another instance of the same type. Swaps @c lhs.first with @c rhs.first and swaps @c
431/// lhs.second with @c rhs.second
432///
433/// This is disabled if either @c T1 or @c T2 is not swappable
434/// @param lhs The first pair to swap
435/// @param rhs The second pair to swap
436template <
437 typename T1,
438 typename T2,
441 enable_if_t<arene::base::is_swappable_v<T2>>> = nullptr>
442void swap(
443 pair<T1, T2>& lhs,
444 pair<T1, T2>& rhs
446 lhs.swap(rhs);
447}
448// parasoft-end-suppress AUTOSAR-M3_3_2-a
449// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
450
451// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Conditionally noexcept based on underlying comparison"
452// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: Inline function for use in multiple translation units"
453/// @brief Compare two pairs to see if the first is less than the second. Uses lexicographical ordering based on the
454/// less-than comparisons of the members.
455/// @tparam T1 The type of the first data member of the pairs being compared
456/// @tparam T2 The type of the second data member of the pairs being compared
457/// @param lhs The first pair to compare
458/// @param rhs The second pair to compare
459/// @return @c true if @c lhs is less than @c rhs, @c false otherwise
460/// @pre @c T1 and @c T2 must have less than operators that provide a strict weak ordering
461template <typename T1, typename T2>
462constexpr auto operator<(
463 pair<T1, T2> const& lhs,
464 pair<T1, T2> const& rhs
466 -> bool {
467 return (lhs.first < rhs.first) || ((!(rhs.first < lhs.first)) && (lhs.second < rhs.second));
468}
469// parasoft-end-suppress AUTOSAR-M3_3_2-a
470// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
471
472// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Conditionally noexcept based on underlying comparison"
473// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: Inline function for use in multiple translation units"
474/// @brief Compare two pairs to see if the first is greater than the second. Uses lexicographical ordering based on
475/// the less-than comparisons of the members.
476/// @tparam T1 The type of the first data member of the pairs being compared
477/// @tparam T2 The type of the second data member of the pairs being compared
478/// @param lhs The first pair to compare
479/// @param rhs The second pair to compare
480/// @return @c true if @c lhs is greater than @c rhs, @c false otherwise
481/// @pre @c T1 and @c T2 must have less than operators that provide a strict weak ordering
482template <typename T1, typename T2>
483constexpr auto operator>(
484 pair<T1, T2> const& lhs,
485 pair<T1, T2> const& rhs
487 -> bool {
488 return rhs < lhs;
489}
490// parasoft-end-suppress AUTOSAR-M3_3_2-a
491// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
492
493// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Conditionally noexcept based on underlying comparison"
494// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: Inline function for use in multiple translation units"
495/// @brief Compare two pairs to see if the first is less than or equal to the second. Uses lexicographical ordering
496/// based on the less-than comparisons of the members.
497/// @tparam T1 The type of the first data member of the pairs being compared
498/// @tparam T2 The type of the second data member of the pairs being compared
499/// @param lhs The first pair to compare
500/// @param rhs The second pair to compare
501/// @return @c true if @c lhs is less than or equal to @c rhs, @c false otherwise
502/// @pre @c T1 and @c T2 must have less than operators that provide a strict weak ordering
503template <typename T1, typename T2>
504constexpr auto operator<=(
505 pair<T1, T2> const& lhs,
506 pair<T1, T2> const& rhs
508 -> bool {
509 return !(rhs < lhs);
510}
511// parasoft-end-suppress AUTOSAR-M3_3_2-a
512// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
513
514// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Conditionally noexcept based on underlying comparison"
515// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: Inline function for use in multiple translation units"
516/// @brief Compare two pairs to see if the first is greater than or equal to the second. Uses lexicographical ordering
517/// based on the less-than comparisons of the members.
518/// @tparam T1 The type of the first data member of the pairs being compared
519/// @tparam T2 The type of the second data member of the pairs being compared
520/// @param lhs The first pair to compare
521/// @param rhs The second pair to compare
522/// @return @c true if @c lhs is greater than or equal to @c rhs, @c false otherwise
523/// @pre @c T1 and @c T2 must have less than operators that provide a strict weak ordering
524template <typename T1, typename T2>
525constexpr auto operator>=(
526 pair<T1, T2> const& lhs,
527 pair<T1, T2> const& rhs
529 -> bool {
530 return !(lhs < rhs);
531}
532// parasoft-end-suppress AUTOSAR-M3_3_2-a
533// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
534
535// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Conditionally noexcept based on underlying comparison"
536// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: Inline function for use in multiple translation units"
537/// @brief Compare two pairs to see if they are equal, by checking if both members of the first are equal to the
538/// corresponding members of the second using the equality comparison operators of the members.
539/// @tparam T1 The type of the first data member of the pairs being compared
540/// @tparam T2 The type of the second data member of the pairs being compared
541/// @param lhs The first pair to compare
542/// @param rhs The second pair to compare
543/// @return @c true if @c lhs is equal to @c rhs, @c false otherwise
544/// @pre @c T1 and @c T2 must have equality operators that provide an equivalency comparison
545template <typename T1, typename T2>
546constexpr auto operator==(
547 pair<T1, T2> const& lhs,
548 pair<T1, T2> const& rhs
550 -> bool {
551 return (lhs.first == rhs.first) && (lhs.second == rhs.second);
552}
553// parasoft-end-suppress AUTOSAR-M3_3_2-a
554// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
555
556// parasoft-begin-suppress AUTOSAR-A13_5_5-b-2 "Conditionally noexcept based on underlying comparison"
557// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: Inline function for use in multiple translation units"
558/// @brief Compare two pairs to see if the first is not equal to the second. Uses the equality comparison operators of
559/// the members.
560/// @tparam T1 The type of the first data member of the pairs being compared
561/// @tparam T2 The type of the second data member of the pairs being compared
562/// @param lhs The first pair to compare
563/// @param rhs The second pair to compare
564/// @return @c true if @c lhs is not equal to @c rhs, @c false otherwise
565/// @pre @c T1 and @c T2 must have equality operators that provide an equivalency comparison
566template <typename T1, typename T2>
567constexpr auto operator!=(
568 pair<T1, T2> const& lhs,
569 pair<T1, T2> const& rhs
571 -> bool {
572 return !(lhs == rhs);
573}
574// parasoft-end-suppress AUTOSAR-M3_3_2-a
575// parasoft-end-suppress AUTOSAR-A13_5_5-b-2
576
577namespace pair_detail {
578
579/// @brief Internal helper to deduce the expected @c std::pair type
580/// @tparam T1 The first argument type given to @c std::make_pair
581/// @tparam T2 The second argument type given to @c std::make_pair
582template <class T1, class T2>
584
585} // namespace pair_detail
586
587// parasoft-begin-suppress AUTOSAR-M3_3_2-a-2 "False positive: inline function used in multiple translation units"
588// parasoft-begin-suppress AUTOSAR-A0_1_4-a "False positive: The parameters are used"
589// parasoft-begin-suppress AUTOSAR-A8_4_2-a "False positive: This function does return a value"
590// parasoft-begin-suppress CERT_C-MSC37-a "False positive: This function does return a value"
591// parasoft-begin-suppress CERT_CPP-MSC52-a "False positive: This function does return a value"
592/// @brief Creates a @c std::pair object, deducing the target type from the types of arguments
593/// @tparam T1 The first argument type
594/// @tparam T2 The second argument type
595/// @param first The first argument
596/// @param second The second argument
597///
598/// Given types @c std::decay<T1>::type as @c U1 and @c std::decay<T2>::type as @c U2, the types @c V1 and @c V2 are
599/// defined as follows:
600///
601/// If @c U1 is @c std::reference_wrapper<X>, @c V1 is @c X&; otherwise @c V1 is @c U1.
602/// If @c U2 is @c std::reference_wrapper<Y>, @c V2 is @c Y&; otherwise @c V2 is @c U2.
603/// @return <tt> std::pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y)) </tt>
604template <class T1, class T2>
605constexpr auto make_pair(
606 T1&& first,
607 T2&& second
610 return pair_detail::deduced_pair_type_t<T1, T2>(std::forward<T1>(first), std::forward<T2>(second));
611}
612// parasoft-end-suppress CERT_CPP-MSC52-a
613// parasoft-end-suppress CERT_C-MSC37-a
614// parasoft-end-suppress AUTOSAR-A8_4_2-a
615// parasoft-end-suppress AUTOSAR-A0_1_4-a
616// parasoft-end-suppress AUTOSAR-M3_3_2-a-2
617
618// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
619
620namespace pair_detail {
621
622// parasoft-begin-suppress AUTOSAR-A7_5_1-a "Temporary objects are handled by an overload that forwards the reference
623// category, not the const-ref overload"
624
625/// @brief access an element of a @c pair
626/// @tparam Pair specialization of @c pair
627/// @param values lvalue or rvalue reference to a @c pair
628/// @return reference to the first element in @c values
629///
630template <class Pair>
631constexpr auto get_impl(integral_constant<size_t, 0>, Pair&& values) noexcept
632 -> decltype((std::forward<Pair>(values).first)) {
633 return std::forward<Pair>(values).first;
634}
635
636/// @brief access an element of a @c pair
637/// @tparam Pair specialization of @c pair
638/// @param values lvalue or rvalue reference to a @c pair
639/// @return reference to the second element in @c values
640///
641template <class Pair>
642constexpr auto get_impl(integral_constant<size_t, 1>, Pair&& values) noexcept
643 -> decltype((std::forward<Pair>(values).second)) {
644 return std::forward<Pair>(values).second;
645}
646
647// parasoft-end-suppress AUTOSAR-A7_5_1-a
648
649} // namespace pair_detail
650
651/// @brief access an element of a @c pair
652/// @tparam I index of the element to access
653/// @tparam T1 first pair type
654/// @tparam T2 second pair type
655/// @param values reference to a @c pair
656/// @return reference to a value in @c values
657/// @note ill-formed if <tt> I >= 2 </tt>
658template <size_t I, class T1, class T2>
659constexpr auto get(pair<T1, T2>& values) noexcept -> tuple_element_t<I, pair<T1, T2>>& {
660 return pair_detail::get_impl(integral_constant<size_t, I>{}, values);
661}
662
663/// @brief access an element of a @c pair
664/// @tparam I index of the element to access
665/// @tparam T1 first pair type
666/// @tparam T2 second pair type
667/// @param values reference to a @c pair
668/// @return reference to a value in @c values
669/// @note ill-formed if <tt> I >= 2 </tt>
670template <size_t I, class T1, class T2>
671constexpr auto get(pair<T1, T2> const& values) noexcept -> tuple_element_t<I, pair<T1, T2>> const& {
672 return pair_detail::get_impl(integral_constant<size_t, I>{}, values);
673}
674
675/// @brief access an element of a @c pair
676/// @tparam I index of the element to access
677/// @tparam T1 first pair type
678/// @tparam T2 second pair type
679/// @param values reference to a @c pair
680/// @return reference to a value in @c values
681/// @note ill-formed if <tt> I >= 2 </tt>
682template <size_t I, class T1, class T2>
683constexpr auto get(pair<T1, T2>&& values) noexcept -> tuple_element_t<I, pair<T1, T2>>&& {
684 return pair_detail::get_impl(integral_constant<size_t, I>{}, std::move(values));
685}
686
687// parasoft-begin-suppress AUTOSAR-A18_9_3-a "We want to ensure the qualifier is preserved"
688/// @brief access an element of a @c pair
689/// @tparam I index of the element to access
690/// @tparam T1 first pair type
691/// @tparam T2 second pair type
692/// @param values reference to a @c pair
693/// @return reference to a value in @c values
694/// @note ill-formed if <tt> I >= 2 </tt>
695template <size_t I, class T1, class T2>
696constexpr auto get(pair<T1, T2> const&& values) noexcept -> tuple_element_t<I, pair<T1, T2>> const&& {
697 return pair_detail::get_impl(integral_constant<size_t, I>{}, std::move(values));
698}
699// parasoft-end-suppress AUTOSAR-A18_9_3-a
700
701/// @brief access an element of a @c pair
702/// @tparam T1 first pair type
703/// @tparam T2 second pair type
704/// @param values reference to a @c pair
705/// @return reference to a value in @c values
706/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
707template <class T1, class T2>
708constexpr auto get(pair<T1, T2>& values) noexcept -> T1& {
709 return values.first;
710}
711
712// parasoft-begin-suppress AUTOSAR-A7_5_1-a "Temporary objects are handled by an overload that forwards the reference
713// category, not the const-ref overload"
714
715/// @brief access an element of a @c pair
716/// @tparam T1 first pair type
717/// @tparam T2 second pair type
718/// @param values reference to a @c pair
719/// @return reference to a value in @c values
720/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
721template <class T1, class T2>
722constexpr auto get(pair<T1, T2> const& values) noexcept -> T1 const& {
723 return values.first;
724}
725
726// parasoft-end-suppress AUTOSAR-A7_5_1-a
727
728/// @brief access an element of a @c pair
729/// @tparam T1 first pair type
730/// @tparam T2 second pair type
731/// @param values reference to a @c pair
732/// @return reference to a value in @c values
733/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
734template <class T1, class T2>
735constexpr auto get(pair<T1, T2>&& values) noexcept -> T1&& {
736 return std::move(values.first);
737}
738
739// parasoft-begin-suppress AUTOSAR-A18_9_3-a "We want to ensure the qualifier is preserved"
740/// @brief access an element of a @c pair
741/// @tparam T1 first pair type
742/// @tparam T2 second pair type
743/// @param values reference to a @c pair
744/// @return reference to a value in @c values
745/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
746template <class T1, class T2>
747constexpr auto get(pair<T1, T2> const&& values) noexcept -> T1 const&& {
748 return std::move(values.first);
749}
750// parasoft-end-suppress AUTOSAR-A18_9_3-a
751
752/// @brief access an element of a @c pair
753/// @tparam T1 second pair type
754/// @tparam T2 second pair type
755/// @param values reference to a @c pair
756/// @return reference to a value in @c values
757/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
758template <class T2, class T1>
759constexpr auto get(pair<T1, T2>& values) noexcept -> T2& {
760 return values.second;
761}
762
763// parasoft-begin-suppress AUTOSAR-A7_5_1-a "Temporary objects are handled by an overload that forwards the reference
764// category, not the const-ref overload"
765
766/// @brief access an element of a @c pair
767/// @tparam T1 second pair type
768/// @tparam T2 second pair type
769/// @param values reference to a @c pair
770/// @return reference to a value in @c values
771/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
772template <class T2, class T1>
773constexpr auto get(pair<T1, T2> const& values) noexcept -> T2 const& {
774 return values.second;
775}
776
777// parasoft-end-suppress AUTOSAR-A7_5_1-a
778
779/// @brief access an element of a @c pair
780/// @tparam T1 second pair type
781/// @tparam T2 second pair type
782/// @param values reference to a @c pair
783/// @return reference to a value in @c values
784/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
785template <class T2, class T1>
786constexpr auto get(pair<T1, T2>&& values) noexcept -> T2&& {
787 return std::move(values.second);
788}
789
790// parasoft-begin-suppress AUTOSAR-A18_9_3-a "We want to ensure the qualifier is preserved"
791/// @brief access an element of a @c pair
792/// @tparam T1 second pair type
793/// @tparam T2 second pair type
794/// @param values reference to a @c pair
795/// @return reference to a value in @c values
796/// @note ill-formed if <tt> std::is_same<T1, T2>::value </tt> is <tt> true </tt>
797template <class T2, class T1>
798constexpr auto get(pair<T1, T2> const&& values) noexcept -> T2 const&& {
799 return std::move(values.second);
800}
801// parasoft-end-suppress AUTOSAR-A18_9_3-a
802
803// parasoft-end-suppress AUTOSAR-M3_3_2-a
804
805/// @brief obtain the first type of a @c pair
806/// @tparam T1 first pair type
807/// @tparam T2 second pair type
808template <class T1, class T2>
809class tuple_element<0, pair<T1, T2>> {
810 public:
811 /// @brief type at index 0
812 using type = T1;
813};
814
815/// @brief obtain the second type of a @c pair
816/// @tparam T1 first pair type
817/// @tparam T2 second pair type
818template <class T1, class T2>
819class tuple_element<1, pair<T1, T2>> {
820 public:
821 /// @brief type at index 1
822 using type = T2;
823};
824
825/// @brief obtain the size of a @c pair
826/// @tparam T1 first pair type
827/// @tparam T2 second pair type
828/// @note This is always 2
829template <class T1, class T2>
830class tuple_size<pair<T1, T2>> : public integral_constant<size_t, 2> {};
831
832} // namespace std
833
834#endif // INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_PAIR_HPP_
Definition pair.hpp:577
constexpr auto get_impl(integral_constant< size_t, 0 >, Pair &&values) noexcept ->
access an element of a pair
Definition pair.hpp:631
constexpr auto get(pair< T1, T2 > &&values) noexcept -> tuple_element_t< I, pair< T1, T2 > > &&
access an element of a pair
Definition pair.hpp:683
constexpr auto operator<(pair< T1, T2 > const &lhs, pair< T1, T2 > const &rhs) noexcept(arene::base::is_nothrow_less_than_comparable_v< T1 > &&arene::base::is_nothrow_less_than_comparable_v< T2 >) -> bool
Compare two pairs to see if the first is less than the second. Uses lexicographical ordering based on...
Definition pair.hpp:462
constexpr auto get(pair< T1, T2 > const &&values) noexcept -> tuple_element_t< I, pair< T1, T2 > > const &&
access an element of a pair
Definition pair.hpp:696
constexpr auto make_pair(T1 &&first, T2 &&second) noexcept(is_nothrow_constructible_v< pair_detail::deduced_pair_type_t< T1, T2 >, T1, T2 >) -> pair_detail::deduced_pair_type_t< T1, T2 >
Creates a std::pair object, deducing the target type from the types of arguments.
Definition pair.hpp:605
constexpr auto get(pair< T1, T2 > &&values) noexcept -> T1 &&
access an element of a pair
Definition pair.hpp:735
constexpr auto operator<=(pair< T1, T2 > const &lhs, pair< T1, T2 > const &rhs) noexcept(arene::base::is_nothrow_less_than_comparable_v< T1 > &&arene::base::is_nothrow_less_than_comparable_v< T2 >) -> bool
Compare two pairs to see if the first is less than or equal to the second. Uses lexicographical order...
Definition pair.hpp:504
constexpr auto get(pair< T1, T2 > const &&values) noexcept -> T1 const &&
access an element of a pair
Definition pair.hpp:747
constexpr piecewise_construct_t piecewise_construct
Tag constant for piecewise construction.
Definition pair.hpp:42
constexpr auto get(pair< T1, T2 > const &values) noexcept -> tuple_element_t< I, pair< T1, T2 > > const &
access an element of a pair
Definition pair.hpp:671
constexpr auto operator!=(pair< T1, T2 > const &lhs, pair< T1, T2 > const &rhs) noexcept(arene::base::is_nothrow_equality_comparable_v< T1 > &&arene::base::is_nothrow_equality_comparable_v< T2 >) -> bool
Compare two pairs to see if the first is not equal to the second. Uses the equality comparison operat...
Definition pair.hpp:567
constexpr auto operator==(pair< T1, T2 > const &lhs, pair< T1, T2 > const &rhs) noexcept(arene::base::is_nothrow_equality_comparable_v< T1 > &&arene::base::is_nothrow_equality_comparable_v< T2 >) -> bool
Compare two pairs to see if they are equal, by checking if both members of the first are equal to the...
Definition pair.hpp:546
constexpr auto get(pair< T1, T2 > &values) noexcept -> tuple_element_t< I, pair< T1, T2 > > &
access an element of a pair
Definition pair.hpp:659
constexpr auto get(pair< T1, T2 > const &values) noexcept -> T1 const &
access an element of a pair
Definition pair.hpp:722
constexpr auto get(pair< T1, T2 > &values) noexcept -> T1 &
access an element of a pair
Definition pair.hpp:708
constexpr auto operator>=(pair< T1, T2 > const &lhs, pair< T1, T2 > const &rhs) noexcept(arene::base::is_nothrow_less_than_comparable_v< T1 > &&arene::base::is_nothrow_less_than_comparable_v< T2 >) -> bool
Compare two pairs to see if the first is greater than or equal to the second. Uses lexicographical or...
Definition pair.hpp:525
constexpr auto operator>(pair< T1, T2 > const &lhs, pair< T1, T2 > const &rhs) noexcept(arene::base::is_nothrow_less_than_comparable_v< T1 > &&arene::base::is_nothrow_less_than_comparable_v< T2 >) -> bool
Compare two pairs to see if the first is greater than the second. Uses lexicographical ordering based...
Definition pair.hpp:483
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827
Tag type for piecewise construction.
Definition pair.hpp:39