Query_base类和Query类
class Query_base {friend class Query;protected:using line_no = TextQuery::line_no;virtual ~Query_base() = default;private:virtual QueryResult eval(const TextQuery&) const = 0;virtual std::string rep() const = 0;
};
class Query{friend Query operator~(const Query &);friend Query operator|(const Query&,const Query&);friend Query operator&(const Query&,const Query&);public:Query(const std::string&);QueryResult eval(const TextQuery &t) const{return q->eval(t);}std::string rep() const {return q->req();}private:Query(std::shared_ptr<Query_base> query):q(query){ }std::shared_ptr<Query_base> q;
};
Query的输出运算符
std::ostream &
operator<<(std::ostream &os,const Query &query)
{return os<<query.rep();
}Query andq = Query(sought1) & Query(sought2);
cout<<andq<<endl;
派生类
class WordQuery: public Query_base {friend class Query; WordQuery(const std::string &s) : query_word(s) { }QueryResult eval(const TextQuery &t) const{return t.query(query_word);}std::string rep() const {return query_word;}std::string query_word;
};
NotQuery类及 ~
运算符
class NotQuery : public Query_base {friend Query operator~(const Query &);NotQuery(const Query &q):query(q){ }std::string rep() const {return "~(" + query.rep() + ")";}QueryResult eval(const TextQuery&) const;Query query;
};
inline Query operator~(const Query &operand)
{return std::shared_ptr<Query_base>(new NotQuery(oprand));
}
shared_ptr<Query_base> tmp(new NotQuery(expr));
return Query(tmp);
BinaryQuery类
class BinaryQuery : public Query_base{protected:BinaryQuery(const Query &l,const Query &r,std::string s):lhs(l),rhs(r),opSym(s){ }std::string rep() const { return "(" + lhs.rep() + " " +opSym + "" +rhs.rep() + ")";}Query lhs,rhs; std::string opSym;
};
AndQuery类、OrQuery类及相应的运算符
class AndQuery : public BinaryQuery {friend Query operator&(const Query&,const Query&);AndQuery(const Query &left,const Query &right) : BinaryQuery(left,right,"&"){ }QueryResult eval(const TextQuery&) const;};inline Query operator&(const Query &lhs,const Query &rhs){return std::shared_ptr<Query_base>(new AndQuery(lhs,rhs));}class OrQuery : public BinaryQuery{friend Query operator|(const Query&,const Query&);OrQuery(const Query &left,const Query &right):BinaryQuery(left,right,"|"){ }QueryResult eval(const TextQuery&)const;};inline Query operator|(const Query &lhs,const Query &rhs){return std::shared_ptr<Query_base>(new OrQuery(lhs,rhs));}
eval
函数
OrQuery::eval(const TextQuery& text) const
{auto right = rhs.eval(text),left = lhs.eval(text);auto ret_lines =make_shared<set<line_no>>(left.begin(),left.end());ret_lines->insert(right.begin(),right.end());return QueryResult(rep(),ret_lines,left.get_file());
}
QueryResult
AndQuery::eval(const TextQuery& text) const
{auto left = lhs.eval(text),right = rhs.eval(text);auto ret_lines = make_shared<set<line_no>>();set_intersection(left.begin(),left.end(),right.begin(),right.end(),inserter(*ret_lines,ret_lines->begin()));return QueryResult(rep(),ret_lines,left.get_file());
}
QueryResult
NotQuery::eval(const TextQuery& text) const
{auto result = query.eval(text);auto ret_lines = make_shared<set<line_no>>();auto beg = result.begin(),end = result.end();auto sz = result.get_file()->size();for(size_t n = 0;n != sz; ++n){if(beg = end || *beg != n)ret_lines->insert(n); else if(beg != end)++beg; }return QueryResult(rep(),ret_lines,result.get_file());
}