| 261 | } |
| 262 | |
| 263 | absl::InlinedVector<std::pair<int64, int64>, 8> CommonFactors( |
| 264 | absl::Span<const int64> a, absl::Span<const int64> b) { |
| 265 | CHECK_EQ(Product(a), Product(b)); |
| 266 | if (0 == Product(a)) { |
| 267 | return {std::make_pair(0, 0), std::make_pair(a.size(), b.size())}; |
| 268 | } |
| 269 | |
| 270 | absl::InlinedVector<std::pair<int64, int64>, 8> bounds; |
| 271 | for (int64 i = 0, j = 0, prior_i = -1, prior_j = -1, partial_size_a = 1, |
| 272 | partial_size_b = 1; |
| 273 | ;) { |
| 274 | if (partial_size_a == partial_size_b && (i > prior_i || j > prior_j)) { |
| 275 | std::tie(prior_i, prior_j) = std::make_pair(i, j); |
| 276 | bounds.emplace_back(i, j); |
| 277 | continue; |
| 278 | } |
| 279 | bool in_bounds_i = i < a.size(); |
| 280 | bool in_bounds_j = j < b.size(); |
| 281 | if (!(in_bounds_i || in_bounds_j)) { |
| 282 | break; |
| 283 | } |
| 284 | bool next_a = |
| 285 | partial_size_a < partial_size_b || |
| 286 | (in_bounds_i && |
| 287 | (!in_bounds_j || (partial_size_a == partial_size_b && a[i] <= b[j]))); |
| 288 | bool next_b = |
| 289 | partial_size_b < partial_size_a || |
| 290 | (in_bounds_j && |
| 291 | (!in_bounds_i || (partial_size_b == partial_size_a && b[j] <= a[i]))); |
| 292 | if (next_a) { |
| 293 | partial_size_a *= a[i]; |
| 294 | ++i; |
| 295 | } |
| 296 | if (next_b) { |
| 297 | partial_size_b *= b[j]; |
| 298 | ++j; |
| 299 | } |
| 300 | } |
| 301 | return bounds; |
| 302 | } |
| 303 | |
| 304 | string SanitizeFileName(string file_name) { |
| 305 | for (char& c : file_name) { |