future-piece-c33967fcbc838e1a36e8ad7665d1b73177716e9d.patch 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. From c33967fcbc838e1a36e8ad7665d1b73177716e9d Mon Sep 17 00:00:00 2001
  2. From: Protobuf Team Bot <protobuf-github-bot@google.com>
  3. Date: Mon, 20 Nov 2023 04:18:49 -0800
  4. Subject: [PATCH] Add iterator_concept support.
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. This allows for better code generation in C++20 for algorithms that take advantage of random access vs contiguous data.
  9. ```
  10. name old INSTRUCTIONS/op new INSTRUCTIONS/op delta
  11. BM_RepeatedField_Sort 5.74k ± 0% 5.74k ± 0% -0.13% (p=0.000 n=179+183)
  12. BM_RepeatedField_ToVector 693 ± 0% 693 ± 0% ~ (p=0.153 n=93+91)
  13. BM_RepeatedPtrField_SortIndirect 562 ± 0% 559 ± 0% -0.53% (p=0.000 n=92+92)
  14. ```
  15. PiperOrigin-RevId: 583983215
  16. ---
  17. src/google/protobuf/BUILD.bazel | 1 +
  18. src/google/protobuf/repeated_field.h | 18 +++--
  19. .../protobuf/repeated_field_unittest.cc | 69 +++++++++++++++++++
  20. src/google/protobuf/repeated_ptr_field.h | 26 +++++--
  21. 4 files changed, 103 insertions(+), 11 deletions(-)
  22. diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
  23. index a3f77153289b..5351846558e6 100644
  24. --- a/src/google/protobuf/repeated_field.h
  25. +++ b/src/google/protobuf/repeated_field.h
  26. @@ -1035,14 +1035,18 @@ namespace internal {
  27. // the compiler isn't allowed to inline them.
  28. template <typename Element>
  29. class RepeatedIterator {
  30. + private:
  31. + using traits =
  32. + std::iterator_traits<typename std::remove_const<Element>::type*>;
  33. +
  34. public:
  35. - using iterator_category = std::random_access_iterator_tag;
  36. - // Note: remove_const is necessary for std::partial_sum, which uses value_type
  37. - // to determine the summation variable type.
  38. - using value_type = typename std::remove_const<Element>::type;
  39. - using difference_type = std::ptrdiff_t;
  40. + // Note: value_type is never cv-qualified.
  41. + using value_type = typename traits::value_type;
  42. + using difference_type = typename traits::difference_type;
  43. using pointer = Element*;
  44. using reference = Element&;
  45. + using iterator_category = typename traits::iterator_category;
  46. + using iterator_concept = typename IteratorConceptSupport<traits>::tag;
  47. constexpr RepeatedIterator() noexcept : it_(nullptr) {}
  48. @@ -1142,10 +1146,10 @@ class RepeatedIterator {
  49. // Allow construction from RepeatedField.
  50. friend class RepeatedField<value_type>;
  51. - explicit RepeatedIterator(Element* it) noexcept : it_(it) {}
  52. + explicit RepeatedIterator(pointer it) noexcept : it_(it) {}
  53. // The internal iterator.
  54. - Element* it_;
  55. + pointer it_;
  56. };
  57. // A back inserter for RepeatedField objects.
  58. diff --git a/src/google/protobuf/repeated_ptr_field.h b/src/google/protobuf/repeated_ptr_field.h
  59. index 64cdd1890e3c..7a57dfee134c 100644
  60. @@ -1852,6 +1853,17 @@ class RepeatedPtrIterator {
  61. void* const* it_;
  62. };
  63. +template <typename Traits, typename = void>
  64. +struct IteratorConceptSupport {
  65. + using tag = typename Traits::iterator_category;
  66. +};
  67. +
  68. +template <typename Traits>
  69. +struct IteratorConceptSupport<Traits,
  70. + std::void_t<typename Traits::iterator_concept>> {
  71. + using tag = typename Traits::iterator_concept;
  72. +};
  73. +
  74. // Provides an iterator that operates on pointers to the underlying objects
  75. // rather than the objects themselves as RepeatedPtrIterator does.
  76. // Consider using this when working with stl algorithms that change
  77. @@ -1861,13 +1873,19 @@ class RepeatedPtrIterator {
  78. // iterator, or "const void* const" for a constant iterator.
  79. template <typename Element, typename VoidPtr>
  80. class RepeatedPtrOverPtrsIterator {
  81. + private:
  82. + using traits =
  83. + std::iterator_traits<typename std::remove_const<Element>::type*>;
  84. +
  85. public:
  86. - using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>;
  87. - using iterator_category = std::random_access_iterator_tag;
  88. - using value_type = typename std::remove_const<Element>::type;
  89. - using difference_type = std::ptrdiff_t;
  90. + using value_type = typename traits::value_type;
  91. + using difference_type = typename traits::difference_type;
  92. using pointer = Element*;
  93. using reference = Element&;
  94. + using iterator_category = typename traits::iterator_category;
  95. + using iterator_concept = typename IteratorConceptSupport<traits>::tag;
  96. +
  97. + using iterator = RepeatedPtrOverPtrsIterator<Element, VoidPtr>;
  98. RepeatedPtrOverPtrsIterator() : it_(nullptr) {}
  99. explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {}