CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/DataFormats/PatCandidates/interface/UserData.h

Go to the documentation of this file.
00001 #ifndef DataFormats_PatCandidates_UserData_h
00002 #define DataFormats_PatCandidates_UserData_h
00003 
00016 #include <string>
00017 #include <vector>
00018 #include <typeinfo>
00019 #include <cxxabi.h>
00020 #include <DataFormats/Common/interface/OwnVector.h>
00021 
00022 
00023 namespace pat {
00024 
00025   class UserData {
00026   public:
00027     UserData() {}
00028     virtual ~UserData() {}
00029 
00031     virtual UserData * clone() const = 0;
00032 
00034     virtual const std::type_info & typeId() const = 0;
00036     virtual const std::string    & typeName() const = 0;
00037 
00039     /*  I don't think there is an easy way to get it working with generic type T,
00040         barrying the use of ROOT::Reflex and all the edm::Ptr technicalities.
00041         I'd say we can live without polymorphic storage of polymorphic data */
00042     template<typename T> const T * get() const {
00043         if (typeid(T) != typeId()) return 0;
00044         return static_cast<const T *>(data_());
00045     }
00046 
00049     //  Really needed for CINT? I would really like to avoid this
00050     const void * bareData() const { return data_(); }
00051 
00054     template<typename T>
00055     static std::auto_ptr<UserData> make(const T &value, bool transientOnly=false) ;
00056 
00057   protected:
00059     virtual const void * data_  () const = 0;
00060 
00061   private:
00062     static void checkDictionaries(const std::type_info &type) ;
00063     
00064   };
00065 
00066   template<typename T>
00067   class UserHolder : public UserData {
00068     public:
00069         UserHolder() : obj_() {}
00070         UserHolder(const T &data) : obj_(data) {}
00072         virtual UserHolder<T> * clone() const { return new UserHolder<T>(*this); }
00074         virtual const std::type_info & typeId()   const { return typeid(T); }
00076         virtual const std::string    & typeName() const { return typeName_(); }
00077     protected:
00078         virtual const void *           data_()  const { return &obj_; }
00079     private: 
00080         T obj_;
00081         static const std::string & typeName_() ;
00082   };
00083 
00084   typedef edm::OwnVector<pat::UserData>   UserDataCollection;
00085 }
00086 
00087 
00088 template<typename T>
00089 std::auto_ptr<pat::UserData> pat::UserData::make(const T &value, bool transientOnly) {
00090     if (!transientOnly) {
00091         checkDictionaries(typeid(T));
00092         checkDictionaries(typeid(pat::UserHolder<T>));
00093     }
00094     return std::auto_ptr<UserData>(new pat::UserHolder<T>(value));  
00095 }
00096 
00097 template<typename T> 
00098 const std::string & pat::UserHolder<T>::typeName_() {
00099     static int status = 0;
00100     static const char * demangled = abi::__cxa_demangle(typeid(T).name(),  0, 0, &status);
00101     static const std::string name(status == 0 ? demangled : "[UNKNOWN]");
00102     return name;
00103 }
00104 
00105 #endif