NEW FILE HEADER / COPYRIGHT FORMAT
[senf.git] / Packets / ListParser.hh
1 // $Id$
2 //
3 // Copyright (C) 2007 
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 ListParser public header */
25
26 #ifndef HH_ListParser_
27 #define HH_ListParser_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31 #include "PacketParser.hh"
32
33 //#include "ListParser.mpp"
34 ///////////////////////////////hh.p////////////////////////////////////////
35
36 namespace senf {
37
38     namespace detail { template <class ElementParser, class IteratorPolicy> 
39                        class ListParser_Iterator; }
40
41     template <class ListPolicy>
42     class ListParser_Container;
43
44     /** \brief Arbitrary sequential element collection
45
46         A List is a sequential collection of elements. The element type is given as an arbitrary
47         parser. The list is more flexible than a vector: It is not limited to fixed-size elements
48         and it might not have direct access to the size of the collection. 
49
50         The cost is however, that a List is only a model of an STL forward sequence. The parser
51         provides a reduced interface to this sequence, the container wrapper provides the complete
52         interface.
53
54         Pare_List makes use of a policy template argument, \a ListPolicy, to customize the way the
55         list is laid out. This policy is given quite some freedom in the list
56         implementation. It is however important, that list elements <em>always follow each other
57         without padding</em> (if padding is needed, it needs to be part of the element parser).
58
59         \see ExampleListPolicy
60         \ingroup parsecollection
61       */
62     template <class ListPolicy>
63     class ListParser 
64         : public PacketParserBase,
65           private ListPolicy
66     {
67     public:
68         ListParser(data_iterator i, state_type s);
69         ListParser(ListPolicy policy, data_iterator i, state_type s);
70                                         ///< Additional policy specific constructor
71                                         /**< This constructor may be used, if the policy needs
72                                              additional parameters. */
73
74         size_type bytes() const;
75         void init() const;
76
77         static const size_type init_bytes = ListPolicy::init_bytes;
78
79         ///////////////////////////////////////////////////////////////////////////
80         // Container interface
81
82         typedef typename ListPolicy::element_type value_type;
83         typedef detail::ListParser_Iterator< 
84             value_type, typename ListPolicy::iterator_policy > iterator;
85         typedef iterator const_iterator;
86         typedef typename ListPolicy::container_type container;
87
88         size_type size() const;
89         bool empty() const;
90         
91         iterator begin() const;
92         iterator end() const;
93
94         value_type front() const;
95         value_type back() const;
96         
97         template <class Value> void push_back        (Value value, size_type n=1) const;
98                                void push_back_space  (size_type n=1) const;
99         template <class Value> void push_front       (Value value, size_type n=1) const;
100                                void push_front_space (size_type n=1) const;
101                                void resize           (size_type n) const;
102         template <class Value> void resize           (size_type n, Value value) const;
103
104     private:
105         template <class Policy> friend class ListParser_Container;
106     };
107
108     /** \brief ListParser container wrapper
109
110         This is the container wrapper used for list parsers. The container wrapper will stay valid
111         after changing the collection. However the container still depends on the packet and will be
112         invalidated if the Packet is deallocated or if the packet size is changed from without the
113         container wrapper (more precisely, it is invalided if the insertion/deletion happens before
114         the vector in the packet data).
115
116         The vector container wrapper provides a complete STL random-access sequence interface.
117         
118         \code
119         SomePacket p (...);
120         SomePacket::aListCollection_t::container c (p->aListCollection());
121         c.insert(c.begin(), ... );
122         \endcode
123
124         \see ListParser
125       */
126     template <class ListPolicy>
127     class ListParser_Container
128         : private ListPolicy
129     {
130     public:
131         ///////////////////////////////////////////////////////////////////////////
132         // Types
133
134         typedef typename ListPolicy::parser_type parser_type;
135         typedef PacketParserBase::data_iterator data_iterator;
136         typedef PacketParserBase::size_type size_type;
137         typedef PacketParserBase::difference_type difference_type;
138         typedef typename ListPolicy::element_type value_type;
139         typedef detail::ListParser_Iterator<
140             value_type, typename ListPolicy::iterator_policy> iterator;
141         typedef iterator const_iterator;
142         typedef PacketParserBase::state_type state_type;
143         
144         ///////////////////////////////////////////////////////////////////////////
145         ///\name Structors and default members
146         ///@{
147
148         // no default constructor
149         // default copy
150         // default destructor
151         // conversion constructors
152
153         ListParser_Container(parser_type const & list);
154         ~ListParser_Container();
155         
156         ///@}
157         ///////////////////////////////////////////////////////////////////////////
158
159         ///\name Accessors
160         ///@{
161
162         size_type size() const;
163         bool empty() const;
164
165         iterator begin() const;
166         iterator end() const;
167
168         value_type front() const;
169         value_type back() const;
170
171         ///@}
172         ///\name Mutators
173         ///@{
174
175         // All these operations can be quite inefficient depending on the list type
176         void shift(iterator pos, size_type n=1);
177         template <class Value>
178         void insert(iterator pos, Value const & t);
179         template <class Value>
180         void insert(iterator pos, size_type n, Value const & t);
181         template <class ForwardIterator>
182 #       ifndef DOXYGEN
183         void insert(iterator pos, ForwardIterator f, ForwardIterator l,
184                     typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type * = 0);
185 #       else
186         void insert(iterator pos, ForwardIterator f, ForwardIterator l);
187 #       endif
188
189         void erase(iterator pos, size_type n=1);
190         void erase(iterator f, iterator l);
191         void clear();
192
193         template <class Value> void push_back        (Value value, size_type n=1);
194                                void push_back_space  (size_type n=1);
195         template <class Value> void push_front       (Value value, size_type n=1);
196                                void push_front_space (size_type n=1);
197                                void resize           (size_type n);
198         template <class Value> void resize           (size_type n, Value value);
199
200         ///@}
201
202         ///\name Parser interface
203         ///@{
204
205         parser_type parser() const;
206         data_iterator i() const;
207         state_type state() const;
208         PacketData & data() const;
209
210         size_type bytes() const;
211         void init() const;
212         
213         ///@}
214
215     private:
216         state_type state_;
217         size_type i_;
218     };
219
220         
221 }
222
223 ///////////////////////////////hh.e////////////////////////////////////////
224 #endif
225 #if !defined(HH_Packets__decls_) && !defined(HH_ListParser_i_)
226 #define HH_ListParser_i_
227 //#include "ListParser.cci"
228 #include "ListParser.ct"
229 #include "ListParser.cti"
230 #endif
231
232 \f
233 // Local Variables:
234 // mode: c++
235 // fill-column: 100
236 // c-file-style: "senf"
237 // indent-tabs-mode: nil
238 // ispell-local-dictionary: "american"
239 // compile-command: "scons -u test"
240 // comment-column: 40
241 // End: