src/core/attribute-helper.h
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 3094 6e787ec9c8aa
permissions -rw-r--r--
Added tag ns-3.5 for changeset c975274c9707
     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 "fatal-error.h"
    27 
    28 namespace ns3 {
    29 
    30 template <typename T, typename BASE>
    31 Ptr<AttributeChecker>
    32 MakeSimpleAttributeChecker (std::string name, std::string underlying)
    33 {
    34   struct SimpleAttributeChecker : public BASE
    35   {
    36     virtual bool Check (const AttributeValue &value) const {
    37       return dynamic_cast<const T *> (&value) != 0;
    38     }
    39     virtual std::string GetValueTypeName (void) const {
    40       return m_type;
    41     }
    42     virtual bool HasUnderlyingTypeInformation (void) const {
    43       return true;
    44     }
    45     virtual std::string GetUnderlyingTypeInformation (void) const {
    46       return m_underlying;
    47     }
    48     virtual Ptr<AttributeValue> Create (void) const {
    49       return ns3::Create<T> ();
    50     }
    51     virtual bool Copy (const AttributeValue &source, AttributeValue &destination) const {
    52       const T *src = dynamic_cast<const T *> (&source);
    53       T *dst = dynamic_cast<T *> (&destination);
    54       if (src == 0 || dst == 0)
    55         {
    56           return false;
    57         }
    58       *dst = *src;
    59       return true;
    60     }
    61     std::string m_type;
    62     std::string m_underlying;
    63   } *checker = new SimpleAttributeChecker ();
    64   checker->m_type = name;
    65   checker->m_underlying = underlying;
    66   return Ptr<AttributeChecker> (checker, false);
    67 }
    68 
    69 }
    70 
    71 /**
    72  * \ingroup core
    73  * \defgroup AttributeHelper Attribute Helper
    74  *
    75  * All these macros can be used to generate automatically the code
    76  * for subclasses of AttributeValue, AttributeAccessor, and, AttributeChecker,
    77  * which can be used to give attribute powers to a normal class. i.e.,
    78  * the user class can then effectively be made an attribute.
    79  *
    80  * There are two kinds of helper macros:
    81  *  1) The simple macros.
    82  *  2) The more complex macros.
    83  *
    84  * The simple macros are implemented in terms of the complex
    85  * macros and should generally be prefered over the complex macros:
    86  *    - \ref ATTRIBUTE_HELPER_HEADER, and,
    87  *    - \ref ATTRIBUTE_HELPER_CPP,
    88  */
    89 
    90 /**
    91  * \ingroup AttributeHelper
    92  * \param type the name of the class
    93  *
    94  * This macro defines and generates the code for the implementation 
    95  * of the MakeXXXAccessor template functions. This macro is typically
    96  * invoked in a class header to allow users of this class to view and
    97  * use the template functions defined here. This macro is implemented
    98  * through the helper templates functions ns3::MakeAccessorHelper<>.
    99  */
   100 #define ATTRIBUTE_ACCESSOR_DEFINE(type)					\
   101   template <typename T1>						\
   102   Ptr<const AttributeAccessor> Make##type##Accessor (T1 a1)		\
   103   {									\
   104     return MakeAccessorHelper<type##Value> (a1);			\
   105   }									\
   106   template <typename T1, typename T2>					\
   107   Ptr<const AttributeAccessor> Make##type##Accessor (T1 a1, T2 a2)	\
   108   {									\
   109     return MakeAccessorHelper<type##Value> (a1, a2);			\
   110   }
   111 
   112 #define ATTRIBUTE_VALUE_DEFINE_WITH_NAME(type,name)                     \
   113   class name##Value : public AttributeValue				\
   114   {									\
   115   public:								\
   116     name##Value ();							\
   117     name##Value (const type &value);					\
   118     void Set (const type &value);					\
   119     type Get (void) const;						\
   120     template <typename T>                                               \
   121     bool GetAccessor (T &value) const {                                 \
   122       value = T (m_value);                                              \
   123       return true;                                                      \
   124     }                                                                   \
   125     virtual Ptr<AttributeValue> Copy (void) const;                      \
   126     virtual std::string SerializeToString (Ptr<const AttributeChecker> checker) const; \
   127     virtual bool DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker); \
   128   private:								\
   129     type m_value;							\
   130   };
   131 
   132 
   133 /**
   134  * \ingroup AttributeHelper
   135  * \param type the name of the class.
   136  *
   137  * This macro defines the class XXXValue associated to class XXX.
   138  * This macro is typically invoked in a class header.
   139  */
   140 #define ATTRIBUTE_VALUE_DEFINE(type)					\
   141   ATTRIBUTE_VALUE_DEFINE_WITH_NAME (type,type)
   142 
   143 
   144 /**
   145  * \ingroup AttributeHelper
   146  * \param type the name of the class
   147  *
   148  * This macro defines the conversion operators for class XXX to and
   149  * from instances of type Attribute.
   150  * Typically invoked from xxx.h.
   151  */
   152 #define ATTRIBUTE_CONVERTER_DEFINE(type)
   153 
   154 /**
   155  * \ingroup AttributeHelper
   156  * \param type the name of the class
   157  *
   158  * This macro defines the XXXChecker class and the associated
   159  * MakeXXXChecker function.
   160  * Typically invoked from xxx.h.
   161  */
   162 #define ATTRIBUTE_CHECKER_DEFINE(type)				\
   163   class type##Checker : public AttributeChecker {};		\
   164   Ptr<const AttributeChecker> Make##type##Checker (void);	\
   165 
   166 
   167 #define ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME(type,name)                  \
   168   name##Value::name##Value ()						\
   169     : m_value () {}							\
   170   name##Value::name##Value (const type &value)				\
   171   : m_value (value) {}							\
   172   void name##Value::Set (const type &v) {				\
   173     m_value = v;							\
   174   }									\
   175   type name##Value::Get (void) const {					\
   176     return m_value;							\
   177   }									\
   178   Ptr<AttributeValue>                                                   \
   179   name##Value::Copy (void) const {					\
   180     return ns3::Create<name##Value> (*this);                            \
   181   }                                                                     \
   182   std::string								\
   183   name##Value::SerializeToString (Ptr<const AttributeChecker> checker) const { \
   184     std::ostringstream oss;						\
   185     oss << m_value;							\
   186     return oss.str ();							\
   187   }									\
   188   bool									\
   189   name##Value::DeserializeFromString (std::string value, Ptr<const AttributeChecker> checker) { \
   190     std::istringstream iss;						\
   191     iss.str (value);							\
   192     iss >> m_value;							\
   193     return !iss.bad () && !iss.fail ();					\
   194   }
   195 
   196 /**
   197  * \ingroup AttributeHelper
   198  * \param type the name of the class.
   199  *
   200  * This macro implements the XXXValue class (including the 
   201  * XXXValue::SerializeToString and XXXValue::DeserializeFromString 
   202  * methods).
   203  * Typically invoked from xxx.cc.
   204  */
   205 #define ATTRIBUTE_VALUE_IMPLEMENT(type)					\
   206   ATTRIBUTE_VALUE_IMPLEMENT_WITH_NAME(type,type)
   207 
   208 
   209 /**
   210  * \ingroup AttributeHelper
   211  * \param type the name of the class
   212  *
   213  * This macro implements the MakeXXXChecker function.
   214  * Typically invoked from xxx.cc.
   215  */
   216 #define ATTRIBUTE_CHECKER_IMPLEMENT(type)				\
   217   Ptr<const AttributeChecker> Make##type##Checker (void)		\
   218   {									\
   219     return MakeSimpleAttributeChecker<type##Value,type##Checker> (#type "Value", #type); \
   220   }									\
   221 
   222 #define ATTRIBUTE_CHECKER_IMPLEMENT_WITH_NAME(type,name)                    \
   223   Ptr<const AttributeChecker> Make##type##Checker (void)		\
   224   {									\
   225     return MakeSimpleAttributeChecker<type##Value,type##Checker> (#type "Value", name); \
   226   }									\
   227 
   228 /**
   229  * \ingroup AttributeHelper
   230  * \param type the name of the class
   231  *
   232  * This macro should be invoked outside of the class
   233  * declaration in its public header.
   234  */
   235 #define ATTRIBUTE_HELPER_HEADER(type)					\
   236   ATTRIBUTE_VALUE_DEFINE (type);					\
   237   ATTRIBUTE_ACCESSOR_DEFINE (type);					\
   238   ATTRIBUTE_CHECKER_DEFINE (type);
   239 
   240 /**
   241  * \ingroup AttributeHelper
   242  * \param type the name of the class
   243  *
   244  * This macro should be invoked from the class implementation file.
   245  */
   246 #define ATTRIBUTE_HELPER_CPP(type)                                      \
   247   ATTRIBUTE_CHECKER_IMPLEMENT (type);					\
   248   ATTRIBUTE_VALUE_IMPLEMENT (type);
   249 
   250 
   251 #endif /* ATTRIBUTE_HELPER_H */