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