4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
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.
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.
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.
24 \brief PacketImpl public header */
26 #ifndef HH_SENF_Packets_PacketImpl_
27 #define HH_SENF_Packets_PacketImpl_ 1
32 #include <boost/utility.hpp>
33 #include <boost/type_traits/is_base_of.hpp>
34 #include <boost/type_traits/has_trivial_constructor.hpp>
35 #include <boost/type_traits/has_trivial_destructor.hpp>
36 #include <boost/static_assert.hpp>
37 #include "../Utils/pool_alloc_mixin.hh"
38 #include "PacketTypes.hh"
39 #include "../Utils/singleton.hh"
41 //#include "PacketImpl.mpp"
42 ///////////////////////////////hh.p////////////////////////////////////////
46 /** \brief Marker base-class for complex annotations
48 This class is used as a base class to mark an annotation type as complex. A complex
49 annotation will have it's constructor/destructor called. Non-complex annotations will not
50 have their constructor called, they will be zero initialized. The destructor of non-complex
51 annotations is never called.
53 An annotation must be marked as complex if it is not <a
54 href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
55 annotation must be marked as ComplexAnnotation, if
57 \li it has a (user defined) constructor or destructor
58 \li it has any data members which have (user defined) constructors or destructors
60 \see \ref packet_usage_annotation
62 struct ComplexAnnotation {};
68 virtual ~AnnotationP();
71 template <class Annotation>
75 Annotation annotation;
78 union AnnotationEntry {
83 struct AnnotationIndexerBase
85 static unsigned maxAnnotations;
86 static std::vector<bool> & small();
89 template <class Annotation>
90 struct AnnotationIndexer
91 : public senf::singleton< AnnotationIndexer<Annotation> >,
92 public AnnotationIndexerBase
96 static unsigned index();
97 static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
98 static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) && ! Complex);
100 # if 0 // The test is difficult since it does not work with user-defined trivial constructors
101 # ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
103 BOOST_STATIC_ASSERT(( (boost::has_trivial_constructor<Annotation>::value
104 && boost::has_trivial_destructor<Annotation>::value)
111 template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
114 static Annotation & get(AnnotationEntry & e);
117 template <class Annotation>
118 struct GetAnnotation<Annotation, true>
120 static Annotation & get(AnnotationEntry & e);
123 /** \brief Internal: Packet data storage
127 This is the class holding the packet data and the interpreter chain. All manipulations of
128 the packet data are performed via the interface exported here. This is very important, since
129 PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
133 : boost::noncopyable,
134 public pool_alloc_mixin<PacketImpl>
137 typedef senf::detail::packet::byte byte;
138 typedef senf::detail::packet::raw_container raw_container;
139 typedef senf::detail::packet::size_type size_type;
140 typedef senf::detail::packet::difference_type difference_type;
141 typedef senf::detail::packet::interpreter_list interpreter_list;
142 typedef senf::detail::packet::iterator iterator;
143 typedef senf::detail::packet::const_iterator const_iterator;
144 typedef senf::detail::packet::refcount_t refcount_t;
149 PacketImpl(size_type size, byte initValue);
150 template <class InputIterator>
151 PacketImpl(InputIterator b, InputIterator e);
154 // rerference/memory management
156 void add_ref(refcount_t n=1);
157 void release(refcount_t n=1);
158 refcount_t refcount() const;
162 PacketInterpreterBase * first();
163 PacketInterpreterBase * last();
165 PacketInterpreterBase * next(PacketInterpreterBase * p);
166 PacketInterpreterBase * prev(PacketInterpreterBase * p);
168 void appendInterpreter (PacketInterpreterBase * p);
169 void prependInterpreter (PacketInterpreterBase * p);
170 void truncateInterpreters (PacketInterpreterBase * p);
171 void truncateInterpretersBackwards (PacketInterpreterBase * p);
179 void insert(PacketData * self, iterator pos, byte v);
180 void insert(PacketData * self, iterator pos, size_type n, byte v);
181 template <class ForwardIterator>
182 void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
184 void erase(PacketData * self, iterator pos);
185 void erase(PacketData * self, iterator first, iterator last);
186 void clear(PacketData * self);
188 void reserve(size_type n);
189 size_type capacity() const;
192 template <class Annotation>
193 Annotation & annotation();
195 /** \brief Internal: Keep PacketImpl instance alive
199 The Guard will keep the PacketImpl instance alive during a members execution time
200 It the refcount should drop to 0, PacketImpl will be deleted after the member
201 has completed executing.
204 Guard(PacketImpl * impl);
210 refcount_t refcount_;
212 interpreter_list interpreters_;
214 typedef std::vector<AnnotationEntry> Annotations;
215 Annotations annotations_;
217 void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
218 void updateIterators(PacketData * self, difference_type pos, difference_type n);
223 ///////////////////////////////hh.e////////////////////////////////////////
225 #if !defined(HH_SENF_Packets_Packets__decls_) && !defined(HH_SENF_Packets_PacketImpl_i_)
226 #define HH_SENF_Packets_PacketImpl_i_
227 #include "PacketImpl.cci"
228 //#include "PacketImpl.ct"
229 #include "PacketImpl.cti"
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