Fixed whitespace in all files (no tabs)
[senf.git] / Packets / ParseListS.hh
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
5 // Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
6 //     Stefan Bund <stefan.bund@fokus.fraunhofer.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
25     \idea Add an optional state to the sentinel and an optional
26     transition function. See ParseListS.hh for more.
27
28     We should write a baseclass for sentinels which has no \c check()
29     member, en empty \c next() member and \c void as the state
30     type. This simplifies writing simple sentinels.
31
32     The parse_listS iterator will have to pass the state in addition
33     to the current list element to \c check(). The \c next() member
34     will be invoked to advance the iterator. It is passer the current
35     element and a (non-const) reference to the state which it may
36     update. The Parse_ListS constructor must take an arbitrary number
37     of additional arguments which are forwarded to the state
38     initialization.
39
40     This structure makes it simple to optimize away the overhead if
41     the state type is void. If we would always instantiate the
42     sentinel, this will always take up space.
43
44     Another possibility would be to always instantiate the sentinel
45     and make the baseclass mandatory. The baseclass would then hold
46     the current raw iterator. The iterator itself would ONLY include a
47     single sentinel instance .. I think, this is the best solution,
48     sentinel members then have intrinsic access to the
49     state. Arguments are forwarded from the list constructor to the
50     Sentinel constructor.
51  */
52
53 #ifndef HH_ParseListS_
54 #define HH_ParseListS_ 1
55
56 // Custom includes
57 #include <utility> // for std::pair
58 #include <boost/iterator/iterator_facade.hpp>
59 #include <boost/utility.hpp> // for boost::noncopyable
60 #include "ParserBase.hh"
61
62 //#include "ParseListS.mpp"
63 ///////////////////////////////hh.p////////////////////////////////////////
64
65 namespace senf {
66
67
68     template <class Parser, class Sentinel, class Container> class Parse_ListS_wrapper;
69     namespace impl {
70         template <class Parser, class Sentinel, class Container> class Parse_ListS_iterator;
71     }
72
73     template <class Parser, class Sentinel, class Iterator=nil, class IPacket=nil>
74     struct Parse_ListS : public ParserBase<Iterator,IPacket>
75     {
76         ///////////////////////////////////////////////////////////////////////////
77         // Parser interface
78
79         template <class I=nil, class P=nil>
80         struct rebind { typedef Parse_ListS<Parser,Sentinel,I,P> parser; };
81         typedef Iterator byte_iterator;
82
83         Parse_ListS();
84         Parse_ListS(Iterator const & i);
85
86         unsigned bytes() const;
87         bool check(Iterator const & e) const;
88         void init() const;
89
90         ///////////////////////////////////////////////////////////////////////////
91         // Container interface
92
93         typedef typename Parser::template rebind<Iterator>::parser value_type;
94         typedef Sentinel sentinel;
95         typedef impl::Parse_ListS_iterator<value_type,sentinel,byte_iterator> iterator;
96         typedef unsigned size_type;
97         typedef int difference_type;
98         typedef std::pair<iterator,iterator> range_type;
99
100         template <class Container>
101         struct wrapper { typedef Parse_ListS_wrapper<value_type, Sentinel, Container> t; };
102
103         size_type size() const;
104         bool empty() const;
105
106         iterator begin() const;
107         iterator end() const;
108         range_type range() const;
109         range_type value() const;
110
111      private:
112         template <class P, class S, class C> friend class Parse_ListS_wrapper;
113     };
114
115     /** \brief
116
117         Holds a reference to the container !
118       */
119     template <class Parser, class Sentinel, class Container>
120     class Parse_ListS_wrapper
121         : public boost::noncopyable
122     {
123     public:
124         ///////////////////////////////////////////////////////////////////////////
125         // Types
126
127         typedef Container container;
128         typedef Sentinel sentinel;
129         typedef typename Parser::byte_iterator byte_iterator;
130         typedef Parser value_type;
131         typedef impl::Parse_ListS_iterator<value_type,sentinel,byte_iterator> iterator;
132         typedef unsigned size_type;
133         typedef int difference_type;
134         typedef std::pair<iterator,iterator> range_type;
135
136         ///////////////////////////////////////////////////////////////////////////
137         ///\name Structors and default members
138         ///@{
139
140         template <class P, class S, class I, class IP>
141         Parse_ListS_wrapper(Parse_ListS<P,S,I,IP> const & list, Container & container);
142
143         // no default constructor
144         // no copy
145         // default destructor
146         // no conversion constructors
147
148         ///@}
149         ///////////////////////////////////////////////////////////////////////////
150         ///\name Accessors
151         ///@{
152
153         size_type size() const;
154         bool empty() const;
155
156         iterator begin() const;
157         iterator end() const;
158         range_type range() const;
159
160         ///@}
161         ///////////////////////////////////////////////////////////////////////////
162         ///\name Mutators
163         ///@{
164
165         template <class Value> void insert(iterator pos, Value const & t);
166         template <class Value> void insert(iterator pos, size_type n, Value const & t);
167         template <class InputIterator> void insert(iterator pos, InputIterator f, InputIterator l);
168
169         void erase(iterator pos, size_type n=1);
170         void erase(iterator f, iterator l);
171         void clear();
172
173         ///@}
174
175     protected:
176
177     private:
178
179         size_type i_;
180         Container & container_;
181     };
182
183 }
184
185 ///////////////////////////////hh.e////////////////////////////////////////
186 //#include "ParseListS.cci"
187 #include "ParseListS.ct"
188 #include "ParseListS.cti"
189 #endif
190
191 \f
192 // Local Variables:
193 // mode: c++
194 // fill-column: 100
195 // c-file-style: "senf"
196 // indent-tabs-mode: nil
197 // ispell-local-dictionary: "american"
198 // End: