std::tr1在visual c++ 实现中使用的宏

也许是我不适应的原因,在visual c++中std::tr1的代码比stl明显难读了很多。 对于可接受多个参数的function,用错之后,那个错误信息看得是云里雾里。原因是这份代码中使用了大量的宏来辅助多个参数的实现。

晚上花了不少时间弄清楚宏的问题。

以std::tr1::mem_fn为例,对于每一个可接受多参数的function, 都有类似实现:

     #define _INCL_FILE <xxmem_fn>
     #include <xfwrap>

其中xxmem_fn是真正的实现,里面使用了大量让人头晕的宏。 <xfwrap>是tricky。真是服了dinkumware的人,想出这样的创举。估计他们平时调试也很郁闷:)。难道现在还是P.J. Plauger一个人完成库的实现?反正版权信息上只有他名字。

下面是对几个相关有文件的粗略分析,知道这些,应该可以阅读实现代码了。下面的内容仅作参考,这只是推断和猜测的结果。

 <xfwrap>
    iterator 0 to N to include <xfwrap1>

 <xtr1common>
    #define _XNAME(x, z)        x ## z
    #define _YNAME(x, z)        _XNAME(x, z)
    #define _YNAME15(x, y, z)   _XNAME(x, z) y
    #define _YNAME2(x, y, z)    _XNAME(x, z) _XNAME(y, z)


    #define _CORE_0(x)
    #define _CORE_1(x)
    #define _CORE_2(x)
    #define _CORE_3(x)          _YNAME(x, 1)
    ...
    #define _CORE_n(x)          _CORE_n-1(x), _YNAME(x, n-2)

    #define _CORE15_n(x, y)     _CORE_n but in which _YNAME = _YNAME15
    #define _CORE2_n(x, y)      _CORE_n but in which _YNAME = _YNAME2

    ex.
        _CORE(X)                X1,    X2,    X3,    ..., Xn-2
        _CORE15(X, Y)           X1 Y,  X2 Y,  X3 Y,  ..., Xn-2 Y
        _CORE2(X, Y)            X1 Y1, X2 Y2, X3 Y3, ..., Xn-2 Yn-2


    #define _NARGSm1_0          0
    #define _NARGSm1_1          0
    #define _NARGSm1_2          1
    ...
    #define _NARGSm1_n          n-1
        Used to indicate the last index of the list.

    #define _TAIL_N(x)
    #define _TAIL_n-1(x)        x
    #define _TAIL_n-2(x)        TAIL_n-1(x), x
    ...
    #define _TAIL_0             TAIL_1(x),   x
        It will make a list with N-n items. In current tr1 implement, then N is
        10. This TAIL(x) will make a list with specific tag x to fill the actual
        arguments list. _Nil will be the empty type in this std::tr1 implement.


    #define _ARG_MAX            9
    #define _CDR_MAX(x)         _CORE_10(x), _YNAME(x, _ARG_MAX)
    #define _CDR15_MAX(x, y)    _CORE15_10(x, y), _YNAME15(x, y, _ARG_MAX)
    #define _CDR2_MAX(x, y)     _CORE2_10(x, y), _YNAME2(x, y, _ARG_MAX)
    #define _LIST_MAX(x)        _YNAME(x, 0), _CDR_MAX(x)
    #define _LIST15_MAX(x, y)   _YNAME15(x, y, 0), _CDR15_MAX(x, y)
    #define _LIST2_MAX(x, y)    _YNAME2(x, y, 0), _CDR2_MAX(x, y)

    #define _CLASS_ARG0_MAX     _LIST_MAX(class _Arg)
    #define _CLASS_FARG0_MAX    _LIST_MAX(class _Farg)
    #define _ARG0_A0_REF_MAX    _LIST2_MAX(_Arg, &_Ax)

    #define _ARG1_ARG2_MAX      _CDR_MAX(_Arg)
    #define _ARG0_ARG1_MAX      _LIST_MAX(_Arg)
    #define _FARG1_FARG2_MAX    _CDR_MAX(_Farg)
    #define _FARG0_FARG1_MAX    _LIST_MAX(_Farg)

    #define _A1_A2_MAX          _CDR_MAX(_Ax)
    #define _A0_A1_MAX          _LIST_MAX(_Ax)

    #define _NIL_TAIL_MAXm1     _TAIL_1(_Nil)
    #define _NIL_TAIL_MAX       _TAIL_0(_Nil)
    #define _TAIL_MAX(x)        _TAIL_0(x)
    #define _CLASS_ARG0_DEF_MAX _LIST15_MAX(class _Arg, = _Nil)

    Many max define. Some rule could be concluded:
        list: (first itme with index0, the cdr list wich equal to
               core(item)).
        class_arg0_list: (class, list), class will be the first member of
                          the new list.
        arg0_arg1_list: equal to list.
        arg1_arg2_list: equal to cdr part of list.


<xfwrap1>

    item0 _COMMA0 item1 _COMMA1 item2 _MCOMMA item3 _LCOMMA ... itemN-1 _LCOMMA itemN

    #define _MCOMMA             n >= 2 ? "," : ""
    #define _LCOMMA             n >= 3 ? "," : ""

    #define _FIRST(x)           n >= 1 ? _YNAME(x, 0)             : ""
    #define _FIRSTm1(x)         n >= 2 ? _FIRST(x)                : ""
        _FIRST15*, _FIRST2* are similar to _FIRST
    #define _LAST(x)            n >= 2 ? _YNAME(x, _NARGSm1)      : ""
    #define _LAST15(x, y)       n >= 2 ? _YNAME15(x, y, _NARGSm1) : ""
    #define _LAST2(x, y)        n >= 2 ? _YNAME2(x, y, _NARGSm1)  : ""


    #define _CDR(x)             _CORE(x) _LCOMMA _LAST(x)
    #define _CDR15(x, y)        _CORE15(x, y) _LCOMMA _LAST15(x, y)
    #define _CDR2(x, y)         _CORE2(x, y) _LCOMMA _LAST2(x, y)
    #define _LIST(x)            _FIRST(x) _MCOMMA _CDR(x)
    #define _LISTm1(x)          _FIRSTm1(x) _LCOMMA _CORE(x)
    #define _LIST15(x, y)       _FIRST15(x, y) _MCOMMA _CDR15(x, y)
    #define _LIST15m1(x, y)     _FIRST15m1(x, y) _LCOMMA _CORE15(x, y)
    #define _LIST2(x, y)        _FIRST2(x, y) _MCOMMA _CDR2(x, y)
    #define _LIST2m1(x, y)      _FIRST2m1(x, y) _LCOMMA _CORE2(x, y)


    #define _CLASS_NAME(x)      _YNAME(x, _NARGS)
    #define _PREV_NAME(x)       _YNAME(x, _NARGSm1)
        _NARGS is n, from 0 ... N
        _NARGSm1 is the lastest index

    #define _CLASS_ARG0         _LIST(class _Arg)
    #define _CLASS_ARG0m1       _LISTm1(class _Arg)
    #define _CLASS_ARG1         _CDR(class _Arg)
    #define _CLASS_FARG0        _LIST(class _Farg)
    #define _ARG0_ARG1          _LIST(_Arg)
    #define _ARG0_ARG1_REF      _LIST15(_Arg, &)
    #define _ARG0_ARG1_CREF     _LIST15(const _Arg, &)
        the 5 part is reference tag.
    #define _ARG0_ARG1m1        _LISTm1(_Arg)
    #define _ARG1_ARG2          _CDR(_Arg)
    #define _ARG1_ARG2m1        _CORE(_Arg)
    #define _FARG0_FARG1        _LIST(_Farg)
    #define _FARG0_FARG1_REF    _LIST15(_Farg, &)
    #define _FARG0_FARG1_CREF   _LIST15(const _Farg, &)
    #define _FARG1_FARG2        _CDR(_Farg)
    #define _FARG1_FARG2_REF    _CDR15(_Farg, &)
    #define _FARG1_FARG2_CREF   _CDR15(const _Farg, &)
    #define _ARG0_A0            _LIST2(_Arg, _Ax)
    #define _ARG0_A0_REF        _LIST2(_Arg, &_Ax)
    #define _ARG0_A0_CREF       _LIST2(const _Arg, &_Ax)
    #define _FARG1_F1           _CDR2(_Farg, _Fx)
    #define _FARG1_F1_REF       _CDR2(_Farg, &_Fx)
    #define _FARG1_F1_CREF      _CDR2(const _Farg, &_Fx)
    #define _FARG0_F0           _LIST2(_Farg, _Fx)
    #define _FARG0_F0_REF       _LIST2(_Farg, &_Fx)
    #define _FARG0_F0_CREF      _LIST2(const _Farg, &_Fx)
        the 2 part is used to indicate type value.
    #define _A0_A1              _LIST(_Ax)
    #define _F0_F1              _LIST(_Fx)
    #define _F1_F2              _CDR(_Fx)
    #define _A0_A1m1            _LISTm1(_Ax)
    #define _A1_A2m1            _CORE(_Ax)
    #define _ARG0_A0_TO_REF     _LIST2(typename _Remove_reference<_Arg, >::_Type& _Ax)
    #define _ARG0_ARG1_TO_REF   _LIST15(typename _Remove_reference<_Arg, >::_Type&)

    #define _C_***
        add comma0 or comma1 to the list

        after define these macros, at last:
    #include _INCL_FILE

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值