vtable.h
Go to the documentation of this file.
1 
81 #ifndef VTABLE_H
82 #define VTABLE_H
83 
84 #include <vector>
85 #include <cstddef>
86 
87 #include <argos3/core/utility/logging/argos_log.h>
88 
89 namespace argos {
90 
94  template <typename BASE>
95  struct STagCounter {
96  static size_t Count;
97  };
101  template <typename BASE>
102  size_t STagCounter<BASE>::Count(0);
103 
107  template <typename DERIVED, typename BASE>
108  struct STagHolder {
109  static size_t Tag;
110  };
111 
115  template <typename DERIVED, typename BASE>
116  size_t GetTag() {
118  if(unTag == 0) {
119  /* First call of this function, generate non-zero tag */
122  }
123  return unTag;
124  }
125 
129  template <typename DERIVED, typename BASE>
130  size_t STagHolder<DERIVED, BASE>::Tag = GetTag<DERIVED, BASE>();
131 
135  template <typename BASE>
137  template <typename DERIVED>
138  size_t GetTagHelper(const DERIVED*) const {
139  return GetTag<DERIVED, BASE>();
140  }
141  };
142 
146 #define ENABLE_VTABLE() \
147  virtual size_t GetTag() { \
148  return GetTagHelper(this); \
149  }
150 
154  template <typename CONTEXT, typename BASE, typename FUNCTION>
155  class CVTable {
156  public:
157  template <typename DERIVED>
158  void Add(FUNCTION t_function) {
159  /* Find the slot */
160  size_t unIndex = GetTag<DERIVED, BASE>();
161  /* Does the table have a slot for this index? */
162  if(unIndex >= m_vecVTable.size()) {
163  /* No, new slots must be created
164  * Fill the slots with the default function that handles BASE
165  * or NULL if such function does not exist
166  */
167  /* Get the tag associated to the base class */
168  const size_t unBaseTag = GetTag<BASE, BASE>();
169  FUNCTION tDefaultFunction = 0;
170  if(unBaseTag < m_vecVTable.size()) {
171  tDefaultFunction = m_vecVTable[unBaseTag];
172  }
173  /* Create new slots up to index+1 and fill them with tDefaultFunction */
174  m_vecVTable.resize(unIndex+1, tDefaultFunction);
175  }
176  m_vecVTable[unIndex] = t_function;
177  }
178 
179  FUNCTION operator[](size_t un_index) const {
180  if(un_index >= m_vecVTable.size()) {
181  un_index = GetTag<BASE, BASE>();
182  }
183  return m_vecVTable[un_index];
184  }
185 
186  inline size_t Size() const {
187  return m_vecVTable.size();
188  }
189 
190  private:
191  std::vector<FUNCTION> m_vecVTable;
192 
193  };
194 
198  template <typename CONTEXT, typename BASE, typename FUNCTION>
200  static CVTable<CONTEXT, BASE, FUNCTION> cVTable;
201  return cVTable;
202  }
203 
204 #define INIT_VTABLE_FOR(BASE) \
205  struct SVTableInitializerFor ## BASE { \
206  SVTableInitializerFor ## BASE() { \
207  GetTag<BASE, BASE>(); \
208  } \
209  } sVTableInitializerFor ## BASE;
210 
211 }
212 
213 #endif
The namespace containing all the ARGoS related code.
Definition: ci_actuator.h:12
size_t GetTag()
Returns the value of the tag associated to DERIVED
Definition: vtable.h:116
CVTable< CONTEXT, BASE, FUNCTION > & GetVTable()
Function that returns a reference to the static vtable.
Definition: vtable.h:199
Holds the value of the last used tag.
Definition: vtable.h:95
static size_t Count
Holds the value of the last used tag.
Definition: vtable.h:96
Holds the value of the tag associated to DERIVED
Definition: vtable.h:108
static size_t Tag
Force initialization of tag holder.
Definition: vtable.h:109
Helper to make a class hierarchy vtable-enabled.
Definition: vtable.h:136
size_t GetTagHelper(const DERIVED *) const
Definition: vtable.h:138
The actual vtable.
Definition: vtable.h:155
FUNCTION operator[](size_t un_index) const
Definition: vtable.h:179
void Add(FUNCTION t_function)
Definition: vtable.h:158
size_t Size() const
Definition: vtable.h:186