| 2172 | } |
| 2173 | |
| 2174 | struct Matches { |
| 2175 | // referents[i] is referenced by prefixes[i] |
| 2176 | std::vector<FieldPath> prefixes; |
| 2177 | FieldVector referents; |
| 2178 | |
| 2179 | Matches(std::vector<FieldPath> matches, const FieldVector& fields) { |
| 2180 | for (auto& match : matches) { |
| 2181 | Add({}, std::move(match), fields); |
| 2182 | } |
| 2183 | } |
| 2184 | |
| 2185 | Matches() = default; |
| 2186 | |
| 2187 | size_t size() const { return referents.size(); } |
| 2188 | |
| 2189 | void Add(const FieldPath& prefix, const FieldPath& suffix, |
| 2190 | const FieldVector& fields) { |
| 2191 | auto maybe_field = suffix.Get(fields); |
| 2192 | DCHECK_OK(maybe_field); |
| 2193 | referents.push_back(std::move(maybe_field).ValueOrDie()); |
| 2194 | |
| 2195 | std::vector<int> concatenated_indices(prefix.indices().size() + |
| 2196 | suffix.indices().size()); |
| 2197 | auto it = concatenated_indices.begin(); |
| 2198 | for (auto path : {&prefix, &suffix}) { |
| 2199 | it = std::copy(path->indices().begin(), path->indices().end(), it); |
| 2200 | } |
| 2201 | prefixes.emplace_back(std::move(concatenated_indices)); |
| 2202 | } |
| 2203 | }; |
| 2204 | |
| 2205 | std::vector<FieldPath> operator()(const std::vector<FieldRef>& refs) { |
| 2206 | DCHECK_GE(refs.size(), 1); |