123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- From c33967fcbc838e1a36e8ad7665d1b73177716e9d Mon Sep 17 00:00:00 2001
- From: Protobuf Team Bot <protobuf-github-bot@google.com>
- Date: Mon, 20 Nov 2023 04:18:49 -0800
- Subject: [PATCH] Add iterator_concept support.
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- This allows for better code generation in C++20 for algorithms that take advantage of random access vs contiguous data.
- ```
- name old INSTRUCTIONS/op new INSTRUCTIONS/op delta
- BM_RepeatedField_Sort 5.74k ± 0% 5.74k ± 0% -0.13% (p=0.000 n=179+183)
- BM_RepeatedField_ToVector 693 ± 0% 693 ± 0% ~ (p=0.153 n=93+91)
- BM_RepeatedPtrField_SortIndirect 562 ± 0% 559 ± 0% -0.53% (p=0.000 n=92+92)
- ```
- PiperOrigin-RevId: 583983215
- ---
- src/google/protobuf/BUILD.bazel | 1 +
- src/google/protobuf/repeated_field.h | 18 +++--
- .../protobuf/repeated_field_unittest.cc | 69 +++++++++++++++++++
- src/google/protobuf/repeated_ptr_field.h | 26 +++++--
- 4 files changed, 103 insertions(+), 11 deletions(-)
- diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
- index a3f77153289b..5351846558e6 100644
- --- a/src/google/protobuf/repeated_field.h
- +++ b/src/google/protobuf/repeated_field.h
- @@ -1035,14 +1035,18 @@ namespace internal {
- // the compiler isn't allowed to inline them.
- template <typename Element>
- class RepeatedIterator {
- + private:
- + using traits =
- + std::iterator_traits<typename std::remove_const<Element>::type*>;
- +
- public:
- - using iterator_category = std::random_access_iterator_tag;
- - // Note: remove_const is necessary for std::partial_sum, which uses value_type
- - // to determine the summation variable type.
- - using value_type = typename std::remove_const<Element>::type;
- - using difference_type = std::ptrdiff_t;
- + // Note: value_type is never cv-qualified.
- + using value_type = typename traits::value_type;
- + using difference_type = typename traits::difference_type;
- using pointer = Element*;
- using reference = Element&;
- + using iterator_category = typename traits::iterator_category;
- + using iterator_concept = typename IteratorConceptSupport<traits>::tag;
-
- constexpr RepeatedIterator() noexcept : it_(nullptr) {}
-
- @@ -1142,10 +1146,10 @@ class RepeatedIterator {
-
- // Allow construction from RepeatedField.
- friend class RepeatedField<value_type>;
- - explicit RepeatedIterator(Element* it) noexcept : it_(it) {}
- + explicit RepeatedIterator(pointer it) noexcept : it_(it) {}
-
- // The internal iterator.
- - Element* it_;
- + pointer it_;
- };
-
- // A back inserter for RepeatedField objects.
- diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h
- index 64cdd1890e3c..7a57dfee134c 100644
- @@ -1852,6 +1853,17 @@ class RepeatedPtrIterator {
- void* const* it_;
- };
-
- +template <typename Traits, typename = void>
- +struct IteratorConceptSupport {
- + using tag = typename Traits::iterator_category;
- +};
- +
- +template <typename Traits>
- +struct IteratorConceptSupport<Traits,
- + std::void_t<typename Traits::iterator_concept>> {
- + using tag = typename Traits::iterator_concept;
- +};
- +
- // Provides an iterator that operates on pointers to the underlying objects
- // rather than the objects themselves as RepeatedPtrIterator does.
- // Consider using this when working with stl algorithms that change
- @@ -1861,13 +1873,19 @@ class RepeatedPtrIterator {
- // iterator, or "const void* const" for a constant iterator.
- template <typename Element, typename VoidPtr>
- class RepeatedPtrOverPtrsIterator {
- + private:
- + using traits =
- + std::iterator_traits<typename std::remove_const<Element>::type*>;
- +
- public:
- - using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>;
- - using iterator_category = std::random_access_iterator_tag;
- - using value_type = typename std::remove_const<Element>::type;
- - using difference_type = std::ptrdiff_t;
- + using value_type = typename traits::value_type;
- + using difference_type = typename traits::difference_type;
- using pointer = Element*;
- using reference = Element&;
- + using iterator_category = typename traits::iterator_category;
- + using iterator_concept = typename IteratorConceptSupport<traits>::tag;
- +
- + using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>;
-
- RepeatedPtrOverPtrsIterator() : it_(nullptr) {}
- explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}
|