CMS 3D CMS Logo

DataViewImpl.h

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

Generated on Tue Jun 9 17:35:28 2009 for CMSSW by  doxygen 1.5.4