overload rvalue refs to const for tuple

master
Daniel Kolesa 2016-05-02 18:21:54 +01:00
parent 34cb1f1fbd
commit 75e27a14b0
5 changed files with 40 additions and 4 deletions

View File

@ -96,7 +96,12 @@ const TupleElement<I, Array<T, N>> &get(const Array<T, N> &a) {
template<Size I, typename T, Size N>
TupleElement<I, Array<T, N>> &&get(Array<T, N> &&a) {
return a[I];
return move(a.p_buf[I]);
}
template<Size I, typename T, Size N>
const TupleElement<I, Array<T, N>> &&get(const Array<T, N> &&a) {
return move(a.p_buf[I]);
}
template<typename T, Size N>

View File

@ -64,6 +64,9 @@ const TupleElement<I, Tuple<A...>> &get(const Tuple<A...> &);
template<Size I, typename ...A>
TupleElement<I, Tuple<A...>> &&get(Tuple<A...> &&);
template<Size I, typename ...A>
const TupleElement<I, Tuple<A...>> &&get(const Tuple<A...> &&);
/* pair specializations */
template<typename T, typename U> constexpr bool IsTupleLike<Pair<T, U>> = true;
@ -77,6 +80,9 @@ const TupleElement<I, Pair<T, U>> &get(const Pair<T, U> &);
template<Size I, typename T, typename U>
TupleElement<I, Pair<T, U>> &&get(Pair<T, U> &&);
template<Size I, typename T, typename U>
const TupleElement<I, Pair<T, U>> &&get(const Pair<T, U> &&);
/* array specializations */
template<typename T, Size I> constexpr bool IsTupleLike<Array<T, I>> = true;
@ -90,6 +96,9 @@ const T &get(const Array<T, S> &);
template<Size I, typename T, Size S>
T &&get(Array<T, S> &&);
template<Size I, typename T, Size S>
const T &&get(const Array<T, S> &&);
/* make tuple indices */
namespace detail {

View File

@ -609,12 +609,12 @@ inline auto chunks(T n) {
namespace detail {
template<typename T, typename ...R, Size ...I>
inline auto join_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) {
return obj.join(forward<R>(get<I>(tup))...);
return obj.join(forward<R>(get<I>(forward<Tuple<R &&...>>(tup)))...);
}
template<typename T, typename ...R, Size ...I>
inline auto zip_proxy(T &&obj, Tuple<R &&...> &&tup, TupleIndices<I...>) {
return obj.zip(forward<R>(get<I>(tup))...);
return obj.zip(forward<R>(get<I>(forward<Tuple<R &&...>>(tup)))...);
}
}

View File

@ -277,6 +277,9 @@ class Tuple {
template<Size I, typename ...T>
friend TupleElement<I, Tuple<T...>> &&get(Tuple<T...> &&);
template<Size I, typename ...T>
friend const TupleElement<I, Tuple<T...>> &&get(const Tuple<T...> &&);
public:
template<bool D = true, typename = EnableIf<
detail::TupleAll<(D && IsDefaultConstructible<A>)...>
@ -421,7 +424,13 @@ inline const TupleElement<I, Tuple<A...>> &get(const Tuple<A...> &t) {
template<Size I, typename ...A>
inline TupleElement<I, Tuple<A...>> &&get(Tuple<A...> &&t) {
using Type = TupleElement<I, Tuple<A...>>;
return ((detail::TupleLeaf<I, Type> &&)t.p_base).get();
return (Type &&)(((detail::TupleLeaf<I, Type> &&)t.p_base).get());
}
template<Size I, typename ...A>
inline const TupleElement<I, Tuple<A...>> &&get(const Tuple<A...> &&t) {
using Type = TupleElement<I, Tuple<A...>>;
return (const Type &&)(((const detail::TupleLeaf<I, Type> &&)t.p_base).get());
}
/* tie */

View File

@ -231,6 +231,10 @@ namespace detail {
static const T &get(const Pair<T, U> &p) { return p.first; }
template<typename T, typename U>
static T &&get(Pair<T, U> &&p) { return forward<T>(p.first); }
template<typename T, typename U>
static const T &&get(const Pair<T, U> &&p) {
return forward<const T>(p.first);
}
};
template<> struct GetPair<1> {
@ -240,6 +244,10 @@ namespace detail {
static const U &get(const Pair<T, U> &p) { return p.second; }
template<typename T, typename U>
static U &&get(Pair<T, U> &&p) { return forward<U>(p.second); }
template<typename T, typename U>
static const T &&get(const Pair<T, U> &&p) {
return forward<const T>(p.second);
}
};
}
@ -258,6 +266,11 @@ TupleElement<I, Pair<T, U>> &&get(Pair<T, U> &&p) {
return detail::GetPair<I>::get(move(p));
}
template<Size I, typename T, typename U>
const TupleElement<I, Pair<T, U>> &&get(const Pair<T, U> &&p) {
return detail::GetPair<I>::get(move(p));
}
namespace detail {
template<typename T, typename U,
bool = IsSame<RemoveCv<T>, RemoveCv<U>>,