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