$ g++ -DSENF_MPL_SLOT_NOEXPAND -o <path-to-file>.ii -E -DSENF_DEBUG -Iinclude <path-to-file>.cc $ sed -i -e 's/}/}\n/g' -e '/^#.*$/d' <path-to-file>.ii $ astyle --style=linux -b <path-to-file>.ii
I normally just cut-and-paste the g++
command from a normal build and add -DSENF_MPL_SLOT_NOEXPAND
. astyle
is found at http://astyle.sourceforge.net/. If needed, I then reissue this file (the precessed \.ii file) back to the compiler using the original commandline (just replacing the .cc with .ii) to get error messages with meaningful line numbers.
The following packet parser definition (taken from VariantParser.test.cc) has been subject to macro-expansion (and a lot of manual reformatting) to show the inner workings of the packet parser macros:
struct TestParser : public senf::PacketParserBase { # include SENF_PARSER() SENF_PARSER_SKIP_BITS( 4 ); SENF_PARSER_BITFIELD_RO( type, 4, unsigned ); SENF_PARSER_PRIVATE_VARIANT( content_, type, ( novalue( nocontent, key(10, senf::VoidPacketParser)) ) ( id( content, SubParser ) ) ); SENF_PARSER_FINALIZE(TestParser); };
Here the reformated and sparsly commented expansion. I have left all the SENF_MPL_SLOT_
calls unexpanded, otherwise the code would be absolutely unreadable. This is quite a lot of source-code which however should create only a small amount of additional compiled code.
Also remember, that all this code is generated by C++ makros. Some detours are needed to work around makro problems (e.g. templates with multiple arguments are parsed as seperate makro arguments at each komma, inability to redefine a makro from another makro ...).
struct TestParser : public senf::PacketParserBase { //-///////////////////////////////////////////////////////////////////////// // #include SENF_PARSER() private: SENF_MPL_SLOT_INIT_ZERO(index); SENF_MPL_SLOT_INIT_ZERO(init_bytes); SENF_MPL_SLOT_INIT_ZERO(bit); SENF_MPL_SLOT_INIT_ZERO(bitfield_size); SENF_MPL_SLOT_INIT_ZERO(group); void init_chain (senf::mpl::rv <0> *) const {} size_type field_offset_ (senf::mpl::rv <0> *) const { return 0; } //-///////////////////////////////////////////////////////////////////////// // SENF_PARSER_SKIP_BITS( 4 ); SENF_MPL_SLOT_SET(bit, SENF_MPL_SLOT_GET(bit) + 4); //-///////////////////////////////////////////////////////////////////////// // SENF_PARSER_BITFIELD_RO( type, 4, unsigned ); public: static size_type const type_bit = SENF_MPL_SLOT_GET(bit); private: SENF_MPL_SLOT_SET(bit, type_bit + 4); typedef senf::UIntFieldParser <type_bit, type_bit + 4> type_bit_t; public: typedef type_bit_t type_t; static size_type const type_index = SENF_MPL_SLOT_GET(index) + 1; private: SENF_MPL_SLOT_SET(index, type_index); void init_chain (senf::mpl::rv<type_index> *) const { init_chain (static_cast<senf::mpl::rv<type_index - 1> *>(0)); } public: size_type type_offset() const { return field_offset_(static_cast<senf::mpl::rv<type_index - 1> *>(0)) - SENF_MPL_SLOT_GET(bitfield_size); } static size_type const type_init_bytes = SENF_MPL_SLOT_GET(init_bytes) - SENF_MPL_SLOT_GET(bitfield_size); size_type type_next_offset () const { return type_offset() + type_t::fixed_bytes; } static size_type const type_next_init_bytes = type_init_bytes + type_t::fixed_bytes; private: size_type field_offset_(senf::mpl::rv<type_index> *) const { return type_next_offset(); } SENF_MPL_SLOT_SET(init_bytes, type_next_init_bytes); static size_type const type_group = SENF_MPL_SLOT_GET(group) + 0; SENF_MPL_SLOT_SET(group, type_group); SENF_MPL_SLOT_SET(bitfield_size, type_t::fixed_bytes); type_t type_() const { return parse <type_bit_t> (type_offset ()); } public: type_t::value_type type() const { return type_(); } //-///////////////////////////////////////////////////////////////////////// // SENF_PARSER_PRIVATE_VARIANT( content_, type, // ( novalue( nocontent, key(10, senf::VoidPacketParser)) ) // ( id( content, SubParser ) ) // ); private: typedef boost::mpl::vector <senf::VoidPacketParser, SubParser> content__parsers; typedef type_t::value_type content__chooser_value_type; static content__chooser_value_type content__key_0 () { return 10; } static content__chooser_value_type content__key_1 () { return 1; } template <content__chooser_value_type (*KeyFn) ()> struct content__key_value_template : public senf::detail::VariantKey<content__chooser_value_type, KeyFn> {}; template <class T, T (*K)()> friend class senf::detail::VariantKey; typedef senf::detail::VariantKeyTransform< content__chooser_value_type, boost::mpl::vector< content__key_value_template<&content__key_0>, content__key_value_template<&content__key_1> > > content__transform; typedef senf::detail::VariantParserTraits<content__parsers, content__transform> content__traits; // start SENF_PARSER_COLLECTION_I static bool const content__aux_fixed = (SENF_MPL_SLOT_GET(group) - type_group) == 0; typedef senf::detail::ParserAuxPolicySelect < type_t, SENF_MPL_SLOT_GET(init_bytes) - type_init_bytes, content__aux_fixed >::type content__aux_policy; typedef content__traits::parser<content__aux_policy, senf::detail::auxtag::none>::type content__collection_t; SENF_MPL_SLOT_SET(bit, 0); SENF_MPL_SLOT_SET(bitfield_size, 0); typedef content__collection_t content__t; static size_type const content__index = SENF_MPL_SLOT_GET(index) + 1; SENF_MPL_SLOT_SET(index, content__index); void init_chain (senf::mpl::rv<content__index> *) const { init_chain (static_cast<senf::mpl::rv<content__index - 1> *>(0)); content_().init(); } size_type content__offset() const { return field_offset_ (static_cast<senf::mpl::rv<content__index - 1> *>(0)); } static size_type const content__init_bytes = SENF_MPL_SLOT_GET(init_bytes); size_type content__next_offset () const { return content__offset() + senf::bytes(content__()); } static size_type const content__next_init_bytes = content__init_bytes + senf::init_bytes<content__collection_t>::value; size_type field_offset_(senf::mpl::rv<content__index> *) const { return content__next_offset(); } SENF_MPL_SLOT_SET(init_bytes, content__next_init_bytes); static size_type const content__group = SENF_MPL_SLOT_GET(group) + (senf::is_fixed<content__collection_t>::value ? 0 : 1); SENF_MPL_SLOET_SET(group, content__group); template < class T > T content__dispatch (boost::true_type) const { return parse<T>(content__offset()); } template < class T > T content__dispatch(boost::false_type) const { return parse<T>(type(), content__offset()); } content__t content__() const { return content__dispatch<content__t>( boost::integral_constant<bool, content__aux_fixed>()); } content__t content_() const { return content__ (); } // end SENF_PARSER_COLLECTION_I public: void nocontent() const { content_().init<0>(); } typedef SubParser content_t; SubParser content() const { return content_().get<1>(); } void init_content() const { content_().init<1>(); } bool has_content() const { return content_().variant() == 1; }; //-///////////////////////////////////////////////////////////////////////// // SENF_PARSER_FINALIZE(TestParser); void defaultInit() const { init_chain(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)> *>(0)); } TestParser(data_iterator i, state_type s) : parser_base_type (i, s) {} private: template <class T> void init(T) const { defaultInit (); } public: void init() const { init (0); } size_type bytes() const { return field_offset_(static_cast<senf::mpl::rv<SENF_MPL_SLOT_GET(index)> *>(0)); } static size_type const init_bytes = SENF_MPL_SLOT_GET(init_bytes); };