Packets: Migrate VariantParser to use AuxParser/container infrstructure
[senf.git] / Packets / VectorParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief VectorParser public header */
25
26 #ifndef HH_VectorParser_
27 #define HH_VectorParser_ 1
28
29 // Custom includes
30 #include <boost/iterator/iterator_facade.hpp>
31 #include <boost/utility.hpp>
32 #include <boost/range.hpp>
33 #include <boost/type_traits.hpp>
34 #include "PacketParser.hh"
35 #include "ArrayParser.hh" // for ArrayParser_iterator
36 #include "AuxParser.hh" // for the AuxPolicies
37
38 //#include "VectorParser.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
40
41 namespace senf {
42
43     template <class ElementParser, class AuxPolicy> class VectorParser_Container;
44
45     /** \brief Collection of fixed-size elements
46
47         A Vector is a collection of fixed-size elements of which the size of the collection can be
48         determined directly (that is without traversing the collection). This allows very efficient
49         random access to the elements of the collection.
50         
51         A vector is a model of an STL random-access sequence. The parser only provides a reduced
52         interface, the container wrapper however completes this interface.
53
54         VectorParser makes use of a policy template argument, \a Sizer, to customize the way the
55         containers size is obtained. You will normally not instantiate Parser_Vector directly, you
56         will use one of the 'template typedefs' (which are templated structures since C++ does not
57         provide real template typedefs) provided with the policy implementations.
58         
59         \todo Make the sizer a private base-class to profit from the empty-base-class optimization
60
61         \see ExampleVectorPolicy
62         \ingroup parsecollection
63      */
64     template <class ElementParser, class AuxPolicy>
65     struct VectorParser 
66         : public PacketParserBase, 
67           private AuxPolicy
68     {
69         VectorParser(data_iterator i, state_type s);
70         VectorParser(AuxPolicy policy, data_iterator i, state_type s);
71                                         ///< Additional sizer specific constructor
72                                         /**< This constructor may be used, if the sizer needs
73                                              additional parameters. */
74
75         size_type bytes() const;
76         void init() const;
77
78         static const size_type init_bytes = AuxPolicy::aux_bytes;
79
80         ///////////////////////////////////////////////////////////////////////////
81         // Container interface
82
83         typedef ElementParser value_type;
84         typedef detail::ArrayParser_iterator<value_type> iterator;
85         typedef iterator const_iterator;
86         typedef VectorParser_Container<ElementParser,AuxPolicy> container;
87
88         size_type size() const;
89         bool empty() const;
90
91         iterator begin() const;
92         iterator end() const;
93
94         value_type operator[](difference_type i) const;
95         value_type front() const;
96         value_type back() const;
97
98         // Mutators
99         
100         // The mutators provided here are those which don't take an iterator argument.
101         // If you need to pass an iterator it is much simpler and cleaner to use the
102         // 'container' wrapper
103                    
104         template <class Value> void push_back        (Value value, size_type n=1) const;
105                                void push_back_space  (size_type n=1) const;
106         template <class Value> void push_front       (Value value, size_type n=1) const;
107                                void push_front_space (size_type n=1) const;
108                                void resize           (size_type n) const;
109         template <class Value> void resize           (size_type n, Value value) const;
110
111      private:
112
113         friend class VectorParser_Container<ElementParser,AuxPolicy>;
114     };
115
116     /** \brief Define VectorNParser field
117         
118         This macro is a special helper to define a senf::VectorNParser type field, a vector of
119         elements of type \a elt_type (a parser) which size is given by the \a size field.
120
121         \code
122         // The size field should be declared private (size is accessible via the vector)
123         SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
124         // Define the vector, here it has 32bit unsigned integer elements
125         SENF_PARSER_VEC_N         ( vec,       vec_size_, senf::UInt32Parser );
126         \endcode
127         
128         \param[in] name field name
129         \param[in] size name of field giving the vector size
130         \param[in] elt_type vector element type
131         \hideinitializer
132         \ingroup packetparsermacros
133      */
134
135     /** \brief Define VectorNParser field
136
137         \see \ref SENF_PARSER_VEC_N()
138         \hideinitializer
139         \ingroup packetparsermacros
140      */
141
142 #   define SENF_PARSER_VECTOR(name, size, elt_type) \
143         SENF_PARSER_VECTOR_I(public, name, size, elt_type)
144
145 #   define SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) \
146         SENF_PARSER_VECTOR_I(private, name, size, elt_type)
147
148
149
150     /** \brief VectorParser container wrapper
151
152         This is the container wrapper used for vector parsers. The container wrapper will stay valid
153         after changing the collection. However the container still depends on the packet and will be
154         invalidated if the Packet is deallocated or if the packet size is changed from without the
155         container wrapper (more precisely, it is invalided if the insertion/deletion happens before
156         the vector in the packet data).
157
158         The vector container wrapper provides a complete STL random-access sequence interface.
159         
160         \code
161         SomePacket p (...);
162         SomePacket::aVectorCollection_t::container c (p->aVectorCollection());
163         c.insert(c.begin(), ... );
164         \endcode
165
166         \see VectorParser
167       */
168     template <class ElementParser, class AuxPolicy>
169     class VectorParser_Container
170         : private AuxPolicy
171     {
172     public:
173         ///////////////////////////////////////////////////////////////////////////
174         // Types
175
176         typedef VectorParser<ElementParser,AuxPolicy> parser_type;
177         typedef PacketParserBase::data_iterator data_iterator;
178         typedef PacketParserBase::size_type size_type;
179         typedef PacketParserBase::difference_type difference_type;
180         typedef ElementParser value_type;
181         typedef detail::ArrayParser_iterator<value_type> iterator;
182         typedef iterator const_iterator;
183         typedef PacketParserBase::state_type state_type;
184
185         ///////////////////////////////////////////////////////////////////////////
186         ///\name Structors and default members
187         ///@{
188
189         // no default constructor
190         // default copy
191         // default destructor
192         // conversion constructors
193
194         VectorParser_Container(parser_type const & vector);
195
196         ///@}
197         ///////////////////////////////////////////////////////////////////////////
198
199         ///\name Accessors
200         ///@{
201
202         size_type size() const;
203         bool empty() const;
204
205         iterator begin() const;
206         iterator end() const;
207
208         value_type operator[](difference_type i) const;
209         value_type front() const;
210         value_type back() const;
211
212         ///@}
213         ///\name Mutators
214         ///@{
215
216         iterator shift(iterator pos, size_type n=1);
217         template <class Value>
218         void insert(iterator pos, Value const & t);
219         template <class Value>
220         void insert(iterator pos, size_type n, Value const & t);
221 #       ifndef DOXYGEN
222         template <class ForwardIterator>
223         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
224                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
225 #       else
226         template <class ForwardIterator>
227         void insert(iterator pos, ForwardIterator f, ForwardIterator l);
228 #       endif
229
230         void erase(iterator pos, size_type n=1);
231         void erase(iterator f, iterator l);
232         void clear();
233
234         template <class Value> void push_back        (Value value, size_type n=1);
235                                void push_back_space  (size_type n=1);
236         template <class Value> void push_front       (Value value, size_type n=1);
237                                void push_front_space (size_type n=1);
238                                void resize           (size_type n);
239         template <class Value> void resize           (size_type n, Value value);
240
241         ///@}
242
243         ///\name Parser interface
244         ///@{
245
246         parser_type parser() const;
247         data_iterator i() const;
248         state_type state() const;
249         PacketData & data() const;
250
251         size_type bytes() const;
252         void init() const;
253         
254         ///@}
255
256     protected:
257
258     private:
259         void setSize(size_type value);
260
261         state_type state_;
262         size_type i_;
263     };
264
265 }
266
267 ///////////////////////////////hh.e////////////////////////////////////////
268 #endif
269 #if !defined(HH_Packets__decls_) && !defined(HH_VectorParser_i_)
270 #define HH_VectorParser_i_
271 //#include "VectorParser.cci"
272 #include "VectorParser.ct"
273 #include "VectorParser.cti"
274 #endif
275
276 \f
277 // Local Variables:
278 // mode: c++
279 // fill-column: 100
280 // c-file-style: "senf"
281 // indent-tabs-mode: nil
282 // ispell-local-dictionary: "american"
283 // compile-command: "scons -u test"
284 // comment-column: 40
285 // End: