1#ifndef NEFORCE_CORE_UTILITY_PAIR_HPP__
2#define NEFORCE_CORE_UTILITY_PAIR_HPP__
14NEFORCE_BEGIN_NAMESPACE__
28#ifdef NEFORCE_STANDARD_14
41template <
size_t Index,
typename... Tuple>
51template <
size_t Index,
typename... Types>
59template <
size_t Index,
typename... Types>
62template <
size_t Index,
typename... Types>
63NEFORCE_NODISCARD
constexpr tuple_element_t<Index, Types...>&
get(tuple<Types...>& t)
noexcept;
64template <
size_t Index,
typename... Types>
65NEFORCE_NODISCARD
constexpr const tuple_element_t<Index, Types...>&
get(
const tuple<Types...>& t)
noexcept;
66template <
size_t Index,
typename... Types>
67NEFORCE_NODISCARD
constexpr tuple_element_t<Index, Types...>&&
get(tuple<Types...>&& t)
noexcept;
68template <
size_t Index,
typename... Types>
69NEFORCE_NODISCARD
constexpr const tuple_element_t<Index, Types...>&&
get(
const tuple<Types...>&& t)
noexcept;
73template <
size_t Index,
typename... Types>
74NEFORCE_NODISCARD
constexpr tuple_element_t<Index, Types...>&& __pair_get_from_tuple(tuple<Types...>&& t)
noexcept;
95template <
typename T1,
typename T2>
103#ifdef NEFORCE_STANDARD_20
111 template <
typename U1 = T1,
typename U2 = T2,
127 template <
typename U1 = T1,
typename U2 = T2,
130 pair(
const T1& a,
const T2& b)
noexcept(
144 template <
typename U1,
typename U2,
160 template <
typename U1,
typename U2,
176 template <
typename U1,
typename U2,
186 template <
typename U1 = T1,
typename U2 = T2,
191 explicit pair() noexcept(
198 template <
typename U1 = T1,
typename U2 = T2,
200 conjunction<is_implicitly_default_constructible<U1>,
201 is_implicitly_default_constructible<U2>>::value,
203 pair() noexcept(conjunction<is_nothrow_default_constructible<U1>, is_nothrow_default_constructible<U2>>::value) :
210 template <
typename U1 = T1,
typename U2 = T2,
212 !conjunction<is_convertible<const U1&, U1>, is_convertible<const U2&, U2>>::value,
214 explicit pair(
const T1& a,
const T2& b)
noexcept(
215 conjunction<is_nothrow_copy_constructible<U1>, is_nothrow_copy_constructible<U2>>::value) :
222 template <
typename U1 = T1,
typename U2 = T2,
224 conjunction<is_convertible<const U1&, U1>, is_convertible<const U2&, U2>>::value,
226 pair(
const T1& a,
const T2& b)
noexcept(
227 conjunction<is_nothrow_copy_constructible<U1>, is_nothrow_copy_constructible<U2>>::value) :
234 template <
typename U1,
typename U2,
236 !conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
238 explicit pair(U1&& a, U2&& b)
noexcept(
239 conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
246 template <
typename U1,
typename U2,
248 conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
251 U2&& b)
noexcept(conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
258 template <
typename U1,
typename U2,
260 !conjunction<is_convertible<const U1&, T1>, is_convertible<const U2&, T2>>::value,
263 conjunction<is_nothrow_constructible<T1, const U1&>, is_nothrow_constructible<T2, const U2&>>::value) :
270 template <
typename U1,
typename U2,
272 conjunction<is_convertible<const U1&, T1>, is_convertible<const U2&, T2>>::value,
275 conjunction<is_nothrow_constructible<T1, const U1&>, is_nothrow_constructible<T2, const U2&>>::value) :
282 template <
typename U1,
typename U2,
284 !conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
287 conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
294 template <
typename U1,
typename U2,
296 conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
299 conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
320 template <
typename Tuple1,
typename Tuple2,
size_t... Index1,
size_t... Index2>
322 first(inner::__pair_get_from_tuple<Index1>(_NEFORCE
move(t1))...),
323 second(inner::__pair_get_from_tuple<Index2>(_NEFORCE
move(t2))...) {}
334 template <
typename... Types1,
typename... Types2>
344 template <
typename T = pair, enable_if_t<conjunction<is_copy_assignable<
typename T::first_type>,
345 is_copy_assignable<
typename T::second_type>>::value,
360 template <
typename T = pair, enable_if_t<conjunction<is_move_assignable<
typename T::first_type>,
361 is_move_assignable<
typename T::second_type>>::value,
377 template <
typename U1,
typename U2,
395 template <
typename U1,
typename U2,
408 NEFORCE_CONSTEXPR20
~pair() =
default;
418 noexcept(
noexcept(this->
first == y.first && this->
second == y.second)) {
419 return this->
first == y.first && this->
second == y.second;
430 noexcept(
noexcept(this->
first < y.first || (!(y.first < this->
first) && this->
second < y.second))) {
431 return this->
first < y.first || (!(y.first < this->
first) && this->
second < y.second);
440 NEFORCE_NODISCARD
constexpr size_t to_hash() const
449 NEFORCE_CONSTEXPR14
void
456#ifdef NEFORCE_STANDARD_17
457template <
typename T1,
typename T2>
472template <
typename T1,
typename T2>
493template <
typename... Types>
501template <
size_t Index>
509template <
typename This,
typename... Rest>
512 using tuple_type = tuple<This, Rest...>;
521template <
size_t Index,
typename This,
typename... Rest>
530template <
size_t Index,
typename... Types>
539template <
typename T1,
typename T2>
548template <
size_t Index,
typename T1,
typename T2>
550 static_assert(Index < 2,
"pair element index out of range.");
564#ifndef NEFORCE_STANDARD_17
568template <
size_t Index,
typename T1,
typename T2>
569struct __pair_get_helper;
570template <
typename T1,
typename T2>
571struct __pair_get_helper<0, T1, T2> {
586template <
typename T1,
typename T2>
587struct __pair_get_helper<1, T1, T2> {
609template <
size_t Index,
typename T1,
typename T2>
612#ifdef NEFORCE_STANDARD_17
613template <
size_t Index,
typename T1,
typename T2>
615 if constexpr (Index == 0) {
622template <
size_t Index,
typename T1,
typename T2>
624 return inner::__pair_get_helper<Index, T1, T2>::get(pir);
631template <
typename T1,
typename T2>
639template <
typename T2,
typename T1>
648template <
size_t Index,
typename T1,
typename T2>
651#ifdef NEFORCE_STANDARD_17
652template <
size_t Index,
typename T1,
typename T2>
654 if constexpr (Index == 0) {
661template <
size_t Index,
typename T1,
typename T2>
663 return inner::__pair_get_helper<Index, T1, T2>::get(pir);
670template <
typename T1,
typename T2>
678template <
typename T2,
typename T1>
687template <
size_t Index,
typename T1,
typename T2>
690#ifdef NEFORCE_STANDARD_17
691template <
size_t Index,
typename T1,
typename T2>
693 if constexpr (Index == 0) {
700template <
size_t Index,
typename T1,
typename T2>
710template <
typename T1,
typename T2>
718template <
typename T2,
typename T1>
727template <
size_t Index,
typename T1,
typename T2>
730#ifdef NEFORCE_STANDARD_17
731template <
size_t Index,
typename T1,
typename T2>
733 if constexpr (Index == 0) {
740template <
size_t Index,
typename T1,
typename T2>
750template <
typename T1,
typename T2>
758template <
typename T2,
typename T1>
765NEFORCE_END_NAMESPACE__
767#ifdef NEFORCE_STANDARD_17
770 template <
typename T1,
typename T2>
771 struct tuple_size<_NEFORCE pair<T1, T2>> : _NEFORCE integral_constant<_NEFORCE size_t, 2> {};
773 template <_NEFORCE
size_t I,
typename T1,
typename T2>
774 struct tuple_element<I, _NEFORCE pair<T1, T2>> {
NEFORCE_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
NEFORCE_ALWAYS_INLINE enable_if_t< is_void_v< T >, future_result_t< T > > get(future< T > &f)
通用future结果获取函数
integer_sequence< size_t, Values... > index_sequence
索引序列
make_index_sequence< sizeof...(Types)> index_sequence_for
根据类型参数包生成索引序列
constexpr pair< unwrap_ref_decay_t< T1 >, unwrap_ref_decay_t< T2 > > make_pair(T1 &&x, T2 &&y) noexcept(conjunction< is_nothrow_constructible< unwrap_ref_decay_t< T1 >, T1 >, is_nothrow_constructible< unwrap_ref_decay_t< T2 >, T2 > >::value)
创建pair的辅助函数
typename unwrap_ref_decay< T >::type unwrap_ref_decay_t
unwrap_ref_decay的便捷别名
typename remove_cvref< T >::type remove_cvref_t
remove_cvref的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
void swap()=delete
删除无参数的swap重载
typename tuple_element< Index, Types... >::tuple_type tuple_extract_base_t
获取tuple元素基类型的类型别名
constexpr size_t tuple_size_v
tuple_size的类型别名
typename tuple_element< Index, Types... >::type tuple_element_t
tuple_element的类型别名
NEFORCE_NODISCARD constexpr tuple_element_t< Index, Types... > & get(tuple< Types... > &t) noexcept
获取元组中指定位置的元素引用
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename type_identity< T >::type type_identity_t
type_identity的便捷别名
NEFORCE_INLINE17 constexpr bool conjunction_v
conjunction的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
constexpr pair(Tuple1 &t1, Tuple2 &t2, index_sequence< Index1... > idx1, index_sequence< Index2... > idx2)
从两个tuple构造pair
NEFORCE_CONSTEXPR14 pair & operator=(const pair< U1, U2 > &p) noexcept(conjunction< is_nothrow_assignable< T1 &, const U1 & >, is_nothrow_assignable< T2 &, const U2 & > >::value)
从不同类型pair的拷贝赋值运算符
NEFORCE_NODISCARD constexpr size_t to_hash() const noexcept(noexcept(hash< remove_cvref_t< T1 > >()(first) ^ hash< remove_cvref_t< T2 > >()(second)))
计算hash值
NEFORCE_CONSTEXPR14 pair & operator=(pair< U1, U2 > &&p) noexcept(conjunction< is_nothrow_assignable< T1 &, U1 >, is_nothrow_assignable< T2 &, U2 > >::value)
从不同类型pair的移动赋值运算符
NEFORCE_CONSTEXPR14 pair & operator=(type_identity_t< T && > p) noexcept(conjunction< is_nothrow_move_assignable< T1 >, is_nothrow_move_assignable< T2 > >::value)
移动赋值运算符
constexpr bool operator<(const pair &y) const noexcept(noexcept(this->first< y.first||(!(y.first< this->first) &&this->second< y.second)))
小于比较运算符
pair(const pair &p)=default
默认拷贝构造函数
constexpr pair(unpack_utility_construct_tag, tuple< Types1... > t1, tuple< Types2... > t2)
从两个tuple构造pair
NEFORCE_CONSTEXPR20 ~pair()=default
析构函数
NEFORCE_CONSTEXPR14 void swap(pair &p) noexcept(conjunction< is_nothrow_swappable< T1 >, is_nothrow_swappable< T2 > >::value)
交换两个pair的内容
NEFORCE_CONSTEXPR14 pair & operator=(type_identity_t< const T & > p) noexcept(conjunction< is_nothrow_copy_assignable< T1 >, is_nothrow_copy_assignable< T2 > >::value)
拷贝赋值运算符
pair & operator=(const volatile pair &)=delete
禁止volatile拷贝赋值
constexpr bool operator==(const pair &y) const noexcept(noexcept(this->first==y.first &&this->second==y.second))
相等比较运算符
pair(pair &&p)=default
默认移动构造函数
conditional_t< Index==0, T1, T2 > type
根据索引返回对应类型
tuple< T1, T2 > tuple_type
对应的tuple类型