CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/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 "FWCore/Utilities/interface/ObjectWithDict.h"
00004 #include "FWCore/Utilities/interface/FunctionWithDict.h"
00005 #include "FWCore/Utilities/interface/MemberWithDict.h"
00006 #include "FWCore/Utilities/interface/TypeID.h"
00007 #include "CommonTools/Utils/src/AnyMethodArgument.h"
00008 #include "CommonTools/Utils/src/TypeCode.h"
00009 #include <boost/utility.hpp>
00010 #include <boost/shared_ptr.hpp>
00011 #include <vector>
00012 #include <map>
00013 
00014 namespace reco {
00015   namespace parser {
00016 
00017     struct MethodInvoker {
00018       explicit MethodInvoker(const edm::FunctionWithDict & method,
00019                              const std::vector<AnyMethodArgument>    & ints   = std::vector<AnyMethodArgument>() );
00020       explicit MethodInvoker(const edm::MemberWithDict & member);
00021       MethodInvoker(const MethodInvoker &); 
00022 
00026       edm::ObjectWithDict
00027       invoke(const edm::ObjectWithDict & o, edm::ObjectWithDict &retstore) const;
00028       edm::FunctionWithDict const method() const {return method_;}
00029       edm::MemberWithDict const member() const {return member_;}
00030       MethodInvoker & operator=(const MethodInvoker &);
00031       bool isFunction() const {return isFunction_;}
00032       std::string methodName() const;
00033       std::string returnTypeName() const;
00034     private:
00035       edm::FunctionWithDict method_;
00036       edm::MemberWithDict member_;
00037       std::vector<AnyMethodArgument> ints_; // already fixed to the correct type
00038       std::vector<void*> args_;
00039       bool isFunction_;
00040       void setArgs();
00041     };
00042 
00047     struct SingleInvoker : boost::noncopyable {
00048         SingleInvoker(const edm::TypeWithDict &t,
00049                       const std::string &name, 
00050                       const std::vector<AnyMethodArgument> &args)  ;
00051         ~SingleInvoker();
00052 
00057         std::pair<edm::ObjectWithDict,bool> invoke(const edm::ObjectWithDict & o, std::vector<edm::ObjectWithDict> &v) const;
00058         
00059         // convert the output of invoke to a double, if possible
00060         double retToDouble(const edm::ObjectWithDict & o) const;
00061         void   throwFailedConversion(const edm::ObjectWithDict & o) const;
00062       private:
00063         method::TypeCode            retType_;
00064         std::vector<MethodInvoker>  invokers_;
00065         mutable edm::ObjectWithDict      storage_;
00066         bool                        storageNeedsDestructor_;
00068         bool isRefGet_;
00069     };
00070 
00071 
00073     struct LazyInvoker {
00074       explicit LazyInvoker(const std::string &name,
00075                            const std::vector<AnyMethodArgument> &args);
00076       ~LazyInvoker();
00081       edm::ObjectWithDict invoke(const edm::ObjectWithDict & o, std::vector<edm::ObjectWithDict> &v) const;
00083       double invokeLast(const edm::ObjectWithDict & o, std::vector<edm::ObjectWithDict> &v) const;
00084     private:
00085       std::string name_;
00086       std::vector<AnyMethodArgument> argsBeforeFixups_;
00087       typedef boost::shared_ptr<SingleInvoker> SingleInvokerPtr; // the shared ptr is only to make the code exception safe
00088       mutable std::map<edm::TypeID, SingleInvokerPtr> invokers_;        // otherwise I think it could leak if the constructor of
00089       const SingleInvoker & invoker(const edm::TypeWithDict &t) const ; // SingleInvoker throws an exception (which can happen)
00090     };
00091 
00092   }
00093 }
00094 
00095 #endif