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