Pregunta

La división de esta fuera de mi pregunta acerca de a CPP macros :

Alguien aquí

Ha utilizado el Boost.Preprocessor tipos de datos de la biblioteca para poner en práctica algo así como el X -macro?

¿Fue útil?

Solución

Acabo de mirar lo que se supone un X-Macro ser y Creo que hice algo parecido a lo que está pidiendo.

Lo que quería hacer es apoyar con facilidad y rapidez la serialización de una serie de clases bastante similares. El problema que tuve es que tuve para convertir algunos datos de tiempo de ejecución (un int) en un tipo de tiempo de compilación (una clase) para poder hacer mi serialización. Podría haber escrito un par de declaraciones de casos para hacer el trabajo, pero eso significaría que tengo que actualizar varias funciones cada vez que quería añadir una clase.

Para solucionar este problema, lo primero que se define una secuencia de tuplas que contienen el mapeo:

#define WIN_MESSAGE_TYPE_SEQ \
    ((EM_REPLACESEL, em_replacesel))((WM_CHAR, wm_char)) //...

Los nombres de los casos son superiores que sujetan define un int y minúsculas nombres son clases que I definidos en otro lugar.

I puede entonces usar esta secuencia en conjunto con algunos de los preprocesadores Boost para generar todo tipo de código para mí. Por ejemplo, para obtener una declaración adelantada de las clases que sólo puede hacer esto:

#define WIN_MESSAGE_TYPE_BUILD_MACRO(r, _data_, _elem_) \
    class BOOST_PP_TUPLE_ELEM(2,1,_elem_);

BOOST_PP_SEQ_FOR_EACH(WIN_MESSAGE_TYPE_BUILD_MACRO, BOOST_PP_NIL, WIN_MESSAGE_TYPE_SEQ)

#undef WIN_MESSAGE_TYPE_BUILD_MACRO

Para hacer el tiempo de ejecución para compilar mapeo vez, generar una serie de declaraciones de casos como éste:

#define WIN_MESSAGE_TYPE_BUILD_MACRO(r, _data_, _elem_) \
    case BOOST_PP_TUPLE_ELEM(2,0,_elem_): return win_message_serializer<BOOST_PP_TUPLE_ELEM(2,1,_elem_)>::serialize(msg, o_arch);

template <typename Archive>
void serialize_win_message (p_win_message_base msg, Archive& o_arch) {
    message_type_t message_type = msg->type();

    switch (message_type) {

    // This will generate a series of case statement for each message type that will invoke
    // the serializer for the correct types.
    BOOST_PP_SEQ_FOR_EACH(WIN_MESSAGE_TYPE_BUILD_MACRO, BOOST_PP_NIL, WIN_MESSAGE_TYPE_SEQ)

    default: //...
    };
}

#undef WIN_MESSAGE_TYPE_BUILD_MACRO

Todo el código implica un poco más de esto, pero esto todavía le debe dar una idea sobre cómo generar código usando los preprocesadores Boost. En mi ejemplo, yo puedo rápida y fácilmente añadir soporte para una clase de serialización simplemente actualizando mi secuencia.

Tenga en cuenta que el uso del preprocesador Boost no produce código muy legible, así que trato de mantener la macro que utiliza el para cada macro tan simple como sea posible. Además, no me sorprendería que alguien en algún lugar tiene una solución más elegante a este problema. Esto es justo lo que se me ocurrió para un proyecto personal en el que no me importa la complejidad adicional.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top