A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
attribute-accessor-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_ACCESSOR_HELPER_H
9#define ATTRIBUTE_ACCESSOR_HELPER_H
10
11#include "attribute.h"
12
13/**
14 * @file
15 * @ingroup attributeimpl
16 * ns3::MakeAccessorHelper declarations and template implementations.
17 */
18
19namespace ns3
20{
21
22/**
23 * @ingroup attributeimpl
24 *
25 * Create an AttributeAccessor for a class data member,
26 * or a lone class get functor or set method.
27 *
28 * The get functor method should have a signature like
29 * @code
30 * typedef U (T::*getter)() const
31 * @endcode
32 * where \pname{T} is the class and \pname{U} is the type of
33 * the return value.
34 *
35 * The set method should have one of these signatures:
36 * @code
37 * typedef void (T::*setter)(U)
38 * typedef bool (T::*setter)(U)
39 * @endcode
40 * where \pname{T} is the class and \pname{U} is the type of the value to set
41 * the attribute to, which should be compatible with the
42 * specific AttributeValue type \pname{V} which holds the value
43 * (or the type implied by the name \c Make<V>Accessor of this function.)
44 * In the case of a \pname{setter} returning \pname{bool,} the return value
45 * should be \c true if the value could be set successfully.
46 *
47 * @tparam V \explicit (If present) The specific AttributeValue type
48 * to use to represent the Attribute. (If not present,
49 * the type \pname{V} is implicit in the name of this function,
50 * as "Make<V>Accessor"
51 * @tparam T1 \deduced The type of the class data member,
52 * or the type of the class get functor or set method.
53 * @param [in] a1 The address of the data member,
54 * or the get or set method.
55 * @returns The AttributeAccessor
56 */
57template <typename V, typename T1>
58inline Ptr<const AttributeAccessor> MakeAccessorHelper(T1 a1);
59
60/**
61 * @ingroup attributeimpl
62 *
63 * Create an AttributeAccessor using a pair of get functor
64 * and set methods from a class.
65 *
66 * The get functor method should have a signature like
67 * @code
68 * typedef U (T::*getter)() const
69 * @endcode
70 * where \pname{T} is the class and \pname{U} is the type of
71 * the return value.
72 *
73 * The set method should have one of these signatures:
74 * @code
75 * typedef void (T::*setter)(U)
76 * typedef bool (T::*setter)(U)
77 * @endcode
78 * where \pname{T} is the class and \pname{U} is the type of the value to set
79 * the attribute to, which should be compatible with the
80 * specific AttributeValue type \pname{V} which holds the value
81 * (or the type implied by the name \c Make<V>Accessor of this function.)
82 * In the case of a \pname{setter} returning \pname{bool,} the return value
83 * should be true if the value could be set successfully.
84 *
85 * In practice the setter and getter arguments can appear in either order,
86 * but setter first is preferred.
87 *
88 * @tparam V \explicit (If present) The specific AttributeValue type to use to represent
89 * the Attribute. (If not present, the type \pname{V} is implicit
90 * in the name of this function as "Make<V>Accessor"
91 * @tparam T1 \deduced The type of the class data member,
92 * or the type of the class get functor or set method.
93 *
94 * @tparam T2 \deduced The type of the getter class functor method.
95 * @param [in] a2 The address of the class method to set the attribute.
96 * @param [in] a1 The address of the data member,
97 * or the get or set method.
98 * @returns The AttributeAccessor
99 */
100template <typename V, typename T1, typename T2>
101inline Ptr<const AttributeAccessor> MakeAccessorHelper(T1 a1, T2 a2);
102
103} // namespace ns3
104
105/***************************************************************
106 * Implementation of the templates declared above.
107 ***************************************************************/
108
109#include <type_traits>
110
111namespace ns3
112{
113
114/**
115 * @ingroup attributeimpl
116 *
117 * The non-const and non-reference type equivalent to \pname{T}.
118 *
119 * @tparam T \explicit The original (possibly qualified) type.
120 */
121template <typename T>
123{
124 /** The non-const, non reference type. */
125 using Result = std::remove_cvref_t<T>;
126};
127
128/**
129 * @ingroup attributeimpl
130 *
131 * Basic functionality for accessing class attributes via
132 * class data members, or get functor/set methods.
133 *
134 * @tparam T \explicit Class of object holding the attribute.
135 * @tparam U \explicit AttributeValue type for the underlying class member
136 * which is an attribute.
137 */
138template <typename T, typename U>
140{
141 public:
142 /** Constructor */
144 {
145 }
146
147 /**
148 * Set the underlying member to the argument AttributeValue.
149 *
150 * Handle dynamic casting from generic ObjectBase and AttributeValue
151 * up to desired object class and specific AttributeValue.
152 *
153 * Forwards to DoSet method.
154 *
155 * @param [in] object Generic object pointer, to upcast to \pname{T}.
156 * @param [in] val Generic AttributeValue, to upcast to \pname{U}.
157 * @returns true if the member was set successfully.
158 */
159 bool Set(ObjectBase* object, const AttributeValue& val) const override
160 {
161 const U* value = dynamic_cast<const U*>(&val);
162 if (value == nullptr)
163 {
164 return false;
165 }
166 T* obj = dynamic_cast<T*>(object);
167 if (obj == nullptr)
168 {
169 return false;
170 }
171 return DoSet(obj, value);
172 }
173
174 /**
175 * Get the value of the underlying member into the AttributeValue.
176 *
177 * Handle dynamic casting from generic ObjectBase and AttributeValue
178 * up to desired object class and specific AttributeValue.
179 *
180 * Forwards to DoGet method.
181 *
182 * @param [out] object Generic object pointer, to upcast to \pname{T}.
183 * @param [out] val Generic AttributeValue, to upcast to \pname{U}.
184 * @returns true if the member value could be retrieved successfully
185 */
186 bool Get(const ObjectBase* object, AttributeValue& val) const override
187 {
188 U* value = dynamic_cast<U*>(&val);
189 if (value == nullptr)
190 {
191 return false;
192 }
193 const T* obj = dynamic_cast<const T*>(object);
194 if (obj == nullptr)
195 {
196 return false;
197 }
198 return DoGet(obj, value);
199 }
200
201 private:
202 /**
203 * Setter implementation.
204 *
205 * @see Set()
206 * @param [in] object The parent object holding the attribute.
207 * @param [in] v The specific AttributeValue to set.
208 * @returns true if the member was set successfully.
209 */
210 virtual bool DoSet(T* object, const U* v) const = 0;
211 /**
212 * Getter implementation.
213 *
214 * @see Get()
215 * @param [out] object The parent object holding the attribute.
216 * @param [out] v The specific AttributeValue to set.
217 * @returns true if the member value could be retrieved successfully
218 */
219 virtual bool DoGet(const T* object, U* v) const = 0;
220
221 // end of class AccessorHelper
222};
223
224/**
225 * @ingroup attributeimpl
226 *
227 * MakeAccessorHelper implementation for a class data member.
228 *
229 * @tparam V \explicit The specific AttributeValue type to use to represent
230 * the Attribute.
231 * @tparam T \deduced The class holding the data member.
232 * @tparam U \deduced The type of the data member.
233 * @param [in] memberVariable The address of the data member.
234 * @returns The AttributeAccessor.
235 */
236// clang-format off
237// Clang-format guard needed for versions <= 18
238template <typename V, typename T, typename U>
240DoMakeAccessorHelperOne(U T::* memberVariable)
241// clang-format on
242{
243 /* AttributeAccessor implementation for a class member variable. */
244 class MemberVariable : public AccessorHelper<T, V>
245 {
246 public:
247 /*
248 * Construct from a class data member address.
249 * @param [in] memberVariable The class data member address.
250 */
251 // clang-format off
252 // Clang-format guard needed for versions <= 18
253 MemberVariable(U T::* memberVariable)
254 // clang-format on
256 m_memberVariable(memberVariable)
257 {
258 }
259
260 private:
261 bool DoSet(T* object, const V* v) const override
262 {
263 typename AccessorTrait<U>::Result tmp;
264 bool ok = v->GetAccessor(tmp);
265 if (!ok)
266 {
267 return false;
268 }
269 (object->*m_memberVariable) = tmp;
270 return true;
271 }
272
273 bool DoGet(const T* object, V* v) const override
274 {
275 v->Set(object->*m_memberVariable);
276 return true;
277 }
278
279 bool HasGetter() const override
280 {
281 return true;
282 }
283
284 bool HasSetter() const override
285 {
286 return true;
287 }
288
289 // clang-format off
290 // Clang-format guard needed for versions <= 18
291 U T::* m_memberVariable; // Address of the class data member.
292 // clang-format on
293 };
294
295 return Ptr<const AttributeAccessor>(new MemberVariable(memberVariable), false);
296}
297
298/**
299 * @ingroup attributeimpl
300 *
301 * MakeAccessorHelper implementation for a class get functor method.
302 *
303 * @tparam V \explicit The specific AttributeValue type to use to represent
304 * the Attribute.
305 * @tparam T \deduced The class holding the get functor method.
306 * @tparam U \deduced The return type of the get functor method.
307 * @param [in] getter The address of the class get functor method.
308 * @returns The AttributeAccessor.
309 */
310template <typename V, typename T, typename U>
311inline Ptr<const AttributeAccessor>
312DoMakeAccessorHelperOne(U (T::*getter)() const)
313{
314 /* AttributeAccessor implementation with a class get functor method. */
315 class MemberMethod : public AccessorHelper<T, V>
316 {
317 public:
318 /*
319 * Construct from a class get functor method.
320 * @param [in] getter The class get functor method pointer.
321 */
322 MemberMethod(U (T::*getter)() const)
324 m_getter(getter)
325 {
326 }
327
328 private:
329 bool DoSet(T* /* object */, const V* /* v */) const override
330 {
331 return false;
332 }
333
334 bool DoGet(const T* object, V* v) const override
335 {
336 v->Set((object->*m_getter)());
337 return true;
338 }
339
340 bool HasGetter() const override
341 {
342 return true;
343 }
344
345 bool HasSetter() const override
346 {
347 return false;
348 }
349
350 U (T::*m_getter)() const; // The class get functor method pointer.
351 };
352
353 return Ptr<const AttributeAccessor>(new MemberMethod(getter), false);
354}
355
356/**
357 * @ingroup attributeimpl
358 *
359 * MakeAccessorHelper implementation for a class set method
360 * returning void.
361 *
362 * @tparam V \explicit The specific AttributeValue type to use to represent
363 * the Attribute.
364 * @tparam T \deduced The class holding the set method.
365 * @tparam U \deduced The argument type of the set method.
366 * @param [in] setter The address of the class set method, returning void.
367 * @returns The AttributeAccessor.
368 */
369template <typename V, typename T, typename U>
370inline Ptr<const AttributeAccessor>
371DoMakeAccessorHelperOne(void (T::*setter)(U))
372{
373 /* AttributeAccessor implementation with a class set method returning void. */
374 class MemberMethod : public AccessorHelper<T, V>
375 {
376 public:
377 /*
378 * Construct from a class set method.
379 * @param [in] setter The class set method pointer.
380 */
381 MemberMethod(void (T::*setter)(U))
383 m_setter(setter)
384 {
385 }
386
387 private:
388 bool DoSet(T* object, const V* v) const override
389 {
390 typename AccessorTrait<U>::Result tmp;
391 bool ok = v->GetAccessor(tmp);
392 if (!ok)
393 {
394 return false;
395 }
396 (object->*m_setter)(tmp);
397 return true;
398 }
399
400 bool DoGet(const T* /* object */, V* /* v */) const override
401 {
402 return false;
403 }
404
405 bool HasGetter() const override
406 {
407 return false;
408 }
409
410 bool HasSetter() const override
411 {
412 return true;
413 }
414
415 void (T::*m_setter)(U); // The class set method pointer, returning void.
416 };
417
418 return Ptr<const AttributeAccessor>(new MemberMethod(setter), false);
419}
420
421/**
422 * @ingroup attributeimpl
423 *
424 * MakeAccessorHelper implementation with a class get functor method
425 * and a class set method returning \pname{void}.
426 *
427 * The two versions of this function differ only in argument order.
428 *
429 * @tparam W \explicit The specific AttributeValue type to use to represent
430 * the Attribute.
431 * @tparam T \deduced The class holding the functor methods.
432 * @tparam U \deduced The argument type of the set method.
433 * @tparam V \deduced The return type of the get functor method.
434 * @param [in] setter The address of the class set method, returning void.
435 * @param [in] getter The address of the class get functor method.
436 * @returns The AttributeAccessor.
437 */
438template <typename W, typename T, typename U, typename V>
439inline Ptr<const AttributeAccessor>
440DoMakeAccessorHelperTwo(void (T::*setter)(U), V (T::*getter)() const)
441{
442 /*
443 * AttributeAccessor implementation with class get functor and set method,
444 * returning void.
445 */
446 class MemberMethod : public AccessorHelper<T, W>
447 {
448 public:
449 /*
450 * Construct from class get functor and set methods.
451 * @param [in] setter The class set method pointer, returning void.
452 * @param [in] getter The class get functor method pointer.
453 */
454 MemberMethod(void (T::*setter)(U), V (T::*getter)() const)
456 m_setter(setter),
457 m_getter(getter)
458 {
459 }
460
461 private:
462 bool DoSet(T* object, const W* v) const override
463 {
464 typename AccessorTrait<U>::Result tmp;
465 bool ok = v->GetAccessor(tmp);
466 if (!ok)
467 {
468 return false;
469 }
470 (object->*m_setter)(tmp);
471 return true;
472 }
473
474 bool DoGet(const T* object, W* v) const override
475 {
476 v->Set((object->*m_getter)());
477 return true;
478 }
479
480 bool HasGetter() const override
481 {
482 return true;
483 }
484
485 bool HasSetter() const override
486 {
487 return true;
488 }
489
490 void (T::*m_setter)(U); // The class set method pointer, returning void.
491 V (T::*m_getter)() const; // The class get functor method pointer.
492 };
493
494 return Ptr<const AttributeAccessor>(new MemberMethod(setter, getter), false);
495}
496
497/**
498 * @ingroup attributeimpl
499 * @copydoc DoMakeAccessorHelperTwo(void(T::*)(U),V(T::*)()const)
500 */
501template <typename W, typename T, typename U, typename V>
502inline Ptr<const AttributeAccessor>
503DoMakeAccessorHelperTwo(V (T::*getter)() const, void (T::*setter)(U))
504{
505 return DoMakeAccessorHelperTwo<W>(setter, getter);
506}
507
508/**
509 * @ingroup attributeimpl
510 *
511 * MakeAccessorHelper implementation with a class get functor method
512 * and a class set method returning \pname{bool}.
513 *
514 * The two versions of this function differ only in argument order.
515 *
516 * @tparam W \explicit The specific AttributeValue type to use to represent
517 * the Attribute.
518 * @tparam T \deduced The class holding the functor methods.
519 * @tparam U \deduced The argument type of the set method.
520 * @tparam V \deduced The return type of the get functor method.
521 * @param [in] setter The address of the class set method, returning bool.
522 * @param [in] getter The address of the class get functor method.
523 * @returns The AttributeAccessor.
524 */
525template <typename W, typename T, typename U, typename V>
526inline Ptr<const AttributeAccessor>
527DoMakeAccessorHelperTwo(bool (T::*setter)(U), V (T::*getter)() const)
528{
529 /*
530 * AttributeAccessor implementation with class get functor and
531 * set method, returning bool.
532 */
533 class MemberMethod : public AccessorHelper<T, W>
534 {
535 public:
536 /*
537 * Construct from class get functor and set method, returning bool.
538 * @param [in] setter The class set method pointer, returning bool.
539 * @param [in] getter The class get functor method pointer.
540 */
541 MemberMethod(bool (T::*setter)(U), V (T::*getter)() const)
543 m_setter(setter),
544 m_getter(getter)
545 {
546 }
547
548 private:
549 bool DoSet(T* object, const W* v) const override
550 {
551 typename AccessorTrait<U>::Result tmp;
552 bool ok = v->GetAccessor(tmp);
553 if (!ok)
554 {
555 return false;
556 }
557 ok = (object->*m_setter)(tmp);
558 return ok;
559 }
560
561 bool DoGet(const T* object, W* v) const override
562 {
563 v->Set((object->*m_getter)());
564 return true;
565 }
566
567 bool HasGetter() const override
568 {
569 return true;
570 }
571
572 bool HasSetter() const override
573 {
574 return true;
575 }
576
577 bool (T::*m_setter)(U); // The class set method pointer, returning bool.
578 V (T::*m_getter)() const; // The class get functor method pointer.
579 };
580
581 return Ptr<const AttributeAccessor>(new MemberMethod(setter, getter), false);
582}
583
584/**
585 * @ingroup attributeimpl
586 * @copydoc ns3::DoMakeAccessorHelperTwo(bool(T::*)(U),V(T::*)()const)
587 */
588template <typename W, typename T, typename U, typename V>
589inline Ptr<const AttributeAccessor>
590DoMakeAccessorHelperTwo(V (T::*getter)() const, bool (T::*setter)(U))
591{
592 return DoMakeAccessorHelperTwo<W>(setter, getter);
593}
594
595template <typename V, typename T1>
596inline Ptr<const AttributeAccessor>
598{
600}
601
602template <typename V, typename T1, typename T2>
603inline Ptr<const AttributeAccessor>
605{
606 return DoMakeAccessorHelperTwo<V>(a1, a2);
607}
608
609} // namespace ns3
610
611#endif /* ATTRIBUTE_ACCESSOR_HELPER_H */
ns3::AttributeValue, ns3::AttributeAccessor and ns3::AttributeChecker declarations.
Basic functionality for accessing class attributes via class data members, or get functor/set methods...
bool Set(ObjectBase *object, const AttributeValue &val) const override
Set the underlying member to the argument AttributeValue.
virtual bool DoGet(const T *object, U *v) const =0
Getter implementation.
bool Get(const ObjectBase *object, AttributeValue &val) const override
Get the value of the underlying member into the AttributeValue.
virtual bool DoSet(T *object, const U *v) const =0
Setter implementation.
allow setting and getting the value of an attribute.
Definition attribute.h:105
Hold a value for an Attribute.
Definition attribute.h:59
Anchor the ns-3 type and attribute system.
Smart pointer class similar to boost::intrusive_ptr.
Ptr< const AttributeAccessor > DoMakeAccessorHelperOne(U T::*memberVariable)
MakeAccessorHelper implementation for a class data member.
Ptr< const AttributeAccessor > MakeAccessorHelper(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Ptr< const AttributeAccessor > DoMakeAccessorHelperTwo(void(T::*setter)(U), V(T::*getter)() const)
MakeAccessorHelper implementation with a class get functor method and a class set method returning vo...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
The non-const and non-reference type equivalent to T .
std::remove_cvref_t< T > Result
The non-const, non reference type.