[cr133] Drop cherry-picked base::zip
This CL had been cherry-picked into brave to help with the unsafe buffers fixes, but now it is available in chromium's master. Chromium change: https://chromium.googlesource.com/chromium/src/+/e4c7665bcd2e1f8b5f480bfd937beed994633f50 commit e4c7665bcd2e1f8b5f480bfd937beed994633f50 Author: Claudio DeSouza <cdesouza@chromium.org> Date: Wed Nov 13 04:28:00 2024 +0000 Add a for-range loop `zip` adapter This CL adds a `zip` helper to base utility types to allows us to do basic `zip` operations in lockstep with different ranges. ```cxx std::vector<int> a = {1, 2, 3}; std::vector<double> b = {4.5, 5.5, 6.5}; std::vector<std::string> c = {"x", "y", "z"}; for (auto [x, y, z] : zip(a, b, c)) { LOG(INFO) << x << " " << y << " " << z; } ``` Bug: 377940847
This commit is contained in:
@@ -1,136 +0,0 @@
|
||||
// Copyright (c) 2024 The Brave Authors. All rights reserved.
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
// You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BRAVE_CHROMIUM_SRC_BASE_TYPES_ZIP_H_
|
||||
#define BRAVE_CHROMIUM_SRC_BASE_TYPES_ZIP_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/compiler_specific.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename... Ranges>
|
||||
class Zipper {
|
||||
public:
|
||||
constexpr explicit Zipper(Ranges&... ranges LIFETIME_BOUND) noexcept
|
||||
: ranges_(ranges...) {}
|
||||
|
||||
// A sentinel used by the iterator to constrain the comparison to make sure it
|
||||
// has the proper end of each range.
|
||||
struct ZipEnd {};
|
||||
|
||||
class iterator {
|
||||
public:
|
||||
using value_type = std::tuple<
|
||||
std::remove_cv_t<decltype(*std::begin(std::declval<Ranges&>()))>...>;
|
||||
using reference = value_type;
|
||||
using element_type = value_type;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = void;
|
||||
// TODO(https://crbug.com/377940847): This could be improved going forward
|
||||
// to select a better iterator category, based on the common denominator of
|
||||
// the union of iterators, for instance output iterators, etc.
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using iterator_concept = std::input_iterator_tag;
|
||||
|
||||
constexpr iterator& operator++() noexcept LIFETIME_BOUND {
|
||||
advance(std::index_sequence_for<Ranges...>{});
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr auto operator*() const noexcept LIFETIME_BOUND {
|
||||
return deref(std::index_sequence_for<Ranges...>{});
|
||||
}
|
||||
|
||||
// Determines if the iterator has reached the end, so a for-range loop bails
|
||||
// out.
|
||||
constexpr bool operator!=(ZipEnd) const noexcept LIFETIME_BOUND {
|
||||
return has_more(std::index_sequence_for<Ranges...>{});
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Zipper;
|
||||
|
||||
constexpr explicit iterator(
|
||||
std::tuple<decltype(std::begin(std::declval<Ranges&>()))...> begin
|
||||
LIFETIME_BOUND,
|
||||
std::tuple<decltype(std::end(std::declval<Ranges&>()))...> end
|
||||
LIFETIME_BOUND) noexcept
|
||||
: begin_(begin), end_(end) {}
|
||||
|
||||
// Checks if any range has reached the end.
|
||||
template <std::size_t... Is>
|
||||
constexpr bool has_more(std::index_sequence<Is...>) const {
|
||||
return (... && (std::get<Is>(begin_) != std::get<Is>(end_)));
|
||||
}
|
||||
|
||||
template <std::size_t... Is>
|
||||
constexpr void advance(std::index_sequence<Is...>) LIFETIME_BOUND {
|
||||
CHECK(operator!=(ZipEnd()));
|
||||
// SAFETY: The increment is safe as it has been just CHECKed so it is
|
||||
// guaranteed to be inside [begin_, end_).
|
||||
UNSAFE_BUFFERS((++std::get<Is>(begin_), ...));
|
||||
}
|
||||
|
||||
template <size_t... Is>
|
||||
constexpr value_type deref(std::index_sequence<Is...>) const
|
||||
LIFETIME_BOUND {
|
||||
return {*std::get<Is>(begin_)...};
|
||||
}
|
||||
|
||||
std::tuple<decltype(std::begin(std::declval<Ranges&>()))...> begin_;
|
||||
std::tuple<decltype(std::end(std::declval<Ranges&>()))...> end_;
|
||||
};
|
||||
|
||||
constexpr iterator begin() noexcept LIFETIME_BOUND {
|
||||
return begin_impl(std::index_sequence_for<Ranges...>{});
|
||||
}
|
||||
|
||||
constexpr ZipEnd end() noexcept { return ZipEnd(); }
|
||||
|
||||
private:
|
||||
template <size_t... Is>
|
||||
constexpr iterator begin_impl(std::index_sequence<Is...>) LIFETIME_BOUND {
|
||||
return iterator(std::make_tuple(std::begin(std::get<Is>(ranges_))...),
|
||||
std::make_tuple(std::end(std::get<Is>(ranges_))...));
|
||||
}
|
||||
|
||||
std::tuple<Ranges&...> ranges_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Zipping utility that allows iterating over multiple ranges in lockstep.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// std::vector<int> a = {1, 2, 3};
|
||||
// std::vector<double> b = {4.5, 5.5, 6.5};
|
||||
// std::vector<std::string> c = {"x", "y", "z"};
|
||||
// for (auto [x, y, z] : zip(a, b, c)) {
|
||||
// LOG(INFO) << x << " " << y << " " << z;
|
||||
// }
|
||||
//
|
||||
// Zipping will carry on until one of the ranges run out, at which the loop will
|
||||
// bail.
|
||||
template <typename... Ranges>
|
||||
constexpr internal::Zipper<Ranges...> zip(Ranges&... ranges LIFETIME_BOUND) {
|
||||
return internal::Zipper<Ranges...>(ranges...);
|
||||
}
|
||||
|
||||
} // namespace base
|
||||
|
||||
#endif // BRAVE_CHROMIUM_SRC_BASE_TYPES_ZIP_H_
|
||||
@@ -17,7 +17,6 @@
|
||||
// Please, keep in alphabetical order.
|
||||
"path_excludes": [
|
||||
"base/feature_override.h",
|
||||
"base/types/zip.h",
|
||||
"check_chromium_src_config.json5",
|
||||
"chrome/browser/devtools/url_constants_unittest.cc",
|
||||
"chrome/browser/history/history_utils_unittest.cc",
|
||||
|
||||
Reference in New Issue
Block a user