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}; // class AccessorHelper
222
223/**
224 * \ingroup attributeimpl
225 *
226 * MakeAccessorHelper implementation for a class data member.
227 *
228 * \tparam V \explicit The specific AttributeValue type to use to represent
229 * the Attribute.
230 * \tparam T \deduced The class holding the data member.
231 * \tparam U \deduced The type of the data member.
232 * \param [in] memberVariable The address of the data member.
233 * \returns The AttributeAccessor.
234 */
235template <typename V, typename T, typename U>
237DoMakeAccessorHelperOne(U T::*memberVariable)
238{
239 /* AttributeAccessor implementation for a class member variable. */
240 class MemberVariable : public AccessorHelper<T, V>
241 {
242 public:
243 /*
244 * Construct from a class data member address.
245 * \param [in] memberVariable The class data member address.
246 */
247 MemberVariable(U T::*memberVariable)
249 m_memberVariable(memberVariable)
250 {
251 }
252
253 private:
254 bool DoSet(T* object, const V* v) const override
255 {
256 typename AccessorTrait<U>::Result tmp;
257 bool ok = v->GetAccessor(tmp);
258 if (!ok)
259 {
260 return false;
261 }
262 (object->*m_memberVariable) = tmp;
263 return true;
264 }
265
266 bool DoGet(const T* object, V* v) const override
267 {
268 v->Set(object->*m_memberVariable);
269 return true;
270 }
271
272 bool HasGetter() const override
273 {
274 return true;
275 }
276
277 bool HasSetter() const override
278 {
279 return true;
280 }
281
282 U T::*m_memberVariable; // Address of the class data member.
283 };
284
285 return Ptr<const AttributeAccessor>(new MemberVariable(memberVariable), false);
286}
287
288/**
289 * \ingroup attributeimpl
290 *
291 * MakeAccessorHelper implementation for a class get functor method.
292 *
293 * \tparam V \explicit The specific AttributeValue type to use to represent
294 * the Attribute.
295 * \tparam T \deduced The class holding the get functor method.
296 * \tparam U \deduced The return type of the get functor method.
297 * \param [in] getter The address of the class get functor method.
298 * \returns The AttributeAccessor.
299 */
300template <typename V, typename T, typename U>
301inline Ptr<const AttributeAccessor>
302DoMakeAccessorHelperOne(U (T::*getter)() const)
303{
304 /* AttributeAccessor implementation with a class get functor method. */
305 class MemberMethod : public AccessorHelper<T, V>
306 {
307 public:
308 /*
309 * Construct from a class get functor method.
310 * \param [in] getter The class get functor method pointer.
311 */
312 MemberMethod(U (T::*getter)() const)
314 m_getter(getter)
315 {
316 }
317
318 private:
319 bool DoSet(T* /* object */, const V* /* v */) const override
320 {
321 return false;
322 }
323
324 bool DoGet(const T* object, V* v) const override
325 {
326 v->Set((object->*m_getter)());
327 return true;
328 }
329
330 bool HasGetter() const override
331 {
332 return true;
333 }
334
335 bool HasSetter() const override
336 {
337 return false;
338 }
339
340 U (T::*m_getter)() const; // The class get functor method pointer.
341 };
342
343 return Ptr<const AttributeAccessor>(new MemberMethod(getter), false);
344}
345
346/**
347 * \ingroup attributeimpl
348 *
349 * MakeAccessorHelper implementation for a class set method
350 * returning void.
351 *
352 * \tparam V \explicit The specific AttributeValue type to use to represent
353 * the Attribute.
354 * \tparam T \deduced The class holding the set method.
355 * \tparam U \deduced The argument type of the set method.
356 * \param [in] setter The address of the class set method, returning void.
357 * \returns The AttributeAccessor.
358 */
359template <typename V, typename T, typename U>
360inline Ptr<const AttributeAccessor>
361DoMakeAccessorHelperOne(void (T::*setter)(U))
362{
363 /* AttributeAccessor implementation with a class set method returning void. */
364 class MemberMethod : public AccessorHelper<T, V>
365 {
366 public:
367 /*
368 * Construct from a class set method.
369 * \param [in] setter The class set method pointer.
370 */
371 MemberMethod(void (T::*setter)(U))
373 m_setter(setter)
374 {
375 }
376
377 private:
378 bool DoSet(T* object, const V* v) const override
379 {
380 typename AccessorTrait<U>::Result tmp;
381 bool ok = v->GetAccessor(tmp);
382 if (!ok)
383 {
384 return false;
385 }
386 (object->*m_setter)(tmp);
387 return true;
388 }
389
390 bool DoGet(const T* /* object */, V* /* v */) const override
391 {
392 return false;
393 }
394
395 bool HasGetter() const override
396 {
397 return false;
398 }
399
400 bool HasSetter() const override
401 {
402 return true;
403 }
404
405 void (T::*m_setter)(U); // The class set method pointer, returning void.
406 };
407
408 return Ptr<const AttributeAccessor>(new MemberMethod(setter), false);
409}
410
411/**
412 * \ingroup attributeimpl
413 *
414 * MakeAccessorHelper implementation with a class get functor method
415 * and a class set method returning \pname{void}.
416 *
417 * The two versions of this function differ only in argument order.
418 *
419 * \tparam W \explicit The specific AttributeValue type to use to represent
420 * the Attribute.
421 * \tparam T \deduced The class holding the functor methods.
422 * \tparam U \deduced The argument type of the set method.
423 * \tparam V \deduced The return type of the get functor method.
424 * \param [in] setter The address of the class set method, returning void.
425 * \param [in] getter The address of the class get functor method.
426 * \returns The AttributeAccessor.
427 */
428template <typename W, typename T, typename U, typename V>
429inline Ptr<const AttributeAccessor>
430DoMakeAccessorHelperTwo(void (T::*setter)(U), V (T::*getter)() const)
431{
432 /*
433 * AttributeAccessor implementation with class get functor and set method,
434 * returning void.
435 */
436 class MemberMethod : public AccessorHelper<T, W>
437 {
438 public:
439 /*
440 * Construct from class get functor and set methods.
441 * \param [in] setter The class set method pointer, returning void.
442 * \param [in] getter The class get functor method pointer.
443 */
444 MemberMethod(void (T::*setter)(U), V (T::*getter)() const)
446 m_setter(setter),
447 m_getter(getter)
448 {
449 }
450
451 private:
452 bool DoSet(T* object, const W* v) const override
453 {
454 typename AccessorTrait<U>::Result tmp;
455 bool ok = v->GetAccessor(tmp);
456 if (!ok)
457 {
458 return false;
459 }
460 (object->*m_setter)(tmp);
461 return true;
462 }
463
464 bool DoGet(const T* object, W* v) const override
465 {
466 v->Set((object->*m_getter)());
467 return true;
468 }
469
470 bool HasGetter() const override
471 {
472 return true;
473 }
474
475 bool HasSetter() const override
476 {
477 return true;
478 }
479
480 void (T::*m_setter)(U); // The class set method pointer, returning void.
481 V (T::*m_getter)() const; // The class get functor method pointer.
482 };
483
484 return Ptr<const AttributeAccessor>(new MemberMethod(setter, getter), false);
485}
486
487/**
488 * \ingroup attributeimpl
489 * \copydoc DoMakeAccessorHelperTwo(void(T::*)(U),V(T::*)()const)
490 */
491template <typename W, typename T, typename U, typename V>
492inline Ptr<const AttributeAccessor>
493DoMakeAccessorHelperTwo(V (T::*getter)() const, void (T::*setter)(U))
494{
495 return DoMakeAccessorHelperTwo<W>(setter, getter);
496}
497
498/**
499 * \ingroup attributeimpl
500 *
501 * MakeAccessorHelper implementation with a class get functor method
502 * and a class set method returning \pname{bool}.
503 *
504 * The two versions of this function differ only in argument order.
505 *
506 * \tparam W \explicit The specific AttributeValue type to use to represent
507 * the Attribute.
508 * \tparam T \deduced The class holding the functor methods.
509 * \tparam U \deduced The argument type of the set method.
510 * \tparam V \deduced The return type of the get functor method.
511 * \param [in] setter The address of the class set method, returning bool.
512 * \param [in] getter The address of the class get functor method.
513 * \returns The AttributeAccessor.
514 */
515template <typename W, typename T, typename U, typename V>
516inline Ptr<const AttributeAccessor>
517DoMakeAccessorHelperTwo(bool (T::*setter)(U), V (T::*getter)() const)
518{
519 /*
520 * AttributeAccessor implementation with class get functor and
521 * set method, returning bool.
522 */
523 class MemberMethod : public AccessorHelper<T, W>
524 {
525 public:
526 /*
527 * Construct from class get functor and set method, returning bool.
528 * \param [in] setter The class set method pointer, returning bool.
529 * \param [in] getter The class get functor method pointer.
530 */
531 MemberMethod(bool (T::*setter)(U), V (T::*getter)() const)
533 m_setter(setter),
534 m_getter(getter)
535 {
536 }
537
538 private:
539 bool DoSet(T* object, const W* v) const override
540 {
541 typename AccessorTrait<U>::Result tmp;
542 bool ok = v->GetAccessor(tmp);
543 if (!ok)
544 {
545 return false;
546 }
547 ok = (object->*m_setter)(tmp);
548 return ok;
549 }
550
551 bool DoGet(const T* object, W* v) const override
552 {
553 v->Set((object->*m_getter)());
554 return true;
555 }
556
557 bool HasGetter() const override
558 {
559 return true;
560 }
561
562 bool HasSetter() const override
563 {
564 return true;
565 }
566
567 bool (T::*m_setter)(U); // The class set method pointer, returning bool.
568 V (T::*m_getter)() const; // The class get functor method pointer.
569 };
570
571 return Ptr<const AttributeAccessor>(new MemberMethod(setter, getter), false);
572}
573
574/**
575 * \ingroup attributeimpl
576 * \copydoc ns3::DoMakeAccessorHelperTwo(bool(T::*)(U),V(T::*)()const)
577 */
578template <typename W, typename T, typename U, typename V>
579inline Ptr<const AttributeAccessor>
580DoMakeAccessorHelperTwo(V (T::*getter)() const, bool (T::*setter)(U))
581{
582 return DoMakeAccessorHelperTwo<W>(setter, getter);
583}
584
585template <typename V, typename T1>
586inline Ptr<const AttributeAccessor>
588{
590}
591
592template <typename V, typename T1, typename T2>
593inline Ptr<const AttributeAccessor>
595{
596 return DoMakeAccessorHelperTwo<V>(a1, a2);
597}
598
599} // namespace ns3
600
601#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.