2 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
3 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
4 // Stefan Bund <g0dil@berlios.de>
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the
18 // Free Software Foundation, Inc.,
19 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 \brief ParseList public header */
25 #define HH_ParseList_ 1
28 #include <boost/utility.hpp>
29 #include "PacketParser.hh"
31 //#include "ParseList.mpp"
32 ///////////////////////////////hh.p////////////////////////////////////////
36 namespace detail { template <class ElementParser, class IteratorPolicy>
37 class Parse_List_Iterator; }
39 template <class ListPolicy>
40 class Parse_List_Container;
42 /** \brief Arbitrary sequential element collection
44 A List is a sequential collection of elements. The element type is given as an arbitrary
45 parser. The list is more flexible than a vector: It is not limited to fixed-size elements
46 and it might not have direct access to the size of the collection.
48 The cost is however, that a List is only a model of an STL forward sequence. The parser
49 provides a reduced interface to this sequence, the container wrapper provides the complete
52 Pare_List makes use of a policy template argument, \a ListPolicy, to customize the way the
53 list is laid out. This policy is given quite some freedom in the list
54 implementation. It is however important, that list elements <em>always follow each other
55 without padding</em> (if padding is needed, it needs to be part of the element parser).
57 \see ExampleListPolicy
58 \ingroup parsecollection
60 template <class ListPolicy>
62 : public PacketParserBase,
66 Parse_List(data_iterator i, state_type s);
67 Parse_List(ListPolicy policy, data_iterator i, state_type s);
68 ///< Additional policy specific constructor
69 /**< This constructor may be used, if the policy needs
70 additional parameters. */
72 size_type bytes() const;
75 static const size_type init_bytes = ListPolicy::init_bytes;
77 ///////////////////////////////////////////////////////////////////////////
78 // Container interface
80 typedef typename ListPolicy::element_type value_type;
81 typedef detail::Parse_List_Iterator<
82 value_type, typename ListPolicy::iterator_policy > iterator;
83 typedef iterator const_iterator;
84 typedef typename ListPolicy::container_type container;
86 size_type size() const;
89 iterator begin() const;
92 value_type front() const;
93 value_type back() const;
95 template <class Value> void push_back (Value value, size_type n=1) const;
96 void push_back_space (size_type n=1) const;
97 template <class Value> void push_front (Value value, size_type n=1) const;
98 void push_front_space (size_type n=1) const;
99 void resize (size_type n) const;
100 template <class Value> void resize (size_type n, Value value) const;
103 template <class Policy> friend class Parse_List_Container;
106 /** \brief Example of a list policy. ONLY FOR EXPOSITION.
108 This class shows the interface which must be implemented by a list policy. It is not a list
109 policy only a declaration of the interface:
111 struct ExampleListPolicy
113 // optional typedefs used to simplify all other declarations
114 typedef PacketParserBase::data_iterator data_iterator;
115 typedef PacketParserBase::state_type state_type;
116 typedef PacketParserBase::size_type size_type;
118 // mandatory typedefs in the parser and container policy
119 typedef ElementParser element_type;
120 typedef Parse_List< ExampleListPolicy > parser_type;
121 typedef Parse_List_Container< ExampleListPolicy > container_type;
123 // mandatory constant in parser and container policy
124 static const size_type init_bytes = 0;
126 // Members needed in the parser and the container policy
127 size_type bytes (data_iterator i, state_type s) const;
128 size_type size (data_iterator i, state_type s) const;
129 void init (data_iterator i, state_type s) const;
131 // Members needed only in the container policy
132 void erase (data_iterator i, state_type s, iterator p) const;
133 void insert (data_iterator i, state_type s, iterator p) const;
135 struct iterator_policy
137 iterator setBegin (data_iterator i, state_type s);
138 iterator setEnd (data_iterator i, state_type s);
139 void setFromPosition (data_iterator i, state_type s, iterator p);
140 iterator next (data_iterator i, state_type s);
141 iterator raw (data_iterator i, state_type s) const;
146 If necessary, you may use a different policy in the container_type. The ListPolicy must
147 define the elements bytes(), size() and init(), the container policy needs all these and
148 additionally needs erase() and insert(). The container policy will also need the
149 element_type, parser_type and container_type typedefs.
153 struct ExampleListPolicy
155 typedef PacketParserBase::data_iterator iterator;
156 typedef PacketParserBase::state_type state_type;
157 typedef PacketParserBase::size_type size_type;
159 typedef void element_type; ///< Type of list elements
160 /**< This is the parser used to parse the list elements. */
161 typedef void parser_type; ///< List parser type
162 /**< parser_type is the list parser used to parse a list of
164 e.g. <tt>senf::Parse_List<ExampleListPolicy></tt>. */
165 typedef void container_type; ///< Type of container wrapper
166 /**< This is the container wrapper of the list, e.g.
167 <tt>Parse_List_Container<ExampleListPolicy></tt>. The
168 container may however use a \e different policy, as
169 long as that policy is constructible from the parser
172 static const size_type init_bytes = 0; ///< Size of a new list of this type
173 /**< Initial size which needs to be allocated to this type
176 size_type bytes(iterator i, state_type s) const; ///< Size of list in bytes
177 /**< Return the complete size of the list in
178 bytes. Depending on the type of list, this call may
179 need to completely traverse the list ... */
181 size_type size(iterator i, state_type s) const; ///< Number of elements in list
182 /**< Return the number of elements in the list. This
183 operation may be quite inefficient for some lists (the
184 list must be traversed to find that number. */
186 void init(iterator i, state_type s) const; ///< Initialize new list
187 /**< Called after init_size bytes have been allocated to
188 initialize the list. After init() is called, the list
189 is traversed to initialize any members (probably
192 void erase(iterator i, state_type s, iterator p) const; ///< Erase element from list
193 /**< Delete the list element at p from the List (i,s). When
194 this operation is called, the element is still part of
195 the list. This call must update the meta-data as
196 needed. The data will be removed after this call
199 void insert(iterator i, state_type s, iterator p) const; ///< Insert element into list
200 /**< This is called after an element has been inserted at p
201 into the List (i,s) to update the meta-data. */
203 /** \brief Example of a list iterator policy. ONLY FOR EXPOSITION.
205 \see \ref ExampleListPolicy \n
208 struct iterator_policy
210 iterator setBegin(iterator i, state_type s); ///< Initialize iterator to begin()
211 /**< Initialize the policy from the given List (i,s). Set
212 the iterator to the beginning iterator. Return
213 data_iterator to the first element.
215 \warning if the list is empty, the returned iterator
216 \e must be the same as the one returned by setEnd. */
218 iterator setEnd(iterator i, state_type s); ///< Initialize iterator to end()
219 /**< Initialize the policy from the given List (i,s). Set
220 the iterator to the end iterator. Return data_iterator
221 used to mark the end of the range. This may be a
222 special sentinel value (e.g. data().end()) if
225 void setFromPosition(iterator i, state_type s, iterator p);
226 ///< Initialize iterator from the given raw position
227 /**< Set the iterator to the Element at raw position p. This
228 operation can potentially be very inefficient if the
229 list needs to be traversed from the beginning until the
230 iterator is found. */
232 iterator next(iterator i, state_type s); ///< Advance to next element
233 /**< given an iterator to an element, go to the next
236 iterator raw(iterator i, state_type s); ///< Return raw position of element
237 /**< Given the iterator state (i,s), return the raw iterator
238 to the datum. This will be i in almost all cases EXCEPT
239 if a special sentinel value is used as end() value. In
240 this case, this member must return the real position
241 after the last element. */
244 /** \brief Example of a list container policy. ONLY FOR EXPOSITION
246 \see \ref ExampleListPolicy \n
249 struct container_policy
251 void init(iterator i, state_type s); ///< Initialize new container
252 void update(iterator i, state_type s); ///< Called before every container access
256 /** \brief Parse_List container wrapper
258 This is the container wrapper used for list parsers. The container wrapper will stay valid
259 after changing the collection. However the container still depends on the packet and will be
260 invalidated if the Packet is deallocated or if the packet size is changed from without the
261 container wrapper (more precisely, it is invalided if the insertion/deletion happens before
262 the vector in the packet data).
264 The vector container wrapper provides a complete STL random-access sequence interface.
268 SomePacket::aListCollection_t::container c (p->aListCollection());
269 c.insert(c.begin(), ... );
274 template <class ListPolicy>
275 class Parse_List_Container
279 ///////////////////////////////////////////////////////////////////////////
282 typedef typename ListPolicy::parser_type parser_type;
283 typedef PacketParserBase::data_iterator data_iterator;
284 typedef PacketParserBase::size_type size_type;
285 typedef PacketParserBase::difference_type difference_type;
286 typedef typename ListPolicy::element_type value_type;
287 typedef detail::Parse_List_Iterator<
288 value_type, typename ListPolicy::iterator_policy> iterator;
289 typedef iterator const_iterator;
290 typedef PacketParserBase::state_type state_type;
292 ///////////////////////////////////////////////////////////////////////////
293 ///\name Structors and default members
296 // no default constructor
298 // default destructor
299 // conversion constructors
301 Parse_List_Container(parser_type const & list);
302 ~Parse_List_Container();
305 ///////////////////////////////////////////////////////////////////////////
310 size_type size() const;
313 iterator begin() const;
314 iterator end() const;
316 value_type front() const;
317 value_type back() const;
323 // All these operations can be quite inefficient depending on the list type
324 void shift(iterator pos, size_type n=1);
325 template <class Value>
326 void insert(iterator pos, Value const & t);
327 template <class Value>
328 void insert(iterator pos, size_type n, Value const & t);
329 template <class ForwardIterator>
331 void insert(iterator pos, ForwardIterator f, ForwardIterator l,
332 typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
334 void insert(iterator pos, ForwardIterator f, ForwardIterator l);
337 void erase(iterator pos, size_type n=1);
338 void erase(iterator f, iterator l);
341 template <class Value> void push_back (Value value, size_type n=1);
342 void push_back_space (size_type n=1);
343 template <class Value> void push_front (Value value, size_type n=1);
344 void push_front_space (size_type n=1);
345 void resize (size_type n);
346 template <class Value> void resize (size_type n, Value value);
350 ///\name Parser interface
353 parser_type parser() const;
354 data_iterator i() const;
355 state_type state() const;
356 PacketData & data() const;
358 size_type bytes() const;
371 ///////////////////////////////hh.e////////////////////////////////////////
373 #if !defined(SENF_PACKETS_DECL_ONLY) && !defined(HH_ParseList_i_)
374 #define HH_ParseList_i_
375 //#include "ParseList.cci"
376 #include "ParseList.ct"
377 #include "ParseList.cti"
384 // c-file-style: "senf"
385 // indent-tabs-mode: nil
386 // ispell-local-dictionary: "american"
387 // compile-command: "scons -u test"
388 // comment-column: 40