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