X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Packets%2FParseList.hh;h=6f0387fbd702ac2fb81f3e0383a1ff78f5b3fe9a;hb=6116cb96ea7bdcb42b7d12165a05fcbe0687226d;hp=80a5d89c4d8d113fd4c864e5f3959cc613df5a8f;hpb=a3d3979b7daaf22ea63ca356edbfa8047dff7b78;p=senf.git diff --git a/Packets/ParseList.hh b/Packets/ParseList.hh index 80a5d89..6f0387f 100644 --- a/Packets/ParseList.hh +++ b/Packets/ParseList.hh @@ -1,3 +1,5 @@ +// $Id$ +// // Copyright (C) 2007 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) // Kompetenzzentrum fuer Satelitenkommunikation (SatCom) @@ -39,7 +41,23 @@ namespace senf { template class Parse_List_Container; - /** \brief + /** \brief Arbitrary sequential element collection + + A List is a sequential collection of elements. The element type is given as an arbitrary + parser. The list is more flexible than a vector: It is not limited to fixed-size elements + and it might not have direct access to the size of the collection. + + The cost is however, that a List is only a model of an STL forward sequence. The parser + provides a reduced interface to this sequence, the container wrapper provides the complete + interface. + + Pare_List makes use of a policy template argument, \a ListPolicy, to customize the way the + list is laid out. This policy is given quite some freedom in the list + implementation. It is however important, that list elements always follow each other + without padding (if padding is needed, it needs to be part of the element parser). + + \see ExampleListPolicy + \ingroup parsecollection */ template class Parse_List @@ -49,6 +67,9 @@ namespace senf { public: Parse_List(data_iterator i, state_type s); Parse_List(ListPolicy policy, data_iterator i, state_type s); + ///< Additional policy specific constructor + /**< This constructor may be used, if the policy needs + additional parameters. */ size_type bytes() const; void init() const; @@ -84,156 +105,24 @@ namespace senf { template friend class Parse_List_Container; }; - /** \brief Exmaple of a list policy. ONLY FOR EXPOSITION. + /** \brief Parse_List container wrapper + + This is the container wrapper used for list parsers. The container wrapper will stay valid + after changing the collection. However the container still depends on the packet and will be + invalidated if the Packet is deallocated or if the packet size is changed from without the + container wrapper (more precisely, it is invalided if the insertion/deletion happens before + the vector in the packet data). + + The vector container wrapper provides a complete STL random-access sequence interface. - This class shows the interface which must be implemented by a list policy. It is not a list - policy only a declaration of the interface: \code - struct ExampleListPolicy - { - // optional typedefs used to simplify all other declarations - typedef PacketParserBase::data_iterator data_iterator; - typedef PacketParserBase::state_type state_type; - typedef PacketParserBase::size_type size_type; - - // mandatory typedefs in the parser and container policy - typedef ElementParser element_type; - typedef Parse_List< ExampleListPolicy > parser_type; - typedef Parse_List_Container< ExampleListPolicy > container_type; - - // mandatory constant in parser and container policy - static const size_type init_bytes = 0; - - // Members needed in the parser and the container policy - size_type bytes (data_iterator i, state_type s) const; - size_type size (data_iterator i, state_type s) const; - void init (data_iterator i, state_type s) const; - - // Members needed only in the container policy - void erase (data_iterator i, state_type s, iterator p) const; - void insert (data_iterator i, state_type s, iterator p) const; - - struct iterator_policy - { - iterator setBegin (data_iterator i, state_type s); - iterator setEnd (data_iterator i, state_type s); - void setFromPosition (data_iterator i, state_type s, iterator p); - iterator next (data_iterator i, state_type s); - iterator raw (data_iterator i, state_type s) const; - }; - }; + SomePacket p (...); + SomePacket::aListCollection_t::container c (p->aListCollection()); + c.insert(c.begin(), ... ); \endcode - If necessary, you may use a different policy in the container_type. The ListPolicy must - define the elements bytes(), size() and init(), the container policy needs all theese and - additionally needs erase() and insert(). The container policy will also need the - element_type, parser_type and container_type typedefs. - - \see \ref Parse_List - */ - struct ExampleListPolicy - { - typedef PacketParserBase::data_iterator iterator; - typedef PacketParserBase::state_type state_type; - typedef PacketParserBase::size_type size_type; - - typedef void element_type; ///< Type of list elements - /**< This is the parser used to parse the list elements. */ - typedef void parser_type; ///< List parser type - /**< parser_type is the list parser used to parse a list of - this type, - e.g. senf::Parse_List. */ - typedef void container_type; ///< Type of container wrapper - /**< This is the container wrapper of the list, e.g. - Parse_List_Container. The - container may however use a \e different policy, as - long as that policy is constructible from the parser - policy. */ - - static const size_type init_bytes = 0; ///< Size of a new list of this type - /**< Initial size which needs to be allocated to this type - of list */ - - size_type bytes(iterator i, state_type s) const; ///< Size of list in bytes - /**< Return the complete size of the list in - bytes. Depending on the type of list, thie call may - need to completely traverse the list ... */ - - size_type size(iterator i, state_type s) const; ///< Number of elements in list - /**< Return the number of elements in the list. This - operation may be quite inefficient for some lists (the - list must be traversed to find that number. */ - - void init(iterator i, state_type s) const; ///< Initialize new list - /**< Called after init_size bytes have been allocated to - initialize the list. After init() is called, the list - is traversed to initialize any members (probably - none) */ - - void erase(iterator i, state_type s, iterator p) const; ///< Erase element from list - /**< Delete the list element at p from the List (i,s). When - this operation is called, the element is still part of - the list. This call must update the metadata as - needed. The data will be removed after this call - returns. */ - - void insert(iterator i, state_type s, iterator p) const; ///< Insert element into list - /**< This is called after an element has been inserted at p - into the List (i,s) to update the metadata. */ - - /** \brief Example of a list iterator policy. ONLY FOR EXPOSITION. - - \see \ref ExampleListPolicy \n - \ref Parse_List - */ - struct iterator_policy - { - iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin() - /**< Initialize the policy from the given List (i,s). Set - the iterator to the beginning iterator. Return - data_iterator to the first element. - - \warning if the list is empty, the returned iterator - \e must be the same as the one returned by setEnd. */ - - iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end() - /**< Initialize the policy from the given List (i,s). Set - the iterator to the end iterator. Return data_iterator - used to mark the end of the range. This may be a - special sentinel value (e.g. data().end()) if - needed. */ - - void setFromPosition(iterator i, state_type s, iterator p); - ///< Initialize iterator from the given raw position - /**< Set the iterator to the Element at raw position p. This - operation can potentially be very inefficient if the - list needs to be traversed from the beginning until the - iterator is found. */ - - iterator next(iterator i, state_type s); ///< Advance to next element - /**< given an iterator to an element, go to the next - element. */ - - iterator raw(iterator i, state_type s); ///< Return raw position of element - /**< Given the iterator state (i,s), return the raw iterator - to the datum. This will be i in almost all cases EXCEPT - if a special sentinel value is used as end() value. In - this case, this member must return the real position - after the last element. */ - }; - - /** \brief Example of a list container policy. ONLY FOR EXPOSITION - - \see \ref ExampleListPolicy \n - \ref Parse_List - */ - struct container_policy - { - void init(iterator i, state_type s); ///< Initialize new container - void update(iterator i, state_type s); ///< Called before every container access - }; - }; - + \see Parse_List + */ template class Parse_List_Container : private ListPolicy @@ -290,8 +179,12 @@ namespace senf { template void insert(iterator pos, size_type n, Value const & t); template +# ifndef DOXYGEN void insert(iterator pos, ForwardIterator f, ForwardIterator l, typename boost::disable_if< boost::is_convertible >::type * = 0); +# else + void insert(iterator pos, ForwardIterator f, ForwardIterator l); +# endif void erase(iterator pos, size_type n=1); void erase(iterator f, iterator l); @@ -329,7 +222,7 @@ namespace senf { ///////////////////////////////hh.e//////////////////////////////////////// #endif -#if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseList_i_) +#if !defined(HH_Packets__decls_) && !defined(HH_ParseList_i_) #define HH_ParseList_i_ //#include "ParseList.cci" #include "ParseList.ct"