From c33967fcbc838e1a36e8ad7665d1b73177716e9d Mon Sep 17 00:00:00 2001 From: Protobuf Team Bot 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 class RepeatedIterator { + private: + using traits = + std::iterator_traits::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::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::tag; constexpr RepeatedIterator() noexcept : it_(nullptr) {} @@ -1142,10 +1146,10 @@ class RepeatedIterator { // Allow construction from RepeatedField. friend class RepeatedField; - 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 +struct IteratorConceptSupport { + using tag = typename Traits::iterator_category; +}; + +template +struct IteratorConceptSupport> { + 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 class RepeatedPtrOverPtrsIterator { + private: + using traits = + std::iterator_traits::type*>; + public: - using iterator = RepeatedPtrOverPtrsIterator; - using iterator_category = std::random_access_iterator_tag; - using value_type = typename std::remove_const::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::tag; + + using iterator = RepeatedPtrOverPtrsIterator; RepeatedPtrOverPtrsIterator() : it_(nullptr) {} explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}