00001 
00002 #ifndef TRIGNAVSTRUCTURE_TRIGHOLDERSTRUCTURE
00003 #define TRIGNAVSTRUCTURE_TRIGHOLDERSTRUCTURE
00004 #include <memory>
00005 #include <map>
00006 #include <string>
00007 
00008 #include <boost/variant.hpp>
00009 
00010 #include "AsgTools/AsgMessaging.h"
00011 #include "TrigNavStructure/Types.h"
00012 #include "TrigNavStructure/BaseHolder.h"
00013 #include "TrigNavStructure/TriggerElement.h"
00014 
00015 namespace HLT{
00016   class TrigHolderStructure : public asg::AsgMessaging {
00017   public:
00018     TrigHolderStructure();
00019  
00020     void reset();
00021     
00022     bool registerHolder(const std::shared_ptr<BaseHolder>& holder);
00023     
00024     template<typename HolderType = BaseHolder>
00025     HolderType* getHolder(class_id_type clid, const boost::variant<sub_index_type,std::string>& stiOrLabel) const {    
00026       return getCastHolder<HolderType>(getBaseHolder(clid,getSubTypeIndex(clid,stiOrLabel)));
00027     }
00028 
00029     template<typename HolderType = BaseHolder>
00030     HolderType* getHolderForFeature(const TriggerElement::FeatureAccessHelper& fea) const {    
00031       return getCastHolder<HolderType>(getBaseHolder(fea.getCLID(),fea.getIndex().subTypeIndex()));
00032     }
00033     
00034     template<typename HolderType = BaseHolder>
00035     std::vector<HolderType*> getAllHolders() const {    
00036       std::vector<HolderType*> result;
00037       for(auto& clid_indexmap : m_holderByClidAndIndex){
00038     for(auto& index_holder : clid_indexmap.second){
00039       result.push_back(getCastHolder<HolderType>(index_holder.second.get()));
00040     }
00041       }
00042       return result;
00043     }
00044 
00045     template<typename HolderType = BaseHolder>
00046     std::vector<HolderType*> getHoldersOfClid(class_id_type clid) const {
00047       std::vector<HolderType*> result;
00048       auto lookup_it = m_holderByClidAndIndex.find(clid);
00049       if(lookup_it == m_holderByClidAndIndex.end()) return result;
00050 
00051       for(auto& index_holder : lookup_it->second){
00052     result.push_back(getCastHolder<HolderType>(index_holder.second.get())); 
00053       }
00054       return result;
00055     }
00056 
00057 
00058     sub_index_type getSubTypeIndex(class_id_type clid, const index_or_label_type& stiOrLabel) const {
00059       
00060       if (stiOrLabel.which() == 0){
00061     return boost::get<sub_index_type>(stiOrLabel);
00062       }
00063 
00064       auto lookup_it = m_lookupSubIndex.find(clid);
00065       if(lookup_it == m_lookupSubIndex.end()) return invalid_sub_index;
00066       
00067       auto it = lookup_it->second.find(boost::get<std::string>(stiOrLabel));
00068       if(it==lookup_it->second.end()) return invalid_sub_index;
00069 
00070       return  it->second;
00071     }
00072 
00073     std::string getLabel(class_id_type clid, const index_or_label_type& stiOrLabel) const {
00074       
00075       if (stiOrLabel.which() == 1){
00076     return boost::get<std::string>(stiOrLabel);
00077       }
00078 
00079       std::string invalid_label = "inavalid_label";
00080 
00081       auto lookup_it = m_lookupLabels.find(clid);
00082       if(lookup_it == m_lookupLabels.end()) return invalid_label;
00083       
00084       auto it = lookup_it->second.find(boost::get<sub_index_type>(stiOrLabel));
00085       if(it==lookup_it->second.end()) return invalid_label;
00086 
00087       return  it->second;
00088     }
00089 
00090     
00091   private:
00092 
00093     BaseHolder* getBaseHolder(class_id_type clid,sub_index_type sti) const;
00094 
00095     template<typename T>
00096     T* getCastHolder(BaseHolder* holder) const {
00097       if(!holder){
00098     return 0;
00099       }
00100       auto cast_holder = dynamic_cast<T*>(holder);
00101       if(!cast_holder){
00102     ATH_MSG_ERROR("cast failed");
00103       }
00104       return cast_holder;
00105     }
00106 
00107     typedef std::map<sub_index_type, std::shared_ptr<BaseHolder> > IndexToHolderMap;
00108     typedef std::map<std::string,sub_index_type> LabelToSubIndexMap;
00109     typedef std::map<sub_index_type,std::string> SubIndexToLabelMap;
00110 
00111     std::map<class_id_type, IndexToHolderMap> m_holderByClidAndIndex;
00112 
00113     std::map<class_id_type, SubIndexToLabelMap > m_lookupLabels;
00114     std::map<class_id_type, LabelToSubIndexMap > m_lookupSubIndex;
00115 
00116   };
00117 }
00118 #endif