aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/protobuf/patches/future-piece-c33967fcbc838e1a36e8ad7665d1b73177716e9d.patch
blob: 29f4d9e075838c82601ddc781743f31459f63ed6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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) {}