CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_2_9_HLT1_bphpatch4/src/FWCore/Framework/src/GenericHandle.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Framework
00004 // Class  :     GenericHandle
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Thu Mar 30 15:48:37 EST 2006
00011 //
00012 
00013 // system include files
00014 
00015 // user include files
00016 #include "FWCore/Framework/interface/GenericHandle.h"
00017 
00018 namespace edm {
00019 void convert_handle(BasicHandle const& orig,
00020                     Handle<GenericObject>& result)
00021 {
00022   if(orig.failedToGet()) {
00023     result.setWhyFailed(orig.whyFailed());
00024     return;
00025   }
00026   EDProduct const* originalWrap = orig.wrapper();
00027   if (originalWrap == 0)
00028     throw edm::Exception(edm::errors::InvalidReference,"NullPointer")
00029       << "edm::BasicHandle has null pointer to Wrapper";
00030   
00031   //Since a pointer to an EDProduct is not necessarily the same as a pointer to the actual type
00032   // (compilers are allowed to offset the two) we must get our object via a two step process
00033   Reflex::Object edproductObject(Reflex::Type::ByTypeInfo(typeid(EDProduct)), const_cast<EDProduct*>(originalWrap));
00034   assert(edproductObject != Reflex::Object());
00035   
00036   Reflex::Object wrap(edproductObject.CastObject(edproductObject.DynamicType()));
00037   assert(wrap != Reflex::Object());
00038   
00039   Reflex::Object product(wrap.Get("obj"));
00040   if(!product){
00041     throw edm::Exception(edm::errors::LogicError)<<"GenericObject could not find 'obj' member";
00042   }
00043   if(product.TypeOf().IsTypedef()){
00044     //For a 'Reflex::Typedef' the 'ToType' method returns the actual type
00045     // this is needed since you are now allowed to 'invoke' methods of a 'Typedef'
00046     // only for a 'real' class
00047     product = Reflex::Object(product.TypeOf().ToType(), product.Address());
00048     assert(!product.TypeOf().IsTypedef());
00049   }
00050   //NOTE: comparing on type doesn't seem to always work! The problem appears to be if we have a typedef
00051   if(product.TypeOf()!=result.type() &&
00052      !product.TypeOf().IsEquivalentTo(result.type()) &&
00053      product.TypeOf().TypeInfo()!= result.type().TypeInfo()){
00054     throw edm::Exception(edm::errors::LogicError)<<"GenericObject asked for "<<result.type().Name()
00055     <<" but was given a "<<product.TypeOf().Name();
00056   }
00057   
00058   Handle<GenericObject> h(product, orig.provenance(), orig.id());
00059   h.swap(result);
00060 }
00061 
00063 template<>
00064 bool
00065 edm::Event::getByLabel<GenericObject>(std::string const& label,
00066                                       const std::string& productInstanceName,
00067                                       Handle<GenericObject>& result) const
00068 {
00069   BasicHandle bh = provRecorder_.getByLabel_(TypeID(result.type().TypeInfo()), label, productInstanceName, std::string());
00070   convert_handle(bh, result);  // throws on conversion error
00071   if(!bh.failedToGet()) {
00072     addToGotBranchIDs(*bh.provenance());
00073     return true;
00074   }
00075   return false;
00076 }
00077 
00078 template<>
00079 bool
00080 edm::Event::getByLabel<GenericObject>(edm::InputTag const& tag,
00081                                              Handle<GenericObject>& result) const
00082 {
00083   if (tag.process().empty()) {
00084     return this->getByLabel(tag.label(), tag.instance(), result);
00085   } else {
00086     BasicHandle bh = provRecorder_.getByLabel_(TypeID(result.type().TypeInfo()), tag.label(), tag.instance(),tag.process());
00087     convert_handle(bh, result);  // throws on conversion error
00088     if(!bh.failedToGet()) {
00089       addToGotBranchIDs(*bh.provenance());
00090       return true;
00091     }
00092   }
00093   return false;
00094 }
00095 
00096 }