/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FastSimulation/TrackingRecHitProducer/interface/TrackerDetIdSelector.h
239 строк
8 KB
Christopher Jones
Make operator functions 'hidden' friends of ExpressionAST
19 авг 2021, 00:46
19 авг 2021, 00:46
4743cd8
Код
Авторство
О чём код?
#ifndef FastSimulation_TrackingRecHitProducer_TrackerDetIdSelector_H #define FastSimulation_TrackingRecHitProducer_TrackerDetIdSelector_H #include "DataFormats/DetId/interface/DetId.h" #include "DataFormats/TrackerCommon/interface/TrackerTopology.h" #include "FWCore/Utilities/interface/Exception.h" #include <boost/variant/recursive_variant.hpp> #include <iostream> #include <cstdlib> #include <typeinfo> #include <functional> #include <unordered_map> struct BinaryOP; struct UnaryOP; struct ExpressionAST; struct Nil {}; namespace detail { ExpressionAST opLesser(ExpressionAST const& lhs, ExpressionAST const& rhs); ExpressionAST opLesserEq(ExpressionAST const& lhs, ExpressionAST const& rhs); ExpressionAST opEq(ExpressionAST const& lhs, ExpressionAST const& rhs); ExpressionAST opNotEq(ExpressionAST const& lhs, ExpressionAST const& rhs); ExpressionAST opGreater(ExpressionAST const& lhs, ExpressionAST const& rhs); ExpressionAST opGreaterEq(ExpressionAST const& lhs, ExpressionAST const& rhs); ExpressionAST opAnd(ExpressionAST const& lhs, ExpressionAST const& rhs); ExpressionAST opOr(ExpressionAST const& lhs, ExpressionAST const& rhs); } // namespace detail struct ExpressionAST { typedef boost::variant<Nil, int, std::string, boost::recursive_wrapper<ExpressionAST>, boost::recursive_wrapper<BinaryOP>, boost::recursive_wrapper<UnaryOP> > Type; ExpressionAST() : expr(Nil()) {} template <typename Expr> ExpressionAST(Expr const& expr) : expr(expr) {} int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const; ExpressionAST& operator!(); Type expr; friend ExpressionAST operator>(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opGreater(lhs, rhs); } friend ExpressionAST operator>=(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opGreaterEq(lhs, rhs); } friend ExpressionAST operator==(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opEq(lhs, rhs); } friend ExpressionAST operator!=(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opNotEq(lhs, rhs); } friend ExpressionAST operator<(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opLesser(lhs, rhs); } friend ExpressionAST operator<=(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opLesserEq(lhs, rhs); } friend ExpressionAST operator&&(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opAnd(lhs, rhs); } friend ExpressionAST operator||(ExpressionAST const& lhs, ExpressionAST const& rhs) { return detail::opOr(lhs, rhs); } }; struct BinaryOP { enum class OP { GREATER, GREATER_EQUAL, EQUAL, LESS_EQUAL, LESS, NOT_EQUAL, AND, OR } op; ExpressionAST left; ExpressionAST right; BinaryOP(OP op, ExpressionAST const& left, ExpressionAST const& right) : op(op), left(left), right(right) {} int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const { switch (op) { case OP::GREATER: return left.evaluate(detId, trackerTopology) > right.evaluate(detId, trackerTopology); case OP::GREATER_EQUAL: return left.evaluate(detId, trackerTopology) >= right.evaluate(detId, trackerTopology); case OP::EQUAL: return left.evaluate(detId, trackerTopology) == right.evaluate(detId, trackerTopology); case OP::LESS_EQUAL: return left.evaluate(detId, trackerTopology) <= right.evaluate(detId, trackerTopology); case OP::LESS: return left.evaluate(detId, trackerTopology) < right.evaluate(detId, trackerTopology); case OP::NOT_EQUAL: return left.evaluate(detId, trackerTopology) != right.evaluate(detId, trackerTopology); case OP::AND: return left.evaluate(detId, trackerTopology) && right.evaluate(detId, trackerTopology); case OP::OR: return left.evaluate(detId, trackerTopology) || right.evaluate(detId, trackerTopology); } return 0; } }; struct UnaryOP { enum class OP { NEG } op; ExpressionAST subject; UnaryOP(OP op, ExpressionAST const& subject) : op(op), subject(subject) {} int evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const { switch (op) { case OP::NEG: return !subject.evaluate(detId, trackerTopology); } return 0; } }; class TrackerDetIdSelector { private: const DetId& _detId; const TrackerTopology& _trackerTopology; public: typedef std::function<int(const TrackerTopology& trackerTopology, const DetId&)> DetIdFunction; typedef std::unordered_map<std::string, DetIdFunction> StringFunctionMap; const static StringFunctionMap functionTable; TrackerDetIdSelector(const DetId& detId, const TrackerTopology& trackerTopology) : _detId(detId), _trackerTopology(trackerTopology) {} bool passSelection(const std::string& selectionStr) const; }; class Accessor : public boost::static_visitor<int> { private: const DetId& _detId; const TrackerTopology& _trackerTopology; public: Accessor(const DetId& detId, const TrackerTopology& trackerTopology) : _detId(detId), _trackerTopology(trackerTopology) {} int operator()(Nil i) const { throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector", "while evaluating a DetId selection a symbol was not set"); } int operator()(const int& i) const { return i; } int operator()(const std::string& s) const { TrackerDetIdSelector::StringFunctionMap::const_iterator it = TrackerDetIdSelector::functionTable.find(s); int value = 0; if (it != TrackerDetIdSelector::functionTable.cend()) { value = (it->second)(_trackerTopology, _detId); //std::cout<<"attr="<<s<<", value="<<value<<std::endl; } else { //std::cout<<"attr="<<s<<" unknown"<<std::endl; std::string msg = "error while parsing DetId selection: named identifier '" + s + "' not known. Possible values are: "; for (const TrackerDetIdSelector::StringFunctionMap::value_type& pair : TrackerDetIdSelector::functionTable) { msg += pair.first + ","; } throw cms::Exception("FastSimulation/TrackingRecHitProducer/TrackerDetIdSelector", msg); } return value; } int operator()(const ExpressionAST& ast) const { return ast.evaluate(_detId, _trackerTopology); } int operator()(const BinaryOP& binaryOP) const { return binaryOP.evaluate(_detId, _trackerTopology); } int operator()(const UnaryOP& unaryOP) const { return unaryOP.evaluate(_detId, _trackerTopology); } }; struct WalkAST { Accessor _acc; WalkAST(const DetId& detId, const TrackerTopology& trackerTopology) : _acc(detId, trackerTopology) {} typedef void result_type; void operator()() const {} void operator()(int n) const { std::cout << n; std::cout << " [" << _acc(n) << "] "; } void operator()(std::string str) const { std::cout << str; std::cout << " [" << _acc(str) << "] "; } void operator()(ExpressionAST const& ast) const { boost::apply_visitor(*this, ast.expr); std::cout << " [=" << _acc(ast) << "] "; } void operator()(BinaryOP const& expr) const { std::cout << "("; boost::apply_visitor(*this, expr.left.expr); switch (expr.op) { case BinaryOP::OP::GREATER: std::cout << " > "; break; case BinaryOP::OP::GREATER_EQUAL: std::cout << " >= "; break; case BinaryOP::OP::EQUAL: std::cout << " == "; break; case BinaryOP::OP::LESS_EQUAL: std::cout << " <= "; break; case BinaryOP::OP::LESS: std::cout << " < "; break; case BinaryOP::OP::NOT_EQUAL: std::cout << " != "; break; case BinaryOP::OP::AND: std::cout << " && "; break; case BinaryOP::OP::OR: std::cout << " || "; break; } boost::apply_visitor(*this, expr.right.expr); std::cout << ')'; } void operator()(UnaryOP const& expr) const { switch (expr.op) { case UnaryOP::OP::NEG: std::cout << " !("; break; } boost::apply_visitor(*this, expr.subject.expr); std::cout << ')'; } }; inline int ExpressionAST::evaluate(const DetId& detId, const TrackerTopology& trackerTopology) const { return boost::apply_visitor(Accessor(detId, trackerTopology), this->expr); } #endif