4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
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
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.
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.
19 // The Original Code is Fraunhofer FOKUS code.
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.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief PacketImpl internal header */
31 #ifndef IH_SENF_senf_Packets_PacketImpl_
32 #define IH_SENF_senf_Packets_PacketImpl_ 1
38 #include <ext/functional>
39 #include <boost/iterator/transform_iterator.hpp>
40 #include <boost/type_traits/is_convertible.hpp>
41 #include <boost/mpl/sizeof.hpp>
42 #include <boost/mpl/int.hpp>
43 #include <boost/mpl/or.hpp>
44 #include <boost/mpl/greater.hpp>
45 #include <boost/ptr_container/ptr_map.hpp>
46 #include <senf/Utils/TypeInfo.hh>
47 #include <senf/Utils/singleton.hh>
48 #include <senf/config.hh>
49 #include <senf/Utils/IgnoreValue.hh>
51 //-/////////////////////////////////////////////////////////////////////////////////////////////////
55 struct ComplexAnnotation;
59 template <class Annotation>
60 struct IsComplexAnnotation
61 : public boost::mpl::or_< boost::is_convertible<Annotation*, ComplexAnnotation*>,
63 boost::mpl::sizeof_<Annotation>,
64 boost::mpl::int_<SENF_PACKET_ANNOTATION_SLOTSIZE> > >
67 class AnnotationRegistry
68 : public senf::singleton<AnnotationRegistry>
74 struct RegistrationBase
76 virtual ~RegistrationBase () {};
78 virtual void v_dump(std::ostream & os, void * annotation) const = 0;
79 virtual std::string v_name() const = 0;
80 virtual bool v_isComplex() const = 0;
81 virtual unsigned v_size() const = 0;
84 template <class Annotation>
86 : public RegistrationBase
88 void v_dump(std::ostream & os, void * annotation) const
89 { os << * static_cast<Annotation*>(annotation); }
90 std::string v_name() const
91 { return prettyName(typeid(Annotation)); }
92 bool v_isComplex() const
93 { return boost::is_convertible<Annotation*, ComplexAnnotation*>::value; }
94 unsigned v_size() const
95 { return sizeof(Annotation); }
98 typedef boost::ptr_map<key_type, RegistrationBase> Registry;
99 // Index must be a multi-map since two identically named classes
100 // both in the anonymous namespace both have the same demangled name.
101 // we could sort on the mangled name instead ...
102 typedef std::multimap<std::string, key_type> Index;
105 typedef boost::transform_iterator< ::__gnu_cxx::select2nd<Index::value_type>,
106 Index::const_iterator > iterator;
108 using senf::singleton<AnnotationRegistry>::instance;
110 template <class Annotation> class RegistrationProxy;
113 template <class Annotation> class Entry;
115 template <class Annotation>
116 key_type registerAnnotation();
118 void dump(key_type key, std::ostream & os, void * annotation) const;
119 std::string name(key_type key) const;
120 bool isComplex(key_type key) const;
121 unsigned size(key_type key) const;
123 template <class Annotation>
124 static key_type lookup();
126 iterator begin() const;
127 iterator end() const;
129 void dumpRegistrations(std::ostream & os);
132 AnnotationRegistry();
134 key_type simpleAnnotationCount_;
135 key_type complexAnnotationCount_;
138 // The index is needed to ensure a persistent and reproducible
139 // ordering of the annotations when dumping
142 friend class senf::singleton<AnnotationRegistry>;
145 template <class Annotation>
146 class AnnotationRegistry::RegistrationProxy
151 AnnotationRegistry::Entry<Annotation>::key_ =
152 AnnotationRegistry::instance().registerAnnotation<Annotation>();
156 class AnnotationRegistry::EntryBase
159 virtual ~EntryBase() {}
161 virtual void * get() = 0;
163 typedef EntryBase * ptr;
164 virtual ptr clone() const = 0;
167 inline AnnotationRegistry::EntryBase::ptr new_clone( AnnotationRegistry::EntryBase const & entry)
169 return entry.clone();
172 template <class Annotation>
173 class AnnotationRegistry::Entry
174 : public AnnotationRegistry::EntryBase
176 static RegistrationProxy<Annotation> proxy_;
177 static AnnotationRegistry::key_type key_;
179 // We use this member to force instantiation of proxy_ ...
180 static AnnotationRegistry::key_type key()
181 { senf::IGNORE(&proxy_); return key_; }
183 virtual void * get() { return & annotation_; }
184 virtual EntryBase::ptr clone() const { return new Entry<Annotation>( *this); }
187 Annotation annotation_;
189 friend class AnnotationRegistry::RegistrationProxy<Annotation>;
194 //-/////////////////////////////////////////////////////////////////////////////////////////////////
201 // comment-column: 40
202 // c-file-style: "senf"
203 // indent-tabs-mode: nil
204 // ispell-local-dictionary: "american"
205 // compile-command: "scons -u test"