NexusForce 1.0.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
pair.hpp
浏览该文件的文档.
1#ifndef NEFORCE_CORE_UTILITY_PAIR_HPP__
2#define NEFORCE_CORE_UTILITY_PAIR_HPP__
3
10
14NEFORCE_BEGIN_NAMESPACE__
15
21
22template <typename...>
23struct tuple;
24
25template <typename>
27
28#ifdef NEFORCE_STANDARD_14
36template <typename T>
37constexpr size_t tuple_size_v = tuple_size<remove_cvref_t<T>>::value;
38#endif
39
40
41template <size_t Index, typename... Tuple>
42struct tuple_element;
43
51template <size_t Index, typename... Types>
52using tuple_element_t = typename tuple_element<Index, Types...>::type;
53
59template <size_t Index, typename... Types>
60using tuple_extract_base_t = typename tuple_element<Index, Types...>::tuple_type;
61
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;
70
72NEFORCE_BEGIN_INNER__
73template <size_t Index, typename... Types>
74NEFORCE_NODISCARD constexpr tuple_element_t<Index, Types...>&& __pair_get_from_tuple(tuple<Types...>&& t) noexcept;
75NEFORCE_END_INNER__
77 // Tuple
79
85
95template <typename T1, typename T2>
96struct pair : icommon<pair<T1, T2>> {
97 using first_type = T1;
98 using second_type = T2;
99
100 T1 first;
102
103#ifdef NEFORCE_STANDARD_20
111 template <typename U1 = T1, typename U2 = T2,
117
127 template <typename U1 = T1, typename U2 = T2,
130 pair(const T1& a, const T2& b) noexcept(
132 first(a),
133 second(b) {}
134
144 template <typename U1, typename U2,
147 pair(U1&& a,
149 first(_NEFORCE forward<U1>(a)),
150 second(_NEFORCE forward<U2>(b)) {}
151
160 template <typename U1, typename U2,
163 pair(const pair<U1, U2>& p) noexcept(
165 first(p.first),
166 second(p.second) {}
167
176 template <typename U1, typename U2,
180 first(_NEFORCE forward<U1>(p.first)),
181 second(_NEFORCE forward<U2>(p.second)) {}
182#else
186 template <typename U1 = T1, typename U2 = T2,
190 int> = 0>
191 explicit pair() noexcept(
193 first(),
194 second() {}
198 template <typename U1 = T1, typename U2 = T2,
199 enable_if_t<conjunction<is_default_constructible<U1>, is_default_constructible<U2>>::value &&
200 conjunction<is_implicitly_default_constructible<U1>,
201 is_implicitly_default_constructible<U2>>::value,
202 int> = 0>
203 pair() noexcept(conjunction<is_nothrow_default_constructible<U1>, is_nothrow_default_constructible<U2>>::value) :
204 first(),
205 second() {}
206
210 template <typename U1 = T1, typename U2 = T2,
211 enable_if_t<conjunction<is_copy_constructible<U1>, is_copy_constructible<U2>>::value &&
212 !conjunction<is_convertible<const U1&, U1>, is_convertible<const U2&, U2>>::value,
213 int> = 0>
214 explicit pair(const T1& a, const T2& b) noexcept(
215 conjunction<is_nothrow_copy_constructible<U1>, is_nothrow_copy_constructible<U2>>::value) :
216 first(a),
217 second(b) {}
218
222 template <typename U1 = T1, typename U2 = T2,
223 enable_if_t<conjunction<is_copy_constructible<U1>, is_copy_constructible<U2>>::value &&
224 conjunction<is_convertible<const U1&, U1>, is_convertible<const U2&, U2>>::value,
225 int> = 0>
226 pair(const T1& a, const T2& b) noexcept(
227 conjunction<is_nothrow_copy_constructible<U1>, is_nothrow_copy_constructible<U2>>::value) :
228 first(a),
229 second(b) {}
230
234 template <typename U1, typename U2,
235 enable_if_t<conjunction<is_constructible<T1, U1>, is_constructible<T2, U2>>::value &&
236 !conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
237 int> = 0>
238 explicit pair(U1&& a, U2&& b) noexcept(
239 conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
240 first(_NEFORCE forward<U1>(a)),
241 second(_NEFORCE forward<U2>(b)) {}
242
246 template <typename U1, typename U2,
247 enable_if_t<conjunction<is_constructible<T1, U1>, is_constructible<T2, U2>>::value &&
248 conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
249 int> = 0>
250 pair(U1&& a,
251 U2&& b) noexcept(conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
252 first(_NEFORCE forward<U1>(a)),
253 second(_NEFORCE forward<U2>(b)) {}
254
258 template <typename U1, typename U2,
259 enable_if_t<conjunction<is_constructible<T1, const U1&>, is_constructible<T2, const U2&>>::value &&
260 !conjunction<is_convertible<const U1&, T1>, is_convertible<const U2&, T2>>::value,
261 int> = 0>
262 explicit pair(const pair<U1, U2>& p) noexcept(
263 conjunction<is_nothrow_constructible<T1, const U1&>, is_nothrow_constructible<T2, const U2&>>::value) :
264 first(p.first),
265 second(p.second) {}
266
270 template <typename U1, typename U2,
271 enable_if_t<conjunction<is_constructible<T1, const U1&>, is_constructible<T2, const U2&>>::value &&
272 conjunction<is_convertible<const U1&, T1>, is_convertible<const U2&, T2>>::value,
273 int> = 0>
274 pair(const pair<U1, U2>& p) noexcept(
275 conjunction<is_nothrow_constructible<T1, const U1&>, is_nothrow_constructible<T2, const U2&>>::value) :
276 first(p.first),
277 second(p.second) {}
278
282 template <typename U1, typename U2,
283 enable_if_t<conjunction<is_constructible<T1, U1>, is_constructible<T2, U2>>::value &&
284 !conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
285 int> = 0>
286 explicit pair(pair<U1, U2>&& p) noexcept(
287 conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
288 first(_NEFORCE forward<U1>(p.first)),
289 second(_NEFORCE forward<U2>(p.second)) {}
290
294 template <typename U1, typename U2,
295 enable_if_t<conjunction<is_constructible<T1, U1>, is_constructible<T2, U2>>::value &&
296 conjunction<is_convertible<U1, T1>, is_convertible<U2, T2>>::value,
297 int> = 0>
298 pair(pair<U1, U2>&& p) noexcept(
299 conjunction<is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>::value) :
300 first(_NEFORCE forward<U1>(p.first)),
301 second(_NEFORCE forward<U2>(p.second)) {}
302#endif
303
304 pair(const pair& p) = default;
305 pair(pair&& p) = default;
306
320 template <typename Tuple1, typename Tuple2, size_t... Index1, size_t... Index2>
321 constexpr pair(Tuple1& t1, Tuple2& t2, index_sequence<Index1...> idx1, index_sequence<Index2...> idx2) :
322 first(inner::__pair_get_from_tuple<Index1>(_NEFORCE move(t1))...),
323 second(inner::__pair_get_from_tuple<Index2>(_NEFORCE move(t2))...) {}
324
334 template <typename... Types1, typename... Types2>
335 constexpr pair(unpack_utility_construct_tag, tuple<Types1...> t1, tuple<Types2...> t2) :
336 pair(t1, t2, index_sequence_for<Types1...>{}, index_sequence_for<Types2...>{}) {}
337
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,
346 int> = 0>
347 NEFORCE_CONSTEXPR14 pair& operator=(type_identity_t<const T&> p) noexcept(
349 first = p.first;
350 second = p.second;
351 return *this;
352 }
353
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,
362 int> = 0>
363 NEFORCE_CONSTEXPR14 pair& operator=(type_identity_t<T&&> p) noexcept(
365 first = _NEFORCE forward<T1>(p.first);
366 second = _NEFORCE forward<T2>(p.second);
367 return *this;
368 }
369
377 template <typename U1, typename U2,
380 int> = 0>
381 NEFORCE_CONSTEXPR14 pair& operator=(const pair<U1, U2>& p) noexcept(
383 first = p.first;
384 second = p.second;
385 return *this;
386 }
387
395 template <typename U1, typename U2,
398 int> = 0>
399 NEFORCE_CONSTEXPR14 pair& operator=(pair<U1, U2>&& p) noexcept(
401 first = _NEFORCE forward<U1>(p.first);
402 second = _NEFORCE forward<U2>(p.second);
403 return *this;
404 }
405
406 pair& operator=(const volatile pair&) = delete;
407
408 NEFORCE_CONSTEXPR20 ~pair() = default;
409
417 constexpr bool operator==(const pair& y) const
418 noexcept(noexcept(this->first == y.first && this->second == y.second)) {
419 return this->first == y.first && this->second == y.second;
420 }
421
429 constexpr bool operator<(const pair& y) const
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);
432 }
433
440 NEFORCE_NODISCARD constexpr size_t to_hash() const
441 noexcept(noexcept(hash<remove_cvref_t<T1>>()(first) ^ hash<remove_cvref_t<T2>>()(second))) {
443 }
444
449 NEFORCE_CONSTEXPR14 void
451 _NEFORCE swap(first, p.first);
452 _NEFORCE swap(second, p.second);
453 }
454};
455
456#ifdef NEFORCE_STANDARD_17
457template <typename T1, typename T2>
458pair(T1, T2) -> pair<T1, T2>;
459#endif
460
461
472template <typename T1, typename T2>
477 return unwrap_pair(_NEFORCE forward<T1>(x), _NEFORCE forward<T2>(y));
478}
479 // Pair
481
487
493template <typename... Types>
494struct tuple_size<tuple<Types...>> : integral_constant<size_t, sizeof...(Types)> {};
495
501template <size_t Index>
502struct tuple_element<Index, tuple<>> {};
503
509template <typename This, typename... Rest>
510struct tuple_element<0, tuple<This, Rest...>> {
511 using type = This;
512 using tuple_type = tuple<This, Rest...>;
513};
514
521template <size_t Index, typename This, typename... Rest>
522struct tuple_element<Index, tuple<This, Rest...>> : tuple_element<Index - 1, tuple<Rest...>> {};
523
530template <size_t Index, typename... Types>
531struct tuple_element : tuple_element<Index, tuple<Types...>> {};
532
533
539template <typename T1, typename T2>
540struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> {};
541
548template <size_t Index, typename T1, typename T2>
549struct tuple_element<Index, pair<T1, T2>> {
550 static_assert(Index < 2, "pair element index out of range.");
551
553 using tuple_type = tuple<T1, T2>;
554};
555 // Tuple
557
563
564#ifndef NEFORCE_STANDARD_17
566NEFORCE_BEGIN_INNER__
567
568template <size_t Index, typename T1, typename T2>
569struct __pair_get_helper;
570template <typename T1, typename T2>
571struct __pair_get_helper<0, T1, T2> {
572 NEFORCE_NODISCARD constexpr static tuple_element_t<0, pair<T1, T2>>& get(pair<T1, T2>& pir) noexcept {
573 return pir.first;
574 }
575 NEFORCE_NODISCARD constexpr static const tuple_element_t<0, pair<T1, T2>>& get(const pair<T1, T2>& pir) noexcept {
576 return pir.first;
577 }
578 NEFORCE_NODISCARD constexpr static tuple_element_t<0, pair<T1, T2>>&& get(pair<T1, T2>&& pir) noexcept {
579 return _NEFORCE forward<T1>(pir.first);
580 }
581 NEFORCE_NODISCARD constexpr static const tuple_element_t<0, pair<T1, T2>>&& get(const pair<T1, T2>&& pir) noexcept {
582 return _NEFORCE forward<const T1>(pir.first);
583 }
584};
585
586template <typename T1, typename T2>
587struct __pair_get_helper<1, T1, T2> {
588 NEFORCE_NODISCARD constexpr static tuple_element_t<1, pair<T1, T2>>& get(pair<T1, T2>& pir) noexcept {
589 return pir.second;
590 }
591 NEFORCE_NODISCARD constexpr static const tuple_element_t<1, pair<T1, T2>>& get(const pair<T1, T2>& pir) noexcept {
592 return pir.second;
593 }
594 NEFORCE_NODISCARD constexpr static tuple_element_t<1, pair<T1, T2>>&& get(pair<T1, T2>&& pir) noexcept {
595 return _NEFORCE forward<T2>(pir.second);
596 }
597 NEFORCE_NODISCARD constexpr static const tuple_element_t<1, pair<T1, T2>>&& get(const pair<T1, T2>&& pir) noexcept {
598 return _NEFORCE forward<const T2>(pir.second);
599 }
600};
601
602NEFORCE_END_INNER__
604#endif // !NEFORCE_STANDARD_17
605
609template <size_t Index, typename T1, typename T2>
610NEFORCE_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>& get(pair<T1, T2>& pir) noexcept;
611
612#ifdef NEFORCE_STANDARD_17
613template <size_t Index, typename T1, typename T2>
614NEFORCE_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>& get(pair<T1, T2>& pir) noexcept {
615 if constexpr (Index == 0) {
616 return pir.first;
617 } else {
618 return pir.second;
619 }
620}
621#else
622template <size_t Index, typename T1, typename T2>
623NEFORCE_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>& get(pair<T1, T2>& pir) noexcept {
624 return inner::__pair_get_helper<Index, T1, T2>::get(pir);
625}
626#endif // NEFORCE_STANDARD_17
627
631template <typename T1, typename T2>
632NEFORCE_NODISCARD constexpr T1& get(pair<T1, T2>& pir) noexcept {
633 return pir.first;
634}
635
639template <typename T2, typename T1>
640NEFORCE_NODISCARD constexpr T2& get(pair<T1, T2>& pir) noexcept {
641 return pir.second;
642}
643
644
648template <size_t Index, typename T1, typename T2>
649NEFORCE_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>& get(const pair<T1, T2>& pir) noexcept;
650
651#ifdef NEFORCE_STANDARD_17
652template <size_t Index, typename T1, typename T2>
653NEFORCE_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>& get(const pair<T1, T2>& pir) noexcept {
654 if constexpr (Index == 0) {
655 return pir.first;
656 } else {
657 return pir.second;
658 }
659}
660#else
661template <size_t Index, typename T1, typename T2>
662NEFORCE_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>& get(const pair<T1, T2>& pir) noexcept {
663 return inner::__pair_get_helper<Index, T1, T2>::get(pir);
664}
665#endif // NEFORCE_STANDARD_17
666
670template <typename T1, typename T2>
671NEFORCE_NODISCARD constexpr const T1& get(const pair<T1, T2>& pir) noexcept {
672 return pir.first;
673}
674
678template <typename T2, typename T1>
679NEFORCE_NODISCARD constexpr const T2& get(const pair<T1, T2>& pir) noexcept {
680 return pir.second;
681}
682
683
687template <size_t Index, typename T1, typename T2>
688NEFORCE_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&& get(pair<T1, T2>&& pir) noexcept;
689
690#ifdef NEFORCE_STANDARD_17
691template <size_t Index, typename T1, typename T2>
692NEFORCE_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&& get(pair<T1, T2>&& pir) noexcept {
693 if constexpr (Index == 0) {
694 return _NEFORCE forward<T1>(pir.first);
695 } else {
696 return _NEFORCE forward<T2>(pir.second);
697 }
698}
699#else
700template <size_t Index, typename T1, typename T2>
701NEFORCE_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&& get(pair<T1, T2>&& pir) noexcept {
703 inner::__pair_get_helper<Index, T1, T2>::get(_NEFORCE forward<pair<T1, T2>>(pir)));
704}
705#endif // NEFORCE_STANDARD_17
706
710template <typename T1, typename T2>
711NEFORCE_NODISCARD constexpr T1&& get(pair<T1, T2>&& pir) noexcept {
712 return _NEFORCE forward<T1>(pir.first);
713}
714
718template <typename T2, typename T1>
719NEFORCE_NODISCARD constexpr T2&& get(pair<T1, T2>&& pir) noexcept {
720 return _NEFORCE forward<T2>(pir.second);
721}
722
723
727template <size_t Index, typename T1, typename T2>
728NEFORCE_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&& get(const pair<T1, T2>&& pir) noexcept;
729
730#ifdef NEFORCE_STANDARD_17
731template <size_t Index, typename T1, typename T2>
732NEFORCE_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&& get(const pair<T1, T2>&& pir) noexcept {
733 if constexpr (Index == 0) {
734 return _NEFORCE forward<const T1>(pir.first);
735 } else {
736 return _NEFORCE forward<const T2>(pir.second);
737 }
738}
739#else
740template <size_t Index, typename T1, typename T2>
741NEFORCE_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&& get(const pair<T1, T2>&& pir) noexcept {
743 inner::__pair_get_helper<Index, T1, T2>::get(_NEFORCE forward<const pair<T1, T2>>(pir)));
744}
745#endif // NEFORCE_STANDARD_17
746
750template <typename T1, typename T2>
751NEFORCE_NODISCARD constexpr const T1&& get(const pair<T1, T2>&& pir) noexcept {
752 return _NEFORCE forward<const T1>(pir.first);
753}
754
758template <typename T2, typename T1>
759NEFORCE_NODISCARD constexpr const T2&& get(const pair<T1, T2>&& pir) noexcept {
760 return _NEFORCE forward<const T2>(pir.second);
761}
762 // Pair
764
765NEFORCE_END_NAMESPACE__
766
767#ifdef NEFORCE_STANDARD_17
768# include <utility>
769namespace std {
770 template <typename T1, typename T2>
771 struct tuple_size<_NEFORCE pair<T1, T2>> : _NEFORCE integral_constant<_NEFORCE size_t, 2> {};
772
773 template <_NEFORCE size_t I, typename T1, typename T2>
774 struct tuple_element<I, _NEFORCE pair<T1, T2>> {
775 using type = _NEFORCE tuple_element_t<I, _NEFORCE pair<T1, T2>>;
776 };
777} // namespace std
778#endif
779
780#endif // NEFORCE_CORE_UTILITY_PAIR_HPP__
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的便捷别名
基本接口基类
整数序列工具
引用包装器
类型集合的逻辑与操作
哈希函数的主模板
通用接口,同时具备可比较和可哈希功能
整数常量包装器
判断类型是否可以使用指定类型的值进行赋值
判断类型是否可以使用指定参数构造
判断类型From是否可以隐式转换为类型To
判断类型是否可复制构造
判断类型是否可默认构造
判断类型是否可隐式默认构造
判断类型是否可以使用指定类型的值进行无异常赋值
判断类型是否可以使用指定参数无异常构造
判断类型是否可无异常复制赋值
判断类型是否可无异常复制构造
判断类型是否可无异常默认构造
判断类型是否可无异常移动赋值
判断类型是否可以与自身无异常交换
存储两个值的元组对
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类型
获取tuple元素类型的特化
获取tuple大小的特化
解包工具构造标签