Orocos Real-Time Toolkit
2.5.0
|
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 EnumTypeInfo.hpp 00003 00004 EnumTypeInfo.hpp - description 00005 ------------------- 00006 begin : Tue September 07 2010 00007 copyright : (C) 2010 The SourceWorks 00008 email : peter@thesourceworks.com 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 #include "../rtt-config.h" 00040 #include "Types.hpp" 00041 #include "TemplateTypeInfo.hpp" 00042 #include "TemplateConstructor.hpp" 00043 00044 namespace RTT 00045 { 00046 namespace types 00047 { 00048 00055 template<class T> 00056 struct EnumTypeInfo: public TemplateTypeInfo<T, false> 00057 { 00058 protected: 00059 static int enum_to_int(T e) 00060 { 00061 return (int) e; 00062 } 00063 00064 static T int_to_enum(int i) 00065 { 00066 return (T) i; 00067 } 00068 00069 std::map<T,std::string> to_string; 00070 typedef std::map<T,std::string> MapType; 00071 public: 00072 EnumTypeInfo(std::string type) : 00073 TemplateTypeInfo<T, false> (type) 00074 { 00075 if (!Types()->type("int")) { 00076 log(Error) << "Failed to register enum <-> int conversion because type int is not known in type system."<<endlog(); 00077 } else { 00078 Types()->type("int")->addConstructor(newConstructor( 00079 &EnumTypeInfo<T>::enum_to_int, true)); 00080 } 00081 this->addConstructor( newConstructor( &EnumTypeInfo<T>::int_to_enum, true) ); 00082 } 00083 00090 virtual bool composeType(base::DataSourceBase::shared_ptr source, 00091 base::DataSourceBase::shared_ptr result) const 00092 { 00093 // First, try a plain update. 00094 if (result->update(source.get())) 00095 return true; 00096 // try conversion from int to enum: 00097 internal::DataSource<int>::shared_ptr ds = 00098 internal::DataSource<int>::narrow( source.get() ); 00099 if (ds) 00100 { 00101 typename internal::AssignableDataSource<T>::shared_ptr menum = 00102 internal::AssignableDataSource<T>::narrow( source.get() ); 00103 assert(menum); 00104 menum->set( (T)ds->get() ); 00105 return true; 00106 } 00107 // try conversion from string to enum: 00108 internal::DataSource<std::string>::shared_ptr dss = 00109 internal::DataSource<std::string>::narrow( source.get() ); 00110 if (dss) 00111 { 00112 typename internal::AssignableDataSource<T>::shared_ptr menum = 00113 internal::AssignableDataSource<T>::narrow( result.get() ); 00114 assert(menum); 00115 for( typename MapType::const_iterator it = to_string.begin(); it != to_string.end(); ++it) 00116 if ( it->second == dss->get() ) { 00117 menum->set( it->first ); 00118 return true; 00119 } 00120 } 00121 // no conversion possible. 00122 return false; 00123 } 00124 00132 virtual base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const 00133 { 00134 // Convert enum to string 00135 typename internal::DataSource<T>::shared_ptr ds = internal::DataSource<T>::narrow( source.get() ); 00136 if ( ds ) 00137 { 00138 // if not available, just convert to int. 00139 if ( to_string.count( ds->get() ) == 0 ) { 00140 log(Warning) << "No enum-to-string mapping defined for enum " << this->getTypeName() <<". Converting to int."<<endlog(); 00141 return new internal::ValueDataSource<int>( ds->get() ); 00142 } 00143 internal::ValueDataSource<std::string>::shared_ptr vds = new internal::ValueDataSource<std::string>( to_string.find(ds->get())->second ); 00144 return vds; 00145 } 00146 // convert string to enum 00147 return base::DataSourceBase::shared_ptr(); 00148 } 00149 }; 00150 } 00151 }