zoukankan      html  css  js  c++  java
  • 一个基于typelist的typemap

    前面的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;
    }
  • 相关阅读:
    klinux下JDK的安装和卸载
    MySQL设置定时任务执行事务
    Burp Suite Intruder的4种攻击类型
    Intel重大漏洞之Meltdown和Spectre
    你的Mac还安全吗
    渗透技巧——Windows系统的帐户隐藏
    Office--CVE-2017-11882【远程代码执行】
    Kali下安装Java环境
    自动化渗透测试工具(Cobalt Strike)3.1 最新破解版
    跟着安全牛大表哥学渗透
  • 原文地址:https://www.cnblogs.com/flytrace/p/3563834.html
Copyright © 2011-2022 走看看