CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/FWCore/Framework/interface/PrincipalGetAdapter.h

Go to the documentation of this file.
00001 #ifndef Framework_PrincipalGetAdapter_h
00002 #define Framework_PrincipalGetAdapter_h
00003 
00004 // -*- C++ -*-
00005 //
00006 
00007 // Class  :     PrincipalGetAdapter
00008 // 
00082 /*----------------------------------------------------------------------
00083 
00084 ----------------------------------------------------------------------*/
00085 #include <cassert>
00086 #include <typeinfo>
00087 #include <string>
00088 #include <vector>
00089 
00090 #include "DataFormats/Common/interface/EDProductfwd.h"
00091 #include "DataFormats/Provenance/interface/ProvenanceFwd.h"
00092 #include "FWCore/Framework/interface/Frameworkfwd.h"
00093 
00094 #include "DataFormats/Common/interface/traits.h"
00095 
00096 #include "DataFormats/Common/interface/BasicHandle.h"
00097 
00098 #include "DataFormats/Common/interface/ConvertHandle.h"
00099 
00100 #include "DataFormats/Common/interface/Handle.h"
00101 
00102 #include "FWCore/Utilities/interface/InputTag.h"
00103 
00104 namespace edm {
00105 
00106   namespace principal_get_adapter_detail {
00107     struct deleter {
00108       void operator()(std::pair<WrapperOwningHolder, ConstBranchDescription const*> const p) const;
00109     };
00110     void
00111     throwOnPutOfNullProduct(char const* principalType, TypeID const& productType, std::string const& productInstanceName);
00112   }
00113   class PrincipalGetAdapter {
00114   public:
00115     PrincipalGetAdapter(Principal & pcpl,
00116                  ModuleDescription const& md);
00117 
00118     ~PrincipalGetAdapter();
00119 
00120     //size_t size() const;
00121 
00122     template <typename PROD>
00123     bool 
00124     get(SelectorBase const&, Handle<PROD>& result) const;
00125   
00126     template <typename PROD>
00127     bool 
00128     getByLabel(std::string const& label, Handle<PROD>& result) const;
00129 
00130     template <typename PROD>
00131     bool 
00132     getByLabel(std::string const& label,
00133                std::string const& productInstanceName, 
00134                Handle<PROD>& result) const;
00135 
00137     template <typename PROD>     
00138     bool         
00139     getByLabel(InputTag const& tag, Handle<PROD>& result) const;         
00140 
00141     template <typename PROD>
00142     void 
00143     getMany(SelectorBase const&, std::vector<Handle<PROD> >& results) const;
00144 
00145     template <typename PROD>
00146     bool
00147     getByType(Handle<PROD>& result) const;
00148 
00149     template <typename PROD>
00150     void 
00151     getManyByType(std::vector<Handle<PROD> >& results) const;
00152 
00153     ProcessHistory const&
00154     processHistory() const;
00155 
00156     Principal& principal() {return principal_;}
00157     Principal const& principal() const {return principal_;}
00158 
00159     ConstBranchDescription const&
00160     getBranchDescription(TypeID const& type, std::string const& productInstanceName) const;
00161 
00162     typedef std::vector<BasicHandle>  BasicHandleVec;
00163 
00164     //------------------------------------------------------------
00165     // Protected functions.
00166     //
00167 
00168     // The following 'get' functions serve to isolate the PrincipalGetAdapter class
00169     // from the Principal class.
00170 
00171     BasicHandle 
00172     get_(TypeID const& tid, SelectorBase const&) const;
00173     
00174     BasicHandle 
00175     getByLabel_(TypeID const& tid,
00176                 std::string const& label,
00177                 std::string const& productInstanceName,
00178                 std::string const& processName) const;
00179 
00180     BasicHandle 
00181     getByLabel_(TypeID const& tid, InputTag const& tag) const;
00182 
00183     void 
00184     getMany_(TypeID const& tid, 
00185              SelectorBase const& sel, 
00186              BasicHandleVec& results) const;
00187 
00188     BasicHandle 
00189     getByType_(TypeID const& tid) const;
00190 
00191     void 
00192     getManyByType_(TypeID const& tid, 
00193                    BasicHandleVec& results) const;
00194 
00195     int 
00196     getMatchingSequence_(TypeID const& typeID,
00197                          SelectorBase const& selector,
00198                          BasicHandle& result) const;
00199 
00200     int 
00201     getMatchingSequenceByLabel_(TypeID const& typeID,
00202                                 std::string const& label,
00203                                 std::string const& productInstanceName,
00204                                 BasicHandle& result) const;
00205 
00206     int 
00207     getMatchingSequenceByLabel_(TypeID const& typeID,
00208                                 std::string const& label,
00209                                 std::string const& productInstanceName,
00210                                 std::string const& processName,
00211                                 BasicHandle& result) const;
00212     
00213     // Also isolates the PrincipalGetAdapter class
00214     // from the Principal class.
00215     EDProductGetter const* prodGetter() const;
00216   private:
00217     //------------------------------------------------------------
00218     // Copying and assignment of PrincipalGetAdapters is disallowed
00219     //
00220     PrincipalGetAdapter(PrincipalGetAdapter const&);                  // not implemented
00221     PrincipalGetAdapter const& operator=(PrincipalGetAdapter const&);   // not implemented
00222 
00223     // Is this an Event, a LuminosityBlock, or a Run.
00224     BranchType const& branchType() const;
00225 
00226   private:
00227     //------------------------------------------------------------
00228     // Data members
00229     //
00230 
00231     // Each PrincipalGetAdapter must have an associated Principal, used as the
00232     // source of all 'gets' and the target of 'puts'.
00233     Principal & principal_;
00234 
00235     // Each PrincipalGetAdapter must have a description of the module executing the
00236     // "transaction" which the PrincipalGetAdapter represents.
00237     ModuleDescription const& md_;
00238 
00239   };
00240 
00241   template <typename PROD>
00242   inline
00243   std::ostream& 
00244   operator<<(std::ostream& os, Handle<PROD> const& h) {
00245     os << h.product() << " " << h.provenance() << " " << h.id();
00246     return os;
00247   }
00248 
00249 
00250   //------------------------------------------------------------
00251   // Metafunction support for compile-time selection of code used in
00252   // PrincipalGetAdapter::put member template.
00253   //
00254 
00255   // has_postinsert is a metafunction of one argument, the type T.  As
00256   // with many metafunctions, it is implemented as a class with a data
00257   // member 'value', which contains the value 'returned' by the
00258   // metafunction.
00259   //
00260   // has_postinsert<T>::value is 'true' if T has the post_insert
00261   // member function (with the right signature), and 'false' if T has
00262   // no such member function.
00263 
00264   namespace detail {
00265     typedef char (& no_tag)[1]; // type indicating FALSE
00266     typedef char (& yes_tag)[2]; // type indicating TRUE
00267 
00268     // Definitions forthe following struct and function templates are
00269     // not needed; we only require the declarations.
00270     template <typename T, void (T::*)()>  struct postinsert_function;
00271     template <typename T> no_tag  has_postinsert_helper(...);
00272     template <typename T> yes_tag has_postinsert_helper(postinsert_function<T, &T::post_insert> * p);
00273 
00274 
00275     template<typename T>
00276     struct has_postinsert {
00277       static bool const value = 
00278         sizeof(has_postinsert_helper<T>(0)) == sizeof(yes_tag) &&
00279         !boost::is_base_of<DoNotSortUponInsertion, T>::value;
00280     };
00281 
00282 
00283     // has_donotrecordparents<T>::value is true if we should not
00284     // record parentage for type T, and false otherwise.
00285 
00286     template <typename T>
00287     struct has_donotrecordparents {
00288       static bool const value = 
00289         boost::is_base_of<DoNotRecordParents,T>::value;
00290     };
00291 
00292   }
00293 
00294   //------------------------------------------------------------
00295 
00296   // The following function objects are used by Event::put, under the
00297   // control of a metafunction if, to either call the given object's
00298   // post_insert function (if it has one), or to do nothing (if it
00299   // does not have a post_insert function).
00300   template <typename T>
00301   struct DoPostInsert {
00302     void operator()(T* p) const { p->post_insert(); }
00303   };
00304 
00305   template <typename T>
00306   struct DoNotPostInsert {
00307     void operator()(T*) const { }
00308   };
00309 
00310   // Implementation of  PrincipalGetAdapter  member templates. See  PrincipalGetAdapter.cc for the
00311   // implementation of non-template members.
00312   //
00313 
00314   template <typename PROD>
00315   inline
00316   bool 
00317   PrincipalGetAdapter::get(SelectorBase const& sel,
00318                     Handle<PROD>& result) const {
00319     result.clear();
00320     BasicHandle bh = this->get_(TypeID(typeid(PROD)),sel);
00321     convert_handle(bh, result);  // throws on conversion error
00322     if (bh.failedToGet()) {
00323       return false;
00324     }
00325     return true;
00326   }
00327   
00328   template <typename PROD>
00329   inline
00330   bool
00331   PrincipalGetAdapter::getByLabel(std::string const& label,
00332                            Handle<PROD>& result) const {
00333     result.clear();
00334     return getByLabel(label, std::string(), result);
00335   }
00336 
00337   template <typename PROD>
00338   inline
00339   bool
00340   PrincipalGetAdapter::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
00341     result.clear();
00342     BasicHandle bh = this->getByLabel_(TypeID(typeid(PROD)), tag);
00343     convert_handle(bh, result);  // throws on conversion error
00344     if (bh.failedToGet()) {
00345       return false;
00346     }
00347     return true;
00348   }
00349 
00350   template <typename PROD>
00351   inline
00352   bool
00353   PrincipalGetAdapter::getByLabel(std::string const& label,
00354                            std::string const& productInstanceName,
00355                            Handle<PROD>& result) const {
00356     result.clear();
00357     BasicHandle bh = this->getByLabel_(TypeID(typeid(PROD)), label, productInstanceName, std::string());
00358     convert_handle(bh, result);  // throws on conversion error
00359     if (bh.failedToGet()) {
00360       return false;
00361     }
00362     return true;
00363   }
00364 
00365   template <typename PROD>
00366   inline
00367   void 
00368   PrincipalGetAdapter::getMany(SelectorBase const& sel,
00369                         std::vector<Handle<PROD> >& results) const { 
00370     BasicHandleVec bhv;
00371     this->getMany_(TypeID(typeid(PROD)), sel, bhv);
00372     
00373     // Go through the returned handles; for each element,
00374     //   1. create a Handle<PROD> and
00375     //
00376     // This function presents an exception safety difficulty. If an
00377     // exception is thrown when converting a handle, the "got
00378     // products" record will be wrong.
00379     //
00380     // Since EDProducers are not allowed to use this function,
00381     // the problem does not seem too severe.
00382     //
00383     // Question: do we even need to keep track of the "got products"
00384     // for this function, since it is *not* to be used by EDProducers?
00385     std::vector<Handle<PROD> > products;
00386 
00387     typename BasicHandleVec::const_iterator it = bhv.begin();
00388     typename BasicHandleVec::const_iterator end = bhv.end();
00389 
00390     while (it != end) {
00391       Handle<PROD> result;
00392       convert_handle(*it, result);  // throws on conversion error
00393       products.push_back(result);
00394       ++it;
00395     }
00396     results.swap(products);
00397   }
00398 
00399   template <typename PROD>
00400   inline
00401   bool
00402   PrincipalGetAdapter::getByType(Handle<PROD>& result) const {
00403     result.clear();
00404     BasicHandle bh = this->getByType_(TypeID(typeid(PROD)));
00405     convert_handle(bh, result);  // throws on conversion error
00406     if (bh.failedToGet()) {
00407       return false;
00408     }
00409     return true;
00410   }
00411 
00412   template <typename PROD>
00413   inline
00414   void 
00415   PrincipalGetAdapter::getManyByType(std::vector<Handle<PROD> >& results) const { 
00416     BasicHandleVec bhv;
00417     this->getManyByType_(TypeID(typeid(PROD)), bhv);
00418     
00419     // Go through the returned handles; for each element,
00420     //   1. create a Handle<PROD> and
00421     //
00422     // This function presents an exception safety difficulty. If an
00423     // exception is thrown when converting a handle, the "got
00424     // products" record will be wrong.
00425     //
00426     // Since EDProducers are not allowed to use this function,
00427     // the problem does not seem too severe.
00428     //
00429     // Question: do we even need to keep track of the "got products"
00430     // for this function, since it is *not* to be used by EDProducers?
00431     std::vector<Handle<PROD> > products;
00432 
00433     typename BasicHandleVec::const_iterator it = bhv.begin();
00434     typename BasicHandleVec::const_iterator end = bhv.end();
00435 
00436     while (it != end) {
00437       Handle<PROD> result;
00438       convert_handle(*it, result);  // throws on conversion error
00439       products.push_back(result);
00440       ++it;
00441     }
00442     results.swap(products);
00443   }
00444 }
00445 #endif