2012-11-02 14 views
10

Considera il seguente codice.In che modo la macro BOOST_BINARY analizza gli spazi?

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

Qualcuno può spiegare come BOOST_BINARY calcoli il valore int lì?

+1

Santo schifo. Dopo aver guardato la fonte, sto iniziando a sospettare che la risposta alla tua domanda sia "no" ... – Thomas

+4

Alcune cose sono meglio lasciate sconosciute. –

risposta

3

È molto, molto complicato. Questa libreria BOOST utilizza macro costruite da altre macro.

che sto per presentarvi qualche esempio semplificato di programmazione preprocessore:

La domanda semplificata:

Come rendere macro l'aggiunta di 0 o 1 all'inizio del resto - come in questi esempi:

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

Quindi - in qualche modo , deve essere messo tra di loro entrambi gli argomenti in sequenza. Beh, ho fatto questo:

// 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) 

Funziona davvero (almeno a gcc): http://ideone.com/EKlTGt

Ora immaginate quanto complicato è il lavoro fatto da gente spinta nella loro biblioteca? Sì, è molto complicato - ma uso questi trucchi per il preprocessore che ho presentato, e forse molti altri - ho esaminato la fonte di questa libreria BOOST http://www.boost.org/doc/libs/1_46_1/boost/utility/binary.hpp oggi per la prima volta (credo o no).

4

Usa la fonte, Luke!

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. 

E questo è abbastanza facile. Abbiamo solo bisogno di definire alcune macro. Tieni duro.

#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), 

Questo fa uso pesante delle macro in boost/preprocessor/, ma non voglio ripetere quelli che sono qui. Sono migliaia di righe di codice tutte insieme.

So che questa non è una risposta molto utile e approfondita, ma la pubblicherò comunque perché è meglio di niente. Speriamo che qualcuno abbia il coraggio di guadare questo e fornire qualcosa di più perspicace!

Problemi correlati