CppUnit project page CppUnit home page

reflection.h

Go to the documentation of this file.
00001 #ifndef CPPTL_REFLECTION_H_INCLUDED
00002 # define CPPTL_REFLECTION_H_INCLUDED
00003 
00004 # include <cpptl/conststring.h>
00005 # include <cpptl/enumerator.h>
00006 # include <cpptl/sharedptr.h>
00007 # include <cpptl/any.h>
00008 # include <map>
00009 # include <vector>
00010 
00011 
00012 
00013 namespace CppTL {
00014 
00015 typedef std::vector<Any> MethodParameters;
00016 
00018 namespace Impl {
00019    class AttributAccessor;
00020    class InvokableBase;
00021 
00022    typedef SharedPtr<AttributAccessor> AttributAccessorPtr;
00023    typedef SharedPtr<InvokableBase> InvokableBasePtr;
00024 
00025    class MethodCall
00026    {
00027    public:
00028       MethodCall( const Method &method,
00029                   const Any &holder,
00030                   const MethodParameters &args,
00031                   Any &result )
00032          : method_( method )
00033          , holder_( holder )
00034          , args_( args )
00035          , result_( result )
00036       {
00037       }
00038 
00039       const Method &method_;
00040       const Any &holder_;
00041       const MethodParameters &args_;
00042       Any &result_;
00043    };
00044 
00045 
00046    class InvokableBase
00047    {
00048    public:
00049       virtual ~InvokableBase()
00050       {
00051       }
00052 
00053       virtual void invoke( MethodCall &call ) const = 0;
00054    };
00055 
00056 
00057    class Invokable
00058    {
00059    public:
00060       Invokable( const Impl::InvokableBasePtr &invokable );
00061 
00062       virtual ~Invokable()
00063       {
00064       }
00065 
00066       void invoke( Impl::MethodCall &call ) const;
00067 
00068       TypeId returnType_;
00069       std::vector<TypeId> argTypes_;
00070       InvokableBasePtr invokable_;
00071    };
00072 
00073 
00074    class AttributAccessor
00075    {
00076    public:
00077       virtual ~AttributAccessor()
00078       {
00079       }
00080 
00081       virtual TypeId getType() const =0;
00082 
00083       virtual Any get( const Any &holder) const = 0;
00084 
00085       virtual void set( const Any &holder,
00086                         const Any &value ) const = 0;
00087    };
00088 
00089 
00090    template<class Object, class AttributType>
00091    class AttributAccessorImpl : public AttributAccessor
00092    {
00093    public:
00094       typedef AttributType Object::*Attribut;
00095 
00096       AttributAccessorImpl( Attribut attribut )
00097          : attribut_( attribut )
00098       {
00099       }
00100 
00101       TypeId getType() const
00102       {
00103          return typeId( Type<AttributType>() );
00104       }
00105 
00106       Any get( const Any &holder ) const
00107       {
00108          Object &object = *any_cast( holder, Type<Object *>() );
00109          return makeAny( object.*attribut_ );
00110       }
00111 
00112       void set( const Any &holder,
00113                 const Any &value ) const
00114       {
00115          Object &object = *any_cast( holder, Type<Object *>() );
00116          object.*attribut_ = any_cast( value, Type<AttributType>() );
00117       }
00118 
00119    private:
00120       Attribut attribut_;
00121    };
00122 
00123 
00124    template<class Object, class TheAttributType>
00125    AttributAccessorPtr makeAccessor( TheAttributType Object::*attribut )
00126    {
00127       return AttributAccessorPtr( 
00128          new AttributAccessorImpl<Object
00129                                  ,TheAttributType>( attribut ) );
00130    }
00131 
00132 } // namespace Impl
00134 
00135 
00136 class Attribut
00137 {
00138 public:
00139    Attribut( const ConstString &name,
00140              const Impl::AttributAccessorPtr &accessor );
00141 
00142    ConstString getName() const;
00143 
00144    TypeId getType() const;
00145 
00146    void set( const Any &object, 
00147              const Any &value ) const;
00148 
00149    Any get( const Any &object ) const;
00150 
00151 private:
00152    Class *class_;
00153    ConstString name_;
00154    Impl::AttributAccessorPtr accessor_;
00155 };
00156 
00157 
00158 class Method
00159 {
00160 public:
00161    Method( const ConstString &name,
00162            const Impl::Invokable &invokable );
00163 
00164    Any invoke( const Any &object,
00165                const MethodParameters &args ) const;
00166 
00167    ConstString getName() const;
00168 
00169    size_type getArgCount() const;
00170 
00171    TypeId getArgType( size_type index ) const;
00172 
00173    TypeId getReturnType() const;
00174 
00175    AnyEnumerator<TypeId> getArgTypes() const;
00176 
00177 private:
00178    Class *class_;
00179    ConstString name_;
00180    Impl::Invokable invokable_;
00181 };
00182 
00183 
00184 class Class
00185 {
00186 public:
00187    static Class &create( const ConstString &name,
00188                          TypeId type );
00189 
00190    static const Class *findClass( const ConstString &name );
00191 
00192    ConstString getName() const;
00193 
00194    const Method *findMethod( const ConstString &name ) const;
00195 
00196    void addMethod( const ConstString &name, 
00197                    const Impl::Invokable &invokable );
00198 
00199    const Attribut *findAttribut( const ConstString &name ) const;
00200 
00201    void addAttribut( const ConstString &name, 
00202                      const Impl::AttributAccessorPtr &accessor );
00203 
00204 private:
00205    typedef SharedPtr<Class> ClassPtr;
00206    typedef SharedPtr<Method> MethodPtr;
00207    typedef SharedPtr<Attribut> AttributPtr;
00208    typedef std::map<ConstString,ClassPtr> ClassesByName;
00209    typedef std::map<ConstString,MethodPtr> MethodsByName;
00210    typedef std::map<ConstString,AttributPtr> AttributsByName;
00211 
00212    static ClassesByName &registry();
00213 
00214    Class( const ConstString &name,
00215           TypeId type );
00216 
00217    AttributsByName attributsByName_;
00218    MethodsByName methodsByName_;
00219    ConstString name_;
00220    TypeId type_;
00221 };
00222 
00223 
00224 template<class ClassType>
00225 class AutoRegisterClassReflection
00226 {
00227 public:
00228    AutoRegisterClassReflection()
00229    {
00230       ClassType::registerClassReflection();
00231    }
00232 };
00233 
00234 
00235 } // namespace CppTL
00236 
00237 
00238 
00239 
00240 # define CPPTL_REFLECT_CLASS_BEGIN( ClassType )                             \
00241    typedef ClassType _Reflection_SelfType;                                  \
00242    virtual const ::CppTL::Class *getClass() const                           \
00243    {                                                                        \
00244       return ::CppTL::Class::findClass( #ClassType );                       \
00245    }                                                                        \
00246    static void registerClassReflection()                                    \
00247    {                                                                        \
00248       ::CppTL::Class &class_ = ::CppTL::Class::create( #ClassType,          \
00249                          ::CppTL::typeId( ::CppTL::Type<ClassType>() ) );
00250 
00251 //# define CPPTL_REFLECT_CLASS_EXTEND( ClassType )
00252 # define CPPTL_REFLECT_METHOD( method )                                           \
00253       {                                                                           \
00254          ::CppTL::Impl::Invokable invokable = ::CppTL::Impl::makeInvokable(       \
00255                                               &_Reflection_SelfType::method );    \
00256          class_.addMethod( #method, invokable );                                  \
00257       }
00258 
00259 # define CPPTL_REFLECT_METHOD_WITH_RETURN( method )                               \
00260       {                                                                           \
00261          ::CppTL::Impl::Invokable invokable = ::CppTL::Impl::makeInvokableR(      \
00262                                               &_Reflection_SelfType::method );    \
00263          class_.addMethod( #method, invokable );                                  \
00264       }
00265 
00266 # define CPPTL_REFLECT_RENAMED_ATTRIBUT( attribut, name )                           \
00267       {                                                                             \
00268          ::CppTL::Impl::AttributAccessorPtr accessor = ::CppTL::Impl::makeAccessor( \
00269                                               &_Reflection_SelfType::attribut );    \
00270          class_.addAttribut( name, accessor );                                      \
00271       }
00272 
00273 # define CPPTL_REFLECT_ATTRIBUT( attribut )                 \
00274    CPPTL_REFLECT_RENAMED_ATTRIBUT( attribut, #attribut )
00275 
00276 # define CPPTL_REFLECT_CLASS_END() \
00277    }
00278 
00279 # define CPPTL_REFLECT_REGISTER_CLASS( ClassType )          \
00280    static ::CppTL::AutoRegisterClassReflection<ClassType>   \
00281       CPPTL_MAKE_UNIQUE_NAME(cpptlReflectRegisterClass);
00282 
00283 
00284 # include <cpptl/reflection.inl>
00285 # include <cpptl/reflectionimpl10.h>
00286 
00287 #endif // CPPTL_REFLECTION_H_INCLUDED
00288 

SourceForge Logo hosts this site. Send comments to:
CppUnit Developers