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 ( ) ) ;
}