Fix SCons 1.2.0 build failure
[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_SENF_Packets_VectorParser_
27 #define HH_SENF_Packets_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 AuxPolicy, to customize the way the
55         containers size is obtained. You will normally not instantiate VectorParser directly, you
56         will use the \ref SENF_PARSER_VECTOR() helper macro.
57
58         Some basic vector access methods are defined as parser members. To access the complete list
59         API however you will need to instantiate a container wrapper for the vector. See \ref
60         packet_usage_fields_collection.
61         
62         \see
63             \ref How to access \ref packet_usage_fields_collection \n
64             SENF_PARSER_VECTOR() macro used to define vector fields \n
65             VectorParser_Container vector container wrapper API
66
67         \ingroup parsecollection
68      */
69     template <class ElementParser, class AuxPolicy>
70     struct VectorParser 
71         : public PacketParserBase, 
72           private AuxPolicy
73     {
74         VectorParser(data_iterator i, state_type s);
75         VectorParser(AuxPolicy policy, data_iterator i, state_type s);
76                                         ///< Additional sizer specific constructor
77                                         /**< This constructor may be used, if the sizer needs
78                                              additional parameters. */
79
80         size_type bytes() const;
81         void init() const;
82
83         static const size_type init_bytes = AuxPolicy::aux_bytes;
84
85         ///////////////////////////////////////////////////////////////////////////
86         // Container interface
87
88         typedef ElementParser value_type;
89         typedef detail::ArrayParser_iterator<value_type> iterator;
90         typedef iterator const_iterator;
91         typedef VectorParser_Container<ElementParser,AuxPolicy> container;
92
93         size_type size() const;
94         bool empty() const;
95
96         iterator begin() const;
97         iterator end() const;
98
99         value_type operator[](difference_type i) const;
100         value_type front() const;
101         value_type back() const;
102
103         // Mutators
104         
105         // The mutators provided here are those which don't take an iterator argument.
106         // If you need to pass an iterator it is much simpler and cleaner to use the
107         // 'container' wrapper
108                    
109         template <class Value> void push_back        (Value value, size_type n=1) const;
110                                void push_back_space  (size_type n=1) const;
111         template <class Value> void push_front       (Value value, size_type n=1) const;
112                                void push_front_space (size_type n=1) const;
113                                void resize           (size_type n) const;
114         template <class Value> void resize           (size_type n, Value value) const;
115
116      private:
117
118         friend class VectorParser_Container<ElementParser,AuxPolicy>;
119     };
120
121     /** \brief VectorParser container wrapper
122
123         This is the container wrapper used for vector parsers. The container wrapper will stay valid
124         after changing the collection. However the container still depends on the packet and will be
125         invalidated if the Packet is deallocated or if the packet size is changed from without the
126         container wrapper (more precisely, it is invalided if the insertion/deletion happens before
127         the vector in the packet data).
128
129         The vector container wrapper provides a complete STL random-access sequence interface.
130         
131         \code
132         SomePacket p (...);
133         SomePacket::aVectorCollection_t::container c (p->aVectorCollection());
134         c.insert(c.begin(), ... );
135         \endcode
136
137         \see VectorParser
138       */
139     template <class ElementParser, class AuxPolicy>
140     class VectorParser_Container
141         : private AuxPolicy::WrapperPolicy
142     {
143     public:
144         ///////////////////////////////////////////////////////////////////////////
145         // Types
146
147         typedef VectorParser<ElementParser,AuxPolicy> parser_type;
148         typedef PacketParserBase::data_iterator data_iterator;
149         typedef PacketParserBase::size_type size_type;
150         typedef PacketParserBase::difference_type difference_type;
151         typedef ElementParser value_type;
152         typedef detail::ArrayParser_iterator<value_type> iterator;
153         typedef iterator const_iterator;
154         typedef PacketParserBase::state_type state_type;
155
156         ///////////////////////////////////////////////////////////////////////////
157         ///\name Structors and default members
158         ///@{
159
160         // no default constructor
161         // default copy
162         // default destructor
163         // conversion constructors
164
165         VectorParser_Container(parser_type const & vector);
166
167         ///@}
168         ///////////////////////////////////////////////////////////////////////////
169
170         ///\name Accessors
171         ///@{
172
173         size_type size() const;
174         bool empty() const;
175
176         iterator begin() const;
177         iterator end() const;
178
179         value_type operator[](difference_type i) const;
180         value_type front() const;
181         value_type back() const;
182
183         ///@}
184         ///\name Mutators
185         ///@{
186
187         iterator shift(iterator pos, size_type n=1);
188         template <class Value>
189         void insert(iterator pos, Value const & t);
190         template <class Value>
191         void insert(iterator pos, size_type n, Value const & t);
192 #       ifndef DOXYGEN
193         template <class ForwardIterator>
194         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
195                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
196 #       else
197         template <class ForwardIterator>
198         void insert(iterator pos, ForwardIterator f, ForwardIterator l);
199 #       endif
200
201         void erase(iterator pos, size_type n=1);
202         void erase(iterator f, iterator l);
203         void clear();
204
205         template <class Value> void push_back        (Value value, size_type n=1);
206                                void push_back_space  (size_type n=1);
207         template <class Value> void push_front       (Value value, size_type n=1);
208                                void push_front_space (size_type n=1);
209                                void resize           (size_type n);
210         template <class Value> void resize           (size_type n, Value value);
211
212         ///@}
213
214         ///\name Parser interface
215         ///@{
216
217         parser_type parser() const;
218         data_iterator i() const;
219         state_type state() const;
220         PacketData & data() const;
221
222         size_type bytes() const;
223         void init() const;
224         
225         ///@}
226
227     protected:
228
229     private:
230         void setSize(size_type value);
231
232         state_type state_;
233         size_type i_;
234     };
235
236     /** \brief Define VectorParser field
237         
238         This macro is a special helper to define a senf::VectorParser type field, a vector of
239         elements of type \a elt_type (a parser) which size is given by the \a size field.
240
241         \code
242         // The size field should be declared private (size is accessible via the vector)
243         SENF_PARSER_PRIVATE_FIELD ( vec_size_, senf::UInt16Parser );
244         // Define the vector, here it has 32bit unsigned integer elements
245         SENF_PARSER_VECTOR        ( vec,       vec_size_, senf::UInt32Parser );
246         \endcode
247
248         \warning Realize, that the \a size field is controlled by the vector parser. This field
249             should therefore be declared either read-only or private and must be changed only via
250             the vector parser.
251
252         Further additional tags are supported which modify the way, the \a size field is
253         interpreted:
254
255         <table class="senf fixedcolumn">
256         <tr><td>\c bytes(\a size)</td><td>\a size gives the size of the vector in bytes not the
257         number of contained elements</td></tr>
258         
259         <tr><td>\c packetSize()</td><td>Use the size of the packet to get the vector size. The
260         vector will occupy all space up to the end of the packet.</td></tr>
261
262         <tr><td>\c transform(\a transform, \a size)</td><td>The \a transform is applied to the \a
263         size value, the value is not used directly</td>
264         </table>
265
266         The optional \a transform is a class with the following layout
267
268         \code
269         struct MyTransform
270         {
271             typedef ... value_type;
272             static value_type get(other_type v);
273             static other_type set(value_type v);
274         };
275         \endcode \c other_type is the \a size ::\c value_type where as the \c value_type typedef is
276         the arbitrary return type of the transform.
277
278         The tags are applied to the \a size parameter:
279         \code
280         SENF_PARSER_VECTOR ( vec, transform(MyTransform, vec_size_), senf::UInt32Parser );
281         SENF_PARSER_VECTOR ( vec, packetSize(), senf::UInt32Parser );
282         \endcode
283         
284         \param[in] name field name
285         \param[in] size name of field giving the vector size
286         \param[in] elt_type vector element type
287
288         \see 
289             How to use \ref packet_usage_fields_collection \n
290             senf::VectorParser the vector parser API for vector field access
291             senf::VectorParser_Container the vector parser container API for vector field access
292
293         \hideinitializer
294         \ingroup packetparsermacros
295      */
296 #   define SENF_PARSER_VECTOR(name, size, elt_type) \
297         SENF_PARSER_VECTOR_I(public, name, size, elt_type)
298
299     /** \brief Define private VectorParser field
300
301         \see \ref SENF_PARSER_VECTOR()
302
303         \hideinitializer
304         \ingroup packetparsermacros
305      */
306 #   define SENF_PARSER_PRIVATE_VECTOR(name, size, elt_type) \
307         SENF_PARSER_VECTOR_I(protected, name, size, elt_type)
308 }
309
310 ///////////////////////////////hh.e////////////////////////////////////////
311 #endif
312 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_VectorParser_i_)
313 #define HH_SENF_Packets_VectorParser_i_
314 //#include "VectorParser.cci"
315 #include "VectorParser.ct"
316 #include "VectorParser.cti"
317 #endif
318
319 \f
320 // Local Variables:
321 // mode: c++
322 // fill-column: 100
323 // c-file-style: "senf"
324 // indent-tabs-mode: nil
325 // ispell-local-dictionary: "american"
326 // compile-command: "scons -u test"
327 // comment-column: 40
328 // End: