Skip to content

Instantly share code, notes, and snippets.

@zuoyan
Created December 6, 2012 14:37
Show Gist options
  • Save zuoyan/4224862 to your computer and use it in GitHub Desktop.
Save zuoyan/4224862 to your computer and use it in GitHub Desktop.
rearranged std::tule
#include <atomic>
#include <iostream>
#include <tuple>
#include "tmp.hpp" // see http://github.com/zuoyan/tmp
template <template <class ...> class F, class ...A>
struct tcurry {
template <class ...T>
struct apply {
typedef F<A..., T...> type;
};
};
template <class ...T>
struct rearranged_tuple_help {
typedef tmp::vector<T...> vector_;
typedef tmp::range_c<int, sizeof...(T)> indices_;
typedef tmp::zip<vector_, indices_> vector_indices_;
template <class A, class B>
struct ti_cmp_ {
typedef tmp::int_<
((sizeof(std::tuple<std::aligned_storage<1, 2>, char>)
> sizeof(std::tuple<char, std::aligned_storage<1, 2> >))
? alignof(tmp::nth_c<0, A>) < alignof(tmp::nth_c<0, B>)
: alignof(tmp::nth_c<0, A>) > alignof(tmp::nth_c<0, B>)
) > type;
};
typedef tmp::sort<
ti_cmp_<boost::mpl::_1, boost::mpl::_2>,
vector_indices_> vector_indices_in_align_;
typedef tmp::seq_to_tuple<
tmp::map<
tcurry<tmp::nth, tmp::int_<0> >,
vector_indices_in_align_> > type;
typedef tmp::map<
tcurry<tmp::nth, tmp::int_<1> >,
vector_indices_in_align_> to_origin;
typedef tmp::map<
tcurry<tmp::find, to_origin>,
indices_> from_origin;
};
template <class ...T>
using rearranged_tuple_type = typename rearranged_tuple_help<T...>::type;
template <std::size_t I, class ...T>
using rearranged_tuple_from_origin = tmp::nth_c<
I, typename rearranged_tuple_help<T...>::from_origin>;
template <std::size_t I, class ...T>
using rearranged_tuple_to_origin = tmp::nth_c<
I, typename rearranged_tuple_help<T...>::to_origin>;
template <std::size_t I, class T>
struct rearranged_tuple_element;
template <class ...T>
struct rearranged_tuple;
template <std::size_t I, class ...T>
struct rearranged_tuple_element<I, rearranged_tuple<T...> > {
typedef tmp::nth_c<I, tmp::vector<T...> > type;
};
namespace std {
template <std::size_t I, class ...T,
std::size_t LI=rearranged_tuple_from_origin<I, T...>::value >
auto get(const rearranged_tuple<T...> & r) ->
decltype(get<LI>((const rearranged_tuple_type<T...>&)r)) {
return get<LI>((const rearranged_tuple_type<T...>&)r);
}
template <std::size_t I, class ...T,
std::size_t LI=rearranged_tuple_from_origin<I, T...>::value >
auto get(rearranged_tuple<T...> & r) ->
decltype(get<LI>((rearranged_tuple_type<T...>&)r)) {
return get<LI>((rearranged_tuple_type<T...>&)r);
}
template <std::size_t I, class ...T,
std::size_t LI=rearranged_tuple_from_origin<I, T...>::value >
auto get(rearranged_tuple<T...> && r) ->
decltype(get<LI>((rearranged_tuple_type<T...>&&)r)) {
return get<LI>((rearranged_tuple_type<T...>&&)r);
}
template <std::size_t I, class ...T>
struct tuple_element<I, rearranged_tuple<T...> > {
typedef tmp::nth_c<I, tmp::vector<T...> > type;
};
} // namespace std
template <class ...T>
struct rearranged_tuple : rearranged_tuple_type<T...> { };
int main(int argc, char *argv[]) {
std::cerr << sizeof(std::tuple<char, int, char>) << std::endl;
std::cerr << sizeof(rearranged_tuple<char, int, char>) << std::endl;
std::cerr << sizeof(std::tuple<char, int, char, double, char>) << std::endl;
std::cerr << sizeof(rearranged_tuple<char, int, char, double, char>) << std::endl;
rearranged_tuple<char, int, char, double, char> t;
std::get<0>(t) = 'a';
std::get<1>(t) = 1985;
std::get<2>(t) = 'b';
std::get<3>(t) = 3.12;
std::get<4>(t) = 'c';
std::cerr << std::get<0>(t) << std::endl;
std::cerr << std::get<1>(t) << std::endl;
std::cerr << std::get<2>(t) << std::endl;
std::cerr << std::get<3>(t) << std::endl;
std::cerr << std::get<4>(t) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment