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