1. basic types implement with variadic template
2. light-weight boost::fusion::vector like type container implement with variadic template
3. ref<sequence> , ref<type> dereference function for light-weight type container vector implement with variadic template
This provided some demo code of using variadic template to get rid of traditional type_list, empty type, and use type deduction to extract types in a row.
ideone:
#include <iostream> #include <string> #include <typeinfo> namespace VS_TEST_SUITE { //not necessary in C++11 struct empty { }; template<typename T1, typename T2> struct type_pair { using head_t = T1; using tail_t = T2; }; template<typename... Ts> struct type_array { }; template<typename T, T VALUE> struct static_parameter { }; template<typename T, T VALUE> struct static_value : static_parameter<T, VALUE> { static const T value = VALUE; }; //------------- template<typename... Ts> struct front; template<> struct front<>; template<typename T1, typename... Ts> struct front<T1, Ts...> { using type = T1; }; template<typename... Ts> struct back; template<> struct back<>; template<typename T> struct back<T> { using type = T; }; template<typename T1, typename... Ts> struct back<T1, Ts... > : back<Ts...> { }; //---------- template<unsigned int N, typename... Ts> struct type_at { using type = empty; }; template<typename T, typename... Ts> struct type_at<0, T, Ts...> { using type = T; }; template<unsigned int N, typename T, typename... Ts> struct type_at<N, T, Ts...> { using type = typename type_at<N-1, Ts...>::type; }; // <int, double> // at 3 //---------- template<typename... Ts> struct depth; template<> struct depth<> : static_value<unsigned int, 0> { }; template<typename T, typename... Ts> struct depth<T, Ts...> : static_value<unsigned int, depth<Ts...>::value+1> { }; //<int,double> //---------- template<typename T, typename... Ts> struct type_index : static_value<int, -1> { }; template<typename T, typename... Ts> struct type_index<T, T, Ts...> : static_value<int, 0> { }; template<typename T, typename T1, typename... Ts> struct type_index<T, T1, Ts...> : static_value<int, (type_index<T, Ts...>::value == -1) ? -1 : type_index<T, Ts...>::value + 1 > { }; //<int, double> //---------- template<typename... Ts> struct Vector; template<> struct Vector<> { }; template<typename T, typename... Ts> struct Vector<T, Ts...> : Vector<Ts...> { using value_type = T; value_type member; }; //--------- template<typename T, typename... Ts> T& ref(Vector<T, Ts...>& a_) { return a_.member; } //--------- template<unsigned int N, template<typename...> class AGG, typename... Ts> struct ref_traits; template<template<typename...> class AGG, typename T, typename... Ts> struct ref_traits<0, AGG, T, Ts...> { using value_type = typename AGG<T, Ts...>::value_type; static value_type& ref(AGG<T, Ts...>& agg) { return agg.member; } }; template<unsigned int N, template<typename...> class AGG, typename T, typename... Ts> struct ref_traits<N, AGG, T, Ts...> { using next_t = ref_traits<N-1, AGG, Ts...>; using value_type = typename next_t::value_type; static value_type& ref(AGG<T, Ts...>& agg) { return next_t::ref(agg); } }; template<unsigned int N, template<typename...> class AGG, typename... Ts> inline typename ref_traits<N, AGG, Ts...>::value_type& ref(AGG<Ts...>& agg) { return ref_traits<N, AGG, Ts...>::ref(agg); } } //end of namespace VS_TEST_SUITE int main(){ using namespace std; using namespace VS_TEST_SUITE; cout << typeid(back<int, double, std::string>::type).name() << endl; //print string cout << typeid(front<int, double, std::string>::type).name() << endl; //print int cout << typeid(type_at<2, double, double, std::string>::type).name() << endl; //print string cout << typeid(type_at<12, int, double, std::string>::type).name() << endl; //print empty cout << depth<int, int, int>::value << endl; //print 3 cout << depth<>::value << endl; //print 0 cout << type_index<float, int, double, std::string>::value << endl; //print -1 cout << type_index<double, int, double, std::string>::value << endl; //print 1 Vector<std::string, double> derived; Vector<double>& base = derived; Vector<int,std::string, double> agg_1; ref<int>(agg_1) = 7; ref<std::string>(agg_1) = "i am a string!"; ref<double>(agg_1) = 20.3; cout << ref<std::string>(agg_1) << endl; cout << ref<int>(agg_1) << endl; cout << ref<double>(agg_1) << endl; Vector<int, double, std::string> agg_2; ref<0>(agg_2) = 10; ref<1>(agg_2) = 3.14; ref<2>(agg_2) = "i am a string, again!!"; cout << ref<0>(agg_2) << endl; cout << ref<1>(agg_2) << endl; cout << ref<2>(agg_2) << endl; }
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.