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,
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,
203 pair() noexcept(conjunction<is_nothrow_default_constructible<U1>, is_nothrow_default_constructible<U2>>::value) :
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,
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,
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,
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,
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,
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)) {}
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,
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)) {}
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,
262 explicit pair(
const pair<U1, U2>& p)
noexcept(
263 conjunction<is_nothrow_constructible<T1, const U1&>, is_nothrow_constructible<T2, const U2&>>::value) :
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,
274 pair(
const pair<U1, U2>& p)
noexcept(
275 conjunction<is_nothrow_constructible<T1, const U1&>, is_nothrow_constructible<T2, const U2&>>::value) :
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,
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)) {}
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,
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)) {}
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);
446 NEFORCE_CONSTEXPR14
void
453#ifdef NEFORCE_STANDARD_17
454template <
typename T1,
typename T2>
455pair(T1, T2) -> pair<T1, T2>;
469template <
typename T1,
typename T2>
470constexpr pair<unwrap_ref_decay_t<T1>, unwrap_ref_decay_t<T2>>
490template <
typename... Types>
491struct tuple_size<tuple<Types...>> : integral_constant<size_t, sizeof...(Types)> {};
493#define __NEFORCE_BUILD_TUPLE_TUPLE_SIZE(CV) \
494 template <typename... Types> \
495 struct tuple_size<tuple<Types...> CV> : integral_constant<size_t, sizeof...(Types)> {};
497#undef __NEFORCE_BUILD_TUPLE_TUPLE_SIZE
505template <
size_t Index>
513template <
typename This,
typename... Rest>
516 using tuple_type = tuple<This, Rest...>;
525template <
size_t Index,
typename This,
typename... Rest>
534template <
size_t Index,
typename... Types>
543template <
typename T1,
typename T2>
546#define __NEFORCE_BUILD_PAIR_TUPLE_SIZE(CV) \
547 template <typename T1, typename T2> \
548 struct tuple_size<pair<T1, T2> CV> : integral_constant<size_t, 2> {};
550#undef __NEFORCE_BUILD_PAIR_TUPLE_SIZE
558template <
size_t Index,
typename T1,
typename T2>
560 static_assert(Index < 2,
"pair element index out of range.");
563 using tuple_type = tuple<T1, T2>;
574#ifndef NEFORCE_STANDARD_17
578template <
size_t Index,
typename T1,
typename T2>
579struct __pair_get_helper;
580template <
typename T1,
typename T2>
581struct __pair_get_helper<0, T1, T2> {
582 NEFORCE_NODISCARD
constexpr static tuple_element_t<0, pair<T1, T2>>& get(pair<T1, T2>& pir)
noexcept {
585 NEFORCE_NODISCARD
constexpr static const tuple_element_t<0, pair<T1, T2>>&
get(
const pair<T1, T2>& pir)
noexcept {
588 NEFORCE_NODISCARD
constexpr static tuple_element_t<0, pair<T1, T2>>&&
get(pair<T1, T2>&& pir)
noexcept {
589 return _NEFORCE forward<T1>(pir.first);
591 NEFORCE_NODISCARD
constexpr static const tuple_element_t<0, pair<T1, T2>>&&
get(
const pair<T1, T2>&& pir)
noexcept {
592 return _NEFORCE forward<const T1>(pir.first);
596template <
typename T1,
typename T2>
597struct __pair_get_helper<1, T1, T2> {
598 NEFORCE_NODISCARD
constexpr static tuple_element_t<1, pair<T1, T2>>&
get(pair<T1, T2>& pir)
noexcept {
601 NEFORCE_NODISCARD
constexpr static const tuple_element_t<1, pair<T1, T2>>&
get(
const pair<T1, T2>& pir)
noexcept {
604 NEFORCE_NODISCARD
constexpr static tuple_element_t<1, pair<T1, T2>>&&
get(pair<T1, T2>&& pir)
noexcept {
605 return _NEFORCE forward<T2>(pir.second);
607 NEFORCE_NODISCARD
constexpr static const tuple_element_t<1, pair<T1, T2>>&&
get(
const pair<T1, T2>&& pir)
noexcept {
608 return _NEFORCE forward<const T2>(pir.second);
619template <
size_t Index,
typename T1,
typename T2>
620NEFORCE_NODISCARD
constexpr tuple_element_t<Index, pair<T1, T2>>&
get(pair<T1, T2>& pir)
noexcept;
622#ifdef NEFORCE_STANDARD_17
623template <
size_t Index,
typename T1,
typename T2>
625 if constexpr (Index == 0) {
632template <
size_t Index,
typename T1,
typename T2>
633NEFORCE_NODISCARD
constexpr tuple_element_t<Index, pair<T1, T2>>& get(pair<T1, T2>& pir)
noexcept {
634 return inner::__pair_get_helper<Index, T1, T2>::get(pir);
641template <
typename T1,
typename T2>
649template <
typename T2,
typename T1>
658template <
size_t Index,
typename T1,
typename T2>
659NEFORCE_NODISCARD
constexpr const tuple_element_t<Index, pair<T1, T2>>& get(
const pair<T1, T2>& pir)
noexcept;
661#ifdef NEFORCE_STANDARD_17
662template <
size_t Index,
typename T1,
typename T2>
664 if constexpr (Index == 0) {
671template <
size_t Index,
typename T1,
typename T2>
672NEFORCE_NODISCARD
constexpr const tuple_element_t<Index, pair<T1, T2>>& get(
const pair<T1, T2>& pir)
noexcept {
673 return inner::__pair_get_helper<Index, T1, T2>::get(pir);
680template <
typename T1,
typename T2>
688template <
typename T2,
typename T1>
697template <
size_t Index,
typename T1,
typename T2>
698NEFORCE_NODISCARD
constexpr tuple_element_t<Index, pair<T1, T2>>&& get(pair<T1, T2>&& pir)
noexcept;
700#ifdef NEFORCE_STANDARD_17
701template <
size_t Index,
typename T1,
typename T2>
703 if constexpr (Index == 0) {
710template <
size_t Index,
typename T1,
typename T2>
711NEFORCE_NODISCARD
constexpr tuple_element_t<Index, pair<T1, T2>>&& get(pair<T1, T2>&& pir)
noexcept {
712 return _NEFORCE forward<tuple_element_t<Index, pair<T1, T2>>>(
713 inner::__pair_get_helper<Index, T1, T2>::get(_NEFORCE forward<pair<T1, T2>>(pir)));
720template <
typename T1,
typename T2>
728template <
typename T2,
typename T1>
737template <
size_t Index,
typename T1,
typename T2>
738NEFORCE_NODISCARD
constexpr const tuple_element_t<Index, pair<T1, T2>>&& get(
const pair<T1, T2>&& pir)
noexcept;
740#ifdef NEFORCE_STANDARD_17
741template <
size_t Index,
typename T1,
typename T2>
743 if constexpr (Index == 0) {
750template <
size_t Index,
typename T1,
typename T2>
751NEFORCE_NODISCARD
constexpr const tuple_element_t<Index, pair<T1, T2>>&& get(
const pair<T1, T2>&& pir)
noexcept {
752 return _NEFORCE forward<const tuple_element_t<Index, pair<T1, T2>>>(
753 inner::__pair_get_helper<Index, T1, T2>::get(_NEFORCE forward<
const pair<T1, T2>>(pir)));
760template <
typename T1,
typename T2>
768template <
typename T2,
typename T1>
775NEFORCE_END_NAMESPACE__
777#ifdef NEFORCE_STANDARD_17
780 template <
typename T1,
typename T2>
781 struct tuple_size<_NEFORCE pair<T1, T2>> : _NEFORCE integral_constant<_NEFORCE size_t, 2> {};
783 template <_NEFORCE
size_t I,
typename T1,
typename T2>
784 struct tuple_element<I, _NEFORCE pair<T1, T2>> {
785 using type = _NEFORCE tuple_element_t<I, _NEFORCE pair<T1, T2>>;
constexpr T && forward(remove_reference_t< T > &x) noexcept
完美转发左值
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的便捷别名
constexpr Iterator2 move(Iterator1 first, Iterator1 last, Iterator2 result) noexcept(noexcept(inner::__move_aux(first, last, result)))
移动范围元素
typename tuple_element< Index, Types... >::type tuple_element_t
tuple_element的类型别名
constexpr size_t tuple_size_v
tuple_size的类型别名
typename tuple_element< Index, Types... >::tuple_type tuple_extract_base_t
获取tuple元素基类型的类型别名
#define NEFORCE_MACRO_RANGES_CV(MAC)
cv限定符列表宏
constexpr bool conjunction_v
conjunction的便捷变量模板
typename enable_if< Test, T >::type enable_if_t
enable_if的便捷别名
typename conditional< Test, T1, T2 >::type conditional_t
conditional的便捷别名
typename type_identity< T >::type type_identity_t
type_identity的便捷别名
constexpr size_t hash_combine_all(const Types &... values) noexcept
混合多个哈希值
pair(const pair &p)=default
默认拷贝构造函数
constexpr void swap(pair &p) noexcept(conjunction< is_nothrow_swappable< T1 >, is_nothrow_swappable< T2 > >::value)
交换两个pair的内容
constexpr ~pair()=default
析构函数
constexpr size_t to_hash() const noexcept
计算hash值
pair(pair &&p)=default
默认移动构造函数
constexpr pair & operator=(type_identity_t< T && > p) noexcept(conjunction< is_nothrow_move_assignable< T1 >, is_nothrow_move_assignable< T2 > >::value)
移动赋值运算符
constexpr pair(Tuple1 &t1, Tuple2 &t2, index_sequence< Index1... > idx1, index_sequence< Index2... > idx2)
从两个tuple构造pair
constexpr bool less_than(const pair &y) const noexcept(noexcept(this->first< y.first||(!(y.first< this->first) &&this->second< y.second)))
小于比较运算符
constexpr pair(unpack_utility_construct_tag, tuple< Types1... > t1, tuple< Types2... > t2)
从两个tuple构造pair
constexpr pair & operator=(pair< U1, U2 > &&p) noexcept(conjunction< is_nothrow_assignable< T1 &, U1 >, is_nothrow_assignable< T2 &, U2 > >::value)
从不同类型pair的移动赋值运算符
constexpr bool equal_to(const pair &y) const noexcept(noexcept(this->first==y.first &&this->second==y.second))
相等比较运算符
pair & operator=(const volatile pair &)=delete
禁止volatile拷贝赋值
constexpr pair & operator=(const pair< U1, U2 > &p) noexcept(conjunction< is_nothrow_assignable< T1 &, const U1 & >, is_nothrow_assignable< T2 &, const U2 & > >::value)
从不同类型pair的拷贝赋值运算符
constexpr pair & operator=(type_identity_t< const T & > p) noexcept(conjunction< is_nothrow_copy_assignable< T1 >, is_nothrow_copy_assignable< T2 > >::value)
拷贝赋值运算符