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_SEQUENCE_TYPE_INFO_HPP
00040 #define ORO_SEQUENCE_TYPE_INFO_HPP
00041
00042 #include "TemplateTypeInfo.hpp"
00043 #include "type_discovery.hpp"
00044 #include "../internal/DataSourceGenerator.hpp"
00045 #include "SequenceConstructor.hpp"
00046 #include "TemplateConstructor.hpp"
00047 #include "PropertyComposition.hpp"
00048 #include <boost/lexical_cast.hpp>
00049
00050 namespace RTT
00051 {
00052 namespace types
00053 {
00059 template<class T>
00060 int get_capacity(T const& cont)
00061 {
00062 return cont.capacity();
00063 }
00064
00070 template<class T>
00071 int get_size(T const& cont)
00072 {
00073 return cont.size();
00074 }
00075
00083 template<class T>
00084 typename T::reference get_container_item(T & cont, int index)
00085 {
00086 if (index >= (int) (cont.size()) || index < 0)
00087 return internal::NA<typename T::reference>::na();
00088 return cont[index];
00089 }
00090
00098 template<class T>
00099 typename T::value_type get_container_item_copy(const T & cont, int index)
00100 {
00101 if (index >= (int) (cont.size()) || index < 0)
00102 return internal::NA<typename T::value_type>::na();
00103 return cont[index];
00104 }
00105
00114 bool get_container_item(std::vector<bool> & cont, int index);
00115 bool get_container_item_copy(const std::vector<bool> & cont, int index);
00116
00124 template<typename T, bool has_ostream = false>
00125 class SequenceTypeInfo: public TemplateTypeInfo<T, has_ostream>
00126 {
00127 public:
00128 SequenceTypeInfo(std::string name) :
00129 TemplateTypeInfo<T, has_ostream> (name)
00130 {
00131 this->addConstructor( new SequenceBuilder<T>() );
00132 this->addConstructor( newConstructor( sequence_ctor<T>() ) );
00133 this->addConstructor( newConstructor( sequence_ctor2<T>() ) );
00134 }
00135
00136 using TemplateTypeInfo<T, has_ostream>::buildVariable;
00137 base::AttributeBase* buildVariable(std::string name,int size) const
00138 {
00139
00140 T t_init(size, typename T::value_type() );
00141
00142 log(Debug) << "Building variable '"<<name <<"' of type " << this->getTypeName() <<" and size "<< size <<Logger::endl;
00143 return new Attribute<T>( name, new internal::UnboundDataSource<internal::ValueDataSource<T> >( t_init ) );
00144 }
00145
00146 bool resize(base::DataSourceBase::shared_ptr arg, int size) const
00147 {
00148 if (arg->isAssignable()) {
00149 typename internal::AssignableDataSource<T>::shared_ptr asarg = internal::AssignableDataSource<T>::narrow( arg.get() );
00150 asarg->set().resize( size );
00151 asarg->updated();
00152 return true;
00153 }
00154 return false;
00155 }
00156
00160 virtual bool composeTypeImpl(const PropertyBag& source, typename internal::AssignableDataSource<T>::reference_t result) const
00161 {
00162
00163 base::PropertyBase* sz = source.find("Size");
00164 if (!sz)
00165 sz = source.find("size");
00166 if (sz)
00167 {
00168 internal::DataSource<int>::shared_ptr sz_ds = internal::DataSource<int>::narrow(sz->getDataSource().get());
00169 if (sz_ds)
00170 result.resize( sz_ds->get() );
00171 }
00172 else
00173 {
00174
00175 result.resize( source.size() );
00176 }
00177
00178 PropertyBag target( source.getType() );
00179 PropertyBag decomp;
00180 internal::ReferenceDataSource<T> rds(result);
00181 rds.ref();
00182
00183
00184
00185 if ( composePropertyBag(source, target) && typeDecomposition( &rds, decomp, false) && ( decomp.getType() == target.getType() ) && refreshProperties(decomp, target, true) ) {
00186 assert(result.size() == source.size());
00187 assert(source.size() == target.size());
00188 assert(source.size() == decomp.size());
00189 return true;
00190 }
00191 return false;
00192 }
00193
00194 virtual std::vector<std::string> getMemberNames() const {
00195
00196 std::vector<std::string> result;
00197 result.push_back("size");
00198 result.push_back("capacity");
00199 return result;
00200 }
00201
00202 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00203
00204 try {
00205 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00206
00207 return getMember( item, new internal::ConstantDataSource<int>(indx));
00208 } catch(...) {}
00209
00210 return getMember( item, new internal::ConstantDataSource<std::string>(name) );
00211 }
00212
00213 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00214 base::DataSourceBase::shared_ptr id) const {
00215
00216 typename internal::DataSource<int>::shared_ptr id_indx = internal::DataSource<int>::narrow( internal::DataSourceTypeInfo<int>::getTypeInfo()->convert(id).get() );
00217 typename internal::DataSource<string>::shared_ptr id_name = internal::DataSource<string>::narrow( id.get() );
00218 if ( id_name ) {
00219 if ( id_name->get() == "size" ) {
00220 try {
00221 return internal::newFunctorDataSource(&get_size<T>, internal::GenerateDataSource()(item.get()) );
00222 } catch(...) {}
00223 }
00224 if ( id_name->get() == "capacity" ) {
00225 try {
00226 return internal::newFunctorDataSource(&get_capacity<T>, internal::GenerateDataSource()(item.get()) );
00227 } catch(...) {}
00228 }
00229 }
00230
00231 if ( id_indx ) {
00232 try {
00233 if ( item->isAssignable() )
00234 return internal::newFunctorDataSource(&get_container_item<T>, internal::GenerateDataSource()(item.get(), id_indx.get() ) );
00235 else
00236 return internal::newFunctorDataSource(&get_container_item_copy<T>, internal::GenerateDataSource()(item.get(), id_indx.get() ) );
00237 } catch(...) {}
00238 }
00239 if (id_name) {
00240 log(Error) << "SequenceTypeInfo: No such member : " << id_name->get() << endlog();
00241 }
00242 if (id_indx) {
00243 log(Error) << "SequenceTypeInfo: Invalid index : " << id_indx->get() <<":"<< id_indx->getTypeName() << endlog();
00244 }
00245 if ( !id_name && ! id_indx)
00246 log(Error) << "SequenceTypeInfo: Not a member or index : " << id <<":"<< id->getTypeName() << endlog();
00247 return base::DataSourceBase::shared_ptr();
00248 }
00249 };
00250 }
00251 }
00252
00253 #endif