switch to new MPL based Fraunhofer FOKUS Public License
[senf.git] / senf / Packets / PacketRegistry.ih
1 // $Id$
2 //
3 // Copyright (C) 2006
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 //
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
10 //
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.
14 //
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.
18 //
19 // The Original Code is Fraunhofer FOKUS code.
20 //
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.
24 //
25 // Contributor(s):
26 //   Stefan Bund <g0dil@berlios.de>
27
28 /** \file
29     \brief PacketRegistry internal header */
30
31 #ifndef IH_SENF_Packets_PacketRegistry_
32 #define IH_SENF_Packets_PacketRegistry_ 1
33
34 // Custom includes
35 #include <limits>
36 #include <boost/multi_index_container.hpp>
37 #include <boost/multi_index/ordered_index.hpp>
38 #include <boost/multi_index/composite_key.hpp>
39 #include <boost/multi_index/member.hpp>
40 #include <boost/multi_index/mem_fun.hpp>
41 #include <boost/intrusive_ptr.hpp>
42 #include <boost/utility.hpp> // for boost::noncopyable
43 #include <senf/Utils/TypeIdValue.hh>
44
45 //-/////////////////////////////////////////////////////////////////////////////////////////////////
46
47 namespace senf {
48 namespace detail {
49
50     struct TypeInfoCompare
51     {
52         bool operator()(std::type_info const & a, std::type_info const & b) const
53             { return a.before(b); }
54     };
55
56     /** \brief Internal: Registry implementation base-class and registry of registries
57
58         \internal
59      */
60     class PacketRegistryImplBase
61         : private boost::noncopyable
62     {
63     public:
64         virtual ~PacketRegistryImplBase();
65
66         static void dump(std::ostream & os);
67         static void clear();
68
69     protected:
70         typedef std::map<std::string, PacketRegistryImplBase*>  RegistryMap;
71         static RegistryMap & registries();
72
73     private:
74         virtual bool v_empty() const = 0;
75         virtual void v_dump(std::ostream & os) const = 0;
76         virtual void v_clear() = 0;
77     };
78
79     /** \brief Internal: Singleton class implementing the packet registry.
80
81         \internal
82      */
83     template <class KeyType>
84     class PacketRegistryImpl
85         : public PacketRegistryImplBase
86     {
87     public:
88         typedef KeyType key_t;
89
90         struct Entry : public intrusive_refcount
91         {
92             typedef boost::intrusive_ptr<Entry> ptr;
93
94             Entry(KeyType const & key_, int priority_);
95             virtual ~Entry();
96
97             virtual Packet::factory_t factory() const = 0;
98
99             virtual std::string name() const = 0;
100             virtual std::type_info const & type() const = 0;
101
102             KeyType key;
103             int priority;
104         };
105
106     private:
107         struct ByKey {};
108         struct ByType {};
109
110         struct RegistryIndices
111             : public boost::multi_index::indexed_by<
112                 boost::multi_index::ordered_unique<
113                     boost::multi_index::tag<ByKey>,
114                     boost::multi_index::composite_key<
115                         Entry,
116                         boost::multi_index::member<Entry,KeyType,&Entry::key>,
117                         boost::multi_index::member<Entry,int,&Entry::priority> >,
118                     boost::multi_index::composite_key_compare<
119                         std::less<KeyType>,
120                         std::greater<int> > >,
121                 boost::multi_index::ordered_unique<
122                     boost::multi_index::tag<ByType>,
123                     boost::multi_index::mem_fun<Entry const,std::type_info const &,&Entry::type>,
124                     TypeInfoCompare> >
125         {};
126
127         typedef boost::multi_index_container<typename Entry::ptr, RegistryIndices> Registry;
128
129         template <class PacketType>
130         struct EntryImpl : public Entry
131         {
132             EntryImpl(KeyType const & key, int priority);
133
134             virtual Packet::factory_t factory() const;
135             virtual std::string name() const;
136             virtual std::type_info const & type() const;
137         };
138
139     public:
140         //-/////////////////////////////////////////////////////////////////////////////////////////
141         // Types
142
143         typedef typename Registry::template index<ByKey>::type::const_iterator iterator;
144
145         //-/////////////////////////////////////////////////////////////////////////////////////////
146         ///\name Structors and default members
147         //\{
148
149         PacketRegistryImpl(std::string const & name);
150
151         //\}
152         //-/////////////////////////////////////////////////////////////////////////////////////////
153
154         template <class PacketType>
155         void registerPacket(key_t key, int priority=0);
156
157         template <class PacketType>
158         void unregisterPacket();
159         void unregisterPacket(key_t key, int priority=0);
160
161         key_t key(senf::TypeIdValue const & type);
162         boost::optional<key_t> key(senf::TypeIdValue const & type, bool);
163
164         Entry const & lookup(key_t key);
165         Entry const * lookup(key_t key, bool);
166
167         iterator begin() const;
168         iterator end() const;
169
170     protected:
171
172     private:
173         virtual bool v_empty() const;
174         virtual void v_dump(std::ostream & os) const;
175         virtual void v_clear();
176
177         Registry registry_;
178     };
179
180     template <class KeyType, bool is_integral=std::numeric_limits<KeyType>::is_integer>
181     struct DumpKey
182     {
183         static void dump(KeyType const & v, std::ostream & os);
184     };
185
186     template <class KeyType>
187     struct DumpKey<KeyType, true>
188     {
189         static void dump(KeyType const & v, std::ostream & os);
190     };
191
192 }}
193
194 //-/////////////////////////////////////////////////////////////////////////////////////////////////
195 #endif
196
197 \f
198 // Local Variables:
199 // mode: c++
200 // fill-column: 100
201 // c-file-style: "senf"
202 // indent-tabs-mode: nil
203 // ispell-local-dictionary: "american"
204 // compile-command: "scons -u test"
205 // comment-column: 40
206 // End: