前面的typelist的e一个小扩展,http://www.cnblogs.com/flytrace/p/3551414.html.
可以插入pair<key_type, value_type>,然后传入key_type查找对应的value_type.
虽然是map,但仍是线性查找。基本就是一个基于typelist的体力活。
基于二叉树的typemap,可能的思路是通过编译时递增整数常量作为key_type的索引。递归层次复杂了不见得一定会比线性查找来的快。
#ifndef HI_MPL_TYPEMAP_H_INCLUDED #define HI_MPL_TYPEMAP_H_INCLUDED #include "TypeList.h" #include <type_traits> template<typename first_, typename second_> struct pair { typedef first_ first; typedef second_ second; }; //linear map ////////////////////////////////////////////////////////// template<typename... TList> struct build_linear_map; template<typename... TList> struct build_linear_map { typedef typelist<TList...> type; }; template<typename... TList> struct build_linear_map< typelist<TList...> > { typedef typelist<TList...> type; }; template<typename A, typename... AList, typename B, typename... BList> struct build_linear_map< typelist<A, AList...>, typelist<B, BList...> > { static_assert(sizeof...(AList) == sizeof...(BList), "length is not same"); typedef typename concat< pair<A, B>, typename build_linear_map< typelist<AList...>, typelist<BList...> >::type >::type type; }; template<typename A, typename B> struct build_linear_map< typelist<A>, typelist<B> > { typedef typelist< pair<A, B> > type; }; template<> struct build_linear_map< typelist<>, typelist<> > { typedef typelist<> type; }; ////////////////////////////////////////////////////////// template<typename Key, typename TList> struct linear_map_find; template<typename Key, typename T, typename... TList> struct linear_map_find<Key, typelist<T, TList...>> { typedef typename linear_map_find<Key, typelist<TList...> >::type type; }; template<typename Key, typename Second, typename... TList> struct linear_map_find<Key, typelist< pair<Key, Second>, TList... >> { typedef Second type; }; template<typename Key> struct linear_map_find<Key, nulllist> { typedef nulllist type; }; ////////////////////////////////////////////////////////// template<typename Key, typename TList> struct linear_map_find_all; template<typename Key, typename T, typename... TList> struct linear_map_find_all<Key, typelist<T, TList...>> { typedef typename linear_map_find_all<Key, typelist<TList...> >::type type; }; template<typename Key, typename Second, typename... TList> struct linear_map_find_all<Key, typelist< pair<Key, Second>, TList... > > { typedef typename concat<Second, typename linear_map_find_all<Key, typelist<TList...> >::type >::type type; }; template<typename Key> struct linear_map_find_all<Key, nulllist> { typedef nulllist type; }; ////////////////////////////////////////////////////////// template<typename T, typename... TList> struct linear_map_add; template<typename T, typename... TList> struct linear_map_add< T, typelist<TList...> > { typedef typename concat<T, typelist<TList...> >::type type; }; template<typename Key, typename NewValue, typename... TList> struct linear_map_add<Key, NewValue, typelist<TList...> > { typedef typename concat<pair<Key, NewValue>, typelist<TList...> >::type type; }; ////////////////////////////////////////////////////////// template<typename T, typename... TList> struct linear_map_insert; template<typename T, typename... TList> struct linear_map_insert<T, typelist<TList...> > { static_assert( std::is_same< typename linear_map_find<typename T::first, typelist<TList...> >::type, nulllist>::value, "key already exist"); typedef typename concat<T, typelist<TList...> >::type type; }; template<typename First, typename Second, typename... TList> struct linear_map_insert<First, Second, typelist<TList...> > { static_assert( std::is_same< typename linear_map_find<First, typelist<TList...> >::type, nulllist>::value, "key already exist"); typedef typename concat<pair<First, Second>, typelist<TList...> >::type type; }; ////////////////////////////////////////////////////////// template<typename T, typename... TList> struct linear_map_replace; template<typename T, typename H, typename... TList> struct linear_map_replace<T, typelist<H, TList...> > { typedef typename concat<H, typename linear_map_replace<T, typelist<TList...> >::type>::type type; }; template<typename Key, typename NewValue, typename OldValue, typename... TList> struct linear_map_replace<pair<Key, NewValue>, typelist<pair<Key, OldValue>, TList...> > { typedef typename concat<pair<Key, NewValue>, typelist<TList...> >::type type; }; template<typename T> struct linear_map_replace<T, nulllist> { typedef nulllist type; }; template<typename Key, typename NewValue, typename... TList> struct linear_map_replace<Key, NewValue, typelist<TList...> > { typedef typename linear_map_replace<pair<Key, NewValue>, typelist<TList...> >::type type; }; ////////////////////////////////////////////////////////// template<typename T, typename... TList> struct linear_map_earse; template<typename T, typename H, typename... TList> struct linear_map_earse<T, typelist<H, TList...> > { typedef typename concat<H, typename linear_map_earse<T, typelist<TList...> >::type>::type type; }; template<typename Key, typename Value_, typename... TList> struct linear_map_earse<Key, typelist<pair<Key, Value_>, TList...> > { typedef typelist<TList...> type; }; template<typename T> struct linear_map_earse<T, nulllist> { typedef nulllist type; }; ////////////////////////////////////////////////////////// template<typename T, typename... TList> struct linear_map_earse_all; template<typename T, typename H, typename... TList> struct linear_map_earse_all<T, typelist<H, TList...> > { typedef typename concat<H, typename linear_map_earse_all<T, typelist<TList...> >::type>::type type; }; template<typename Key, typename Value_, typename... TList> struct linear_map_earse_all<Key, typelist<pair<Key, Value_>, TList...> > { typedef typename linear_map_earse_all<Key, typelist<TList...>>::type type; }; template<typename T> struct linear_map_earse_all<T, nulllist> { typedef nulllist type; }; ////////////////////////////////////////////////////////// template<typename T, typename... TList> struct linear_map_no_duplicate; template<typename T, typename...TList> struct linear_map_no_duplicate< typelist<T, TList...> > { private: typedef typename linear_map_no_duplicate< typelist<TList...> >::type inner; typedef typename linear_map_earse<typename T::first, inner>::type inner_result; public: typedef typename concat<T, inner_result>::type type; }; template<> struct linear_map_no_duplicate< nulllist > { typedef nulllist type; }; #endif // HI_MPL_TYPEMAP_H_INCLUDED
例子:
#include <iostream> #include "TypeTraits.h" #include "TypeList.h" #include "TypeMap.h" int main() { typedef build_linear_map< pair<int, float>, pair<float, double>, pair<bool, char> >::type testmap; typedef typelist<int, float, bool> keylist; typedef typelist<float, double, char> valuelist; typedef typelist<float, bool, char> newvaluelist; typedef build_linear_map<keylist, valuelist>::type testmapcopy; typedef build_linear_map<keylist, newvaluelist>::type testmapnew; typedef build_linear_map< pair<int, float>, pair<float, double>, pair<bool, char>, pair<int, char> >::type testmap2; typedef build_linear_map< pair<int, float>, pair<float, double>, pair<bool, char>, pair<double, char> >::type testmap3; typedef build_linear_map< pair<int, float>, pair<float, double>, pair<bool, char>, pair<double, char>, pair<double, int> >::type testmap4; bool b; b = std::is_same<linear_map_find<float, testmap>::type, double>::value; std::cout << "is same: " << b << std::endl; b = std::is_same<testmapcopy, testmap>::value; std::cout << "is same: " << b << std::endl; b = std::is_same<linear_map_insert<pair<short, long>, testmapcopy>::type, linear_map_add<pair<short, long>,testmap>::type>::value; std::cout << "is same: " << b << std::endl; b = std::is_same<linear_map_replace<pair<float, bool>, testmap>::type, testmapnew>::value; std::cout << "is same: " << b << std::endl; b = std::is_same<linear_map_find_all<int, testmap2>::type, typelist<float, char>>::value; std::cout << "is same: " << b << std::endl; b = std::is_same<linear_map_earse<double, testmap3>::type, testmap>::value; std::cout << "is same: " << b << std::endl; b = std::is_same<linear_map_earse_all<double, testmap4>::type, testmap>::value; std::cout << "is same: " << b << std::endl; b = std::is_same<linear_map_no_duplicate<testmap4>::type, testmap3>::value; std::cout << "is same: " << b << std::endl; return 0; }