X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FVariantParser.hh;h=17b0ca414445dfeaebcbb89ead5bde5424f04799;hb=92f8630b75f3ef50e73c48cde58645dcd1534e27;hp=1887cd911e3e0a6fc57213db6644dd0c6b143c29;hpb=43ebe17b77586542dff65f2535815a19812e4316;p=senf.git diff --git a/Packets/VariantParser.hh b/Packets/VariantParser.hh index 1887cd9..17b0ca4 100644 --- a/Packets/VariantParser.hh +++ b/Packets/VariantParser.hh @@ -23,10 +23,10 @@ /** \file \brief VariantParser public header */ -#ifndef HH_VariantParser_ -#define HH_VariantParser_ 1 +#ifndef HH_SENF_Packets_VariantParser_ +#define HH_SENF_Packets_VariantParser_ 1 -#ifndef HH_Packets_ +#ifndef HH_SENF_Packets_Packets_ #error "Don't include 'VariantParser.hh' directly, include 'Packets.hh'" #endif @@ -125,48 +125,88 @@ namespace senf { /** \brief Define VariantParser field - This macro is a special helper to define a senf::DirectVariantParser type field. This is a - variant field which chooses the sub-type by directly taking the value of some other field. - + This macro is a special helper to define a senf::VariantParser type field. \code struct SomeParser : public PacketParserBase { # include SENF_PARSER() SENF_PARSER_PRIVATE_FIELD( type, senf::UInt8Parser ); - SENF_PARSER_PRIVATE_VARIANT( content, type, - (senf::VoidPacketParser) - (senf::UInt8Parser) - (senf::UInt16Parser) - (senf::UInt24Parser) - (senf::UInt32Parser) ); - - senf::UInt8Parser uint8() const { return content().get<1>(); } - senf::UInt16Parser uint16() const { return content().get<2>(); } - senf::UInt24Parser uint24() const { return content().get<3>(); } - senf::UInt32Parser uint32() const { return content().get<4>(); } - - void disable() const { content().init<0>(); } - void set_uint8() const { content().init<1>(); } - void set_uint16() const { content().init<2>(); } - void set_uint24) const { content().init<3>(); } - void set_uint23() const { content().init<4>(); } + SENF_PARSER_VARIANT( content, type, + (novalue( disable, senf::VoidPacketParser )) + ( id( uint8value, senf::UInt8Parser )) + ( id( uint16value, senf::UInt16Parser )) + ( id( uint24value, senf::UInt24Parser )) + ( id( uint32value, senf::UInt32Parser )) ); SENF_PARSER_FINALIZE(SomeParser); }; - \endcode - + \endcode + The variant \c content chooses one of the sub parsers depending on the \c type field. If \c type is 0, senf::VoidPacketParser is selected, if it is 1, senf::UInt8Parser and so on. - It is customary, to hide the variant parser (by defining it private) and provide more - conveniently named accessors. + \warning Realize, that the \a chooser field is controlled by the variant parser. This field + should therefore be declared either read-only or private and must be changed only via + the variant parser. + + The \a types parameter specifies the types of sub-objects supported by this variant + parser. This parameter is a (Boost.Preprocessor style) sequence +
(\a type) (\a type) ...
+ of parser types with additional optional information: + + + + + + + + + + + + + +
\a typeDo not provide accessor and use the 0-based type index as + key.
\c id(\a name, \a type)Automatically create an accessor \a name, a test + function has_\a name and a function to switch to this type init_\a name + for this type. Identical to \c ids(\a name, has_\a name, init_\a name, \a + type)
\c novalue(\a name, \a type)This is like \c id but only provides an + initializer called \a name and no accessor. Identical to \c ids(\c na, \c na, \a name, \a + type)
\c ids(\a accessorId, \a testId, \a initId, \a type)This is again like \c + id but the names of the accessor, test function and init function are given + explicitly. Setting any of the id's to \c na will disable that function.
\c key(\a value, \a type)Use \a value to identity this type. The type is + selected, when the \a chooser is equal to \a value
\c id(\a name, \c key(\a value, \a type))
\c novalue(\a name, \c key(\a value, + \a type))
The options may be nested in this way.
+ + Whenever an id is specified for any type, the variant itself will automatically be made + private so the only access to the variant from the outside is via the accessors. + + The functions defined by specifying an id are: + + + + + + + + + +
name_tThe type for this specific variant value if not \c + novalue.
name_t name()Return the variant value at this id + if not \c novalue.
void init_name()Set the variant to have a value + of this type. If the field is \c novalue, the \c init_ prefix is omitted.
bool has_name()Return \c true, if the variant + currently holds this kind of value, \c false otherwise. Only if not \c novalue.
+ + If \c key specs are given, they designate the value to expect in the \a chooser field to + select a specific variant type. If the \a chooser value does not match any key, the variant + will be initialized to the \e first type. Further additional tags are supported which modify the way, the \a chooser field is interpreted: -
\c transform(\a transform, \a size)The \a transform is applied to the \a +
\c transform(\a transform, \a chooser)The \a transform is applied to the \a chooser value, the value is not used directly
@@ -179,12 +219,12 @@ namespace senf { static value_type get(other_type v); static other_type set(value_type v); }; - \endcode \c other_type is the \a chooser ::\c value_type where as the \c value_type typedef + \endcode \c other_type is the \a chooser ::\c value_type whereas the \c value_type typedef is the arbitrary return type of the transform. The tags are applied to the \a chooser parameter: \code - SENF_PARSER_VARIANT ( content, transform(MyTransform, type_), + SENF_PARSER_VARIANT ( content, transform(MyTransform, type), (senf::VoidPacketParser) (senf::UInt8Parser) (senf::UInt16Parser) @@ -197,7 +237,7 @@ namespace senf { \param[in] types a Boost.Preprocessor style sequence of sub-parser types \see - senf::VariantParser \n + senf::VariantParser for the VariantParser API\n \ref SENF_PARSER_PRIVATE_VARIANT() \hideinitializer \ingroup packetparsermacros @@ -217,8 +257,8 @@ namespace senf { ///////////////////////////////hh.e//////////////////////////////////////// #endif -#if !defined(HH_Packets__decls_) && !defined(HH_VariantParser_i_) -#define HH_VariantParser_i_ +#if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_VariantParser_i_) +#define HH_SENF_Packets_VariantParser_i_ //#include "VariantParser.cci" #include "VariantParser.ct" #include "VariantParser.cti"