
Am 24.03.2016 um 20:34 schrieb Antony Polukhin:
I've improved the implementation, now it has more functionality.
Github repo: https://github.com/apolukhin/magic_get
Changes: * separate ready-for-inclusion header "magic_get.hpp" that depends only on C++14 features (noo Boost deps) * support for nested PODs * now works with libstdc++ too * more fundamental types supported * improved compilation time * now works with arrays too * more extensions are allowed * support for detecting volatile pointers * added flat_ to public API (flat_get, flat_tuple_size) * added multiple comments
I found a way to get a type_name type at compile type, i.e. a template which has a sequence of chars representing the type. This could be added to boost.type_index and would allow constexpr sorting of types by names etc. E.g. making boost::variant<int, double> and boost::variant<double, int> the same, by ordering the arguments alphabetically. Has lot of compiler overhead though. That might also be a workaround for the REGISTER_TYPE thing in you magic get, though I have to admit: I don't really get how this approach works, so I don't know. Here's the code for that (would need some polishing for sure), I've built it with Gcc 6. Don't know if other compiler play along with that. #include <iostream> #include <array> #include <type_traits> #include <boost/type_index.hpp> #include <tuple> using namespace std; template<char ...C> struct char_seq {}; template<std::size_t ... Idx> struct index_seq { }; template<typename T, std::size_t Append> struct append; template<std::size_t ...indexes, std::size_t Append> struct append<index_seq<indexes...>, Append> { using type = index_seq<indexes ..., Append>; }; template<typename T, std::size_t Append> using append_t = typename append<T, Append>::type; template<std::size_t Size, std::size_t Counter = 0, typename T = index_seq<>> struct make_index_seq { typedef typename make_index_seq<Size, Counter+1, append_t<T, Counter>>::type type; }; template<std::size_t Size, typename T> struct make_index_seq<Size, Size, T> { typedef T type; }; template<std::size_t Size> using make_index_seq_t = typename make_index_seq<Size>::type; template<char c> struct char_entry {}; template<typename T> struct constexpr_ti { template<std::size_t Index> constexpr static char step() { return __PRETTY_FUNCTION__[Index]; } template<std::size_t ...Indexes> constexpr static auto impl(index_seq<Indexes...> * = nullptr) { return char_seq<step<Indexes>()...>(); } constexpr static auto make() { //the 37 is determined by hand using idx_seq = make_index_seq_t<sizeof(__PRETTY_FUNCTION__)+ 37> *; return impl(idx_seq()); } }; template<typename T> constexpr auto make_type_idx() { return constexpr_ti<T>::make(); } template<char ...C> void print(char_seq<C...>) { std::array<char, sizeof...(C) + 1> arr = {C..., '\0'}; cout << arr.data() << endl; } int main() { using boost::typeindex::type_id; constexpr auto x = make_type_idx<std::tuple<int, double, void*>>(); { using t = make_index_seq_t<12>; cout << type_id<t>().pretty_name() << endl; } { using t = decltype(x); cout << type_id<t>().pretty_name() << endl; } print(x); return 0; }