BOOST_BINARY宏如何解析空格?

时间:2012-11-02 17:28:22

标签: c++ boost macros

考虑以下代码。

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

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

2 个答案:

答案 0 :(得分:4)

使用来源,卢克!

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/中的宏,但我不会在这里重复这些。它共有数千行代码。

我知道这不是一个非常有用的,深入的答案,但无论如何我会发布它,因为它总比没有好。希望有人有勇气通过这个来提供更有见地的东西!

答案 1 :(得分:3)

非常非常复杂。此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的来源(相信与否)。