switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / ListParser.ct
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at 
9 // http://senf.berlios.de/license.html
10 //
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on, 
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
14 //
15 // Software distributed under the License is distributed on an "AS IS" basis, 
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
17 // for the specific language governing rights and limitations under the License.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V. 
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief ListParser non-inline template implementation  */
30
31 #include "ListParser.ih"
32
33 // Custom includes
34 #include <senf/Utils/senfassert.hh>
35
36 #define prefix_
37 //-/////////////////////////////////////////////////////////////////////////////////////////////////
38
39 //-/////////////////////////////////////////////////////////////////////////////////////////////////
40 // senf::ListParser<ElementParser,ListPolicy>
41
42 template <class ListPolicy>
43 prefix_ void senf::ListParser<ListPolicy>::init()
44     const
45 {
46     ListPolicy::init(i(),state());
47     container c (*this);
48     typename container::iterator i (c.begin());
49     typename container::iterator const e (c.end());
50     for (; i!=e; ++i)
51         i->init();
52 }
53
54 template <class ListPolicy>
55 prefix_ typename senf::ListParser<ListPolicy>::value_type
56 senf::ListParser<ListPolicy>::back()
57     const
58 {
59     SENF_ASSERT( ! empty(), "back() called on empty list" );
60     container c(*this);
61     typename container::iterator i (c.begin()), j;
62     typename container::iterator const e (c.end());
63     for (j=i; i!=e; j=i, ++i) ;
64     return *j;
65 }
66
67 //-/////////////////////////////////////////////////////////////////////////////////////////////////
68 // senf::ListParser_Container<ListPolicy>
69
70 template <class ListPolicy>
71 prefix_ typename senf::ListParser_Container<ListPolicy>::value_type
72 senf::ListParser_Container<ListPolicy>::back()
73     const
74 {
75     SENF_ASSERT( ! empty(), "back() called on empty list" );
76     iterator i (begin()), j;
77     iterator const e (end());
78     for (j=i; i!=e; j=i, ++i) ;
79     return *j;
80 }
81
82 template <class ListPolicy>
83 prefix_ typename senf::ListParser_Container<ListPolicy>::value_type
84 senf::ListParser_Container<ListPolicy>::shift(iterator pos, size_type n)
85 {
86     ListPolicy::update(*this);
87     safe_data_iterator sp (data(),pos.raw());
88     for (; n>0; --n) {
89         data().insert(sp,senf::init_bytes<value_type>::value,0);
90         value_type(sp,state()).init();
91         ListPolicy::insert(*this,sp);
92     }
93     return value_type(sp,state());
94 }
95
96 template <class ListPolicy>
97 template <class Value>
98 prefix_ void senf::ListParser_Container<ListPolicy>::insert(iterator pos,
99                                                             size_type n,
100                                                             Value const & t)
101 {
102     ListPolicy::update(*this);
103     safe_data_iterator sp (data(),pos.raw());
104     for (; n>0; --n) {
105         data().insert(sp,senf::init_bytes<value_type>::value,0);
106         value_type(sp,state()).init();
107         value_type(sp,state()) << t;
108         ListPolicy::insert(*this,sp);
109     }
110 }
111
112 #ifndef DOXYGEN
113 template <class ListPolicy>
114 template <class ForwardIterator>
115 prefix_ void senf::ListParser_Container<ListPolicy>::
116 insert(iterator pos, ForwardIterator f, ForwardIterator l,
117        typename boost::disable_if< boost::is_convertible<ForwardIterator,size_type> >::type *)
118 {
119     ListPolicy::update(*this);
120     safe_data_iterator sp (data(),pos.raw());
121     for (; f!=l; ++f) {
122         data().insert(sp,senf::init_bytes<value_type>::value,0);
123         value_type(sp,state()).init();
124         value_type(sp,state()) << *f;
125         ListPolicy::insert(*this,sp);
126         sp += senf::bytes(value_type(sp,state()));
127     }
128 }
129 #else
130 template <class ListPolicy>
131 template <class ForwardIterator>
132 prefix_ void senf::ListParser_Container<ListPolicy>::
133 insert(iterator pos, ForwardIterator f, ForwardIterator l)
134 {}
135 #endif
136
137 template <class ListPolicy>
138 prefix_ void senf::ListParser_Container<ListPolicy>::erase(iterator pos,
139                                                            size_type n)
140 {
141     ListPolicy::update(*this);
142     safe_data_iterator sp (data(),pos.raw());
143     for (; n>0; --n) {
144         ListPolicy::erase(*this,sp);
145         data().erase(sp,boost::next(sp,senf::bytes(value_type(sp,state()))));
146     }
147 }
148
149 template <class ListPolicy>
150 prefix_ void senf::ListParser_Container<ListPolicy>::clear()
151 {
152     size_type sz (bytes());
153     if (sz > ListPolicy::init_bytes)
154         data().erase(boost::next(i(),ListPolicy::init_bytes),boost::next(i(),sz));
155     else
156         data().insert(boost::next(i(),sz), ListPolicy::init_bytes-sz, 0u);
157     std::fill(i(),boost::next(i(),ListPolicy::init_bytes), 0u);
158     ListPolicy::init(i(),state());
159 }
160
161 template <class ListPolicy>
162 prefix_ void senf::ListParser_Container<ListPolicy>::resize(size_type n)
163 {
164     size_type sz (size());
165     if (sz>n)
166         erase(boost::next(begin(),n),end());
167     else
168         push_back_space(n-sz);
169 }
170
171 template <class ListPolicy>
172 template <class Value>
173 prefix_ void senf::ListParser_Container<ListPolicy>::resize(size_type n,
174                                                             Value value)
175 {
176     size_type sz (size());
177     if (sz>n)
178         erase(boost::next(begin(),n),end());
179     else
180         push_back(value,n-sz);
181 }
182
183 //-/////////////////////////////////////////////////////////////////////////////////////////////////
184 #undef prefix_
185
186 \f
187 // Local Variables:
188 // mode: c++
189 // fill-column: 100
190 // comment-column: 40
191 // c-file-style: "senf"
192 // indent-tabs-mode: nil
193 // ispell-local-dictionary: "american"
194 // compile-command: "scons -u test"
195 // End: