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ì?
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ì?
È 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).
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!
Santo schifo. Dopo aver guardato la fonte, sto iniziando a sospettare che la risposta alla tua domanda sia "no" ... – Thomas
Alcune cose sono meglio lasciate sconosciute. –