MSTL 1.4.0
A Modern C++ Library with extended functionality, web components, and utility libraries
载入中...
搜索中...
未找到
pair.hpp
浏览该文件的文档.
1#ifndef MSTL_CORE_UTILITY_PAIR_HPP__
2#define MSTL_CORE_UTILITY_PAIR_HPP__
3
10
15
16template <typename...>
17struct tuple;
18
19template <typename>
21
22#ifdef MSTL_STANDARD_14__
30template <typename T>
31constexpr size_t tuple_size_v = tuple_size<remove_cvref_t<T>>::value;
32#endif
33
34
35template <size_t Index, typename... Tuple>
36struct tuple_element;
37
45template <size_t Index, typename... Types>
46using tuple_element_t = typename tuple_element<Index, Types...>::type;
47
53template <size_t Index, typename... Types>
54using tuple_extract_base_t = typename tuple_element<Index, Types...>::tuple_type;
55
56template <size_t Index, typename... Types>
57MSTL_NODISCARD constexpr tuple_element_t<Index, Types...>& get(tuple<Types...>& t) noexcept;
58template <size_t Index, typename... Types>
59MSTL_NODISCARD constexpr const tuple_element_t<Index, Types...>& get(const tuple<Types...>& t) noexcept;
60template <size_t Index, typename... Types>
61MSTL_NODISCARD constexpr tuple_element_t<Index, Types...>&& get(tuple<Types...>&& t) noexcept;
62template <size_t Index, typename... Types>
63MSTL_NODISCARD constexpr const tuple_element_t<Index, Types...>&& get(const tuple<Types...>&& t) noexcept;
64
67template <size_t Index, typename... Types>
68MSTL_NODISCARD constexpr tuple_element_t<Index, Types...>&&
69__pair_get_from_tuple(tuple<Types...>&& t) noexcept;
72
73
79
89template <typename T1, typename T2>
90struct pair : icommon<pair<T1, T2>> {
91 using first_type = T1;
92 using second_type = T2;
93
94 T1 first;
95 T2 second;
96
97#ifdef MSTL_STANDARD_20__
105 template <typename U1 = T1, typename U2 = T2, enable_if_t<
106 conjunction_v<is_default_constructible<U1>, is_default_constructible<U2>>, int> = 0>
107 constexpr explicit(!conjunction_v<
109 pair() noexcept(conjunction_v<
111 : first(), second() {}
112
122 template <typename U1 = T1, typename U2 = T2, enable_if_t<
123 conjunction_v<is_copy_constructible<U1>, is_copy_constructible<U2>>, int> = 0>
124 constexpr explicit(!conjunction_v<is_convertible<const U1&, U1>, is_convertible<const U2&, U2>>)
125 pair(const T1& a, const T2& b) noexcept(conjunction_v<
127 : first(a), second(b) {}
128
138 template <typename U1, typename U2, enable_if_t<
139 conjunction_v<is_constructible<T1, U1>, is_constructible<T2, U2>>, int> = 0>
140 constexpr explicit(!conjunction_v<is_convertible<U1, T1>, is_convertible<U2, T2>>)
141 pair(U1&& a, U2&& b) noexcept(conjunction_v<
142 is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>)
143 : first(_MSTL forward<U1>(a)), second(_MSTL forward<U2>(b)) {}
144
153 template <typename U1, typename U2, enable_if_t<
154 conjunction_v<is_constructible<T1, const U1&>, is_constructible<T2, const U2&>>, int> = 0>
155 constexpr explicit(!conjunction_v<is_convertible<const U1&, T1>, is_convertible<const U2&, T2>>)
156 pair(const pair<U1, U2>& p) noexcept(conjunction_v<
157 is_nothrow_constructible<T1, const U1&>, is_nothrow_constructible<T2, const U2&>>)
158 : first(p.first), second(p.second) {}
159
168 template <typename U1, typename U2, enable_if_t<
169 conjunction_v<is_constructible<T1, U1>, is_constructible<T2, U2>>, int> = 0>
170 constexpr explicit(!conjunction_v<
171 is_convertible<U1, T1>, is_convertible<U2, T2>>)
172 pair(pair<U1, U2>&& p) noexcept(conjunction_v<
173 is_nothrow_constructible<T1, U1>, is_nothrow_constructible<T2, U2>>)
174 : first(_MSTL forward<U1>(p.first)), second(_MSTL forward<U2>(p.second)) {}
175#else
179 template <typename U1 = T1, typename U2 = T2, enable_if_t<
180 conjunction<is_default_constructible<U1>, is_default_constructible<U2>>::value &&
181 !conjunction<is_implicitly_default_constructible<U1>,
182 is_implicitly_default_constructible<U2>>::value, int> = 0>
183 explicit pair() noexcept(conjunction<
185 : first(), second() {}
186
189 template <typename U1 = T1, typename U2 = T2, enable_if_t<
196
200 template <typename U1 = T1, typename U2 = T2, enable_if_t<
203 explicit pair(const T1& a, const T2& b) noexcept(conjunction<
205 : first(a), second(b) {}
206
210 template <typename U1 = T1, typename U2 = T2, enable_if_t<
213 pair(const T1& a, const T2& b) noexcept(conjunction<
215 : first(a), second(b) {}
216
220 template <typename U1, typename U2, enable_if_t<
223 explicit pair(U1&& a, U2&& b) noexcept(conjunction<
225 : first(_MSTL forward<U1>(a)), second(_MSTL forward<U2>(b)) {}
226
230 template <typename U1, typename U2, enable_if_t<
236
240 template <typename U1, typename U2, enable_if_t<
246
250 template <typename U1, typename U2, enable_if_t<
256
260 template <typename U1, typename U2, enable_if_t<
266
270 template <typename U1, typename U2, enable_if_t<
276#endif
277
278 pair(const pair& p) = default;
279 pair(pair&& p) = default;
280
294 template <typename Tuple1, typename Tuple2, size_t... Index1, size_t... Index2>
295 constexpr pair(Tuple1& t1, Tuple2& t2, index_sequence<Index1...> idx1, index_sequence<Index2...> idx2)
296 : first(_INNER __pair_get_from_tuple<Index1>(_MSTL move(t1))...),
297 second(_INNER __pair_get_from_tuple<Index2>(_MSTL move(t2))...) {}
298
308 template <typename... Types1, typename... Types2>
309 constexpr pair(unpack_utility_construct_tag, tuple<Types1...> t1, tuple<Types2...> t2)
310 : pair(t1, t2, index_sequence_for<Types1...>{}, index_sequence_for<Types2...>{}) {}
311
318 template <typename T = pair, enable_if_t<conjunction<
319 is_copy_assignable<typename T::first_type>, is_copy_assignable<typename T::second_type>>::value, int> = 0>
322 first = p.first;
323 second = p.second;
324 return *this;
325 }
326
333 template <typename T = pair, enable_if_t<conjunction<
335 MSTL_CONSTEXPR14 pair& operator =(type_identity_t<T&&> p) noexcept(conjunction<
337 first = _MSTL forward<T1>(p.first);
338 second = _MSTL forward<T2>(p.second);
339 return *this;
340 }
341
349 template <typename U1, typename U2, enable_if_t<conjunction<negation<
351 MSTL_CONSTEXPR14 pair& operator =(const pair<U1, U2>& p) noexcept(conjunction<
353 first = p.first;
354 second = p.second;
355 return *this;
356 }
357
365 template <typename U1, typename U2, enable_if_t<conjunction<negation<
367 MSTL_CONSTEXPR14 pair& operator =(pair<U1, U2>&& p) noexcept(conjunction<
369 first = _MSTL forward<U1>(p.first);
370 second = _MSTL forward<U2>(p.second);
371 return *this;
372 }
373
374 pair& operator =(const volatile pair&) = delete;
375
376 MSTL_CONSTEXPR20 ~pair() = default;
377
385 constexpr bool operator ==(const pair& y) const
386 noexcept(noexcept(this->first == y.first && this->second == y.second)) {
387 return this->first == y.first && this->second == y.second;
388 }
389
397 constexpr bool operator <(const pair& y) const
398 noexcept(noexcept(this->first < y.first || (!(y.first < this->first) && this->second < y.second))) {
399 return this->first < y.first || (!(y.first < this->first) && this->second < y.second);
400 }
401
408 MSTL_NODISCARD constexpr size_t to_hash() const
409 noexcept(noexcept(hash<remove_cvref_t<T1>>()(first) ^ hash<remove_cvref_t<T2>>()(second))) {
411 }
412
417 MSTL_CONSTEXPR14 void swap(pair& p)
419 _MSTL swap(first, p.first);
420 _MSTL swap(second, p.second);
421 }
422};
423
424#if MSTL_SUPPORT_DEDUCTION_GUIDES__
425template <typename T1, typename T2>
426pair(T1, T2) -> pair<T1, T2>;
427#endif
428
429
440template <typename T1, typename T2>
447 // Pair
449
455
461template <typename... Types>
462struct tuple_size<tuple<Types...>> : integral_constant<size_t, sizeof...(Types)> {};
463
469template <size_t Index>
470struct tuple_element<Index, tuple<>> {};
471
477template <typename This, typename... Rest>
478struct tuple_element<0, tuple<This, Rest...>> {
479 using type = This;
480 using tuple_type = tuple<This, Rest...>;
481};
482
489template <size_t Index, typename This, typename... Rest>
490struct tuple_element<Index, tuple<This, Rest...>>
491 : tuple_element<Index - 1, tuple<Rest...>> {};
492
499template <size_t Index, typename... Types>
500struct tuple_element : tuple_element<Index, tuple<Types...>> {};
501
502
508template <typename T1, typename T2>
509struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> {};
510
517template <size_t Index, typename T1, typename T2>
518struct tuple_element<Index, pair<T1, T2>> {
519 static_assert(Index < 2, "pair element index out of range.");
520
522 using tuple_type = tuple<T1, T2>;
523};
524
525
526#ifndef MSTL_STANDARD_17__
529
530template <size_t Index, typename T1, typename T2>
531struct __pair_get_helper;
532template <typename T1, typename T2>
533struct __pair_get_helper<0, T1, T2> {
534 MSTL_NODISCARD constexpr static tuple_element_t<0, pair<T1, T2>>&
535 get(pair<T1, T2>& pir) noexcept {
536 return pir.first;
537 }
538 MSTL_NODISCARD constexpr static const tuple_element_t<0, pair<T1, T2>>&
539 get(const pair<T1, T2>& pir) noexcept {
540 return pir.first;
541 }
542 MSTL_NODISCARD constexpr static tuple_element_t<0, pair<T1, T2>>&&
543 get(pair<T1, T2>&& pir) noexcept {
544 return _MSTL forward<T1>(pir.first);
545 }
546 MSTL_NODISCARD constexpr static const tuple_element_t<0, pair<T1, T2>>&&
547 get(const pair<T1, T2>&& pir) noexcept {
548 return _MSTL forward<const T1>(pir.first);
549 }
550};
551
552template <typename T1, typename T2>
553struct __pair_get_helper<1, T1, T2> {
554 MSTL_NODISCARD constexpr static tuple_element_t<1, pair<T1, T2>>&
555 get(pair<T1, T2>& pir) noexcept {
556 return pir.second;
557 }
558 MSTL_NODISCARD constexpr static const tuple_element_t<1, pair<T1, T2>>&
559 get(const pair<T1, T2>& pir) noexcept {
560 return pir.second;
561 }
562 MSTL_NODISCARD constexpr static tuple_element_t<1, pair<T1, T2>>&&
563 get(pair<T1, T2>&& pir) noexcept {
564 return _MSTL forward<T2>(pir.second);
565 }
566 MSTL_NODISCARD constexpr static const tuple_element_t<1, pair<T1, T2>>&&
567 get(const pair<T1, T2>&& pir) noexcept {
568 return _MSTL forward<const T2>(pir.second);
569 }
570};
571
574#endif // !MSTL_STANDARD_17__
575
579template <size_t Index, typename T1, typename T2>
580MSTL_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&
581get(pair<T1, T2>& pir) noexcept;
582
583#ifdef MSTL_STANDARD_17__
584template <size_t Index, typename T1, typename T2>
585MSTL_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&
586get(pair<T1, T2>& pir) noexcept {
587 if constexpr (Index == 0) {
588 return pir.first;
589 } else {
590 return pir.second;
591 }
592}
593#else
594template <size_t Index, typename T1, typename T2>
595MSTL_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&
596get(pair<T1, T2>& pir) noexcept {
597 return _INNER __pair_get_helper<Index, T1, T2>::get(pir);
598}
599#endif // MSTL_STANDARD_17__
600
604template <typename T1, typename T2>
605MSTL_NODISCARD constexpr T1& get(pair<T1, T2>& pir) noexcept {
606 return pir.first;
607}
608
612template <typename T2, typename T1>
613MSTL_NODISCARD constexpr T2& get(pair<T1, T2>& pir) noexcept {
614 return pir.second;
615}
616
617
621template <size_t Index, typename T1, typename T2>
622MSTL_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&
623get(const pair<T1, T2>& pir) noexcept;
624
625#ifdef MSTL_STANDARD_17__
626template <size_t Index, typename T1, typename T2>
627MSTL_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&
628get(const pair<T1, T2>& pir) noexcept {
629 if constexpr (Index == 0)
630 return pir.first;
631 else
632 return pir.second;
633}
634#else
635template <size_t Index, typename T1, typename T2>
636MSTL_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&
637get(const pair<T1, T2>& pir) noexcept {
638 return _INNER __pair_get_helper<Index, T1, T2>::get(pir);
639}
640#endif // MSTL_STANDARD_17__
641
645template <typename T1, typename T2>
646MSTL_NODISCARD constexpr const T1& get(const pair<T1, T2>& pir) noexcept {
647 return pir.first;
648}
649
653template <typename T2, typename T1>
654MSTL_NODISCARD constexpr const T2& get(const pair<T1, T2>& pir) noexcept {
655 return pir.second;
656}
657
658
662template <size_t Index, typename T1, typename T2>
663MSTL_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&&
664get(pair<T1, T2>&& pir) noexcept;
665
666#ifdef MSTL_STANDARD_17__
667template <size_t Index, typename T1, typename T2>
668MSTL_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&&
669get(pair<T1, T2>&& pir) noexcept {
670 if constexpr (Index == 0)
671 return _MSTL forward<T1>(pir.first);
672 else
673 return _MSTL forward<T2>(pir.second);
674}
675#else
676template <size_t Index, typename T1, typename T2>
677MSTL_NODISCARD constexpr tuple_element_t<Index, pair<T1, T2>>&&
678get(pair<T1, T2>&& pir) noexcept {
680 _INNER __pair_get_helper<Index, T1, T2>::get(_MSTL forward<pair<T1, T2>>(pir)));
681}
682#endif // MSTL_STANDARD_17__
683
687template <typename T1, typename T2>
688MSTL_NODISCARD constexpr T1&& get(pair<T1, T2>&& pir) noexcept {
689 return _MSTL forward<T1>(pir.first);
690}
691
695template <typename T2, typename T1>
696MSTL_NODISCARD constexpr T2&& get(pair<T1, T2>&& pir) noexcept {
697 return _MSTL forward<T2>(pir.second);
698}
699
700
704template <size_t Index, typename T1, typename T2>
705MSTL_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&&
706get(const pair<T1, T2>&& pir) noexcept;
707
708#ifdef MSTL_STANDARD_17__
709template <size_t Index, typename T1, typename T2>
710MSTL_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&&
711get(const pair<T1, T2>&& pir) noexcept {
712 if constexpr (Index == 0)
713 return _MSTL forward<const T1>(pir.first);
714 else
715 return _MSTL forward<const T2>(pir.second);
716}
717#else
718template <size_t Index, typename T1, typename T2>
719MSTL_NODISCARD constexpr const tuple_element_t<Index, pair<T1, T2>>&&
720get(const pair<T1, T2>&& pir) noexcept {
722 _INNER __pair_get_helper<Index, T1, T2>::get(_MSTL forward<const pair<T1, T2>>(pir)));
723}
724#endif // MSTL_STANDARD_17__
725
729template <typename T1, typename T2>
730MSTL_NODISCARD constexpr const T1&& get(const pair<T1, T2>&& pir) noexcept {
731 return _MSTL forward<const T1>(pir.first);
732}
733
737template <typename T2, typename T1>
738MSTL_NODISCARD constexpr const T2&& get(const pair<T1, T2>&& pir) noexcept {
739 return _MSTL forward<const T2>(pir.second);
740}
741 // PairUtilities
743
745
748namespace std {
749 template <typename T>
750 struct tuple_size;
751
752 template <_MSTL size_t I, typename T>
753 struct tuple_element;
754
755 template <typename T1, typename T2>
756 struct tuple_size<_MSTL pair<T1, T2>> : _MSTL integral_constant<_MSTL size_t, 2> {};
757
758 template <_MSTL size_t I, typename T1, typename T2>
759 struct tuple_element<I, _MSTL pair<T1, T2>> {
761 };
762}
764
765#endif // MSTL_CORE_UTILITY_PAIR_HPP__
MSTL_NODISCARD constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
MSTL_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
根据类型参数包生成索引序列
#define _MSTL
全局命名空间MSTL前缀
#define MSTL_END_INNER__
结束inner命名空间
#define _INNER
inner命名空间前缀
#define MSTL_END_NAMESPACE__
结束全局命名空间MSTL
#define MSTL_BEGIN_NAMESPACE__
开始全局命名空间MSTL
#define MSTL_BEGIN_INNER__
开始inner命名空间
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)
移动范围元素
void swap()=delete
删除无参数的swap重载
MSTL_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的便捷别名
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
基本接口基类
MSTL整数序列工具
typename tuple_element< Index, Types... >::tuple_type tuple_extract_base_t
获取tuple元素基类型的类型别名
typename tuple_element< Index, Types... >::type tuple_element_t
tuple_element的类型别名
MSTL引用包装器
类型集合的逻辑与操作
哈希函数的主模板
通用接口,同时具备可比较和可哈希功能
整数常量包装器
判断类型是否可以使用指定类型的值进行赋值
判断类型是否可以使用指定参数构造
判断类型From是否可以隐式转换为类型To
判断类型是否可复制构造
判断类型是否可默认构造
判断类型是否可隐式默认构造
判断类型是否可移动赋值
判断类型是否可以使用指定类型的值进行无异常赋值
判断类型是否可以使用指定参数无异常构造
判断类型是否可无异常复制赋值
判断类型是否可无异常复制构造
判断类型是否可无异常默认构造
判断类型是否可无异常移动赋值
判断类型是否可以与自身无异常交换
判断两个类型是否相同
逻辑非包装器
存储两个值的元组对
pair() noexcept(conjunction< is_nothrow_default_constructible< U1 >, is_nothrow_default_constructible< U2 > >::value)
显式默认构造函数
constexpr pair(Tuple1 &t1, Tuple2 &t2, index_sequence< Index1... > idx1, index_sequence< Index2... > idx2)
从两个tuple构造pair
pair(pair< U1, U2 > &&p) noexcept(conjunction< is_nothrow_constructible< T1, U1 >, is_nothrow_constructible< T2, U2 > >::value)
显式移动pair构造函数
MSTL_CONSTEXPR14 void swap(pair &p) noexcept(conjunction< is_nothrow_swappable< T1 >, is_nothrow_swappable< T2 > >::value)
交换两个pair的内容
constexpr bool operator<(const pair &y) const noexcept(noexcept(this->first< y.first||(!(y.first< this->first) &&this->second< y.second)))
小于比较运算符
pair(const pair< U1, U2 > &p) noexcept(conjunction< is_nothrow_constructible< T1, const U1 & >, is_nothrow_constructible< T2, const U2 & > >::value)
显式拷贝pair构造函数
pair(const pair &p)=default
默认拷贝构造函数
MSTL_CONSTEXPR20 ~pair()=default
析构函数
constexpr pair(unpack_utility_construct_tag, tuple< Types1... > t1, tuple< Types2... > t2)
从两个tuple构造pair
pair(const T1 &a, const T2 &b) noexcept(conjunction< is_nothrow_copy_constructible< U1 >, is_nothrow_copy_constructible< U2 > >::value)
显式拷贝构造函数
MSTL_CONSTEXPR14 pair & operator=(type_identity_t< const T & > p) noexcept(conjunction< is_nothrow_copy_assignable< T1 >, is_nothrow_copy_assignable< T2 > >::value)
拷贝赋值运算符
MSTL_NODISCARD constexpr size_t to_hash() const noexcept(noexcept(hash< remove_cvref_t< T1 > >()(first) ^ hash< remove_cvref_t< T2 > >()(second)))
计算hash值
constexpr bool operator==(const pair &y) const noexcept(noexcept(this->first==y.first &&this->second==y.second))
相等比较运算符
pair(pair &&p)=default
默认移动构造函数
pair(U1 &&a, U2 &&b) noexcept(conjunction< is_nothrow_constructible< T1, U1 >, is_nothrow_constructible< T2, U2 > >::value)
显式通用值构造函数
conditional_t< Index==0, T1, T2 > type
根据索引返回对应类型
tuple< T1, T2 > tuple_type
对应的tuple类型
获取tuple元素类型的特化
获取tuple大小的特化
解包工具构造标签