00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef ORO_TEMPLATE_BOOSTARRAY_INFO_HPP
00040 #define ORO_TEMPLATE_BOOSTARRAY_INFO_HPP
00041
00042 #include "TemplateTypeInfo.hpp"
00043 #include "../internal/ArrayPartDataSource.hpp"
00044 #include "type_discovery.hpp"
00045 #include <boost/lexical_cast.hpp>
00046 #include <boost/array.hpp>
00047
00048 namespace RTT
00049 {
00050 namespace types
00051 {
00057 template<typename T, bool has_ostream = false>
00058 class BoostArrayTypeInfo: public TemplateTypeInfo<T, has_ostream>
00059 {
00060 public:
00061 BoostArrayTypeInfo(std::string name) :
00062 TemplateTypeInfo<T, has_ostream> (name)
00063 {
00064 }
00065
00066 virtual std::vector<std::string> getMemberNames() const {
00067
00068 std::vector<std::string> result;
00069 result.push_back("size");
00070 result.push_back("capacity");
00071 return result;
00072 }
00073
00074 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00075 using namespace internal;
00076 typename AssignableDataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00077 if ( !data ) {
00078 return base::DataSourceBase::shared_ptr();
00079 }
00080
00081
00082 if (name == "size" || name == "capacity") {
00083 return new ConstantDataSource<int>( T::static_size );
00084 }
00085
00086
00087 try {
00088 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00089
00090 return new ArrayPartDataSource<typename T::value_type>( *data->set().c_array(), new ConstantDataSource<unsigned int>(indx), item, T::static_size);
00091 } catch(...) {}
00092 log(Error) << "BoostArrayTypeInfo: No such part (or invalid index): " << name << endlog();
00093 return base::DataSourceBase::shared_ptr();
00094 }
00095
00096 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00097 base::DataSourceBase::shared_ptr id) const {
00098 using namespace internal;
00099 typename AssignableDataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00100 if ( !data ) {
00101 return base::DataSourceBase::shared_ptr();
00102 }
00103
00104
00105 typename DataSource<unsigned int>::shared_ptr id_indx = DataSource<unsigned int>::narrow( id.get() );
00106 typename DataSource<string>::shared_ptr id_name = DataSource<string>::narrow( id.get() );
00107 if ( id_name ) {
00108
00109 if (id_name->get() == "size" || id_name->get() == "capacity") {
00110 return new ConstantDataSource<int>( T::static_size );
00111 }
00112 }
00113
00114 if ( id_indx ) {
00115 return new ArrayPartDataSource<typename T::value_type>( *data->set().c_array(), id_indx, item, T::static_size );
00116 }
00117 log(Error) << "BoostArrayTypeInfo: No such part (or invalid index): " << id_name->get() << id_indx->get() << endlog();
00118 return base::DataSourceBase::shared_ptr();
00119 }
00123 virtual bool composeTypeImpl(const PropertyBag& source, typename internal::AssignableDataSource<T>::reference_t result) const
00124 {
00125
00126 if(result.size() != source.size()) {
00127 log(Error) << "Refusing to compose Boost Arrays from a property list of different size. Use the same number of properties as the C++ boost array size." << endlog();
00128 return false;
00129 }
00130
00131 PropertyBag target( source.getType() );
00132 PropertyBag decomp;
00133 internal::ReferenceDataSource<T> rds(result);
00134 rds.ref();
00135
00136
00137
00138 if ( composePropertyBag(source, target) && typeDecomposition( &rds, decomp, false) && ( decomp.getType() == target.getType() ) && refreshProperties(decomp, target, true) ) {
00139 assert(result.size() == source.size());
00140 assert(source.size() == target.size());
00141 assert(source.size() == decomp.size());
00142 return true;
00143 }
00144 return false;
00145 }
00146
00147 };
00148 }
00149 }
00150
00151 #endif