CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC2_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     getByLabel(std::string const& label, Handle<PROD>& result) const;
00125 
00126     template <typename PROD>
00127     bool 
00128     getByLabel(std::string const& label,
00129                std::string const& productInstanceName, 
00130                Handle<PROD>& result) const;
00131 
00133     template <typename PROD>     
00134     bool         
00135     getByLabel(InputTag const& tag, Handle<PROD>& result) const;         
00136 
00137     template <typename PROD>
00138     void 
00139     getManyByType(std::vector<Handle<PROD> >& results) const;
00140 
00141     ProcessHistory const&
00142     processHistory() const;
00143 
00144     Principal& principal() {return principal_;}
00145     Principal const& principal() const {return principal_;}
00146 
00147     ConstBranchDescription const&
00148     getBranchDescription(TypeID const& type, std::string const& productInstanceName) const;
00149 
00150     typedef std::vector<BasicHandle>  BasicHandleVec;
00151 
00152     //------------------------------------------------------------
00153     // Protected functions.
00154     //
00155 
00156     // The following 'get' functions serve to isolate the PrincipalGetAdapter class
00157     // from the Principal class.
00158 
00159     BasicHandle 
00160     getByLabel_(TypeID const& tid,
00161                 std::string const& label,
00162                 std::string const& productInstanceName,
00163                 std::string const& processName) const;
00164 
00165     BasicHandle 
00166     getByLabel_(TypeID const& tid, InputTag const& tag) const;
00167 
00168     void 
00169     getManyByType_(TypeID const& tid, 
00170                    BasicHandleVec& results) const;
00171 
00172     int 
00173     getMatchingSequenceByLabel_(TypeID const& typeID,
00174                                 std::string const& label,
00175                                 std::string const& productInstanceName,
00176                                 std::string const& processName,
00177                                 BasicHandle& result) const;
00178     
00179     // Also isolates the PrincipalGetAdapter class
00180     // from the Principal class.
00181     EDProductGetter const* prodGetter() const;
00182   private:
00183     //------------------------------------------------------------
00184     // Copying and assignment of PrincipalGetAdapters is disallowed
00185     //
00186     PrincipalGetAdapter(PrincipalGetAdapter const&);                  // not implemented
00187     PrincipalGetAdapter const& operator=(PrincipalGetAdapter const&);   // not implemented
00188 
00189     // Is this an Event, a LuminosityBlock, or a Run.
00190     BranchType const& branchType() const;
00191 
00192   private:
00193     //------------------------------------------------------------
00194     // Data members
00195     //
00196 
00197     // Each PrincipalGetAdapter must have an associated Principal, used as the
00198     // source of all 'gets' and the target of 'puts'.
00199     Principal & principal_;
00200 
00201     // Each PrincipalGetAdapter must have a description of the module executing the
00202     // "transaction" which the PrincipalGetAdapter represents.
00203     ModuleDescription const& md_;
00204 
00205   };
00206 
00207   template <typename PROD>
00208   inline
00209   std::ostream& 
00210   operator<<(std::ostream& os, Handle<PROD> const& h) {
00211     os << h.product() << " " << h.provenance() << " " << h.id();
00212     return os;
00213   }
00214 
00215 
00216   //------------------------------------------------------------
00217   // Metafunction support for compile-time selection of code used in
00218   // PrincipalGetAdapter::put member template.
00219   //
00220 
00221   // has_postinsert is a metafunction of one argument, the type T.  As
00222   // with many metafunctions, it is implemented as a class with a data
00223   // member 'value', which contains the value 'returned' by the
00224   // metafunction.
00225   //
00226   // has_postinsert<T>::value is 'true' if T has the post_insert
00227   // member function (with the right signature), and 'false' if T has
00228   // no such member function.
00229 
00230   namespace detail {
00231     typedef char (& no_tag)[1]; // type indicating FALSE
00232     typedef char (& yes_tag)[2]; // type indicating TRUE
00233 
00234     // Definitions forthe following struct and function templates are
00235     // not needed; we only require the declarations.
00236     template <typename T, void (T::*)()>  struct postinsert_function;
00237     template <typename T> no_tag  has_postinsert_helper(...);
00238     template <typename T> yes_tag has_postinsert_helper(postinsert_function<T, &T::post_insert> * p);
00239 
00240 
00241     template<typename T>
00242     struct has_postinsert {
00243       static bool const value = 
00244         sizeof(has_postinsert_helper<T>(0)) == sizeof(yes_tag) &&
00245         !boost::is_base_of<DoNotSortUponInsertion, T>::value;
00246     };
00247 
00248 
00249     // has_donotrecordparents<T>::value is true if we should not
00250     // record parentage for type T, and false otherwise.
00251 
00252     template <typename T>
00253     struct has_donotrecordparents {
00254       static bool const value = 
00255         boost::is_base_of<DoNotRecordParents,T>::value;
00256     };
00257 
00258   }
00259 
00260   //------------------------------------------------------------
00261 
00262   // The following function objects are used by Event::put, under the
00263   // control of a metafunction if, to either call the given object's
00264   // post_insert function (if it has one), or to do nothing (if it
00265   // does not have a post_insert function).
00266   template <typename T>
00267   struct DoPostInsert {
00268     void operator()(T* p) const { p->post_insert(); }
00269   };
00270 
00271   template <typename T>
00272   struct DoNotPostInsert {
00273     void operator()(T*) const { }
00274   };
00275 
00276   // Implementation of  PrincipalGetAdapter  member templates. See  PrincipalGetAdapter.cc for the
00277   // implementation of non-template members.
00278   //
00279 
00280   template <typename PROD>
00281   inline
00282   bool
00283   PrincipalGetAdapter::getByLabel(std::string const& label,
00284                            Handle<PROD>& result) const {
00285     result.clear();
00286     return getByLabel(label, std::string(), result);
00287   }
00288 
00289   template <typename PROD>
00290   inline
00291   bool
00292   PrincipalGetAdapter::getByLabel(InputTag const& tag, Handle<PROD>& result) const {
00293     result.clear();
00294     BasicHandle bh = this->getByLabel_(TypeID(typeid(PROD)), tag);
00295     convert_handle(bh, result);  // throws on conversion error
00296     if (bh.failedToGet()) {
00297       return false;
00298     }
00299     return true;
00300   }
00301 
00302   template <typename PROD>
00303   inline
00304   bool
00305   PrincipalGetAdapter::getByLabel(std::string const& label,
00306                            std::string const& productInstanceName,
00307                            Handle<PROD>& result) const {
00308     result.clear();
00309     BasicHandle bh = this->getByLabel_(TypeID(typeid(PROD)), label, productInstanceName, std::string());
00310     convert_handle(bh, result);  // throws on conversion error
00311     if (bh.failedToGet()) {
00312       return false;
00313     }
00314     return true;
00315   }
00316 
00317   template <typename PROD>
00318   inline
00319   void 
00320   PrincipalGetAdapter::getManyByType(std::vector<Handle<PROD> >& results) const { 
00321     BasicHandleVec bhv;
00322     this->getManyByType_(TypeID(typeid(PROD)), bhv);
00323     
00324     // Go through the returned handles; for each element,
00325     //   1. create a Handle<PROD> and
00326     //
00327     // This function presents an exception safety difficulty. If an
00328     // exception is thrown when converting a handle, the "got
00329     // products" record will be wrong.
00330     //
00331     // Since EDProducers are not allowed to use this function,
00332     // the problem does not seem too severe.
00333     //
00334     // Question: do we even need to keep track of the "got products"
00335     // for this function, since it is *not* to be used by EDProducers?
00336     std::vector<Handle<PROD> > products;
00337 
00338     typename BasicHandleVec::const_iterator it = bhv.begin();
00339     typename BasicHandleVec::const_iterator end = bhv.end();
00340 
00341     while (it != end) {
00342       Handle<PROD> result;
00343       convert_handle(*it, result);  // throws on conversion error
00344       products.push_back(result);
00345       ++it;
00346     }
00347     results.swap(products);
00348   }
00349 }
00350 #endif