11

考虑下面的代码。

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

有人可以解释 BOOST_BINARY 如何计算那里的 int 值吗?

4

2 回答 2

5

使用来源,卢克!

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/,但我不会在这里重复。它是数千行代码。

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

于 2012-11-02T18:13:57.437 回答
5

这是非常非常复杂的。这个 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今天第一次(信不信由你)。

于 2012-11-02T18:58:32.527 回答