registry.hpp
Go to the documentation of this file.
1 
6 /*****************************************************************************
7 ** Ifdefs
8 *****************************************************************************/
9 
10 #ifndef mm_messages_REGISTRY_HPP_
11 #define mm_messages_REGISTRY_HPP_
12 
13 /*****************************************************************************
14 ** Includes
15 *****************************************************************************/
16 
17 #include <iostream>
18 #include <map>
19 #include <set>
20 #include <sstream>
21 #include <string>
22 #include "exceptions.hpp"
23 #include "verbosity.hpp"
24 
25 /*****************************************************************************
26 ** Namespaces
27 *****************************************************************************/
28 
29 namespace mm_messages {
30 
31 /*****************************************************************************
32 ** Interfaces
33 *****************************************************************************/
34 
36 public:
41  template<int ID, typename T>
42  static bool add(const std::string &description="") {
43  if (ids().insert( std::pair<int, std::string>(ID, description)).second) {
44  add_by_type<T>(ID);
45  #ifdef MM_DEBUG_REGISTRY
46  std::cout << "Registering message packet.............[" << ID << " : '" << description << "']" << std::endl;
47  #endif
48  return true;
49  } else {
50  #ifdef MM_DEBUG_REGISTRY
51  std::cout << "Registering message packet failed......[" << ID << " : '" << description << "']" << std::endl;
52  #endif
53  return false;
54  }
55  }
56  static bool isRegistered(const int& id) {
57  return (ids().find(id) != ids().end());
58  }
59 
60  template <typename T>
61  static bool isRegisteredWithType(const int& id) {
62  return (ids_by_type<T>().find(id) != ids_by_type<T>().end());
63  }
64 
65 private:
66  template <typename T>
67  static void add_by_type(const int& id) {
68  ids_by_type<T>().insert(id);
69  }
70 
71  /****************************************
72  ** Hidden Globals
73  ****************************************/
74  template <typename T>
75  static std::set<int>& ids_by_type() {
76  static std::set<int> ids;
77  return ids;
78  }
79  static std::map<int, std::string>& ids() {
80  static std::map<int, std::string> complete_id_set;
81  return complete_id_set;
82  }
83 };
84 
85 /*****************************************************************************
86  ** Registry Enablers
87  *****************************************************************************/
88 
96 template<int ID, typename T>
97 struct RegistryEntry {
98  RegistryEntry(const std::string& description="") {
99  bool result = MessageRegistry::add<ID, T>(description);
100  if ( !result ) {
101  std::stringstream ss;
102  ss << "registry already holds id '" << ID << "' (our packet desc: '" << description << "')" << std::endl;
103  throw MessageRegistrationFailed(ss.str());
104  }
105  }
106 };
107 
108 } // mm_messages
109 
110 /*****************************************************************************
111  ** Registry Macros
112  *****************************************************************************/
113 
114 // Macro for loading id-type pairs into the registry. If multiple macros
115 // are called for the same id, with different types, you will get
116 // 1) a compile time error if they are in the same translation unit OR
117 // 2) a runtime error (exception) if they are in different, but linked translation units
118 
119 // This requires some heavy macro expansions to work with __COUNTER__ so that
120 // __COUNTER__ gets expanded *before* concatenation happens (this is what goes
121 // wrong in a naive one line implementation). See this url for details:
122 //
123 // http://blog.aaronballman.com/2011/12/stupid-compiler-tricks/
124 //
125 #define MM_REGISTER_IMP_2(uuid) unused_packet_info_##uuid
126 #define MM_REGISTER_IMP_1(id, T, Description, uuid) \
127  namespace mm_messages_registry_entries { \
128  const mm_messages::RegistryEntry<id, T> MM_REGISTER_IMP_2(uuid)(Description); \
129  }
130 #define MM_REGISTER_PACKET_INFO(id, T, Description) MM_REGISTER_IMP_1(id, T, Description, __COUNTER__)
131 
132 #endif /* mm_messages_REGISTRY_HPP_ */
static std::map< int, std::string > & ids()
Definition: registry.hpp:79
Short description of this file.
Short description of this file.
static bool isRegistered(const int &id)
Definition: registry.hpp:56
Library instantiable variable for registration purposes.
Definition: registry.hpp:97
static std::set< int > & ids_by_type()
Definition: registry.hpp:75
static bool isRegisteredWithType(const int &id)
Definition: registry.hpp:61
static void add_by_type(const int &id)
Definition: registry.hpp:67
static bool add(const std::string &description="")
Definition: registry.hpp:42
RegistryEntry(const std::string &description="")
Definition: registry.hpp:98


mm_messages
Author(s): Daniel Stonier
autogenerated on Mon Jun 10 2019 13:52:10