5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_PAIR_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_PAIR_HPP_
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"
48template <
typename T1,
typename T2>
53 using first_type = T1;
55 using second_type = T2;
68 template <
typename Arg1,
typename Arg2>
70 memberwise_copy_constructor_is_explicit{!is_convertible_v<Arg1
const&, Arg1> || !is_convertible_v<Arg2
const&, Arg2>};
75 template <
typename Arg1,
typename Arg2>
77 memberwise_forward_constructor_is_explicit{!is_convertible_v<Arg1&&, first_type> || !is_convertible_v<Arg2&&, second_type>};
82 template <
typename Arg1,
typename Arg2>
84 copy_constructor_is_explicit{!is_convertible_v<Arg1
const&, first_type> || !is_convertible_v<Arg2
const&, second_type>};
89 template <
typename Arg1,
typename Arg2>
91 move_constructor_is_explicit{!is_convertible_v<Arg1&&, first_type> || !is_convertible_v<Arg2&&, second_type>};
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>)
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>)
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>
156 first_type
const& val1,
157 second_type
const& val2
158 )
noexcept(is_nothrow_copy_constructible_v<T1> && is_nothrow_copy_constructible_v<T2>)
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(
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)) {}
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>
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)) {}
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) {}
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>
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) {}
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)) {}
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>
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)) {}
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))...} {}
346 arene::base::constraints<
347 enable_if_t<is_constructible_v<T1, Args1&&...>>,
348 enable_if_t<is_constructible_v<T2, Args2&&...>>> =
nullptr>
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...>{}} {}
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& {
374 second = other.second;
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);
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>) {
422 swap(first, other.first);
423 swap(second, other.second);
461template <
typename T1,
typename T2>
463 pair<T1, T2>
const& lhs,
464 pair<T1, T2>
const& rhs
467 return (lhs.first < rhs.first) || ((!(rhs.first < lhs.first)) && (lhs.second < rhs.second));
482template <
typename T1,
typename T2>
484 pair<T1, T2>
const& lhs,
485 pair<T1, T2>
const& rhs
503template <
typename T1,
typename T2>
505 pair<T1, T2>
const& lhs,
506 pair<T1, T2>
const& rhs
524template <
typename T1,
typename T2>
526 pair<T1, T2>
const& lhs,
527 pair<T1, T2>
const& rhs
545template <
typename T1,
typename T2>
547 pair<T1, T2>
const& lhs,
548 pair<T1, T2>
const& rhs
551 return (lhs.first == rhs.first) && (lhs.second == rhs.second);
566template <
typename T1,
typename T2>
568 pair<T1, T2>
const& lhs,
569 pair<T1, T2>
const& rhs
572 return !(lhs == rhs);
582template <
class T1,
class T2>
604template <
class T1,
class T2>
610 return pair_detail::deduced_pair_type_t<T1, T2>(std::forward<T1>(first), std::forward<T2>(second));
633 return std::forward<Pair>(values).first;
644 return std::forward<Pair>(values).second;
658template <size_t I,
class T1,
class T2>
660 return pair_detail::get_impl(integral_constant<size_t, I>{}, values);
670template <size_t I,
class T1,
class T2>
672 return pair_detail::get_impl(integral_constant<size_t, I>{}, values);
682template <size_t I,
class T1,
class T2>
684 return pair_detail::get_impl(integral_constant<size_t, I>{}, std::move(values));
695template <size_t I,
class T1,
class T2>
697 return pair_detail::get_impl(integral_constant<size_t, I>{}, std::move(values));
707template <
class T1,
class T2>
708constexpr auto get(pair<T1, T2>& values)
noexcept -> T1& {
721template <
class T1,
class T2>
722constexpr auto get(pair<T1, T2>
const& values)
noexcept -> T1
const& {
734template <
class T1,
class T2>
735constexpr auto get(pair<T1, T2>&& values)
noexcept -> T1&& {
736 return std::move(values.first);
746template <
class T1,
class T2>
747constexpr auto get(pair<T1, T2>
const&& values)
noexcept -> T1
const&& {
748 return std::move(values.first);
758template <
class T2,
class T1>
759constexpr auto get(pair<T1, T2>& values)
noexcept -> T2& {
760 return values.second;
772template <
class T2,
class T1>
773constexpr auto get(pair<T1, T2>
const& values)
noexcept -> T2
const& {
774 return values.second;
785template <
class T2,
class T1>
786constexpr auto get(pair<T1, T2>&& values)
noexcept -> T2&& {
787 return std::move(values.second);
797template <
class T2,
class T1>
798constexpr auto get(pair<T1, T2>
const&& values)
noexcept -> T2
const&& {
799 return std::move(values.second);
808template <
class T1,
class T2>
809class tuple_element<0, pair<T1, T2>> {
818template <
class T1,
class T2>
829template <
class T1,
class T2>
830class tuple_size<pair<T1, T2>> :
public integral_constant<size_t, 2> {};
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