Changeset 41:eb5957b12387 in finroc_plugins_data_ports


Ignore:
Timestamp:
06.09.2013 06:47:54 (6 years ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
default
Phase:
public
Message:

Refactored implementation of variadic argument constructors in port wrapper classes.

Files:
8 edited

Legend:

Unmodified
Added
Removed
  • common/tAbstractDataPortCreationInfo.h

    r26 r41  
    6262// Forward declarations / typedefs / enums 
    6363//---------------------------------------------------------------------- 
    64 /*! Can be used to wrap lock order for tAbstractPortCreationInfo variadic template constructor */ 
    65 struct tLockOrder 
    66 { 
    67   int wrapped; 
    68  
    69   tLockOrder(int i) : wrapped(i) {} 
    70 }; 
    7164 
    7265//---------------------------------------------------------------------- 
     
    8982public: 
    9083 
     84  /*! Base class */ 
     85  typedef core::tAbstractPortCreationInfo tBase; 
     86 
    9187  /*! SI Unit of port. NULL for no unit = provides raw numbers */ 
    9288  tUnit unit; 
     
    108104 
    109105  /*! 
    110    * Constructor takes variadic argument list... just any properties you want to assign to port. 
    111    * 
    112    * The first string is interpreted as port name, the second possibly as config entry (relevant for parameters only). 
    113    * A framework element pointer is interpreted as parent. 
    114    * tFrameworkElementFlag arguments are interpreted as flags. 
    115    * A tQueueSettings argument creates an input queue with the specified settings. 
    116    * tBounds<T> are port's bounds. 
    117    * tUnit argument is port's unit. 
    118    * tAbstractPortCreationInfo argument is copied. This is only allowed as first argument. 
    119    */ 
    120   template <typename ARG1, typename ... TArgs> 
    121   explicit tAbstractDataPortCreationInfo(const ARG1& arg1, const TArgs&... rest) : 
    122     unit(), 
    123     max_queue_size(-1), 
    124     min_net_update_interval(-1), 
    125     config_entry(), 
    126     default_value(), 
    127     bounds(), 
    128     name_set(false) 
    129   { 
    130     ProcessFirstArg<ARG1>(arg1); 
    131     ProcessArgs(rest...); 
    132   } 
    133  
    134   /*! 
    135106   * \return Have bounds for port been set? 
    136107   */ 
     
    149120 
    150121  /*! 
    151    * Derive method: Copy port creation info and change specified parameters 
    152    * (Basically, the same arguments as in the constructor are possible) 
    153    */ 
    154   template <typename ... TArgs> 
    155   tAbstractDataPortCreationInfo Derive(const TArgs&... rest) const 
    156   { 
    157     ProcessArgs(rest...); 
    158     return *this; 
    159   } 
    160  
    161   /*! 
    162122   * \return Bounds (when their exact type is not known at compile time) 
    163123   */ 
     
    175135  } 
    176136 
    177   /*! Various set methods for different port properties */ 
    178   void Set(core::tFrameworkElement* parent) 
    179   { 
    180     this->parent = parent; 
    181   } 
    182  
    183   void Set(const char* c) 
    184   { 
    185     SetString(c); 
    186   } 
    187  
    188   void Set(const tString& s) 
    189   { 
    190     SetString(s); 
    191   } 
    192  
     137  /*! Various Set methods for different port properties */ 
    193138  void Set(const tQueueSettings& queue_settings) 
    194139  { 
     
    201146  } 
    202147 
    203   void Set(core::tFrameworkElement::tFlags flags) 
    204   { 
    205     this->flags |= flags; 
    206   } 
    207  
    208148  void Set(const tUnit& unit) 
    209149  { 
     
    211151  } 
    212152 
    213 // This only catches int arguments - and should be used very rarely 
    214 //  void Set(const tLockOrder& lo) 
    215 //  { 
    216 //    this->lock_order = lo.wrapped; 
    217 //  } 
    218  
    219   void Set(const rrlib::rtti::tType& dt) 
    220   { 
    221     this->data_type = dt; 
     153  void Set(const tAbstractDataPortCreationInfo& other) 
     154  { 
     155    *this = other; 
    222156  } 
    223157 
     
    244178    default_val.Serialize(stream); 
    245179  } 
    246  
    247   /*! 
    248    * Set Port flag 
    249    * 
    250    * \param flag Flag to set 
    251    * \param value Value to set flag to 
    252    */ 
    253   void SetFlag(uint flag, bool value); 
    254180 
    255181  /*! 
     
    309235private: 
    310236 
    311   /*! 
    312    * Processes first argument (only here tPortCreationInfoBase argument is allowed) 
    313    */ 
    314   template <typename A> 
    315   void ProcessFirstArg(const typename std::enable_if<std::is_base_of<tAbstractPortCreationInfo, A>::value, A>::type& a) 
    316   { 
    317     (*this) = a; 
    318   } 
    319  
    320   template <typename A> 
    321   void ProcessFirstArg(const typename std::enable_if < !std::is_base_of<tAbstractPortCreationInfo, A>::value, A >::type& a) 
    322   { 
    323     ProcessArg<A>(a); 
    324   } 
    325  
    326   /*! Process constructor arguments */ 
    327   void ProcessArgs() {} 
    328  
    329   template <typename A, typename ... ARest> 
    330   void ProcessArgs(const A& arg, const ARest&... args) 
    331   { 
    332     ProcessArg<A>(arg); 
    333     ProcessArgs(args...); 
    334   } 
    335  
    336   /*! Process single constructor argument */ 
    337   template <typename A> 
    338   void ProcessArg(const A& arg) 
    339   { 
    340     // standard case 
    341     Set(arg); 
    342   } 
    343  
    344237}; 
    345238 
  • standard/tStandardPort.cpp

    r34 r41  
    3434//---------------------------------------------------------------------- 
    3535#include "core/port/tPortFactory.h" 
     36#include "core/port/tPortWrapperBase.h" 
    3637 
    3738//---------------------------------------------------------------------- 
     
    8182      const rrlib::rtti::tType& type, core::tFrameworkElement::tFlags flags) 
    8283  { 
    83     common::tAbstractDataPortCreationInfo creation_info(port_name, &parent, type, flags); 
     84    core::tPortWrapperBase::tConstructorArguments<common::tAbstractDataPortCreationInfo> creation_info(port_name, &parent, type, flags); 
    8485    return IsCheaplyCopiedType(type) ? // TODO: put it 
    8586           *static_cast<core::tAbstractPort*>(new optimized::tCheapCopyPort(creation_info)) : 
  • tGenericPort.h

    r39 r41  
    108108  tGenericPort(const ARGS&... args) 
    109109  { 
    110     common::tAbstractDataPortCreationInfo creation_info(args...); 
     110    tConstructorArguments<common::tAbstractDataPortCreationInfo> creation_info(args...); 
    111111    if ((creation_info.data_type.GetTypeTraits() & rrlib::rtti::trait_flags::cIS_BINARY_SERIALIZABLE) == 0) 
    112112    { 
  • tInputPort.h

    r25 r41  
    8585{ 
    8686  typedef typename tPort<T>::tImplementation tImplementation; 
     87  typedef core::tPortWrapperBase::tNoArgument tNoArgument; 
    8788 
    8889//---------------------------------------------------------------------- 
     
    109110   * The second string argument is interpreted as default_value. The third as config entry. 
    110111   */ 
    111   template <typename ... ARGS> 
    112   tInputPort(const ARGS& ... args) : 
    113     tPort<T>(args..., core::tFrameworkElement::tFlag::ACCEPTS_DATA | core::tFrameworkElement::tFlag::PUSH_STRATEGY) 
     112  template <typename TArg1, typename TArg2, typename ... TRest> 
     113  tInputPort(const TArg1& arg1, const TArg2& arg2, const TRest&... args) : 
     114    tPort<T>(arg1, arg2, args..., core::tFrameworkElement::tFlag::ACCEPTS_DATA | core::tFrameworkElement::tFlag::PUSH_STRATEGY) 
    114115  {} 
     116 
     117  // with a single argument, we do not want catch calls for copy construction 
     118  template < typename TArgument1, bool ENABLE = !std::is_base_of<tInputPort, TArgument1>::value > 
     119  tInputPort(const TArgument1& argument1, typename std::enable_if<ENABLE, tNoArgument>::type no_argument = tNoArgument()) : 
     120    tPort<T>(argument1, core::tFrameworkElement::tFlag::ACCEPTS_DATA | core::tFrameworkElement::tFlag::PUSH_STRATEGY) 
     121  {} 
     122 
    115123 
    116124  /*! 
  • tOutputPort.h

    r25 r41  
    7878{ 
    7979  typedef typename tPort<T>::tImplementation tImplementation; 
     80  typedef core::tPortWrapperBase::tNoArgument tNoArgument; 
    8081 
    8182//---------------------------------------------------------------------- 
     
    102103   * The second string argument is interpreted as default_value. The third as config entry. 
    103104   */ 
    104   template <typename ... ARGS> 
    105   tOutputPort(const ARGS& ... args) : 
    106     tPort<T>(args..., core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::OUTPUT_PORT) 
     105  template <typename TArg1, typename TArg2, typename ... TRest> 
     106  tOutputPort(const TArg1& arg1, const TArg2& arg2, const TRest&... args) : 
     107    tPort<T>(arg1, arg2, args..., core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::OUTPUT_PORT) 
     108  {} 
     109 
     110  // with a single argument, we do not want catch calls for copy construction 
     111  template < typename TArgument1, bool ENABLE = !std::is_base_of<tOutputPort, TArgument1>::value > 
     112  tOutputPort(const TArgument1& argument1, typename std::enable_if<ENABLE, tNoArgument>::type no_argument = tNoArgument()) : 
     113    tPort<T>(argument1, core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::OUTPUT_PORT) 
    107114  {} 
    108115 
  • tPort.h

    r28 r41  
    142142   * The second string argument is interpreted as default_value. The third as config entry. 
    143143   */ 
    144   template <typename TArg1, typename ... TRest> 
    145   tPort(const TArg1& arg1, const TRest&... args) 
    146   { 
    147     if (!this->CopyConstruction<tPort>(&arg1)) 
     144  template <typename TArg1, typename TArg2, typename ... TRest> 
     145  tPort(const TArg1& arg1, const TArg2& arg2, const TRest&... args) 
     146  { 
     147    tConstructorArguments<tPortCreationInfo<T>> creation_info(arg1, arg2, args...); 
     148    creation_info.data_type = rrlib::rtti::tDataType<tPortBuffer>(); 
     149    SetWrapped(tImplementation::CreatePort(creation_info)); 
     150    GetWrapped()->SetWrapperDataType(rrlib::rtti::tDataType<T>()); 
     151    if (creation_info.DefaultValueSet()) 
    148152    { 
    149       tPortCreationInfo<T> creation_info(arg1, args...); 
    150       creation_info.data_type = rrlib::rtti::tDataType<tPortBuffer>(); 
    151       SetWrapped(tImplementation::CreatePort(creation_info)); 
    152       GetWrapped()->SetWrapperDataType(rrlib::rtti::tDataType<T>()); 
    153       if (creation_info.DefaultValueSet()) 
    154       { 
    155         T t = rrlib::rtti::sStaticTypeInfo<T>::CreateByValue(); 
    156         creation_info.GetDefault(t); 
    157         SetDefault(t); 
    158       } 
     153      T t = rrlib::rtti::sStaticTypeInfo<T>::CreateByValue(); 
     154      creation_info.GetDefault(t); 
     155      SetDefault(t); 
    159156    } 
     157  } 
     158 
     159  // with a single argument, we do not want catch calls for copy construction 
     160  template < typename TArgument1, bool ENABLE = !std::is_base_of<tPort, TArgument1>::value > 
     161  tPort(const TArgument1& argument1, typename std::enable_if<ENABLE, tNoArgument>::type no_argument = tNoArgument()) 
     162  { 
     163    // Call the above constructor 
     164    *this = tPort(tFlags(), argument1); 
    160165  } 
    161166 
  • tPortCreationInfo.h

    r33 r41  
    8080public: 
    8181 
    82   tPortCreationInfo() : 
    83     common::tAbstractDataPortCreationInfo() 
    84   { 
    85   } 
    86  
    87   /*! 
    88    * Constructor takes variadic argument list... just any properties you want to assign to port. 
    89    * 
    90    * The first string is interpreted as port name, the second possibly as config entry (relevant for parameters only). 
    91    * A framework element pointer is interpreted as parent. 
    92    * tFrameworkElement::tFlags arguments are interpreted as flags. 
    93    * A tQueueSettings argument creates an input queue with the specified settings. 
    94    * tBounds<T> are port's bounds. 
    95    * tUnit argument is port's unit. 
    96    * const T& is interpreted as port's default value. 
    97    * tPortCreationInfo<T> argument is copied. This is only allowed as first argument. 
    98    * 
    99    * This becomes a little tricky when T is a string type. There we have these rules: 
    100    * The second string argument is interpreted as default_value. The third as config entry. 
    101    */ 
    102   template <typename ARG1, typename ... TArgs> 
    103   explicit tPortCreationInfo(const ARG1& arg1, const TArgs&... rest) : 
    104     common::tAbstractDataPortCreationInfo() 
    105   { 
    106     ProcessFirstArg<ARG1>(arg1); 
    107     ProcessArgs(rest...); 
    108   } 
     82  /*! Base class */ 
     83  typedef common::tAbstractDataPortCreationInfo tBase; 
    10984 
    11085  /*! 
     
    150125  } 
    151126 
    152   using common::tAbstractDataPortCreationInfo::Set; 
    153  
     127  /*! Various Set methods for different port properties */ 
    154128  template < bool DISABLE = tIsString<T>::value > 
    155129  void Set(const typename std::enable_if < !DISABLE, T >::type& default_value) 
     
    165139  } 
    166140 
     141  void Set(const tPortCreationInfo& other) 
     142  { 
     143    *this = other; 
     144  } 
     145 
     146  void Set(const std::string& string) 
     147  { 
     148    SetString(string); 
     149  } 
     150 
     151  // we replicate this here, since Set() for default values catches pointers if T is bool 
     152  void Set(core::tFrameworkElement* parent) 
     153  { 
     154    this->parent = parent; 
     155  } 
     156  void Set(const char* string) 
     157  { 
     158    SetString(string); 
     159  } 
     160 
    167161//---------------------------------------------------------------------- 
    168162// Private fields and methods 
     
    170164private: 
    171165 
    172   /*! Process first constructor argument (tPortCreationInfo allowed) */ 
    173   template <typename A> 
    174   void ProcessFirstArg(const typename std::enable_if<std::is_same<A, tPortCreationInfo>::value, A>::type& a) 
    175   { 
    176     *this = a; 
    177   } 
    178   template <typename A> 
    179   void ProcessFirstArg(const typename std::enable_if<std::is_same<A, common::tAbstractDataPortCreationInfo>::value, A>::type& a) 
    180   { 
    181     static_cast<common::tAbstractDataPortCreationInfo&>(*this) = a; 
    182   } 
    183  
    184   template <typename A> 
    185   void ProcessFirstArg(const typename std::enable_if < !(std::is_same<A, tPortCreationInfo>::value || std::is_same<A, common::tAbstractDataPortCreationInfo>::value), A >::type& a) 
    186   { 
    187     ProcessArg<A>(a); 
    188   } 
    189  
    190   /*! Process constructor arguments */ 
    191   void ProcessArgs() {} 
    192  
    193   template <typename A, typename ... TRest> 
    194   void ProcessArgs(const A& arg, const TRest&... args) 
    195   { 
    196     ProcessArg<A>(arg); 
    197     ProcessArgs(args...); 
    198   } 
    199  
    200   /*! Process single argument */ 
    201   template <typename A> 
    202   void ProcessArg(const typename std::enable_if < !(tIsString<A>::value), A >::type& arg) 
    203   { 
    204     // standard case 
    205     Set(arg); 
    206   } 
    207  
    208   template <typename A> 
    209   void ProcessArg(const typename std::enable_if<tIsString<A>::value, A>::type& arg) 
    210   { 
    211     // string argument, handling it here (no method overloading), produces some nicer compiler error messages 
    212     SetString(arg); 
    213   } 
    214  
    215   /*! 
    216    * This exists so that the copy construction works/compiles with the varargs constructor. 
    217    * At runtime, however, tPortWrapperBase::CopyConstruction should return true - and this is never called 
    218    */ 
    219   void Set(const core::tPortWrapperBase& base) 
    220   { 
    221     throw std::logic_error("This should never be called"); 
    222   } 
    223  
    224   // various helper methods 
    225166  template < bool STRING = tIsString<T>::value > 
    226167  void SetString(const typename std::enable_if < !STRING, tString >::type& s) 
  • tProxyPort.h

    r25 r41  
    7373class tProxyPort : public tPort<T> 
    7474{ 
     75  typedef core::tPortWrapperBase::tNoArgument tNoArgument; 
    7576 
    7677//---------------------------------------------------------------------- 
     
    9798   * The second string argument is interpreted as default_value. The third as config entry. 
    9899   */ 
    99   template <typename ... ARGS> 
    100   tProxyPort(const ARGS& ... args) : 
    101     tPort<T>(std::forward<const ARGS>(args)..., core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::ACCEPTS_DATA | 
     100  template <typename TArg1, typename TArg2, typename ... TRest> 
     101  tProxyPort(const TArg1& arg1, const TArg2& arg2, const TRest&... args) : 
     102    tPort<T>(arg1, arg2, args..., core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::ACCEPTS_DATA | 
     103             (OUTPUT_PORT ? core::tFrameworkElement::tFlag::OUTPUT_PORT : core::tFrameworkElement::tFlag::EMITS_DATA)) 
     104  {} 
     105 
     106  // with a single argument, we do not want catch calls for copy construction 
     107  template < typename TArgument1, bool ENABLE = !std::is_base_of<tProxyPort, TArgument1>::value > 
     108  tProxyPort(const TArgument1& argument1, typename std::enable_if<ENABLE, tNoArgument>::type no_argument = tNoArgument()) : 
     109    tPort<T>(argument1, core::tFrameworkElement::tFlag::EMITS_DATA | core::tFrameworkElement::tFlag::ACCEPTS_DATA | 
    102110             (OUTPUT_PORT ? core::tFrameworkElement::tFlag::OUTPUT_PORT : core::tFrameworkElement::tFlag::EMITS_DATA)) 
    103111  {} 
Note: See TracChangeset for help on using the changeset viewer.