-
-
Save anonymous/0d777cd07c516bc48cf3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template <typename T1, typename T2> struct pair; | |
template <typename T, typename... OtherArgs> | |
struct tuple_helper: tuple_helper<OtherArgs...> { | |
T t; | |
tuple_helper() = default; | |
tuple_helper(const T & arg, const OtherArgs &... args) noexcept( | |
noexcept(T(arg)) && noexcept(tuple_helper<OtherArgs...>(args...)) | |
): t(arg), tuple_helper<OtherArgs...>(args...) {} | |
tuple_helper(T&& arg, OtherArgs&&... args) noexcept( | |
noexcept(T(move(arg))) && | |
noexcept(tuple_helper<OtherArgs...>(move(args)...)) | |
): t(move(arg)), tuple_helper<OtherArgs...>(move(args)...) {} | |
template <typename Arg, typename... Args> | |
tuple_helper(const tuple_helper<Arg, Args...> &th) noexcept( | |
noexcept(T(th.t)) && | |
noexcept(tuple_helper<OtherArgs...>( | |
static_cast<const tuple_helper<Args...> &>(th))) | |
): t(th.t), tuple_helper<OtherArgs...>( | |
static_cast<const tuple_helper<Args...> &>(th)) {} | |
template <typename Arg, typename... Args> | |
tuple_helper(tuple_helper<Arg, Args...> &&th) noexcept( | |
noexcept(T(move(th.t))) && | |
noexcept(tuple_helper<OtherArgs...>( | |
static_cast<tuple_helper<Args...> &&>(th))) | |
): t(move(th.t)), | |
tuple_helper<OtherArgs...>(static_cast<tuple_helper<Args...> &&>(th)) {} | |
tuple_helper(const tuple_helper &th) noexcept( | |
noexcept(T(th.t)) && | |
noexcept(tuple_helper<OtherArgs...>( | |
static_cast<const tuple_helper<OtherArgs...> &>(th))) | |
): t(th.t), tuple_helper<OtherArgs...>( | |
static_cast<const tuple_helper<OtherArgs...> &>(th)) {} | |
tuple_helper(tuple_helper &&th) noexcept( | |
noexcept(T(move(th.t))) && | |
noexcept(tuple_helper<OtherArgs...>( | |
static_cast<tuple_helper<OtherArgs...> &&>(th))) | |
): t(move(th.t)), tuple_helper<OtherArgs...>( | |
static_cast<tuple_helper<OtherArgs...> &&>(th)) {} | |
tuple_helper &operator=(const tuple_helper &th) noexcept( | |
noexcept(t = th.t) && | |
noexcept(tuple_helper<OtherArgs...>::operator=( | |
static_cast<const tuple_helper<OtherArgs...> &>(th)))) | |
{ | |
t = th.t; | |
tuple_helper<OtherArgs...>::operator=( | |
static_cast<const tuple_helper<OtherArgs...> &>(th)); | |
return *this; | |
} | |
tuple_helper &operator=(tuple_helper &&th) noexcept( | |
noexcept(t = move(th.t)) && | |
noexcept(tuple_helper<OtherArgs...>::operator=( | |
static_cast<tuple_helper<OtherArgs...> &&>(th)))) | |
{ | |
t = move(th.t); | |
tuple_helper<OtherArgs...>::operator=( | |
static_cast<tuple_helper<OtherArgs...> &&>(th)); | |
return *this; | |
} | |
template <typename Other, typename... Others> | |
tuple_helper &operator=(const tuple_helper<Other, Others...> &th) | |
noexcept(noexcept(t = th.t) && | |
noexcept(tuple_helper<OtherArgs...>::operator=( | |
static_cast<const tuple_helper<Others...> &>(th)))) | |
{ | |
t = th.t; | |
tuple_helper<OtherArgs...>::operator=( | |
static_cast<const tuple_helper<Others...> &>(th)); | |
return *this; | |
} | |
template <typename Other, typename... Others> | |
tuple_helper &operator=(tuple_helper<Other, Others...> &&th) | |
noexcept(noexcept(t = move(th.t)) && | |
noexcept(tuple_helper<OtherArgs...>::operator=( | |
static_cast<tuple_helper<Others...> &&>(th)))) | |
{ | |
t = move(th.t); | |
tuple_helper<OtherArgs...>::operator=( | |
static_cast<tuple_helper<Others...> &&>(th)); | |
return *this; | |
} | |
void swap(tuple_helper &th) noexcept( | |
noexcept(swap(t, th.t)) && | |
noexcept(tuple_helper<OtherArgs...>::swap( | |
static_cast<tuple_helper &>(th)))) | |
{ | |
swap(t, th.t); | |
tuple_helper<OtherArgs...>::swap(th); | |
} | |
}; | |
template <typename T1, typename T2> | |
struct tuple_helper<T1, T2> { | |
T1 t1; | |
T1 t2; | |
tuple_helper() = default; | |
tuple_helper(const T1 & o1, const T2& o2) | |
noexcept(noexcept(T1(o1)) && noexcept(T2(o2))): t1(o1), t2(o2) {} | |
tuple_helper(T1&& o1, T2&& o2) | |
noexcept(noexcept(T1(move(o1))) && noexcept(T2(move(o2)))): | |
t1(move(o1)), t2(move(o2)) {} | |
template <typename Other1, typename Other2> | |
tuple_helper(const tuple_helper<Other1, Other2> &th) | |
noexcept(noexcept(T1(th.t1)) && noexcept(T2(th.t2))): | |
t1(th.t1), t2(th.t2) {} | |
template <typename Other1, typename Other2> | |
tuple_helper(tuple_helper<Other1, Other2> &&th) | |
noexcept(noexcept(T1(move(th.t1))) && noexcept(T2(move(th.t2)))): | |
t1(move(th.t1)), t2(move(th.t2)) {} | |
template <typename Other1, typename Other2> | |
explicit tuple_helper(const pair<Other1, Other2> &); | |
template <typename Other1, typename Other2> | |
explicit tuple_helper(pair<Other1, Other2> &&); | |
template <typename Other1, typename Other2> | |
tuple_helper &operator=(const pair<Other1, Other2> &); | |
template <typename Other1, typename Other2> | |
tuple_helper &operator=(pair<Other1, Other2> &&); | |
tuple_helper(const tuple_helper &th) | |
noexcept(noexcept(T1(th.t1)) && noexcept(T2(th.t2))): | |
t1(th.t1), t2(th.t2) {} | |
tuple_helper(tuple_helper &&th) | |
noexcept(noexcept(T1(move(th.t1))) && noexcept(T2(move(th.t2)))): | |
t1(move(th.t1)), t2(move(th.t2)) {} | |
tuple_helper &operator=(const tuple_helper &th) | |
noexcept(noexcept(t1 = th.t1) && noexcept(th = th.t2)) | |
{ | |
t1 = th.t1; | |
t2 = th.t2; | |
return *this; | |
} | |
tuple_helper &operator=(tuple_helper &&th) | |
noexcept(noexcept(t1 = move(th.t1)) && noexcept(t2 = move(th.t2))) | |
{ | |
t1 = move(th.t1); | |
t2 = move(th.t2); | |
return *this; | |
} | |
template <typename Other1, typename Other2> | |
tuple_helper &operator=(const tuple_helper<Other1, Other2> &th) | |
noexcept(noexcept(t1 = th.t1) && noexcept(th = th.t2)) | |
{ | |
t1 = th.t1; | |
t2 = th.t2; | |
return *this; | |
} | |
template <typename Other1, typename Other2> | |
tuple_helper &operator=(tuple_helper<Other1, Other2> &&th) | |
noexcept(noexcept(t1 = move(th.t1)) && noexcept(t2 = move(th.t2))) | |
{ | |
t1 = move(th.t1); | |
t2 = move(th.t2); | |
return *this; | |
} | |
void swap(tuple_helper &th) noexcept( | |
noexcept(swap(t1, th.t1)) && noexcept(swap(t2, th.t2))) | |
{ | |
swap(t1, th.t1); | |
swap(t2, th.t2); | |
} | |
}; | |
template <typename T> | |
struct tuple_helper<T> { | |
T t; | |
tuple_helper() = default; | |
explicit | |
tuple_helper(const T & o) noexcept(noexcept(T(o))): t(o) {} | |
explicit | |
tuple_helper(T&& o) noexcept(noexcept(T(move(o)))): t(move(o)) {} | |
template <typename Other> | |
tuple_helper(const tuple_helper<Other> &th) | |
noexcept(noexcept(T(th.t))): t(th.t) {} | |
template <typename Other> | |
tuple_helper(tuple_helper<Other> &&th) | |
noexcept(noexcept(T(move(th.t)))): t(move(th.t)) {} | |
tuple_helper(const tuple_helper &th) | |
noexcept(noexcept(T(th.t))): t(th.t) {} | |
tuple_helper(tuple_helper &&th) | |
noexcept(noexcept(T(move(th.t)))): t(move(th.t)) {} | |
tuple_helper &operator=(const tuple_helper &th) | |
noexcept(noexcept(t = th.t)) | |
{ | |
t = th.t; | |
return *this; | |
} | |
tuple_helper &operator=(tuple_helper &&th) | |
noexcept(noexcept(t = move(th.t))) | |
{ | |
t = move(th.t); | |
return *this; | |
} | |
template <typename Other> | |
tuple_helper &operator=(const tuple_helper<Other> &th) | |
noexcept(noexcept(t = th.t)) | |
{ | |
t = th.t; | |
return *this; | |
} | |
template <typename Other> | |
tuple_helper &operator=(tuple_helper<Other> &&th) | |
noexcept(noexcept(t = move(th.t))) | |
{ | |
t = move(th.t); | |
return *this; | |
} | |
void swap(tuple_helper &th) noexcept(noexcept(swap(t, th.t))) | |
{ | |
swap(t, th.t); | |
} | |
}; | |
template <typename... Args> | |
struct tuple: tuple_helper<Args...> { | |
tuple() = default; | |
template <typename... OtherArgs> explicit | |
tuple(OtherArgs&&... args) noexcept(noexcept( | |
tuple_helper<Args...>(forward<OtherArgs>(args)...))): | |
tuple_helper<Args...>(forward<OtherArgs>(args)...) {} | |
template <typename... OtherArgs> explicit | |
tuple(const tuple<OtherArgs...> &ot) | |
noexcept(noexcept(tuple_helper<Args...>(ot))): | |
tuple_helper<Args...>(ot) {} | |
template <typename... OtherArgs> explicit | |
tuple(tuple<OtherArgs...> &&ot) | |
noexcept(noexcept(tuple_helper<Args...>(move(ot)))): | |
tuple_helper<Args...>(move(ot)) {} | |
template <typename Other1, typename Other2> explicit | |
tuple(const pair<Other1, Other2> &p) noexcept(noexcept( | |
tuple_helper<Args...>(p))): | |
tuple_helper<Args...>(p) {} | |
template <typename Other1, typename Other2> explicit | |
tuple(pair<Other1, Other2> &&p) noexcept(noexcept( | |
tuple_helper<Args...>(move(p)))): | |
tuple_helper<Args...>(move(p)) {} | |
tuple(const tuple &) = default; | |
tuple(tuple &&) = default; | |
tuple &operator=(const tuple &) = default; | |
tuple &operator=(tuple &&) = default; | |
template <typename Other1, typename Other2> | |
tuple &operator=(pair<Other1, Other2> &&p) | |
noexcept(noexcept(tuple_helper<Args...>::operator=(move(p)))) | |
{ | |
tuple_helper<Args...>::operator=(move(p)); | |
return *this; | |
} | |
void swap(tuple &t) noexcept(noexcept(tuple_helper<Args...>::swap(t))) | |
{ | |
tuple_helper<Args...>::swap(t); | |
} | |
}; | |
//!下面是get | |
template <size_t N> | |
struct tuple_helper_get { | |
template <typename T, typename... Args> static | |
auto get_ref(tuple_helper<T, Args...> &t) noexcept | |
-> decltype(tuple_helper_get<N - 1>::get_ref | |
(static_cast<tuple_helper<Args...> &>(t))) | |
{ | |
return tuple_helper_get<N - 1>::get_ref( | |
static_cast<tuple_helper<Args...> &>(t)); | |
} | |
template <typename T, typename... Args> static | |
auto get_ref(tuple_helper<T, Args...> &&t) noexcept | |
-> decltype(tuple_helper_get<N - 1>::get_ref | |
(static_cast<tuple_helper<Args...> &&>(t))) | |
{ | |
return tuple_helper_get<N - 1>::get_ref( | |
static_cast<tuple_helper<Args...> &&>(t)); | |
} | |
template <typename T, typename... Args> static | |
auto get_ref(const tuple_helper<T, Args...> &t) noexcept | |
-> decltype(tuple_helper_get<N - 1>::get_ref | |
(static_cast<const tuple_helper<Args...> &>(t))) | |
{ | |
return tuple_helper_get<N - 1>::get_ref( | |
static_cast<const tuple_helper<Args...> &>(t)); | |
} | |
}; | |
template <> | |
struct tuple_helper_get<0> { | |
template <typename T> static | |
T &&get_ref(T &&t) noexcept | |
{ | |
return forward<T>(t); | |
} | |
template <typename T> static | |
T &get_ref(tuple_helper<T> &t) noexcept | |
{ | |
return t.t; | |
} | |
template <typename T> static | |
T &&get_ref(tuple_helper<T> &&t) noexcept | |
{ | |
return forward<T>(t.t); | |
} | |
template <typename T> static | |
auto get_ref(const tuple_helper<T> &t) noexcept | |
-> typename add_const<T>::type | |
{ | |
return t.t; | |
} | |
template <typename T1, typename T2> static | |
T1 &get_ref(tuple_helper<T1, T2> &t) noexcept | |
{ | |
return t.t1; | |
} | |
template <typename T1, typename T2> static | |
T1 &&get_ref(tuple_helper<T1, T2> &&t) noexcept | |
{ | |
return forward<T1>(t.t1); | |
} | |
template <typename T1, typename T2> static | |
auto get_ref(const tuple_helper<T1, T2> &t) noexcept | |
-> typename add_const<T1>::type | |
{ | |
return t.t1; | |
} | |
template <typename T, typename... Args> static | |
T &get_ref(tuple_helper<T, Args...> &t) noexcept | |
{ | |
return t.t; | |
} | |
template <typename T, typename... Args> static | |
T &&get_ref(tuple_helper<T, Args...> &&t) noexcept | |
{ | |
return forward<T>(t.t); | |
} | |
template <typename T, typename... Args> static | |
auto get_ref(const tuple_helper<T, Args...> &t) noexcept | |
-> typename add_const<T>::type | |
{ | |
return t.t; | |
} | |
}; | |
template <> | |
struct tuple_helper_get<1> { | |
template <typename T1, typename T2> static | |
T2 &get_ref(tuple_helper<T1, T2> &t) noexcept | |
{ | |
return t.t2; | |
} | |
template <typename T1, typename T2> static | |
T2 &&get_ref(tuple_helper<T1, T2> &&t) noexcept | |
{ | |
return forward<T2>(t.t2); | |
} | |
template <typename T1, typename T2> static | |
auto get_ref(const tuple_helper<T1, T2> &t) noexcept | |
-> typename add_const<T2>::type | |
{ | |
return t.t2; | |
} | |
template <typename T, typename... Args> static | |
auto get_ref(tuple_helper<T, Args...> &t) noexcept | |
-> decltype(tuple_helper_get<0>::get_ref | |
(static_cast<tuple_helper<Args...> &>(t))) | |
{ | |
return tuple_helper_get<0>::get_ref( | |
static_cast<tuple_helper<Args...> &>(t)); | |
} | |
template <typename T, typename... Args> static | |
auto get_ref(tuple_helper<T, Args...> &&t) noexcept | |
-> decltype(tuple_helper_get<0>::get_ref | |
(static_cast<tuple_helper<Args...> &&>(t))) | |
{ | |
return tuple_helper_get<0>::get_ref( | |
static_cast<tuple_helper<Args...> &&>(t)); | |
} | |
template <typename T, typename... Args> static | |
auto get_ref(const tuple_helper<T, Args...> &t) noexcept | |
-> decltype(tuple_helper_get<0>::get_ref | |
(static_cast<const tuple_helper<Args...> &>(t))) | |
{ | |
return tuple_helper_get<0>::get_ref( | |
static_cast<const tuple_helper<Args...> &>(t)); | |
} | |
}; | |
template <size_t N, typename T> | |
auto get(T&& t) noexcept | |
-> decltype(tuple_helper_get<N>::get_ref(t)) | |
{ | |
return tuple_helper_get<N>::get_ref(t); | |
} | |
template <size_t N, typename... Args> | |
auto get(tuple<Args...> &t) noexcept | |
-> decltype(tuple_helper_get<N>::get_ref | |
(static_cast<tuple_helper<Args...> &>(t))) | |
{ | |
return tuple_helper_get<N>::get_ref( | |
static_cast<tuple_helper<Args...> &>(t)); | |
} | |
template <size_t N, typename... Args> | |
auto get(tuple<Args...> &&t) noexcept | |
-> decltype(tuple_helper_get<N>::get_ref | |
(static_cast<tuple_helper<Args...> &&>(t))) | |
{ | |
return tuple_helper_get<N>::get_ref( | |
static_cast<tuple_helper<Args...> &&>(t)); | |
} | |
template <size_t N, typename... Args> | |
auto get(const tuple<Args...> &t) noexcept | |
-> decltype(tuple_helper_get<N>::get_ref | |
(static_cast<const tuple_helper<Args...> &>(t))) | |
{ | |
return tuple_helper_get<N>::get_ref( | |
static_cast<const tuple_helper<Args...> &>(t)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment