1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2008 INRIA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 */
20 #ifndef ATTRIBUTE_HELPER_H
21 #define ATTRIBUTE_HELPER_H
22
23 #include "attribute.h"
24 #include "attribute-accessor-helper.h"
25 #include <sstream>
26 #include "abort.h"
27
28 /**
29 * \file
30 * \ingroup attributehelper
31 * Attribute helper (\c ATTRIBUTE_ )macros definition.
32 */
33
34 namespace ns3 {
35
36 /**
37 * \ingroup attributes
38 * \defgroup attributehelper Attribute Helper
39 *
40 * All these macros can be used to generate automatically the code
41 * for subclasses of AttributeValue, AttributeAccessor, and, AttributeChecker,
42 * which can be used to give attribute powers to a normal class. i.e.,
43 * the user class can then effectively be made an attribute.
44 *
45 * There are two kinds of helper macros:
46 * -# The simple macros.
47 * - ATTRIBUTE_HELPER_HEADER(type)
48 * - ATTRIBUTE_HELPER_CPP(type)
49 * -# The more complex macros.
50 *
51 * The simple macros are implemented in terms of the complex
52 * macros and should generally be preferred over the complex macros.
53 *
54 * \note
55 * Because these macros generate class and function definitions, it's
56 * difficult to document the results directly. Instead, we use a
57 * set of functions in print-introspected-doxygen.cc to generate
58 * most of the APi documentation. When using these macros,
59 * please add the required function calls to print-introspected-doxygen.cc
60 * so your new API is documented.
61 */
62
63 /**
64 * \ingroup attributehelper
65 * \defgroup attributeimpl Attribute Implementation
66 *
67 * These are the internal implementation functions for the Attribute
68 * system.
69 *
70 * Module code shouldn't need to call these directly. Instead,
71 * see \ref attributehelper.
72 *
73 * There are three versions of DoMakeAccessorHelperOne:
74 * - With a member variable: DoMakeAccessorHelperOne(U T::*)
75 * - With a class get functor: DoMakeAccessorHelperOne(U(T::*)(void) const)
76 * - With a class set method: DoMakeAccessorHelperOne(void(T::*)(U))
77 *
78 * There are two pairs of DoMakeAccessorHelperTwo (four total):
79 * - Taking two arguments, a set method and get functor, in either order,
80 * - With set methods returning \c void or \c bool.
81 */
82
83 /**
84 * \ingroup attributeimpl
85 *
86 * A simple string-based attribute checker
87 *
88 * \tparam T \explicit The specific AttributeValue type used to represent
89 * the Attribute.
90 * \tparam BASE \explicit The AttributeChecker type corresponding to \pname{T}.
91 * \param [in] name The name of the AttributeValue type, essentially the
92 * string form of \pname{T}.
93 * \param [in] underlying Underlying type name.
94 * \return Ptr to AttributeChecker.
95 */
96 template <typename T, typename BASE>
97 Ptr<AttributeChecker>
MakeSimpleAttributeChecker(std::string name,std::string underlying)98 MakeSimpleAttributeChecker (std::string name, std::string underlying)
99 {
100 /**
101 * String-based AttributeChecker implementation.
102 * \extends AttributeChecker
103 */
104 struct SimpleAttributeChecker : public BASE
105 {
106 virtual bool Check (const AttributeValue &value) const
107 {
108 return dynamic_cast<const T *> (&value) != 0;
109 }
110 virtual std::string GetValueTypeName (void) const
111 {
112 return m_type;
113 }
114 virtual bool HasUnderlyingTypeInformation (void) const
115 {
116 return true;
117 }
118 virtual std::string GetUnderlyingTypeInformation (void) const
119 {
120 return m_underlying;
121 }
122 virtual Ptr<AttributeValue> Create (void) const
123 {
124 return ns3::Create<T> ();
125 }
126 virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const
127 {
128 const T *src = dynamic_cast<const T *> (&source);
129 T *dst = dynamic_cast<T *> (&destination);
130 if (src == 0 || dst == 0)
131 {
132 return false;
133 }
134 *dst = *src;
135 return true;
136 }
137 std::string m_type; // The name of the AttributeValue type.
138 std::string m_underlying; // The underlying attribute type name.
139 } *checker = new SimpleAttributeChecker ();
140 checker->m_type = name;
141 checker->m_underlying = underlying;
142 return Ptr<AttributeChecker> (checker, false);
143 }
144
145 }
146
147 /**
148 * \ingroup attributehelper
149 *
150 * Define the attribute accessor functions \c MakeTypeAccessor
151 * for class \pname{type}.
152 *
153 * \param [in] type The name of the class
154 *
155 * This macro defines and generates the code for the implementation
156 * of the \c MakeTypeAccessor template functions. This macro is typically
157 * invoked in a class header to allow users of this class to view and
158 * use the template functions defined here. This macro is implemented
159 * through the helper templates functions ns3::MakeAccessorHelper<>.
160 */
161 #define ATTRIBUTE_ACCESSOR_DEFINE(type) \
162 template <typename T1> \
163 Ptr<const AttributeAccessor> Make ## type ## Accessor (T1 a1) \
164 { \
165 return MakeAccessorHelper<type ## Value> (a1); \
166 } \
167 template <typename T1, typename T2> \
168 Ptr<const AttributeAccessor> Make ## type ## Accessor (T1 a1, T2 a2) \
169 { \
170 return MakeAccessorHelper<type ## Value> (a1, a2); \
171 }
172
173 /**
174 * \ingroup attributehelper
175 *
176 * Declare the attribute value class \pname{nameValue}
177 * for underlying class \pname{type}.
178 *
179 * \param [in] type The underlying type name token
180 * \param [in] name The token to use in defining the accessor name.
181 *
182 * This macro declares the class \c typeValue associated with class \c type.
183 * This macro is typically invoked in the class header file.
184 *
185 * This can be used directly for things like plain old data,
186 * such as \c std::string, to create the attribute value class
187 * StringValue, as in
188 * `ATTRIBUTE_VALUE_DEFINE_WITH_NAME(std::string, String);`
189 */
190 #define ATTRIBUTE_VALUE_DEFINE_WITH_NAME(type,name) \
191 class name ## Value : public AttributeValue \
192 { \
193 public: \
194 name ## Value (); \
195 name ## Value (const type &value); \
196 void Set (const type &value); \
197 type Get (void) const; \
198 template <typename T> \
199 bool GetAccessor (T & value) const { \
200 value = T (m_value); \
201 return true; \
202 } \
203 virtual Ptr<AttributeValue> Copy (void) const; \
204 virtual std::string \
205 SerializeToString (Ptr<const AttributeChecker> checker) const; \
206 virtual bool \
207 DeserializeFromString (std::string value, \
208 Ptr<const AttributeChecker> checker); \
209 private: \
210 type m_value; \
211 }
212
213
214 /**
215 * \ingroup attributehelper
216 *
217 * Declare the attribute value class \pname{nameValue}
218 * for the class \pname{name}
219 *
220 * \param [in] name The name of the class.
221 *
222 * This macro declares the class \c nameValue associated to class \c name.
223 * This macro is typically invoked in the class header file.
224 */
225 #define ATTRIBUTE_VALUE_DEFINE(name) \
226 ATTRIBUTE_VALUE_DEFINE_WITH_NAME (name,name)
227
228
229 /**
230 * \ingroup attributehelper
231 *
232 * Define the conversion operators class \pname{type} and
233 * Attribute instances.
234 *
235 * \param [in] type The name of the class
236 *
237 * This macro defines the conversion operators for class \c type to and
238 * from instances of \c typeAttribute.
239 * Typically invoked in the class header file.
240 *
241 * \internal
242 * This appears to be unused in the current code base.
243 */
244 #define ATTRIBUTE_CONVERTER_DEFINE(type)
245
246 /**
247 * \ingroup attributehelper
248 *
249 * Declare the AttributeChecker class \pname{typeChecker}
250 * and the \c MaketypeChecker function for class \pname{type}.
251 *
252 * \param [in] type The name of the class
253 *
254 * This macro declares the \pname{typeChecker} class and the associated
255 * \c MaketypeChecker function.
256 *
257 * (Note that the \pname{typeChecker} class needs no implementation
258 * since it just inherits all its implementation from AttributeChecker.)
259 *
260 * Typically invoked in the class header file.
261 */
262 #define ATTRIBUTE_CHECKER_DEFINE(type) \
263 class type ## Checker : public AttributeChecker {}; \
264 Ptr<const AttributeChecker> Make ## type ## Checker (void)
265
266
267 /**
268 * \ingroup attributehelper
269 *
270 * Define the class methods belonging to
271 * the attribute value class \pname{nameValue}
272 * of the underlying class \pname{type}.
273 *
274 * \param [in] type The underlying type name
275 * \param [in] name The token to use in defining the accessor name.
276 *
277 * This macro implements the \pname{typeValue} class methods
278 * (including the \pname{typeValue}%::%SerializeToString
279 * and \pname{typeValue}%::%DeserializeFromString methods).
280 *
281 * Typically invoked in the source file
282 */
283 #define ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME(type,name) \
284 name ## Value::name ## Value () \
285 : m_value () {} \
286 name ## Value::name ## Value (const type &value) \
287 : m_value (value) {} \
288 void name ## Value::Set (const type &v) { \
289 m_value = v; \
290 } \
291 type name ## Value::Get (void) const { \
292 return m_value; \
293 } \
294 Ptr<AttributeValue> \
295 name ## Value::Copy (void) const { \
296 return ns3::Create<name ## Value> (*this); \
297 } \
298 std::string name ## Value::SerializeToString \
299 (Ptr<const AttributeChecker> checker) const { \
300 std::ostringstream oss; \
301 oss << m_value; \
302 return oss.str (); \
303 } \
304 bool name ## Value::DeserializeFromString \
305 (std::string value, Ptr<const AttributeChecker> checker) { \
306 std::istringstream iss; \
307 iss.str (value); \
308 iss >> m_value; \
309 NS_ABORT_MSG_UNLESS (iss.eof (), \
310 "Attribute value " << "\"" << value << "\"" << \
311 " is not properly formatted"); \
312 return !iss.bad () && !iss.fail (); \
313 }
314
315 /**
316 * \ingroup attributehelper
317 *
318 * Define the class methods belonging to
319 * attribute value class \pname{typeValue} for class \pname{type}.
320 *
321 * \param [in] type The name of the class.
322 *
323 * This macro implements the \pname{typeValue} class methods
324 * (including the \pname{typeValue}%::%SerializeToString
325 * and \pname{typeValue}%::%DeserializeFromString methods).
326 *
327 * Typically invoked in the source file.
328 */
329 #define ATTRIBUTE_VALUE_IMPLEMENT(type) \
330 ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME (type,type)
331
332
333 /**
334 * \ingroup attributehelper
335 *
336 * Define the \c MaketypeChecker function for class \pname{type}.
337 *
338 * \param [in] type The name of the class
339 *
340 * This macro implements the \c MaketypeChecker function.
341 *
342 * Typically invoked in the source file..
343 */
344 #define ATTRIBUTE_CHECKER_IMPLEMENT(type) \
345 Ptr<const AttributeChecker> Make ## type ## Checker (void) { \
346 return MakeSimpleAttributeChecker<type ## Value,type ## Checker> \
347 (# type "Value", # type); \
348 } \
349
350 /**
351 * \ingroup attributehelper
352 *
353 * Define the \c MaketypeChecker function for class \pname{type}.
354 *
355 * \param [in] type The name of the class.
356 * \param [in] name The string name of the underlying type.
357 *
358 * This macro implements the \c MaketypeChecker function
359 * for class \pname{type}.
360 *
361 * Typically invoked in the source file..
362 */
363 #define ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME(type,name) \
364 Ptr<const AttributeChecker> Make ## type ## Checker (void) { \
365 return MakeSimpleAttributeChecker<type ## Value,type ## Checker> \
366 (# type "Value", name); \
367 } \
368
369 /**
370 * \ingroup attributehelper
371 *
372 * Declare the attribute value, accessor and checkers for class \pname{type}
373 *
374 * \param [in] type The name of the class
375 *
376 * This macro declares:
377 *
378 * - The attribute value class \pname{typeValue},
379 *
380 * - The attribute accessor functions \c MaketypeAccessor,
381 *
382 * - The AttributeChecker class \pname{typeChecker},
383 * and the \c MaketypeChecker function,
384 *
385 * for class \pname{type}.
386 *
387 * This macro should be invoked outside of the class
388 * declaration in its public header.
389 */
390 #define ATTRIBUTE_HELPER_HEADER(type) \
391 ATTRIBUTE_VALUE_DEFINE (type); \
392 ATTRIBUTE_ACCESSOR_DEFINE (type); \
393 ATTRIBUTE_CHECKER_DEFINE (type)
394
395 /**
396 * \ingroup attributehelper
397 *
398 * Define the attribute value, accessor and checkers for class \pname{type}
399 *
400 * \param [in] type The name of the class
401 *
402 * This macro implements
403 *
404 * - The \pname{typeValue} class methods,
405 *
406 * - The \c MaketypeChecker function,
407 *
408 * for class \pname{type}.
409 *
410 * This macro should be invoked from the class implementation file.
411 */
412 #define ATTRIBUTE_HELPER_CPP(type) \
413 ATTRIBUTE_CHECKER_IMPLEMENT (type); \
414 ATTRIBUTE_VALUE_IMPLEMENT (type)
415
416
417 #endif /* ATTRIBUTE_HELPER_H */
418