Fixes for boost-1.36 + gcc-4.3
[senf.git] / Packets / PacketImpl.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 PacketImpl public header */
25
26 #ifndef HH_PacketImpl_
27 #define HH_PacketImpl_ 1
28
29 // Custom includes
30 #include <memory>
31 #include <vector>
32 #include <boost/utility.hpp>
33 #include <boost/type_traits/is_base_of.hpp>
34 #include <boost/type_traits/is_pod.hpp>
35 #include <boost/static_assert.hpp>
36 #include "../Utils/pool_alloc_mixin.hh"
37 #include "PacketTypes.hh"
38 #include "../Utils/singleton.hh"
39
40 //#include "PacketImpl.mpp"
41 ///////////////////////////////hh.p////////////////////////////////////////
42
43 namespace senf {
44
45     /** \brief Marker base-class for complex annotations
46
47         This class is used as a base class to mark an annotation type as complex. A complex
48         annotation will have it's constructor/destructor called. Non-complex annotations will not
49         have their constructor called, they will be zero initialized. The destructor of non-complex
50         annotations is never called.
51
52         An annotation must be marked as complex if it is not <a
53         href="http://en.wikipedia.org/wiki/Plain_Old_Data_Structures">POD</a>. Simplified, an
54         annotation must be marked as ComplexAnnotation, if
55
56         \li it has a (user defined) constructor or destructor
57         \li it has any data members which have (user defined) constructors or destructors
58
59         \see \ref packet_usage_annotation
60      */
61     struct ComplexAnnotation {};
62
63 namespace detail {
64
65     struct AnnotationP
66     {
67         virtual ~AnnotationP();
68     };
69
70     template <class Annotation>
71     struct TAnnotationP
72         : public AnnotationP
73     {
74         Annotation annotation;
75     };
76
77     union AnnotationEntry {
78         AnnotationP * p;
79         unsigned long long i;
80     };
81
82     struct AnnotationIndexerBase
83     {
84         static unsigned maxAnnotations;
85         static std::vector<bool> & small();
86     };
87
88     template <class Annotation>
89     struct AnnotationIndexer 
90         : public senf::singleton< AnnotationIndexer<Annotation> >, 
91           public AnnotationIndexerBase
92     {
93         AnnotationIndexer();
94         unsigned index_;
95         static unsigned index();
96         static bool const Complex = boost::is_base_of<ComplexAnnotation, Annotation>::value;
97         static bool const Small = (sizeof(Annotation) <= sizeof(AnnotationEntry) && ! Complex);
98
99 #       ifdef BOOST_HAS_TYPE_TRAITS_INTRINSICS
100
101         BOOST_STATIC_ASSERT(( boost::is_pod<Annotation>::value || Complex ));
102
103 #       endif
104     };
105
106     template <class Annotation, bool Small = AnnotationIndexer<Annotation>::Small>
107     struct GetAnnotation
108     {
109         static Annotation & get(AnnotationEntry & e);
110     };
111
112     template <class Annotation>
113     struct GetAnnotation<Annotation, true>
114     {
115         static Annotation & get(AnnotationEntry & e);
116     };
117
118     /** \brief Internal: Packet data storage
119
120         \internal
121
122         This is the class holding the packet data and the interpreter chain. All manipulations of
123         the packet data are performed via the interface exported here. This is very important, since
124         PacketImpl will update the interpreters (that is the vector indices stored therein) whenever
125         the data is changed.
126      */
127     class PacketImpl
128         : boost::noncopyable,
129           public pool_alloc_mixin<PacketImpl>
130     {
131     public:
132         typedef senf::detail::packet::byte byte;
133         typedef senf::detail::packet::raw_container raw_container;
134         typedef senf::detail::packet::size_type size_type;
135         typedef senf::detail::packet::difference_type difference_type;
136         typedef senf::detail::packet::interpreter_list interpreter_list;
137         typedef senf::detail::packet::iterator iterator;
138         typedef senf::detail::packet::const_iterator const_iterator;
139         typedef senf::detail::packet::refcount_t refcount_t;
140
141         // structors
142
143         PacketImpl();
144         PacketImpl(size_type size, byte initValue);
145         template <class InputIterator>
146         PacketImpl(InputIterator b, InputIterator e);
147         ~PacketImpl();
148
149         // rerference/memory management
150
151         void add_ref(refcount_t n=1);
152         void release(refcount_t n=1);
153         refcount_t refcount() const;
154
155         // Interpreter chain
156
157         PacketInterpreterBase * first();
158         PacketInterpreterBase * last();
159
160         PacketInterpreterBase * next(PacketInterpreterBase * p);
161         PacketInterpreterBase * prev(PacketInterpreterBase * p);
162
163         void appendInterpreter    (PacketInterpreterBase * p);
164         void prependInterpreter   (PacketInterpreterBase * p);
165         void truncateInterpreters (PacketInterpreterBase * p);
166         void truncateInterpretersBackwards (PacketInterpreterBase * p);
167
168         // Data container
169
170         iterator begin();
171         iterator end();
172         size_type size();
173
174         void insert(PacketData * self, iterator pos, byte v);
175         void insert(PacketData * self, iterator pos, size_type n, byte v);
176         template <class ForwardIterator>
177         void insert(PacketData * self, iterator pos, ForwardIterator f, ForwardIterator l);
178
179         void erase(PacketData * self, iterator pos);
180         void erase(PacketData * self, iterator first, iterator last);
181         void clear(PacketData * self);
182
183         // Annotations
184         template <class Annotation>
185         Annotation & annotation();
186
187         /** \brief Internal: Keep PacketImpl instance alive
188
189             \internal
190
191             The Guard will keep the PacketImpl instance alive during a members execution time
192             It the refcount should drop to 0, PacketImpl will be deleted after the member
193             has completed executing.
194          */
195         struct Guard {
196             Guard(PacketImpl * impl);
197             ~Guard();
198             PacketImpl * p;
199         };
200
201     private:
202         refcount_t refcount_;
203         raw_container data_;
204         interpreter_list interpreters_;
205         
206         typedef std::vector<AnnotationEntry> Annotations;
207         Annotations annotations_;
208
209         void eraseInterpreters(interpreter_list::iterator b, interpreter_list::iterator e);
210         void updateIterators(PacketData * self, difference_type pos, difference_type n);
211     };
212
213 }}
214
215 ///////////////////////////////hh.e////////////////////////////////////////
216 #endif
217 #if !defined(HH_Packets__decls_) && !defined(HH_PacketImpl_i_)
218 #define HH_PacketImpl_i_
219 #include "PacketImpl.cci"
220 //#include "PacketImpl.ct"
221 #include "PacketImpl.cti"
222 #endif
223
224 \f
225 // Local Variables:
226 // mode: c++
227 // fill-column: 100
228 // c-file-style: "senf"
229 // indent-tabs-mode: nil
230 // ispell-local-dictionary: "american"
231 // compile-command: "scons -u test"
232 // comment-column: 40
233 // End:
234