Набор 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)