PacketRegistry.ih
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief PacketRegistry internal header */
16 
17 #ifndef IH_SENF_Packets_PacketRegistry_
18 #define IH_SENF_Packets_PacketRegistry_ 1
19 
20 // Custom includes
21 #include <limits>
22 #include <boost/multi_index_container.hpp>
23 #include <boost/multi_index/ordered_index.hpp>
24 #include <boost/multi_index/composite_key.hpp>
25 #include <boost/multi_index/member.hpp>
26 #include <boost/multi_index/mem_fun.hpp>
27 #include <boost/intrusive_ptr.hpp>
28 #include <boost/noncopyable.hpp>
29 #include <senf/Utils/TypeIdValue.hh>
30 
31 //-/////////////////////////////////////////////////////////////////////////////////////////////////
32 
33 namespace senf {
34 namespace detail {
35 
36  struct TypeInfoCompare
37  {
38  bool operator()(std::type_info const & a, std::type_info const & b) const
39  { return a.before(b); }
40  };
41 
42  /** \brief Internal: Registry implementation base-class and registry of registries
43 
44  \internal
45  */
46  class PacketRegistryImplBase
47  : private boost::noncopyable
48  {
49  public:
50  virtual ~PacketRegistryImplBase();
51 
52  static void dump(std::ostream & os);
53  static void clear();
54 
55  protected:
56  typedef std::map<std::string, PacketRegistryImplBase*> RegistryMap;
57  static RegistryMap & registries();
58 
59  private:
60  virtual bool v_empty() const = 0;
61  virtual void v_dump(std::ostream & os) const = 0;
62  virtual void v_clear() = 0;
63  };
64 
65  /** \brief Internal: Singleton class implementing the packet registry.
66 
67  \internal
68  */
69  template <class KeyType>
70  class PacketRegistryImpl
71  : public PacketRegistryImplBase
72  {
73  public:
74  typedef KeyType key_t;
75 
76  struct Entry : public intrusive_refcount
77  {
78  typedef boost::intrusive_ptr<Entry> ptr;
79 
80  Entry(KeyType const & key_, int priority_);
81  virtual ~Entry();
82 
83  virtual Packet::factory_t factory() const = 0;
84 
85  virtual std::string name() const = 0;
86  virtual std::type_info const & type() const = 0;
87 
88  KeyType key;
89  int priority;
90  };
91 
92  private:
93  struct ByKey {};
94  struct ByType {};
95 
96  struct RegistryIndices
97  : public boost::multi_index::indexed_by<
98  boost::multi_index::ordered_unique<
99  boost::multi_index::tag<ByKey>,
100  boost::multi_index::composite_key<
101  Entry,
102  boost::multi_index::member<Entry,KeyType,&Entry::key>,
103  boost::multi_index::member<Entry,int,&Entry::priority> >,
104  boost::multi_index::composite_key_compare<
105  std::less<KeyType>,
106  std::greater<int> > >,
107  boost::multi_index::ordered_unique<
108  boost::multi_index::tag<ByType>,
109  boost::multi_index::const_mem_fun<Entry,std::type_info const &,&Entry::type>,
110  TypeInfoCompare> >
111  {};
112 
113  typedef boost::multi_index_container<typename Entry::ptr, RegistryIndices> Registry;
114  typedef typename Registry::template index<ByKey>::type RegistryByKey;
115  typedef typename Registry::template index<ByType>::type RegistryByType;
116 
117  template <class PacketType>
118  struct EntryImpl : public Entry
119  {
120  EntryImpl(KeyType const & key, int priority);
121 
122  virtual Packet::factory_t factory() const;
123  virtual std::string name() const;
124  virtual std::type_info const & type() const;
125  };
126 
127  public:
128  //-/////////////////////////////////////////////////////////////////////////////////////////
129  // Types
130 
131  typedef typename Registry::template index<ByKey>::type::const_iterator iterator;
132 
133  //-/////////////////////////////////////////////////////////////////////////////////////////
134  ///\name Structors and default members
135  //\{
136 
137  PacketRegistryImpl(std::string const & name);
138 
139  //\}
140  //-/////////////////////////////////////////////////////////////////////////////////////////
141 
142  template <class PacketType>
143  void registerPacket(key_t key, int priority=0);
144 
145  template <class PacketType>
146  void unregisterPacket();
147  void unregisterPacket(key_t key, int priority=0);
148 
149  key_t key(senf::TypeIdValue const & type);
150  boost::optional<key_t> key(senf::TypeIdValue const & type, bool);
151 
152  Entry const & lookup(key_t key) const;
153  Entry const * lookup(key_t key, bool) const;
154 
155  iterator begin() const;
156  iterator end() const;
157 
158  protected:
159 
160  private:
161  virtual bool v_empty() const;
162  virtual void v_dump(std::ostream & os) const;
163  virtual void v_clear();
164 
165  Registry registry_;
166  RegistryByKey & registryByKey_;
167  RegistryByType & registryByType_;
168  };
169 
170  template <class KeyType, bool is_integral=std::numeric_limits<KeyType>::is_integer>
171  struct DumpKey
172  {
173  static void dump(KeyType const & v, std::ostream & os);
174  };
175 
176  template <class KeyType>
177  struct DumpKey<KeyType, true>
178  {
179  static void dump(KeyType const & v, std::ostream & os);
180  };
181 
182 }}
183 
184 //-/////////////////////////////////////////////////////////////////////////////////////////////////
185 #endif
186 
187 
188 // Local Variables:
189 // mode: c++
190 // fill-column: 100
191 // c-file-style: "senf"
192 // indent-tabs-mode: nil
193 // ispell-local-dictionary: "american"
194 // compile-command: "scons -u test"
195 // comment-column: 40
196 // End: