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 #ifndef ORO_TEMPLATE_TYPEINFO_HPP
00039 #define ORO_TEMPLATE_TYPEINFO_HPP
00040
00041 #include "Types.hpp"
00042 #include "Property.hpp"
00043 #include "Attribute.hpp"
00044 #include "Logger.hpp"
00045 #include <ostream>
00046 #include "FunctorFactory.hpp"
00047 #include "DataSourceArgsMethod.hpp"
00048
00049 #include <boost/type_traits/function_traits.hpp>
00050 #include "boost/function_types/function_type.hpp"
00051 #include "boost/function_types/function_type_signature.hpp"
00052
00053 #include "rtt-config.h"
00054
00055 namespace RTT
00056 {
00057 namespace detail {
00058 template<typename T, bool b_value>
00059 struct TypeStreamSelector;
00060 template<typename T>
00061 struct TypeStreamSelector<T,true>
00062 {
00063 static std::ostream& write(std::ostream& os, T t)
00064 {
00065 #ifdef OS_HAVE_STREAMS
00066 os << t;
00067 #endif
00068 return os;
00069 }
00070 static std::istream& read(std::istream& os, T& t)
00071 {
00072 #ifdef OS_HAVE_STREAMS
00073 os >> t;
00074 #endif
00075 return os;
00076 }
00077 };
00078 template<typename T>
00079 struct TypeStreamSelector<T,false>
00080 {
00081 static std::ostream& write(std::ostream& os, T)
00082 {
00083 return os;
00084 }
00085 static std::istream& read(std::istream& os, T& )
00086 {
00087 return os;
00088 }
00089 };
00090 }
00091
00160 template<typename T, bool use_ostream = false>
00161 class TemplateTypeInfo
00162 : public TypeInfo
00163 {
00164 const std::string tname;
00165 public:
00166 using TypeInfo::buildConstant;
00167 using TypeInfo::buildVariable;
00168
00172 typedef T UserType;
00176 typedef typename Property<T>::DataSourceType PropertyType;
00177
00185 TemplateTypeInfo(std::string name)
00186 : tname(name)
00187 {
00188
00189 if ( detail::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject != 0) {
00190 Logger::log() << Logger::Warning << "Overriding TypeInfo for '"
00191 << detail::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject->getTypeName()
00192 << "'." << Logger::endl;
00193 }
00194 detail::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject = this;
00195
00196 }
00197
00198 AttributeBase* buildConstant(std::string name, DataSourceBase::shared_ptr dsb) const
00199 {
00200 typename DataSource<PropertyType>::shared_ptr res =
00201 AdaptDataSource<PropertyType>()( detail::DataSourceTypeInfo<PropertyType>::getTypeInfo()->convert(dsb));
00202 if ( res ) {
00203 res->get();
00204 Logger::log() << Logger::Info << "Building "<<tname<<" Constant '"<<name<<"' with value "<< dsb->getTypeInfo()->toString(dsb) <<Logger::endl;
00205 return new Constant<PropertyType>( name, res->value() );
00206 }
00207 else
00208 return 0;
00209 }
00210
00211 AttributeBase* buildVariable(std::string name) const
00212 {
00213
00214 Logger::log() << Logger::Debug << "Building variable '"<<name <<"' of type " << tname <<Logger::endl;
00215 return new Attribute<T>( name, new detail::UnboundDataSource<ValueDataSource<T> >() );
00216 }
00217
00218 AttributeBase* buildAttribute( std::string name, DataSourceBase::shared_ptr in) const
00219 {
00220 typename AssignableDataSource<PropertyType>::shared_ptr ds;
00221 if ( !in )
00222 ds = new ValueDataSource<PropertyType>();
00223 else
00224 ds = AssignableDataSource<PropertyType>::narrow( in.get() );
00225 if (!ds)
00226 return 0;
00227
00228 Logger::log() << Logger::Debug << "Building Attribute '"<< name <<"' of type " << tname <<Logger::endl;
00229 return new Attribute<PropertyType>( name, ds.get() );
00230 }
00231
00232 AttributeBase* buildAlias(std::string name, DataSourceBase::shared_ptr in ) const
00233 {
00234 typename DataSource<T>::shared_ptr ds = AdaptDataSource<T>()( detail::DataSourceTypeInfo<T>::getTypeInfo()->convert(in) );
00235 if ( ! ds )
00236 return 0;
00237 return new Alias<T>( name, ds );
00238 }
00239
00240 virtual const std::string& getTypeName() const { return tname; }
00241
00242 virtual PropertyBase* buildProperty(const std::string& name, const std::string& desc, DataSourceBase::shared_ptr source = 0) const {
00243 if (source) {
00244 typename AssignableDataSource<PropertyType>::shared_ptr ad
00245 = AdaptAssignableDataSource<PropertyType>()( source );
00246 if (ad)
00247 return new Property<PropertyType>(name, desc, ad );
00248
00249 }
00250 return new Property<PropertyType>(name, desc);
00251 }
00252
00253 virtual DataSourceBase::shared_ptr buildValue() const {
00254 return new ValueDataSource<PropertyType>();
00255 }
00256
00257 virtual std::ostream& write( std::ostream& os, DataSourceBase::shared_ptr in ) const {
00258 typename DataSource<T>::shared_ptr d = AdaptDataSource<T>()( in );
00259 if ( d && use_ostream )
00260 detail::TypeStreamSelector<T, use_ostream>::write( os, d->value() );
00261 else {
00262 #ifdef OS_HAVE_STREAMS
00263 std::string output = std::string("(")+ in->getTypeName() +")";
00264 os << output;
00265 #endif
00266 }
00267 return os;
00268
00269 }
00270
00271 virtual std::istream& read( std::istream& os, DataSourceBase::shared_ptr out ) const {
00272 typename AssignableDataSource<T>::shared_ptr d = AdaptAssignableDataSource<T>()( out );
00273 if ( d && use_ostream ) {
00274 detail::TypeStreamSelector<T, use_ostream>::read( os, d->set() );
00275 d->updated();
00276 }
00277 return os;
00278 }
00279
00280 virtual bool decomposeType( DataSourceBase::shared_ptr source, PropertyBag& targetbag ) const {
00281
00282 typename DataSource<PropertyType>::shared_ptr ds = AdaptDataSource<PropertyType>()( source.get() );
00283 if ( !ds )
00284 return false;
00285
00286 return decomposeTypeImpl( ds->get(), targetbag );
00287 }
00288
00292 virtual bool decomposeTypeImpl( typename AssignableDataSource<T>::const_reference_t source, PropertyBag& targetbag ) const {
00293 return false;
00294 }
00295
00296 virtual bool composeType( DataSourceBase::shared_ptr source, DataSourceBase::shared_ptr result) const {
00297
00298 if ( result->update( source.get() ) )
00299 return true;
00300
00301
00302 const DataSource<PropertyBag>* pb = dynamic_cast< const DataSource<PropertyBag>* > (source.get() );
00303 if ( !pb )
00304 return false;
00305 typename AssignableDataSource<PropertyType>::shared_ptr ads = AdaptAssignableDataSource<PropertyType>()( result.get() );
00306 if ( !ads )
00307 return false;
00308
00309 if ( composeTypeImpl( pb->value(), ads->set() ) )
00310 ads->updated();
00311 else {
00312 Logger::log() <<Logger::Debug<<"Failed to compose from "<< source->getTypeName() <<Logger::endl;
00313 return false;
00314 }
00315 Logger::log() <<Logger::Debug<<"Successfuly composed type from "<< source->getTypeName() <<Logger::endl;
00316 return true;
00317 }
00318
00322 virtual bool composeTypeImpl(const PropertyBag& source, typename AssignableDataSource<T>::reference_t result) const {
00323 return false;
00324 }
00325
00326 };
00327
00328 template< class T>
00329 struct AlwaysAssignChecker
00330 : public std::binary_function<T, T, bool>
00331 {
00332 bool operator()(const T&, const T& ) const
00333 {
00334 return true;
00335 }
00336 };
00337
00338 template< class T>
00339 struct SizeAssignChecker
00340 : public std::binary_function<T, T, bool>
00341 {
00342 bool operator()(const T& v1, const T& v2) const
00343 {
00344
00345 return v1.capacity() >= v2.size();
00346 }
00347 };
00348
00349
00350 template< class T>
00351 struct ArrayIndexChecker
00352 : public std::binary_function< T, int, bool>
00353 {
00354 bool operator()(const T& v, int i ) const
00355 {
00356 return i > -1 && i < (int)(v.size());
00357 }
00358 };
00359
00360 #if 0
00361
00362 template< class T>
00363 struct MultiVectorIndexChecker
00364 : public std::binary_function< T, int, bool>
00365 {
00366 bool operator()(const T& v, int i ) const
00367 {
00368 return i > -1 && i < T::size;
00369 }
00370 };
00371 #endif
00372
00373
00374 template< class T, int Range>
00375 struct RangeIndexChecker
00376 : public std::binary_function< T, int, bool>
00377 {
00378 bool operator()(const T& v, int i ) const
00379 {
00380 return i > -1 && i < Range;
00381 }
00382 };
00383
00387 template<typename T, typename IndexType, typename SetType, typename IPred, typename APred, bool has_ostream>
00388 class TemplateContainerTypeInfo
00389 : public TemplateTypeInfo<T,has_ostream>
00390 {
00391 typedef typename boost::remove_const<typename boost::remove_reference<T>::type>::type _T;
00392 public:
00393 using TypeInfo::buildConstant;
00394 using TypeInfo::buildVariable;
00395
00396 TemplateContainerTypeInfo(std::string name)
00397 : TemplateTypeInfo<T, has_ostream>(name) {}
00398
00399 AttributeBase* buildVariable(std::string name) const
00400 {
00401
00402 return new Attribute<T>( name, new detail::UnboundDataSource<IndexedValueDataSource<T, IndexType, SetType, IPred, AlwaysAssignChecker<_T> > >() );
00403 }
00404
00405 DataSourceBase::shared_ptr buildValue() const
00406 {
00407 return new IndexedValueDataSource<T, IndexType, SetType, IPred, AlwaysAssignChecker<_T> >();
00408 }
00409
00410 AttributeBase* buildVariable(std::string name,int size) const
00411 {
00412
00413
00414 _T t_init(size, SetType());
00415
00416 return new Attribute<T>( name, new detail::UnboundDataSource<IndexedValueDataSource<T, IndexType, SetType, IPred, APred> >( t_init ) );
00417 }
00418 };
00419
00423 template<typename T, typename IndexType, typename SetType, typename IPred, typename APred, bool has_ostream>
00424 class TemplateIndexTypeInfo
00425 : public TemplateTypeInfo<T,has_ostream>
00426 {
00427 typedef typename boost::remove_const<typename boost::remove_reference<T>::type>::type _T;
00428 public:
00429 using TypeInfo::buildConstant;
00430 using TypeInfo::buildVariable;
00431
00432 TemplateIndexTypeInfo(std::string name)
00433 : TemplateTypeInfo<T, has_ostream>(name) {}
00434
00435 AttributeBase* buildVariable(std::string name) const
00436 {
00437
00438 return new Attribute<T>( name, new detail::UnboundDataSource<IndexedValueDataSource<T, IndexType, SetType, IPred, AlwaysAssignChecker<T> > >() );
00439 }
00440
00441 DataSourceBase::shared_ptr buildValue() const
00442 {
00443 Logger::log() <<Logger::Debug << "Building Indexable value of "<< this->getTypeName()<<Logger::endl;
00444 return new IndexedValueDataSource<T, IndexType, SetType, IPred, AlwaysAssignChecker<T> >();
00445 }
00446
00447 };
00448
00449 namespace detail
00450 {
00456 template<class Signature, int>
00457 struct TemplateConstructor;
00458
00459 template<class S>
00460 struct TemplateConstructor<S,1>
00461 : public TypeBuilder,
00462 public FunctorFactoryPart1<DataSourceBase*, DataSourceArgsMethod<S> >
00463 {
00464 typedef typename boost::function_traits<S>::result_type result_type;
00465 typedef typename boost::function_traits<S>::arg1_type arg1_type;
00466
00467 bool automatic;
00468 template<class FInit>
00469 TemplateConstructor( FInit f, bool autom)
00470 : FunctorFactoryPart1<DataSourceBase*, DataSourceArgsMethod<S> >(f ),
00471 automatic(autom)
00472 {}
00473
00474 virtual DataSourceBase::shared_ptr build(const std::vector<DataSourceBase::shared_ptr>& args) const {
00475
00476
00477 if ( args.size() == 1 && args[0]->getTypeInfo() == DataSourceTypeInfo<result_type>::getTypeInfo() ) {
00478 return args[0];
00479 }
00480
00481 if ( args.size() == 1 && args[0]->getTypeInfo() != DataSourceTypeInfo<arg1_type>::getTypeInfo() ) {
00482 return DataSourceBase::shared_ptr();
00483 }
00484 try {
00485 return this->produce( args );
00486 } catch ( ... ) {
00487 }
00488 return DataSourceBase::shared_ptr();
00489 }
00490
00491 virtual DataSourceBase::shared_ptr convert(DataSourceBase::shared_ptr arg) const {
00492
00493
00494 if ( arg->getTypeInfo() == DataSourceTypeInfo<result_type>::getTypeInfo() ) {
00495 return arg;
00496 }
00497
00498 if ( arg->getTypeInfo() != DataSourceTypeInfo<arg1_type>::getTypeInfo() ) {
00499 return DataSourceBase::shared_ptr();
00500 }
00501
00502 std::vector<DataSourceBase::shared_ptr> args;
00503 args.push_back(arg);
00504 DataSourceBase::shared_ptr ret = this->build(args);
00505 if (ret && !automatic)
00506 log(Warning) << "Conversion from " << arg->getTypeName() << " to " << ret->getTypeName() <<endlog();
00507 return ret;
00508 }
00509 };
00510
00511 template<class S>
00512 struct TemplateConstructor<S,2>
00513 : public TypeBuilder,
00514 public FunctorFactoryPart2<DataSourceBase*, DataSourceArgsMethod<S> >
00515 {
00516 template<class FInit>
00517 TemplateConstructor( FInit f, bool autom)
00518 : FunctorFactoryPart2<DataSourceBase*, DataSourceArgsMethod<S> >(f )
00519 {}
00520
00521 virtual DataSourceBase::shared_ptr build(const std::vector<DataSourceBase::shared_ptr>& args) const {
00522 try {
00523 return this->produce( args );
00524 } catch ( ... ) {
00525 }
00526 return DataSourceBase::shared_ptr();
00527 }
00528
00529 };
00530
00531 template<class S>
00532 struct TemplateConstructor<S,3>
00533 : public TypeBuilder,
00534 public FunctorFactoryPart3<DataSourceBase*, DataSourceArgsMethod<S> >
00535 {
00536 template<class FInit>
00537 TemplateConstructor( FInit f, bool autom)
00538 : FunctorFactoryPart3<DataSourceBase*, DataSourceArgsMethod<S> >(f )
00539 {}
00540
00541 virtual DataSourceBase::shared_ptr build(const std::vector<DataSourceBase::shared_ptr>& args) const {
00542 try {
00543 return this->produce( args );
00544 } catch ( ... ) {
00545 }
00546 return DataSourceBase::shared_ptr();
00547 }
00548
00549 };
00550
00551 template<class S>
00552 struct TemplateConstructor<S,4>
00553 : public TypeBuilder,
00554 public FunctorFactoryPart4<DataSourceBase*, DataSourceArgsMethod<S> >
00555 {
00556 template<class FInit>
00557 TemplateConstructor( FInit f, bool autom)
00558 : FunctorFactoryPart4<DataSourceBase*, DataSourceArgsMethod<S> >(f )
00559 {}
00560
00561 virtual DataSourceBase::shared_ptr build(const std::vector<DataSourceBase::shared_ptr>& args) const {
00562 try {
00563 return this->produce( args );
00564 } catch ( ... ) {
00565 }
00566 return DataSourceBase::shared_ptr();
00567 }
00568
00569 };
00570
00571 template<class S>
00572 struct TemplateConstructor<S,6>
00573 : public TypeBuilder,
00574 public FunctorFactoryPart6<DataSourceBase*, DataSourceArgsMethod<S> >
00575 {
00576 template<class FInit>
00577 TemplateConstructor( FInit f, bool autom)
00578 : FunctorFactoryPart6<DataSourceBase*, DataSourceArgsMethod<S> >(f )
00579 {}
00580
00581 virtual DataSourceBase::shared_ptr build(const std::vector<DataSourceBase::shared_ptr>& args) const {
00582 try {
00583 return this->produce( args );
00584 } catch ( ... ) {
00585 }
00586 return DataSourceBase::shared_ptr();
00587 }
00588
00589 };
00590 }
00591
00599 template<class Function>
00600 TypeBuilder* newConstructor( Function* foo, bool automatic = false ) {
00601 return new detail::TemplateConstructor<Function, boost::function_traits<Function>::arity>(foo, automatic);
00602 }
00603
00612 template<class Object>
00613 TypeBuilder* newConstructor( Object obj, bool automatic = false) {
00614 return new detail::TemplateConstructor<typename Object::Signature, boost::function_traits<typename Object::Signature>::arity>(obj, automatic);
00615 }
00616 }
00617
00618 #endif