00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #ifndef IH_SENF_senf_Packets_PacketImpl_
00027 #define IH_SENF_senf_Packets_PacketImpl_ 1
00028
00029
00030 #include <iostream>
00031 #include <map>
00032 #include <string>
00033 #include <ext/functional>
00034 #include <boost/iterator/transform_iterator.hpp>
00035 #include <boost/type_traits/is_convertible.hpp>
00036 #include <boost/mpl/sizeof.hpp>
00037 #include <boost/mpl/int.hpp>
00038 #include <boost/mpl/or.hpp>
00039 #include <boost/mpl/greater.hpp>
00040 #include <boost/ptr_container/ptr_map.hpp>
00041 #include <senf/Utils/TypeInfo.hh>
00042 #include <senf/Utils/singleton.hh>
00043 #include <senf/config.hh>
00044 #include <senf/Utils/IgnoreValue.hh>
00045
00046
00047
00048 namespace senf {
00049
00050 struct ComplexAnnotation;
00051
00052 namespace detail {
00053
00054 template <class Annotation>
00055 struct IsComplexAnnotation
00056 : public boost::mpl::or_< boost::is_convertible<Annotation*, ComplexAnnotation*>,
00057 boost::mpl::greater<
00058 boost::mpl::sizeof_<Annotation>,
00059 boost::mpl::int_<SENF_PACKET_ANNOTATION_SLOTSIZE> > >
00060 {};
00061
00062 class AnnotationRegistry
00063 : public senf::singleton<AnnotationRegistry>
00064 {
00065 public:
00066 typedef int key_type;
00067
00068 private:
00069 struct RegistrationBase
00070 {
00071 virtual ~RegistrationBase () {};
00072 key_type key;
00073 virtual void v_dump(std::ostream & os, void * annotation) const = 0;
00074 virtual std::string v_name() const = 0;
00075 virtual bool v_isComplex() const = 0;
00076 virtual unsigned v_size() const = 0;
00077 };
00078
00079 template <class Annotation>
00080 struct Registration
00081 : public RegistrationBase
00082 {
00083 void v_dump(std::ostream & os, void * annotation) const
00084 { os << * static_cast<Annotation*>(annotation); }
00085 std::string v_name() const
00086 { return prettyName(typeid(Annotation)); }
00087 bool v_isComplex() const
00088 { return boost::is_convertible<Annotation*, ComplexAnnotation*>::value; }
00089 unsigned v_size() const
00090 { return sizeof(Annotation); }
00091 };
00092
00093 typedef boost::ptr_map<key_type, RegistrationBase> Registry;
00094
00095
00096
00097 typedef std::multimap<std::string, key_type> Index;
00098
00099 public:
00100 typedef boost::transform_iterator< ::__gnu_cxx::select2nd<Index::value_type>,
00101 Index::const_iterator > iterator;
00102
00103 using senf::singleton<AnnotationRegistry>::instance;
00104
00105 template <class Annotation> class RegistrationProxy;
00106
00107 class EntryBase;
00108 template <class Annotation> class Entry;
00109
00110 template <class Annotation>
00111 key_type registerAnnotation();
00112
00113 void dump(key_type key, std::ostream & os, void * annotation) const;
00114 std::string name(key_type key) const;
00115 bool isComplex(key_type key) const;
00116 unsigned size(key_type key) const;
00117
00118 template <class Annotation>
00119 static key_type lookup();
00120
00121 iterator begin() const;
00122 iterator end() const;
00123
00124 void dumpRegistrations(std::ostream & os);
00125
00126 private:
00127 AnnotationRegistry();
00128
00129 key_type simpleAnnotationCount_;
00130 key_type complexAnnotationCount_;
00131
00132 Registry registry_;
00133
00134
00135 Index index_;
00136
00137 friend class senf::singleton<AnnotationRegistry>;
00138 };
00139
00140 template <class Annotation>
00141 class AnnotationRegistry::RegistrationProxy
00142 {
00143 public:
00144 RegistrationProxy()
00145 {
00146 AnnotationRegistry::Entry<Annotation>::key_ =
00147 AnnotationRegistry::instance().registerAnnotation<Annotation>();
00148 }
00149 };
00150
00151 class AnnotationRegistry::EntryBase
00152 {
00153 public:
00154 virtual ~EntryBase() {}
00155
00156 virtual void * get() = 0;
00157
00158 typedef EntryBase * ptr;
00159 virtual ptr clone() const = 0;
00160 };
00161
00162 inline AnnotationRegistry::EntryBase::ptr new_clone( AnnotationRegistry::EntryBase const & entry)
00163 {
00164 return entry.clone();
00165 }
00166
00167 template <class Annotation>
00168 class AnnotationRegistry::Entry
00169 : public AnnotationRegistry::EntryBase
00170 {
00171 static RegistrationProxy<Annotation> proxy_;
00172 static AnnotationRegistry::key_type key_;
00173 public:
00174
00175 static AnnotationRegistry::key_type key()
00176 { senf::IGNORE(&proxy_); return key_; }
00177
00178 virtual void * get() { return & annotation_; }
00179 virtual EntryBase::ptr clone() const { return new Entry<Annotation>( *this); }
00180
00181 private:
00182 Annotation annotation_;
00183
00184 friend class AnnotationRegistry::RegistrationProxy<Annotation>;
00185 };
00186
00187 }}
00188
00189
00190 #endif
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201