src/core/attribute-accessor-helper.h
author Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
Sat, 04 Jul 2009 08:15:48 +0200
changeset 4654 2eaebe77d66b
parent 3527 1548d7e3604f
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_ACCESSOR_HELPER_H
    21 #define ATTRIBUTE_ACCESSOR_HELPER_H
    22 
    23 #include "attribute.h"
    24 
    25 namespace ns3 {
    26 
    27 /**
    28  * \ingroup AttributeHelper
    29  */
    30 template <typename V, typename T1>
    31 Ptr<const AttributeAccessor>
    32 MakeAccessorHelper (T1 a1);
    33 
    34 /**
    35  * \ingroup AttributeHelper
    36  */
    37 template <typename V, typename T1, typename T2>
    38 Ptr<const AttributeAccessor>
    39 MakeAccessorHelper (T1 a1, T2 a2);
    40 
    41 } // namespace ns3
    42 
    43 /***************************************************************
    44  *        The implementation of the above functions.
    45  ***************************************************************/
    46 
    47 #include "type-traits.h"
    48 
    49 namespace ns3 {
    50 
    51 template <typename T>
    52 struct AccessorTrait
    53 {
    54   typedef typename TypeTraits<typename TypeTraits<T>::ReferencedType>::NonConstType Result;
    55 };
    56 
    57 template <typename T, typename U>
    58 class AccessorHelper : public AttributeAccessor
    59 {
    60 public:
    61   AccessorHelper () {}
    62 
    63   virtual bool Set (ObjectBase * object, const AttributeValue & val) const {
    64     const U *value = dynamic_cast<const U *> (&val);
    65     if (value == 0)
    66       {
    67 	return false;
    68       }
    69     T *obj = dynamic_cast<T *> (object);
    70     if (obj == 0)
    71       {
    72 	return false;
    73       }
    74     return DoSet (obj, value);
    75   }
    76 
    77   virtual bool Get (const ObjectBase * object, AttributeValue &val) const {
    78     U *value = dynamic_cast<U *> (&val);
    79     if (value == 0)
    80       {
    81 	return false;
    82       }
    83     const T *obj = dynamic_cast<const T *> (object);
    84     if (obj == 0)
    85       {
    86 	return false;
    87       }
    88     return DoGet (obj, value);
    89   }
    90 
    91 private:
    92   virtual bool DoSet (T *object, const U *v) const = 0;
    93   virtual bool DoGet (const T *object, U *v) const = 0;
    94 };
    95 
    96 template <typename V, typename T, typename U>
    97 Ptr<const AttributeAccessor>
    98 DoMakeAccessorHelperOne (U T::*memberVariable)
    99 {
   100   class MemberVariable : public AccessorHelper<T,V>
   101     {
   102     public:
   103       MemberVariable (U T::*memberVariable)
   104 	: AccessorHelper<T,V> (),
   105 	m_memberVariable (memberVariable)
   106 	{}
   107     private:
   108       virtual bool DoSet (T *object, const V *v) const {
   109         typename AccessorTrait<U>::Result tmp;
   110         bool ok = v->GetAccessor (tmp);
   111         if (!ok)
   112           {
   113             return false;
   114           }
   115 	(object->*m_memberVariable) = tmp;
   116 	return true;
   117       }
   118       virtual bool DoGet (const T *object, V *v) const {
   119 	v->Set (object->*m_memberVariable);
   120 	return true;
   121       }
   122       virtual bool HasGetter (void) const {
   123         return true;
   124       }
   125       virtual bool HasSetter (void) const {
   126         return true;
   127       }
   128       
   129       U T::*m_memberVariable;
   130     };
   131   return Ptr<const AttributeAccessor> (new MemberVariable (memberVariable), false);
   132 }
   133 
   134 template <typename V, typename T, typename U>
   135 Ptr<const AttributeAccessor>
   136 DoMakeAccessorHelperOne (U (T::*getter) (void) const)
   137 {
   138   class MemberMethod : public AccessorHelper<T,V>
   139     {
   140     public:
   141       MemberMethod (U (T::*getter) (void) const)
   142 	: AccessorHelper<T,V> (),
   143 	m_getter (getter)
   144 	{}
   145     private:
   146       virtual bool DoSet (T *object, const V *v) const {
   147 	return false;
   148       }
   149       virtual bool DoGet (const T *object, V *v) const {
   150 	v->Set ((object->*m_getter) ());
   151 	return true;
   152       }
   153       virtual bool HasGetter (void) const {
   154         return true;
   155       }
   156       virtual bool HasSetter (void) const {
   157         return false;
   158       }
   159       U (T::*m_getter) (void) const;
   160     };
   161   return Ptr<const AttributeAccessor> (new MemberMethod (getter), false);
   162 }
   163 
   164 
   165 template <typename V, typename T, typename U>
   166 Ptr<const AttributeAccessor>
   167 DoMakeAccessorHelperOne (void (T::*setter) (U))
   168 {
   169   class MemberMethod : public AccessorHelper<T,V>
   170     {
   171     public:
   172       MemberMethod (void (T::*setter) (U))
   173 	: AccessorHelper<T,V> (),
   174 	m_setter (setter)
   175 	{}
   176     private:
   177       virtual bool DoSet (T *object, const V *v) const {
   178         typename AccessorTrait<U>::Result tmp;
   179         bool ok = v->GetAccessor (tmp);
   180         if (!ok)
   181           {
   182             return false;
   183           }
   184 	(object->*m_setter) (tmp);
   185 	return true;
   186       }
   187       virtual bool DoGet (const T *object, V *v) const {
   188 	return false;
   189       }
   190       virtual bool HasGetter (void) const {
   191         return false;
   192       }
   193       virtual bool HasSetter (void) const {
   194         return true;
   195       }
   196       void (T::*m_setter) (U);
   197     };
   198   return Ptr<const AttributeAccessor> (new MemberMethod (setter), false);
   199 }
   200 
   201 template <typename W, typename T, typename U, typename V>
   202 Ptr<const AttributeAccessor>
   203 DoMakeAccessorHelperTwo (void (T::*setter) (U), 
   204 			  V (T::*getter) (void) const)
   205 {
   206   class MemberMethod : public AccessorHelper<T,W>
   207     {
   208     public:
   209       MemberMethod (void (T::*setter) (U), 
   210 		    V (T::*getter) (void) const)
   211 	: AccessorHelper<T,W> (),
   212 	m_setter (setter),
   213 	m_getter (getter)
   214 	{}
   215     private:
   216       virtual bool DoSet (T *object, const W *v) const {
   217         typename AccessorTrait<U>::Result tmp;
   218         bool ok = v->GetAccessor (tmp);
   219         if (!ok)
   220           {
   221             return false;
   222           }
   223 	(object->*m_setter) (tmp);
   224 	return true;
   225       }
   226       virtual bool DoGet (const T *object, W *v) const {
   227 	v->Set ((object->*m_getter) ());
   228 	return true;
   229       }
   230       virtual bool HasGetter (void) const {
   231         return true;
   232       }
   233       virtual bool HasSetter (void) const {
   234         return true;
   235       }
   236       void (T::*m_setter) (U);
   237       V (T::*m_getter) (void) const;
   238     };
   239   return Ptr<const AttributeAccessor> (new MemberMethod (setter, getter), false);
   240 }
   241 
   242 template <typename W, typename T, typename U, typename V>
   243 Ptr<const AttributeAccessor>
   244 DoMakeAccessorHelperTwo (V (T::*getter) (void) const, 
   245 			  void (T::*setter) (U))
   246 {
   247   return DoMakeAccessorHelperTwo<W> (setter, getter);
   248 }
   249 
   250 template <typename W, typename T, typename U, typename V>
   251 Ptr<const AttributeAccessor>
   252 DoMakeAccessorHelperTwo (bool (T::*setter) (U), 
   253                          V (T::*getter) (void) const)
   254 {
   255   class MemberMethod : public AccessorHelper<T,W>
   256     {
   257     public:
   258       MemberMethod (bool (T::*setter) (U), 
   259 		    V (T::*getter) (void) const)
   260 	: AccessorHelper<T,W> (),
   261 	m_setter (setter),
   262 	m_getter (getter)
   263 	{}
   264     private:
   265       virtual bool DoSet (T *object, const W *v) const {
   266         typename AccessorTrait<U>::Result tmp;
   267         bool ok = v->GetAccessor (tmp);
   268         if (!ok)
   269           {
   270             return false;
   271           }
   272 	ok = (object->*m_setter) (tmp);
   273         return ok;
   274       }
   275       virtual bool DoGet (const T *object, W *v) const {
   276 	v->Set ((object->*m_getter) ());
   277 	return true;
   278       }
   279       virtual bool HasGetter (void) const {
   280         return true;
   281       }
   282       virtual bool HasSetter (void) const {
   283         return true;
   284       }
   285       bool (T::*m_setter) (U);
   286       V (T::*m_getter) (void) const;
   287     };
   288   return Ptr<const AttributeAccessor> (new MemberMethod (setter, getter), false);
   289 }
   290 
   291 template <typename W, typename T, typename U, typename V>
   292 Ptr<const AttributeAccessor>
   293 DoMakeAccessorHelperTwo (bool (T::*getter) (void) const, 
   294                          void (T::*setter) (U))
   295 {
   296   return DoMakeAccessorHelperTwo<W> (setter, getter);
   297 }
   298 
   299 template <typename V, typename T1>
   300 Ptr<const AttributeAccessor>
   301 MakeAccessorHelper (T1 a1)
   302 {
   303   return DoMakeAccessorHelperOne<V> (a1);
   304 }
   305 
   306 template <typename V, typename T1, typename T2>
   307 Ptr<const AttributeAccessor>
   308 MakeAccessorHelper (T1 a1, T2 a2)
   309 {
   310   return DoMakeAccessorHelperTwo<V> (a1, a2);
   311 }
   312 
   313 } // namespace ns3
   314 
   315 #endif /* ATTRIBUTE_ACCESSOR_HELPER_H */