CMS 3D CMS Logo

GenericObjectOwner.h

Go to the documentation of this file.
00001 #ifndef FWCore_Framework_GenericObjectOwner_h
00002 #define FWCore_Framework_GenericObjectOwner_h
00003 // -*- C++ -*-
00004 //
00005 // Package:     Framework
00006 // Class  :     GenericObjectOwner
00007 // 
00016 //
00017 // Original Author:  Chris Jones
00018 //         Created:  Sun Feb  3 19:43:16 EST 2008
00019 //
00020 
00021 // system include files
00022 #include "Reflex/Object.h"
00023 #include "Reflex/Builder/TypeBuilder.h"
00024 
00025 // user include files
00026 #include "FWCore/Framework/interface/Event.h"
00027 #include "FWCore/Utilities/interface/EDMException.h"
00028 #include "FWCore/Utilities/interface/WrappedClassName.h"
00029 
00030 // forward declarations
00031 namespace edm {
00032 class GenericObjectOwner
00033 {
00034 
00035    public:
00036       GenericObjectOwner(): m_ownData(false){}
00037       explicit GenericObjectOwner(ROOT::Reflex::Object const& iObject,
00038                                   bool iOwnData=true):
00039          m_object(iObject), m_ownData(iOwnData) {}
00040       ~GenericObjectOwner();
00041 
00042       // ---------- const member functions ---------------------
00043       ROOT::Reflex::Object object() const;
00044    
00045       // ---------- static member functions --------------------
00046 
00047       // ---------- member functions ---------------------------
00048       void swap(GenericObjectOwner&);
00049       void release();
00050    
00051    private:
00052       GenericObjectOwner(GenericObjectOwner const&); // stop default
00053 
00054       GenericObjectOwner const& operator=(GenericObjectOwner const&); // stop default
00055 
00056       // ---------- member data --------------------------------
00057       ROOT::Reflex::Object m_object;
00058       bool m_ownData;
00059 };
00060 
00061    //Need to specialize OrphanHandle because we don't actually have a long lived GenericObjectOwner
00062    template <>
00063    class OrphanHandle<GenericObjectOwner> {
00064    public:
00065       // Default constructed handles are invalid.
00066       OrphanHandle() {}
00067       
00068       OrphanHandle(OrphanHandle<GenericObjectOwner> const& h):
00069       prod_(h.prod_.object(),false), id_(h.id_) {}
00070       
00071       OrphanHandle(ROOT::Reflex::Object const& prod, ProductID const& id):
00072       prod_(prod,false), id_(id) {}
00073       
00074       //~OrphanHandle();
00075       
00076       void swap(OrphanHandle<GenericObjectOwner>& other){
00077          prod_.swap(other.prod_);
00078          std::swap(id_,other.id_);
00079       }
00080       
00081       
00082       OrphanHandle<GenericObjectOwner>& operator=(OrphanHandle<GenericObjectOwner> const& rhs)
00083       {
00084          OrphanHandle<GenericObjectOwner> temp(rhs);
00085          swap(temp);
00086          return *this;
00087       }
00088       
00089       bool isValid() const {return 0 !=prod_.object().Address();}
00090          
00091       GenericObjectOwner const* product() const {return &prod_;}
00092       GenericObjectOwner const* operator->() const {return product();}
00093       GenericObjectOwner const& operator*() const {return prod_;}
00094       
00095       ProductID id() const {return id_;}
00096          
00097          
00098       private:
00099          GenericObjectOwner prod_;
00100          ProductID id_;
00101       };
00102       
00103    template<>
00104    OrphanHandle<GenericObjectOwner> 
00105    Event::put<GenericObjectOwner>(std::auto_ptr<GenericObjectOwner> product, std::string const& productInstanceName)
00106    {
00107       if (product.get() == 0) {                // null pointer is illegal
00108          throw edm::Exception(edm::errors::NullPointerError)
00109          << "Event::put: A null auto_ptr was passed to 'put'.\n"
00110          << "The pointer is of type " << "GenericObjectOwner" << ".\n"
00111          << "The specified productInstanceName was '" << productInstanceName << "'.\n";
00112       }
00113       
00114       // The following will call post_insert if T has such a function,
00115       // and do nothing if T has no such function.
00116       /*
00117       typename boost::mpl::if_c<detail::has_postinsert<PROD>::value, 
00118       DoPostInsert<PROD>, 
00119       DoNotPostInsert<PROD> >::type maybe_inserter;
00120       maybe_inserter(product.get());
00121       */
00122       ConstBranchDescription const& desc =
00123       getBranchDescription(TypeID(product->object().TypeOf().TypeInfo()), productInstanceName);
00124       
00125       ROOT::Reflex::Type const wrapperType=ROOT::Reflex::Type::ByName(wrappedClassName(desc.fullClassName()));
00126       if(wrapperType == ROOT::Reflex::Type() ) {
00127          throw edm::Exception(errors::DictionaryNotFound, "NoWrapperDictionary")
00128          << "Event::put: the class type '" << desc.fullClassName()
00129          << "' was passed to put but the Reflex dictionary for the required class '"
00130          << wrappedClassName(desc.fullClassName()) << "' could not be found./n"
00131          << "Please change the C++ package which contains the description of '" << desc.fullClassName()
00132          << "' so that the required class also has a dictionary autogenerated.";
00133       }
00134       std::vector<void*> args;
00135       args.reserve(1);
00136       args.push_back(product->object().Address());
00137       //generate the signature of the function we want to call
00138       std::string s("void(");
00139       s+=desc.fullClassName();
00140       s+="*)";
00141       ROOT::Reflex::Type ptrT = ROOT::Reflex::Type::ByName(s);
00142       ROOT::Reflex::Object oWrapper(wrapperType.Construct(ptrT,args));
00143       //ownership was transfered to the wrapper
00144       product.release();
00145 
00146       static ROOT::Reflex::Type s_edproductType( ROOT::Reflex::Type::ByTypeInfo(typeid(EDProduct)));
00147       EDProduct *wp(reinterpret_cast<EDProduct*>(oWrapper.CastObject(s_edproductType).Address()));
00148       putProducts().push_back(std::make_pair(wp, &desc));
00149       
00150       // product.release(); // The object has been copied into the Wrapper.
00151       // The old copy must be deleted, so we cannot release ownership.
00152       
00153       return(OrphanHandle<GenericObjectOwner>(oWrapper.Get("obj"), desc.productIDtoAssign()));
00154    }
00155    
00156 }
00157 #endif

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