#ifndef __JROOT__JROOTCLASSSELECTOR__ #define __JROOT__JROOTCLASSSELECTOR__ #include #include #include "TString.h" #include "TRegexp.h" #include "JLang/JTypeList.hh" #include "JLang/JType.hh" #include "JLang/JEquals.hh" #include "Jeep/JeepToolkit.hh" #include "JROOT/JRootToolkit.hh" /** * \author mdejong */ namespace JROOT {} namespace JPP { using namespace JROOT; } namespace JROOT { using JLANG::JType; using JLANG::JEquals; using JEEP::getNamespace; using JEEP::getClassname; /** * Auxiliary class to select ROOT class based on class name. */ struct JROOTClassSelector : public std::string, public JEquals { /** * Default contructor. */ JROOTClassSelector() : std::string() {} /** * Contructor. * * \param type_name type_name */ JROOTClassSelector(const char* const type_name) : std::string(type_name) {} /** * Contructor. * * \param type_name type_name */ JROOTClassSelector(const std::string& type_name) : std::string(type_name) {} /** * Contructor. * * \param type data type * \param option include namespace */ template JROOTClassSelector(const JType& type, const bool option) : std::string(option ? getName(type) : getClassname(getName(type))) {} /** * Equals method. * * Note that if one of the selectors has an empty name space, * the equality is evaluated by class name only else by class name and name space. * * \param selector selector * \return true if this selector equals given selector; else false */ bool equals(const JROOTClassSelector& selector) const { if (getNamespace(*this) == "" || getNamespace(selector) == "") return (getClassname(*this) == getClassname(selector)); else return (getNamespace(*this) == getNamespace(selector) && getClassname(*this) == getClassname(selector)); } /** * Equals method. * * \param selector selector * \return true if this selector equals given selector; else false */ bool equals(const char* const selector) const { return equals(JROOTClassSelector(selector)); } /** * Get status of given data type. * * \param type data type * \return true if valid class name; else false */ template bool operator()(const JType& type) const { return equals(JROOTClassSelector(type, true)); } }; /** * Auxiliary class for ROOT class selection. */ struct JROOTClassSelection : public std::set { /** * Contructor. * * \param option include namespace */ JROOTClassSelection(const bool option = false) : option(option) {} /** * Contructor. * * \param selection selection * \param option include namespace */ JROOTClassSelection(const std::set& selection, const bool option = false) : std::set(selection), option(option) {} /** * Contructor. * * \param typelist type list * \param option include namespace */ template JROOTClassSelection(const JType& typelist, const bool option = false) : option(option) { JLANG::for_each(*this, typelist); } /** * Get option to include name space. * * \return option */ bool getOption() const { return option; } /** * Add given data type. */ template void add() { this->insert(JROOTClassSelector(JType(), option)); } /** * Remove data type. */ template void remove() { this->erase(JROOTClassSelector(JType(), option)); } /** * Add data type. * * \param type data type */ template void operator()(const JType& type) { add(); } /** * Get status of given data type. * * \param type data type * \return true if valid class name; else false */ template bool operator()(const JType& type) const { const JROOTClassSelector selector(type, option); for (const_iterator i = this->begin(); i != this->end(); ++i) { if (*i == selector) { return true; } } return false; } /** * Get status of given data type. * * \return true if valid class name; else false */ template bool is_valid() const { return (*this)(JType()); } /** * Read ROOT class selection from input. * * Note that if the first character of the read class name is: * - a '+', the remainder of the class name is added; or * - a '-', the remainder of the class name is removed; otherwise * - the complete class name is added. * * \param in input stream * \param object ROOT class selection * \return input stream */ friend inline std::istream& operator>>(std::istream& in, JROOTClassSelection& object) { for (std::string buffer; in >> buffer; ) { const TRegexp regexp(buffer.substr(1).c_str()); switch (buffer[0]) { case '-': for (JROOTClassSelection::iterator i = object.begin(); i != object.end(); ) { if (TString(i->c_str()).Contains(regexp)) object.erase(i++); else ++i; } break; case '+': object.insert(buffer.substr(1)); break; default: object.insert(buffer); break; } } return in; } /** * Write ROOT class selection to output. * * \param out output stream * \param object ROOT class selection * \return output stream */ friend inline std::ostream& operator<<(std::ostream& out, const JROOTClassSelection& object) { for (const_iterator i = object.begin(); i != object.end(); ++i) { out << *i << std::endl; } return out; } private: bool option; //!< include namespace }; /** * Get ROOT class selection. * * \param option include namespace * \return ROOT class selection */ template inline std::set getROOTClassSelection(const bool option = false) { return JROOTClassSelection(JType(), option); } } #endif