• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            歲月流轉(zhuǎn),往昔空明

            C++博客 首頁 新隨筆 聯(lián)系 聚合 管理
              118 Posts :: 3 Stories :: 413 Comments :: 0 Trackbacks
            這個(gè)設(shè)計(jì)主要是拿來保證跨組件的時(shí)候能盡可能的保護(hù)型別安全.

            我今天晚上早些時(shí)候也往SoftArt里面提交了一個(gè)type to id的實(shí)現(xiàn),使用宏和特化機(jī)制
            但是這個(gè)版本的一個(gè)很大的問題就在于用起來不是很方便,每注冊一個(gè)類需要2行代碼,而且都是
            #define PARAM float
            #include REGTYPE()
            這樣的非常規(guī)的宏用法.
            但是由于它是分類實(shí)現(xiàn)的,所以可以在里面補(bǔ)充一些額外的功能,比如自動(dòng)的具名常量的生成.

            所以晚上回來的時(shí)候又用boost的mpl寫了一個(gè)原形,基本上是純模板的.注冊類只需要一行,但是宏實(shí)現(xiàn)版本中一些半自動(dòng)化的特點(diǎn)也損失的差不多了.
            回頭還是要考慮用preprocessor結(jié)合MPL,看看能不能做到兩個(gè)特點(diǎn)兼?zhèn)?

            mingw + gcc 4.2.1下通過

            #include <iostream>
            #include 
            <boost/smart_ptr.hpp>

            #include 
            <boost/mpl/vector.hpp>
            #include 
            <boost/mpl/find.hpp>
            #include 
            <boost/mpl/at.hpp>
            #include 
            <boost/mpl/size.hpp>
            #include 
            <boost/mpl/if.hpp>
            #include 
            <boost/mpl/less.hpp>
            #include 
            <boost/mpl/int.hpp>
            #include 
            <boost/mpl/less_equal.hpp>

            #include 
            <boost/type_traits/is_same.hpp>

            using namespace std;

            struct empty{};

            #define BEGIN_REGISTER_TYPE() typedef boost::mpl::vector<empty
            #define REGISTER_TYPE(type) ,type
            #define END_REGISTER_TYPE() > typelst;

            namespace shader_constant
            {
                BEGIN_REGISTER_TYPE()
                    REGISTER_TYPE(
            int)
                    REGISTER_TYPE(
            float)
                    REGISTER_TYPE(
            bool)
                END_REGISTER_TYPE();

                
            static const int size_of_typelst = boost::mpl::size<typelst>::value;
                typedef boost::mpl::int_
            <size_of_typelst> size_of_typelst_t;

                template
            <class T>
                
            struct type2id{
                    typedef typename boost::mpl::find
            <typelst, T>::type iter;
                    
            static const int id =
                        boost::mpl::if_
            <
                            boost::is_same
            <boost::mpl::end<typelst>::type, iter>,
                            boost::mpl::int_
            <0>,
                            typename iter::pos
                        
            >::type::value;
                }
            ;

                template
            <int id>
                
            struct id2type{
                    typedef boost::mpl::int_
            <id> int_id;
                    typedef boost::mpl::int_
            <0> int_0;

                    
            //type = (0 < id && id <= size) ? typelst[id] : empty;
                    typedef typename boost::mpl::if_<
                        boost::mpl::and_
            <
                            boost::mpl::less
            <int_0, int_id >,
                            boost::mpl::less_equal
            <int_id, boost::mpl::size<typelst>::type >
                        
            >,
                        typename boost::mpl::at
            <typelst, int_id>::type,
                        empty
                    
            >::type type;
                }
            ;
            }


            using namespace shader_constant;

            typedef 
            void (*Assignments)(void* p1, void* p2);

            template
            <class T>
            void AssignImpl(void* p1, void* p2)
            {
                cout 
            << typeid(T).name() << endl;
                
            *(T*)p1 = *(T*)p2;
            }


            template 
            <> void AssignImpl<empty>(void* p1, void* p2)
            {
                cout 
            << "error type!" << endl;
            }


             Assignments assigns[size_of_typelst
            +1];

            template 
            <int i>
            struct assigns_initializer
            {
                assigns_initializer
            <i-1> m;
                assigns_initializer()
            {
                    assigns[i] 
            = &AssignImpl<typename id2type<i>::type >;
                    }

            }
            ;

            template 
            <>
            struct assigns_initializer<-1>
            {
                assigns_initializer()
            {
                    }

            }
            ;

            static assigns_initializer<size_of_typelst> ai;

            typedef 
            double T;
            int main()
            {
                T i1(T(
            0));
                T i2(T(
            10));
                assigns[type2id
            <T>::id](&i1, &i2);
                cout 
            << i1;
                system(
            "pause");
                
            return 0;
            }

            posted on 2008-03-08 00:55 空明流轉(zhuǎn) 閱讀(1299) 評論(4)  編輯 收藏 引用

            評論

            # re: 一個(gè)type2id的程序 2008-03-08 15:53 空明流轉(zhuǎn)
            新的實(shí)現(xiàn),覺得還是這個(gè)好一點(diǎn).
             
            #include <iostream>
            #include 
            <boost/smart_ptr.hpp>

            #include 
            <boost/mpl/vector.hpp>
            #include 
            <boost/mpl/find.hpp>
            #include 
            <boost/mpl/at.hpp>
            #include 
            <boost/mpl/size.hpp>
            #include 
            <boost/mpl/if.hpp>
            #include 
            <boost/mpl/less.hpp>
            #include 
            <boost/mpl/int.hpp>
            #include 
            <boost/mpl/less_equal.hpp>

            #include 
            <boost/type_traits/is_same.hpp>
            #include 
            <boost/preprocessor/seq/for_each.hpp>
            #include 
            <boost/preprocessor/seq/for_each_i.hpp>

            using namespace std;

            struct empty{};

            #define TYPE_LST \
            (empty) \
            (
            bool)(float)(int)

            #define BEGIN_ENUM() enum ENUM_NAME {
            #define REG_ENUM(r, data, i, type_elem) BOOST_PP_CAT(ENUM_PRED, type_elem) = i,
            #define END_ENUM() };

            #define BEGIN_ENCODE_DECODE()    \
            template
            <class T>    struct type_encodestatic const int id = 0static const ENUM_NAME tag = ENUM_NAME(0); };\
            template
            <int i> struct type_decode{ typedef empty type;};

            #define REGISTER_TYPE(r, dummy, i, type_elem) \
            template
            <> struct type_encode< type_elem >{static const int id = i; static const ENUM_NAME tag = ENUM_NAME(i);};\
            template
            <> struct type_decode< i >{typedef type_elem type;};

            #define END_ENCODE_DECODE()
            enum s{
                ebool
            }
            ;

            namespace shader_constant
            {
                
            #define ENUM_NAME sh_typeids
                
            #define ENUM_PRED sh_typeids
                
            #define ENUM_POST
                BEGIN_ENUM()
                BOOST_PP_SEQ_FOR_EACH_I(REG_ENUM, _, TYPE_LST)
                END_ENUM()

                BEGIN_ENCODE_DECODE()
                BOOST_PP_SEQ_FOR_EACH_I(REGISTER_TYPE, _, TYPE_LST)
                END_ENCODE_DECODE()

                
            const int size_of_typelst = BOOST_PP_SEQ_SIZE(TYPE_LST);
            }


            using namespace shader_constant;

            typedef 
            void (*Assignments)(void* p1, void* p2);

            template
            <class T>
            void AssignImpl(void* p1, void* p2)
            {
                cout 
            << typeid(T).name() << endl;
                
            *(T*)p1 = *(T*)p2;
            }


            template 
            <> void AssignImpl<empty>(void* p1, void* p2)
            {
                cout 
            << "error type!" << endl;
            }


             Assignments assigns[size_of_typelst
            +1];

            template 
            <int i>
            struct assigns_initializer
            {
                assigns_initializer
            <i-1> m;
                assigns_initializer()
            {
                    assigns[i] 
            = &AssignImpl<typename type_decode<i>::type >;
                    }

            }
            ;

            template 
            <>
            struct assigns_initializer<-1>
            {
                assigns_initializer()
            {
                    }

            }
            ;

            static assigns_initializer<size_of_typelst> ai;

            typedef 
            double T;
            int main()
            {
                T i1(T(
            0));
                T i2(T(
            10));
                assigns[type_encode
            <T>::id](&i1, &i2);
                cout 
            << i1;
                system(
            "pause");
                
            return 0;
            }

              回復(fù)  更多評論
              

            # re: 一個(gè)type2id的程序 2008-03-08 22:28 橙子
            可有看過《C++設(shè)計(jì)新思維》 ?
            里面有一章Typtlist,專門講這個(gè)。你這個(gè)看起來很高深。  回復(fù)  更多評論
              

            # re: 一個(gè)type2id的程序 2008-03-09 11:39 空明流轉(zhuǎn)
            typelist有typelist不妥的地方。
            我的原帖解法就是typelist的(boost::mpl::vector)。
            但是typelst的解法中,它的類型名稱信息只能用一次,而我在做枚舉或者別的時(shí)候需要再次利用這個(gè)類型名稱生成合適的枚舉值名稱或者別的什么。
            所以我用了boost的preprocessor作為確定序列的工具。  回復(fù)  更多評論
              

            # re: 一個(gè)type2id的程序 2008-03-21 19:06 李錦俊
            空明你的程序我越來越怕了。那么多宏+模板,暈啊。  回復(fù)  更多評論
              

            久久免费高清视频| 久久er99热精品一区二区| 久久婷婷五月综合色高清| 久久久久久久久久免免费精品| 久久超乳爆乳中文字幕| 久久亚洲AV无码精品色午夜麻豆| 品成人欧美大片久久国产欧美| 久久精品无码一区二区无码| 婷婷五月深深久久精品| 亚洲精品tv久久久久久久久| 久久国产亚洲精品| 狠狠综合久久综合88亚洲 | 久久久亚洲欧洲日产国码是AV| 久久久久一本毛久久久| 久久久99精品成人片中文字幕| 狠狠精品久久久无码中文字幕 | 怡红院日本一道日本久久| 99久久99这里只有免费的精品| 亚洲第一极品精品无码久久| 欧美大香线蕉线伊人久久| 老色鬼久久亚洲AV综合| 麻豆AV一区二区三区久久| 麻豆成人久久精品二区三区免费 | 精品国产91久久久久久久| 亚洲成色999久久网站| 国产精品热久久毛片| 看全色黄大色大片免费久久久| 欧美麻豆久久久久久中文| 国产精品久久久久蜜芽| 久久亚洲私人国产精品| 久久99国产亚洲高清观看首页| 久久激情亚洲精品无码?V| 亚洲国产成人精品91久久久| 亚洲国产精品无码久久| 久久精品国产99国产精品澳门| 久久艹国产| 亚洲AV日韩精品久久久久| 999久久久国产精品| 久久99国产精品久久99小说 | 国产精品一区二区久久不卡| 99久久免费只有精品国产|