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