Created
December 6, 2012 14:37
-
-
Save zuoyan/4224862 to your computer and use it in GitHub Desktop.
rearranged std::tule
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
#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