CMS 3D CMS Logo

Selector.h

Go to the documentation of this file.
00001 #ifndef Framework_Selector_h
00002 #define Framework_Selector_h
00003 
00004 /*----------------------------------------------------------------------
00005   
00006 Classes for all "selector" objects, used to select
00007 EDProducts based on information in the associated Provenance.
00008 
00009 Developers who make their own Selector class should inherit
00010 from SelectorBase.
00011 
00012 Users can use the classes defined below
00013 
00014   ModuleLabelSelector
00015   ProcessNameSelector
00016   ProductInstanceNameSelector
00017 
00018 Users can also use the class Selector, which can be constructed given a
00019 logical expression formed from any other selectors, combined with &&
00020 (the AND operator), || (the OR operator) or ! (the NOT operator).
00021 
00022 For example, to select only products produced by a module with label
00023 "mymodule" and made in the process "PROD", one can use:
00024 
00025   Selector s( ModuleLabelSelector("mymodule") && 
00026               ProcessNameSelector("PROD") );
00027 
00028 If a module (EDProducter, EDFilter, EDAnalyzer, or OutputModule) is
00029 to use such a selector, it is best to initialize it directly upon
00030 construction of the module, rather than creating a new Selector instance
00031 for every event.
00032 
00033 $Id: Selector.h,v 1.18 2008/05/12 18:14:07 wmtan Exp $
00034 
00035 ----------------------------------------------------------------------*/
00036 
00037 #include <string>
00038 
00039 #include "boost/type_traits.hpp"
00040 #include "boost/utility/enable_if.hpp"
00041 
00042 #include "FWCore/Framework/interface/SelectorBase.h"
00043 #include "DataFormats/Provenance/interface/ConstBranchDescription.h"
00044 
00045 namespace edm 
00046 {
00047   //------------------------------------------------------------------
00051   //------------------------------------------------------------------
00052   template <class T>
00053   struct has_match
00054   {
00055     static const bool value = boost::is_base_of<SelectorBase,T>::value;
00056   };
00057 
00058   template <>
00059   struct has_match<SelectorBase>
00060   {
00061     static const bool value = true;
00062   };
00063 
00064   //------------------------------------------------------------------
00065   //
00072   //------------------------------------------------------------------
00073 
00074   class ProcessNameSelector : public SelectorBase 
00075   {
00076   public:
00077     ProcessNameSelector(const std::string& pn) :
00078     pn_(pn.empty() ? std::string("*") : pn)
00079       { }
00080     
00081     virtual bool doMatch(ConstBranchDescription const& p) const 
00082     {
00083       return (pn_=="*") || (p.processName() == pn_);
00084     }
00085 
00086     virtual ProcessNameSelector* clone() const
00087     {
00088       return new ProcessNameSelector(*this);
00089     }
00090 
00091     std::string const& name() const
00092     {
00093       return pn_;
00094     }
00095 
00096   private:
00097     std::string pn_;
00098   };
00099 
00100   //------------------------------------------------------------------
00101   //
00104   //
00105   //------------------------------------------------------------------
00106 
00107   class ProductInstanceNameSelector : public SelectorBase
00108   {
00109   public:
00110     ProductInstanceNameSelector(const std::string& pin) :
00111       pin_(pin)
00112     { }
00113     
00114     virtual bool doMatch(ConstBranchDescription const& p) const 
00115     {
00116       return p.productInstanceName() == pin_;
00117     }
00118 
00119     virtual ProductInstanceNameSelector* clone() const
00120     {
00121       return new ProductInstanceNameSelector(*this);
00122     }
00123   private:
00124     std::string pin_;
00125   };
00126 
00127   //------------------------------------------------------------------
00128   //
00131   //
00132   //------------------------------------------------------------------
00133 
00134   class ModuleLabelSelector : public SelectorBase
00135   {
00136   public:
00137     ModuleLabelSelector(const std::string& label) :
00138       label_(label)
00139     { }
00140     
00141     virtual bool doMatch(ConstBranchDescription const& p) const 
00142     {
00143       return p.moduleLabel() == label_;
00144     }
00145 
00146     virtual ModuleLabelSelector* clone() const
00147     {
00148       return new ModuleLabelSelector(*this);
00149     }
00150   private:
00151     std::string label_;
00152   };
00153 
00154   //------------------------------------------------------------------
00155   //
00158   //
00159   //------------------------------------------------------------------
00160 
00161   class MatchAllSelector : public SelectorBase
00162   {
00163   public:
00164     MatchAllSelector()
00165     { }
00166     
00167     virtual bool doMatch(ConstBranchDescription const& p) const 
00168     {
00169       return true;
00170     }
00171 
00172     virtual MatchAllSelector* clone() const
00173     {
00174       return new MatchAllSelector;
00175     }
00176   };
00177 
00178   //----------------------------------------------------------
00179   //
00180   // AndHelper template.
00181   // Used to form expressions involving && between other selectors.
00182   //
00183   //----------------------------------------------------------
00184 
00185   template <class A, class B>
00186   class AndHelper
00187   {
00188   public:
00189     AndHelper(A const& a, B const& b) : a_(a), b_(b) { }
00190     bool match(ConstBranchDescription const& p) const { return a_.match(p) && b_.match(p); }  
00191   private:
00192     A a_;
00193     B b_;
00194   };
00195   
00196   template <class A, class B>
00197   struct has_match<AndHelper<A,B> >
00198   {
00199     static const bool value = true;
00200   };
00201   
00202   template <class A, class B>
00203   typename boost::enable_if_c< has_match<A>::value && has_match<B>::value,
00204                                AndHelper<A,B> >::type
00205   operator&& (A const& a, B const& b)
00206   {
00207     return AndHelper<A,B>(a,b);
00208   }
00209 
00210   //----------------------------------------------------------
00211   //
00212   // OrHelper template.
00213   // Used to form expressions involving || between other selectors.
00214   //
00215   //----------------------------------------------------------
00216 
00217   template <class A, class B>
00218   class OrHelper
00219   {
00220   public:
00221     OrHelper(A const& a, B const& b) : a_(a), b_(b) { }
00222     bool match(ConstBranchDescription const& p) const { return a_.match(p) || b_.match(p); }  
00223   private:
00224     A a_;
00225     B b_;
00226   };
00227   
00228   template <class A, class B>
00229   struct has_match<OrHelper<A,B> >
00230   {
00231     static const bool value = true;
00232   };
00233   
00234   template <class A, class B>
00235   typename boost::enable_if_c< has_match<A>::value && has_match<B>::value,
00236                                OrHelper<A,B> >::type
00237   operator|| (A const& a, B const& b)
00238   {
00239     return OrHelper<A,B>(a,b);
00240   }
00241 
00242 
00243   //----------------------------------------------------------
00244   //
00245   // NotHelper template.
00246   // Used to form expressions involving ! acting on a selector.
00247   //
00248   //----------------------------------------------------------
00249 
00250   template <class A>
00251   class NotHelper
00252   {
00253   public:
00254     explicit NotHelper(A const& a) : a_(a) { }
00255     bool match(ConstBranchDescription const& p) const { return ! a_.match(p); }
00256   private:
00257     A a_;
00258   };
00259   
00260   template <class A>
00261   typename boost::enable_if_c< has_match<A>::value,
00262                                NotHelper<A> >::type
00263   operator! (A const& a)
00264   {
00265     return NotHelper<A>(a);
00266   }
00267   
00268   template <class A>
00269   struct has_match<NotHelper<A> >
00270   {
00271     static const bool value = true;
00272   };
00273 
00274   //----------------------------------------------------------
00275   //
00276   // ComposedSelectorWrapper template
00277   // Used to hold an expression formed from the various helpers.
00278   //
00279   //----------------------------------------------------------
00280 
00281   template <class T>
00282   class ComposedSelectorWrapper : public SelectorBase
00283   {
00284   public:
00285     typedef T wrapped_type;
00286     explicit ComposedSelectorWrapper(T const& t) : expression_(t) { }
00287     ~ComposedSelectorWrapper() {};
00288     virtual bool doMatch(ConstBranchDescription const& p) const { return expression_.match(p); }
00289     ComposedSelectorWrapper<T>* clone() const { return new ComposedSelectorWrapper<T>(*this); }
00290   private:
00291     wrapped_type expression_;
00292   };
00293 
00294   //----------------------------------------------------------
00295   //
00296   // Selector
00297   //
00298   //----------------------------------------------------------
00299 
00300   class Selector : public SelectorBase
00301   {
00302   public:
00303     template <class T> Selector(T const& expression);
00304     Selector(Selector const& other);
00305     Selector& operator= (Selector const& other);
00306     void swap(Selector& other);
00307     virtual ~Selector();
00308     virtual Selector* clone() const;
00309 
00310     virtual bool doMatch(ConstBranchDescription const& p) const;
00311     
00312   private:
00313     SelectorBase* sel_;
00314   };
00315 
00316   template <class T>
00317   Selector::Selector(T const& expression) :
00318     sel_(new ComposedSelectorWrapper<T>(expression))
00319   { }
00320 
00321 
00322 }
00323 
00324 #endif

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