【问题标题】:How does the BOOST_BINARY macro parse spaces?BOOST_BINARY 宏如何解析空格?
【发布时间】:2012-11-02 17:28:22
【问题描述】:

考虑下面的代码。

int value1 = BOOST_BINARY( 100 111000 01 1 110 );

有人能解释一下 BOOST_BINARY 是如何计算那里的 int 值的吗?

【问题讨论】:

  • 天哪。查看源代码后,我开始怀疑您的问题的答案是否定的......
  • 有些事情最好不知道。

标签: c++ boost macros


【解决方案1】:

这是非常非常复杂的。这个 BOOST 库使用由其他宏构造的宏。

我将向您展示一些预处理器编程的简化示例:

简化问题:

如何使宏在休息的开头添加 0 或 1 - 就像在这个例子中:

CAT ( 0 1 ) --> 01
CAT ( 1 100 ) --> 1100

所以 - 不知何故,, 必须按顺序将两个参数放在它们之间。好吧,我做到了:

// start point - this is our desired format
#define CATS(a,b) a##b
// helper macro to invoke preprocessor on result of a
#define CALLP(a) a
// some helper symbols to build CATS() 
#define CATB (
#define CATE )
#define CATSN CATS
//  I use that only 0 or 1 is expected at the beginning:
//  CATS ( 0, 
#define CAT_B0 CATSN CATB 0,
//  CATS ( 1, 
#define CAT_B1 CATSN CATB 1,

// the final macro:
// Example:
//  CAT(0 XXX) --> CALLP( CAT_B ## 0 XXX  ) )  
// --> CALLP(CAT_B0 XXX ) --> CALLP(CATSN ( 0, XXX ) )
// --> CALLP( CATS(0, XXX) ) --> CATS(0,XXX) --> 0##XXX -> 0XXX 
#define CAT(tt)   CALLP (CAT_B ## tt CATE)

它确实有效(至少在 gcc 中):http://ideone.com/EKlTGt

现在想象一下 BOOST 人在他们的图书馆中所做的工作有多复杂?是的,它非常复杂——但是使用我介绍的这些预处理器技巧,也许还有许多其他技巧——我今天第一次查看了这个 BOOST 库http://www.boost.org/doc/libs/1_46_1/boost/utility/binary.hpp 的源代码(信不信由你)。

【讨论】:

    【解决方案2】:

    使用来源,卢克!

    The following code works by converting the input bit pattern into a
    Boost.Preprocessor sequence, then converting groupings of 3 bits each into
    the corresponding octal digit, and finally concatenating all of the digits
    together along with a leading zero. This yields a standard octal literal
    with the desired value as specified in bits.
    

    这很容易。我们只需要定义一些宏。坚持住。

    #define BOOST_BINARY( bit_groupings )                                          \
      BOOST_BINARY_LITERAL_D( BOOST_PP_DEDUCE_D(), bit_groupings ) 
    
    // ...
    
    #define BOOST_BINARY_LITERAL_D( d, bit_groupings )                             \
      BOOST_PP_SEQ_CAT                                                             \
      ( (0) BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings )  \
      ) 
    
    #define BOOST_DETAIL_CREATE_BINARY_LITERAL_OCTAL_SEQUENCE( d, bit_groupings )  \
      BOOST_PP_SEQ_TRANSFORM                                                       \
      ( BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION                                     \
      , BOOST_PP_NIL                                                               \
      , BOOST_PP_IDENTITY( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE )()\
        ( BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE                                    \
          (                                                                        \
            d                                                                      \
          , BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings )    \
          )                                                                        \
        )                                                                          \
      ) 
    
    #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_TRIPLE_SEQUENCE( bit_sequence )   \
      BOOST_PP_CAT                                                                 \
      ( BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1 bit_sequence      \
      , END_BIT                                                                    \
      ) 
    
    #define BOOST_DETAIL_BITS_PER_OCTIT 3
    
    #define BOOST_DETAIL_COMPLETE_TRIPLE_SEQUENCE( d, incomplete_nibble_sequence ) \
      BOOST_PP_CAT                                                                 \
      ( BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_                            \
      , BOOST_PP_MOD_D( d                                                          \
                      , BOOST_PP_SEQ_SIZE( incomplete_nibble_sequence )            \
                      , BOOST_DETAIL_BITS_PER_OCTIT                                \
                      )                                                            \
      )                                                                            \
      incomplete_nibble_sequence 
    
    #define BOOST_DETAIL_FIXED_COMPL( bit )                                        \
      BOOST_PP_CAT( BOOST_DETAIL_FIXED_COMPL_, bit )
    
    #define BOOST_DETAIL_FIXED_COMPL_0 1 
    
    #define BOOST_DETAIL_FIXED_COMPL_1 0 
    
    #define BOOST_DETAIL_CREATE_BINARY_LITERAL_BIT_SEQUENCE( d, bit_groupings )    \
      BOOST_PP_EMPTY                                                               \
      BOOST_PP_CAT( BOOST_PP_WHILE_, d )                                           \
      ( BOOST_DETAIL_BINARY_LITERAL_PREDICATE                                      \
      , BOOST_DETAIL_BINARY_LITERAL_OPERATION                                      \
      , bit_groupings ()                                                           \
      ) 
    
    #define BOOST_DETAIL_BINARY_LITERAL_PREDICATE( d, state )                      \
      BOOST_DETAIL_FIXED_COMPL( BOOST_DETAIL_IS_NULLARY_ARGS( state ) ) 
    
    #define BOOST_DETAIL_BINARY_LITERAL_OPERATION( d, state )                      \
      BOOST_DETAIL_SPLIT_AND_SWAP                                                  \
      ( BOOST_PP_CAT( BOOST_DETAIL_BINARY_LITERAL_ELEMENT_, state ) ) 
    
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_OPERATION( s, dummy_param, tuple )        \
      BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL tuple 
    
    #define BOOST_DETAIL_TERNARY_TRIPLE_TO_OCTAL( bit2, bit1, bit0 )               \
      BOOST_DETAIL_TRIPLE_TO_OCTAL_ ## bit2 ## bit1 ## bit0 
    
    #define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_1 (0)(0)
    #define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_2 (0)
    #define BOOST_DETAIL_CREATE_TRIPLE_COMPLETION_SEQUENCE_0  
    
    #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1END_BIT  
    
    #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1( bit )        \
      ( ( bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2 
    
    #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_2( bit )        \
      bit, BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3 
    
    #define BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_3( bit )        \
      bit ) ) BOOST_DETAIL_CONVERT_BIT_SEQUENCE_TO_PARENTHETIC_TUPLE_1 
    
    #define BOOST_DETAIL_SPLIT_AND_SWAP( params )                                  \
      BOOST_PP_IDENTITY( BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS )()( params )
    
    #define BOOST_DETAIL_SPLIT_AND_SWAP_PARAMS( first_param, second_param )        \
      second_param first_param 
    
    #define BOOST_DETAIL_LEFT_OF_COMMA( params )                                   \
      BOOST_PP_IDENTITY( BOOST_DETAIL_FIRST_MACRO_PARAM )()( params ) 
    
    #define BOOST_DETAIL_FIRST_MACRO_PARAM( first_param, second_param )            \
      first_param 
    
    /* Begin derived concepts from Chaos by Paul Mensonides */
    
    #define BOOST_DETAIL_IS_NULLARY_ARGS( param )                                  \
      BOOST_DETAIL_LEFT_OF_COMMA                                                   \
      ( BOOST_PP_CAT( BOOST_DETAIL_IS_NULLARY_ARGS_R_                              \
                    , BOOST_DETAIL_IS_NULLARY_ARGS_C param                         \
                    )                                                              \
      ) 
    
    #define BOOST_DETAIL_IS_NULLARY_ARGS_C()                                       \
      1 
    
    #define BOOST_DETAIL_IS_NULLARY_ARGS_R_1                                       \
      1, BOOST_PP_NIL 
    
    #define BOOST_DETAIL_IS_NULLARY_ARGS_R_BOOST_DETAIL_IS_NULLARY_ARGS_C          \
      0, BOOST_PP_NIL 
    
    /* End derived concepts from Chaos by Paul Mensonides */
    
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_000 0 
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_001 1 
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_010 2 
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_011 3 
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_100 4 
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_101 5 
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_110 6 
    #define BOOST_DETAIL_TRIPLE_TO_OCTAL_111 7 
    
    #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_0 (0), 
    #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_1 (1), 
    
    #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_00 (0)(0), 
    #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_01 (0)(1), 
    // ... and so on, until ...
    #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111110 (1)(1)(1)(1)(1)(1)(1)(0), 
    #define BOOST_DETAIL_BINARY_LITERAL_ELEMENT_11111111 (1)(1)(1)(1)(1)(1)(1)(1), 
    

    这会大量使用boost/preprocessor/ 中的宏,但我不会在这里重复。总共有数千行代码。

    我知道这不是一个很有帮助的深入答案,但无论如何我都会发布它,因为它总比没有好。希望有人有勇气涉足此过程并提供更有见地的东西!

    【讨论】:

      猜你喜欢
      • 2021-11-01
      • 2022-11-24
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2015-06-17
      • 1970-01-01
      相关资源
      最近更新 更多