CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/CommonTools/Utils/src/MethodInvoker.h

Go to the documentation of this file.
00001 #ifndef CommonTools_Utils_MethodInvoker_h
00002 #define CommonTools_Utils_MethodInvoker_h
00003 #include "Reflex/Object.h"
00004 #include "Reflex/Member.h"
00005 #include "CommonTools/Utils/src/AnyMethodArgument.h"
00006 #include "CommonTools/Utils/src/TypeCode.h"
00007 #include <boost/utility.hpp>
00008 #include <boost/shared_ptr.hpp>
00009 #include <vector>
00010 #include <map>
00011 
00012 namespace reco {
00013   namespace parser {
00014 
00015     struct MethodInvoker {
00016       explicit MethodInvoker(const Reflex::Member & method,
00017                              const std::vector<AnyMethodArgument>    & ints   = std::vector<AnyMethodArgument>() );
00018       MethodInvoker(const MethodInvoker &); 
00019 
00023       Reflex::Object
00024       invoke(const Reflex::Object & o, Reflex::Object &retstore) const;
00025       const Reflex::Member & method() const { return method_; }
00026       MethodInvoker & operator=(const MethodInvoker &);
00027     private:
00028       Reflex::Member method_;
00029       std::vector<AnyMethodArgument> ints_; // already fixed to the correct type
00030       std::vector<void*> args_;
00031       bool isFunction_;
00032       void setArgs();
00033     };
00034 
00039     struct SingleInvoker : boost::noncopyable {
00040         SingleInvoker(const Reflex::Type &t,
00041                       const std::string &name, 
00042                       const std::vector<AnyMethodArgument> &args)  ;
00043         ~SingleInvoker();
00044 
00049         std::pair<Reflex::Object,bool> invoke(const Reflex::Object & o, std::vector<Reflex::Object> &v) const;
00050         
00051         // convert the output of invoke to a double, if possible
00052         double retToDouble(const Reflex::Object & o) const;
00053         void   throwFailedConversion(const Reflex::Object & o) const;
00054       private:
00055         method::TypeCode            retType_;
00056         std::vector<MethodInvoker>  invokers_;
00057         mutable Reflex::Object      storage_;
00058         bool                        storageNeedsDestructor_;
00060         bool isRefGet_;
00061     };
00062 
00063 
00065     struct LazyInvoker {
00066       explicit LazyInvoker(const std::string &name,
00067                            const std::vector<AnyMethodArgument> &args);
00068       ~LazyInvoker();
00073       Reflex::Object invoke(const Reflex::Object & o, std::vector<Reflex::Object> &v) const;
00075       double invokeLast(const Reflex::Object & o, std::vector<Reflex::Object> &v) const;
00076     private:
00077       std::string name_;
00078       std::vector<AnyMethodArgument> argsBeforeFixups_;
00079       typedef boost::shared_ptr<SingleInvoker> SingleInvokerPtr; // the shared ptr is only to make the code exception safe
00080       mutable std::map<void *, SingleInvokerPtr> invokers_;        // otherwise I think it could leak if the constructor of
00081       const SingleInvoker & invoker(const Reflex::Type &t) const ; // SingleInvoker throws an exception (which can happen)
00082     };
00083 
00084   }
00085 }
00086 
00087 #endif