Набор ret_lines инициализируется с использования того конструктора, который получает пару итераторов. Функции-члены begin() и end() класса QueryResult возвращают итераторы на номера строк набора. Таким образом, набор ret_lines создается при копировании элементов из набора left. Затем для вставки элементов из набора right вызывается функция insert(). После этого вызова набор ret_lines содержит номера строк из наборов, которые присутствуют в наборах left или right.
Функция eval() завершает работу, создавая и возвращая объект класса QueryResult, представляющий объединение соответствий. Конструктор QueryResult() (см. раздел 12.3.2) получает три аргумента: строку, представляющую запрос, указатель shared_ptr на набор соответствующих номеров строк и указатель shared_ptr на вектор, представляющий входной файл. Вызов функции rep() позволяет создать строку, а вызов функции get_file() — получить указатель shared_ptr на файл. Поскольку оба набора, left и right, относятся к тому же файлу, не имеет значения, который из них использовать для функции get_file().
AndQuery::eval()Версия функции eval() класса AndQuery подобна версии класса OrQuery, за исключением того, что она использует библиотечный алгоритм для поиска строк, общих для обоих запросов:
//
QueryResult
AndQuery::eval(const TextQuery& text) const {
//
//
auto left = lhs.eval(text), right = rhs.eval(text);
//
auto ret_lines = make_shared
//
//
set_intersection(left.begin(), left.end(),
right.begin(), right.end(),
inserter(*ret_lines, ret_lines->begin()));
return QueryResult(rep(), ret_lines, left.get_file());
}
Здесь для объединения двух наборов используется библиотечный алгоритм set_intersection, описанный в приложении А.2.8.
Алгоритм set_intersection получает пять итераторов. Первые четыре он использует для обозначения двух исходных последовательностей (см. раздел 10.5.2). Его последний аргумент обозначает получателя. Алгоритм выводит элементы, присутствующие в обеих исходных последовательностях, в результирующую.
В данном вызове получателем является итератор вставки (см. раздел 10.4.1). Результатом записи алгоритмом set_intersection в этот итератор будет вставка нового элемента в набор ret_lines.
Подобно функции eval() класса OrQuery, эта завершается созданием и возвращением объекта класса QueryResult, представляющего объединение соответствий.
NotQuery::eval()Функция eval() класса NotQuery ищет в тексте все строки, в которых операнд отсутствует.
//
//
NotQuery::eval(const TextQuery& text) const {
//
auto result = query.eval(text);
//
auto ret_lines = make_shared
//
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)