Go to the documentation of this file.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 "PrimitiveTypeInfo.hpp"
00043 #include "../internal/ArrayPartDataSource.hpp"
00044 #include "type_discovery.hpp"
00045 #include <boost/lexical_cast.hpp>
00046 #include <boost/array.hpp>
00047 #include "PropertyComposition.hpp"
00048 #include "PropertyDecomposition.hpp"
00049 #include "CompositionFactory.hpp"
00050 #include "MemberFactory.hpp"
00051
00052 namespace RTT
00053 {
00054 namespace types
00055 {
00067 template<typename T, bool has_ostream = false>
00068 class BoostArrayTypeInfo :
00069 public PrimitiveTypeInfo<T, has_ostream>,
00070 public MemberFactory, public CompositionFactory
00071 {
00072 public:
00073 BoostArrayTypeInfo(std::string name) :
00074 PrimitiveTypeInfo<T, has_ostream> (name)
00075 {
00076 }
00077
00078 bool installTypeInfoObject(TypeInfo* ti) {
00079
00080 boost::shared_ptr< BoostArrayTypeInfo<T> > mthis = boost::dynamic_pointer_cast<BoostArrayTypeInfo<T> >( this->getSharedPtr() );
00081
00082 PrimitiveTypeInfo<T,has_ostream>::installTypeInfoObject(ti);
00083
00084 ti->setMemberFactory( mthis );
00085 ti->setCompositionFactory( mthis );
00086
00087
00088 return false;
00089 }
00090
00091 virtual std::vector<std::string> getMemberNames() const {
00092
00093 std::vector<std::string> result;
00094 result.push_back("size");
00095 result.push_back("capacity");
00096 return result;
00097 }
00098
00099 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00100 using namespace internal;
00101 typename AssignableDataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00102 if ( !data ) {
00103 return base::DataSourceBase::shared_ptr();
00104 }
00105
00106
00107 if (name == "size" || name == "capacity") {
00108 return new ConstantDataSource<int>( T::static_size );
00109 }
00110
00111
00112 try {
00113 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00114
00115 return new ArrayPartDataSource<typename T::value_type>( *data->set().c_array(), new ConstantDataSource<unsigned int>(indx), item, T::static_size);
00116 } catch(...) {}
00117 log(Error) << "BoostArrayTypeInfo: No such part (or invalid index): " << name << endlog();
00118 return base::DataSourceBase::shared_ptr();
00119 }
00120
00121 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00122 base::DataSourceBase::shared_ptr id) const {
00123 using namespace internal;
00124 typename AssignableDataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< AssignableDataSource<T> >( item );
00125 if ( !data ) {
00126 return base::DataSourceBase::shared_ptr();
00127 }
00128
00129
00130 typename DataSource<unsigned int>::shared_ptr id_indx = DataSource<unsigned int>::narrow( id.get() );
00131 typename DataSource<std::string>::shared_ptr id_name = DataSource<std::string>::narrow( id.get() );
00132 if ( id_name ) {
00133
00134 if (id_name->get() == "size" || id_name->get() == "capacity") {
00135 return new ConstantDataSource<int>( T::static_size );
00136 }
00137 }
00138
00139 if ( id_indx ) {
00140 return new ArrayPartDataSource<typename T::value_type>( *data->set().c_array(), id_indx, item, T::static_size );
00141 }
00142 log(Error) << "BoostArrayTypeInfo: No such part (or invalid index): " << id_name->get() << id_indx->get() << endlog();
00143 return base::DataSourceBase::shared_ptr();
00144 }
00145
00149 virtual base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const
00150 {
00151 return base::DataSourceBase::shared_ptr();
00152 }
00153
00154 virtual bool composeType( base::DataSourceBase::shared_ptr dssource, base::DataSourceBase::shared_ptr dsresult) const {
00155 const internal::DataSource<PropertyBag>* pb = dynamic_cast< const internal::DataSource<PropertyBag>* > (dssource.get() );
00156 if ( !pb )
00157 return false;
00158 typename internal::AssignableDataSource<T>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( dsresult );
00159 if ( !ads )
00160 return false;
00161
00162 PropertyBag const& source = pb->rvalue();
00163 typename internal::AssignableDataSource<T>::reference_t result = ads->set();
00164
00165
00166 if(result.size() != source.size()) {
00167 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();
00168 return false;
00169 }
00170
00171 TypeInfoRepository::shared_ptr tir = Types();
00172 PropertyBag target( source.getType() );
00173 PropertyBag decomp;
00174 internal::ReferenceDataSource<T> rds(result);
00175 rds.ref();
00176
00177
00178
00179 if ( composePropertyBag(source, target) && typeDecomposition( &rds, decomp, false) && ( tir->type(decomp.getType()) == tir->type(target.getType()) ) && refreshProperties(decomp, target, true) ) {
00180 assert(result.size() == source.size());
00181 assert(source.size() == target.size());
00182 assert(source.size() == decomp.size());
00183 return true;
00184 }
00185 return false;
00186 }
00187
00188 };
00189 }
00190 }
00191
00192 #endif