CMS 3D CMS Logo

CMSSW_4_4_3_patch1/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   WrapperHolder originalWrap = orig.wrapperHolder();
00027   if(!originalWrap.isValid()) {
00028     throw edm::Exception(edm::errors::InvalidReference,"NullPointer")
00029       << "edm::BasicHandle has null pointer to Wrapper";
00030   }
00031   
00032   Reflex::Object wrap(Reflex::Type::ByTypeInfo(originalWrap.wrappedTypeInfo()), const_cast<void*>(originalWrap.wrapper()));
00033   assert(wrap != Reflex::Object());
00034   
00035   Reflex::Object product(wrap.Get("obj"));
00036   if(!product){
00037     throw edm::Exception(edm::errors::LogicError)<<"GenericObject could not find 'obj' member";
00038   }
00039   if(product.TypeOf().IsTypedef()){
00040     //For a 'Reflex::Typedef' the 'ToType' method returns the actual type
00041     // this is needed since you are now allowed to 'invoke' methods of a 'Typedef'
00042     // only for a 'real' class
00043     product = Reflex::Object(product.TypeOf().ToType(), product.Address());
00044     assert(!product.TypeOf().IsTypedef());
00045   }
00046   //NOTE: comparing on type doesn't seem to always work! The problem appears to be if we have a typedef
00047   if(product.TypeOf()!=result.type() &&
00048      !product.TypeOf().IsEquivalentTo(result.type()) &&
00049      product.TypeOf().TypeInfo()!= result.type().TypeInfo()){
00050     throw edm::Exception(edm::errors::LogicError)<<"GenericObject asked for "<<result.type().Name()
00051     <<" but was given a "<<product.TypeOf().Name();
00052   }
00053   
00054   Handle<GenericObject> h(product, orig.provenance(), orig.id());
00055   h.swap(result);
00056 }
00057 
00059 template<>
00060 bool
00061 edm::Event::getByLabel<GenericObject>(std::string const& label,
00062                                       std::string const& productInstanceName,
00063                                       Handle<GenericObject>& result) const
00064 {
00065   BasicHandle bh = provRecorder_.getByLabel_(TypeID(result.type().TypeInfo()), label, productInstanceName, std::string());
00066   convert_handle(bh, result);  // throws on conversion error
00067   if(!bh.failedToGet()) {
00068     addToGotBranchIDs(*bh.provenance());
00069     return true;
00070   }
00071   return false;
00072 }
00073 
00074 template<>
00075 bool
00076 edm::Event::getByLabel<GenericObject>(edm::InputTag const& tag,
00077                                              Handle<GenericObject>& result) const
00078 {
00079   if (tag.process().empty()) {
00080     return this->getByLabel(tag.label(), tag.instance(), result);
00081   } else {
00082     BasicHandle bh = provRecorder_.getByLabel_(TypeID(result.type().TypeInfo()), tag.label(), tag.instance(),tag.process());
00083     convert_handle(bh, result);  // throws on conversion error
00084     if(!bh.failedToGet()) {
00085       addToGotBranchIDs(*bh.provenance());
00086       return true;
00087     }
00088   }
00089   return false;
00090 }
00091 
00092 }