xref: /aosp_15_r20/external/protobuf/src/google/protobuf/map.h (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
1*1b3f573fSAndroid Build Coastguard Worker // Protocol Buffers - Google's data interchange format
2*1b3f573fSAndroid Build Coastguard Worker // Copyright 2008 Google Inc.  All rights reserved.
3*1b3f573fSAndroid Build Coastguard Worker // https://developers.google.com/protocol-buffers/
4*1b3f573fSAndroid Build Coastguard Worker //
5*1b3f573fSAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without
6*1b3f573fSAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are
7*1b3f573fSAndroid Build Coastguard Worker // met:
8*1b3f573fSAndroid Build Coastguard Worker //
9*1b3f573fSAndroid Build Coastguard Worker //     * Redistributions of source code must retain the above copyright
10*1b3f573fSAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer.
11*1b3f573fSAndroid Build Coastguard Worker //     * Redistributions in binary form must reproduce the above
12*1b3f573fSAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer
13*1b3f573fSAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the
14*1b3f573fSAndroid Build Coastguard Worker // distribution.
15*1b3f573fSAndroid Build Coastguard Worker //     * Neither the name of Google Inc. nor the names of its
16*1b3f573fSAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from
17*1b3f573fSAndroid Build Coastguard Worker // this software without specific prior written permission.
18*1b3f573fSAndroid Build Coastguard Worker //
19*1b3f573fSAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*1b3f573fSAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*1b3f573fSAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*1b3f573fSAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*1b3f573fSAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*1b3f573fSAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*1b3f573fSAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*1b3f573fSAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*1b3f573fSAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*1b3f573fSAndroid Build Coastguard Worker 
31*1b3f573fSAndroid Build Coastguard Worker // This file defines the map container and its helpers to support protobuf maps.
32*1b3f573fSAndroid Build Coastguard Worker //
33*1b3f573fSAndroid Build Coastguard Worker // The Map and MapIterator types are provided by this header file.
34*1b3f573fSAndroid Build Coastguard Worker // Please avoid using other types defined here, unless they are public
35*1b3f573fSAndroid Build Coastguard Worker // types within Map or MapIterator, such as Map::value_type.
36*1b3f573fSAndroid Build Coastguard Worker 
37*1b3f573fSAndroid Build Coastguard Worker #ifndef GOOGLE_PROTOBUF_MAP_H__
38*1b3f573fSAndroid Build Coastguard Worker #define GOOGLE_PROTOBUF_MAP_H__
39*1b3f573fSAndroid Build Coastguard Worker 
40*1b3f573fSAndroid Build Coastguard Worker 
41*1b3f573fSAndroid Build Coastguard Worker #include <functional>
42*1b3f573fSAndroid Build Coastguard Worker #include <initializer_list>
43*1b3f573fSAndroid Build Coastguard Worker #include <iterator>
44*1b3f573fSAndroid Build Coastguard Worker #include <limits>  // To support Visual Studio 2008
45*1b3f573fSAndroid Build Coastguard Worker #include <map>
46*1b3f573fSAndroid Build Coastguard Worker #include <string>
47*1b3f573fSAndroid Build Coastguard Worker #include <type_traits>
48*1b3f573fSAndroid Build Coastguard Worker #include <utility>
49*1b3f573fSAndroid Build Coastguard Worker 
50*1b3f573fSAndroid Build Coastguard Worker #if defined(__cpp_lib_string_view)
51*1b3f573fSAndroid Build Coastguard Worker #include <string_view>
52*1b3f573fSAndroid Build Coastguard Worker #endif  // defined(__cpp_lib_string_view)
53*1b3f573fSAndroid Build Coastguard Worker 
54*1b3f573fSAndroid Build Coastguard Worker #if !defined(GOOGLE_PROTOBUF_NO_RDTSC) && defined(__APPLE__)
55*1b3f573fSAndroid Build Coastguard Worker #include <mach/mach_time.h>
56*1b3f573fSAndroid Build Coastguard Worker #endif
57*1b3f573fSAndroid Build Coastguard Worker 
58*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/stubs/common.h>
59*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/arena.h>
60*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/generated_enum_util.h>
61*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/map_type_handler.h>
62*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/port.h>
63*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/stubs/hash.h>
64*1b3f573fSAndroid Build Coastguard Worker 
65*1b3f573fSAndroid Build Coastguard Worker #ifdef SWIG
66*1b3f573fSAndroid Build Coastguard Worker #error "You cannot SWIG proto headers"
67*1b3f573fSAndroid Build Coastguard Worker #endif
68*1b3f573fSAndroid Build Coastguard Worker 
69*1b3f573fSAndroid Build Coastguard Worker // Must be included last.
70*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/port_def.inc>
71*1b3f573fSAndroid Build Coastguard Worker 
72*1b3f573fSAndroid Build Coastguard Worker namespace google {
73*1b3f573fSAndroid Build Coastguard Worker namespace protobuf {
74*1b3f573fSAndroid Build Coastguard Worker 
75*1b3f573fSAndroid Build Coastguard Worker template <typename Key, typename T>
76*1b3f573fSAndroid Build Coastguard Worker class Map;
77*1b3f573fSAndroid Build Coastguard Worker 
78*1b3f573fSAndroid Build Coastguard Worker class MapIterator;
79*1b3f573fSAndroid Build Coastguard Worker 
80*1b3f573fSAndroid Build Coastguard Worker template <typename Enum>
81*1b3f573fSAndroid Build Coastguard Worker struct is_proto_enum;
82*1b3f573fSAndroid Build Coastguard Worker 
83*1b3f573fSAndroid Build Coastguard Worker namespace internal {
84*1b3f573fSAndroid Build Coastguard Worker template <typename Derived, typename Key, typename T,
85*1b3f573fSAndroid Build Coastguard Worker           WireFormatLite::FieldType key_wire_type,
86*1b3f573fSAndroid Build Coastguard Worker           WireFormatLite::FieldType value_wire_type>
87*1b3f573fSAndroid Build Coastguard Worker class MapFieldLite;
88*1b3f573fSAndroid Build Coastguard Worker 
89*1b3f573fSAndroid Build Coastguard Worker template <typename Derived, typename Key, typename T,
90*1b3f573fSAndroid Build Coastguard Worker           WireFormatLite::FieldType key_wire_type,
91*1b3f573fSAndroid Build Coastguard Worker           WireFormatLite::FieldType value_wire_type>
92*1b3f573fSAndroid Build Coastguard Worker class MapField;
93*1b3f573fSAndroid Build Coastguard Worker 
94*1b3f573fSAndroid Build Coastguard Worker template <typename Key, typename T>
95*1b3f573fSAndroid Build Coastguard Worker class TypeDefinedMapFieldBase;
96*1b3f573fSAndroid Build Coastguard Worker 
97*1b3f573fSAndroid Build Coastguard Worker class DynamicMapField;
98*1b3f573fSAndroid Build Coastguard Worker 
99*1b3f573fSAndroid Build Coastguard Worker class GeneratedMessageReflection;
100*1b3f573fSAndroid Build Coastguard Worker 
101*1b3f573fSAndroid Build Coastguard Worker // re-implement std::allocator to use arena allocator for memory allocation.
102*1b3f573fSAndroid Build Coastguard Worker // Used for Map implementation. Users should not use this class
103*1b3f573fSAndroid Build Coastguard Worker // directly.
104*1b3f573fSAndroid Build Coastguard Worker template <typename U>
105*1b3f573fSAndroid Build Coastguard Worker class MapAllocator {
106*1b3f573fSAndroid Build Coastguard Worker  public:
107*1b3f573fSAndroid Build Coastguard Worker   using value_type = U;
108*1b3f573fSAndroid Build Coastguard Worker   using pointer = value_type*;
109*1b3f573fSAndroid Build Coastguard Worker   using const_pointer = const value_type*;
110*1b3f573fSAndroid Build Coastguard Worker   using reference = value_type&;
111*1b3f573fSAndroid Build Coastguard Worker   using const_reference = const value_type&;
112*1b3f573fSAndroid Build Coastguard Worker   using size_type = size_t;
113*1b3f573fSAndroid Build Coastguard Worker   using difference_type = ptrdiff_t;
114*1b3f573fSAndroid Build Coastguard Worker 
MapAllocator()115*1b3f573fSAndroid Build Coastguard Worker   constexpr MapAllocator() : arena_(nullptr) {}
MapAllocator(Arena * arena)116*1b3f573fSAndroid Build Coastguard Worker   explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {}
117*1b3f573fSAndroid Build Coastguard Worker   template <typename X>
MapAllocator(const MapAllocator<X> & allocator)118*1b3f573fSAndroid Build Coastguard Worker   MapAllocator(const MapAllocator<X>& allocator)  // NOLINT(runtime/explicit)
119*1b3f573fSAndroid Build Coastguard Worker       : arena_(allocator.arena()) {}
120*1b3f573fSAndroid Build Coastguard Worker 
121*1b3f573fSAndroid Build Coastguard Worker   // MapAllocator does not support alignments beyond 8. Technically we should
122*1b3f573fSAndroid Build Coastguard Worker   // support up to std::max_align_t, but this fails with ubsan and tcmalloc
123*1b3f573fSAndroid Build Coastguard Worker   // debug allocation logic which assume 8 as default alignment.
124*1b3f573fSAndroid Build Coastguard Worker   static_assert(alignof(value_type) <= 8, "");
125*1b3f573fSAndroid Build Coastguard Worker 
126*1b3f573fSAndroid Build Coastguard Worker   pointer allocate(size_type n, const void* /* hint */ = nullptr) {
127*1b3f573fSAndroid Build Coastguard Worker     // If arena is not given, malloc needs to be called which doesn't
128*1b3f573fSAndroid Build Coastguard Worker     // construct element object.
129*1b3f573fSAndroid Build Coastguard Worker     if (arena_ == nullptr) {
130*1b3f573fSAndroid Build Coastguard Worker       return static_cast<pointer>(::operator new(n * sizeof(value_type)));
131*1b3f573fSAndroid Build Coastguard Worker     } else {
132*1b3f573fSAndroid Build Coastguard Worker       return reinterpret_cast<pointer>(
133*1b3f573fSAndroid Build Coastguard Worker           Arena::CreateArray<uint8_t>(arena_, n * sizeof(value_type)));
134*1b3f573fSAndroid Build Coastguard Worker     }
135*1b3f573fSAndroid Build Coastguard Worker   }
136*1b3f573fSAndroid Build Coastguard Worker 
deallocate(pointer p,size_type n)137*1b3f573fSAndroid Build Coastguard Worker   void deallocate(pointer p, size_type n) {
138*1b3f573fSAndroid Build Coastguard Worker     if (arena_ == nullptr) {
139*1b3f573fSAndroid Build Coastguard Worker       internal::SizedDelete(p, n * sizeof(value_type));
140*1b3f573fSAndroid Build Coastguard Worker     }
141*1b3f573fSAndroid Build Coastguard Worker   }
142*1b3f573fSAndroid Build Coastguard Worker 
143*1b3f573fSAndroid Build Coastguard Worker #if !defined(GOOGLE_PROTOBUF_OS_APPLE) && !defined(GOOGLE_PROTOBUF_OS_NACL) && \
144*1b3f573fSAndroid Build Coastguard Worker     !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN)
145*1b3f573fSAndroid Build Coastguard Worker   template <class NodeType, class... Args>
construct(NodeType * p,Args &&...args)146*1b3f573fSAndroid Build Coastguard Worker   void construct(NodeType* p, Args&&... args) {
147*1b3f573fSAndroid Build Coastguard Worker     // Clang 3.6 doesn't compile static casting to void* directly. (Issue
148*1b3f573fSAndroid Build Coastguard Worker     // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall
149*1b3f573fSAndroid Build Coastguard Worker     // not cast away constness". So first the maybe const pointer is casted to
150*1b3f573fSAndroid Build Coastguard Worker     // const void* and after the const void* is const casted.
151*1b3f573fSAndroid Build Coastguard Worker     new (const_cast<void*>(static_cast<const void*>(p)))
152*1b3f573fSAndroid Build Coastguard Worker         NodeType(std::forward<Args>(args)...);
153*1b3f573fSAndroid Build Coastguard Worker   }
154*1b3f573fSAndroid Build Coastguard Worker 
155*1b3f573fSAndroid Build Coastguard Worker   template <class NodeType>
destroy(NodeType * p)156*1b3f573fSAndroid Build Coastguard Worker   void destroy(NodeType* p) {
157*1b3f573fSAndroid Build Coastguard Worker     p->~NodeType();
158*1b3f573fSAndroid Build Coastguard Worker   }
159*1b3f573fSAndroid Build Coastguard Worker #else
construct(pointer p,const_reference t)160*1b3f573fSAndroid Build Coastguard Worker   void construct(pointer p, const_reference t) { new (p) value_type(t); }
161*1b3f573fSAndroid Build Coastguard Worker 
destroy(pointer p)162*1b3f573fSAndroid Build Coastguard Worker   void destroy(pointer p) { p->~value_type(); }
163*1b3f573fSAndroid Build Coastguard Worker #endif
164*1b3f573fSAndroid Build Coastguard Worker 
165*1b3f573fSAndroid Build Coastguard Worker   template <typename X>
166*1b3f573fSAndroid Build Coastguard Worker   struct rebind {
167*1b3f573fSAndroid Build Coastguard Worker     using other = MapAllocator<X>;
168*1b3f573fSAndroid Build Coastguard Worker   };
169*1b3f573fSAndroid Build Coastguard Worker 
170*1b3f573fSAndroid Build Coastguard Worker   template <typename X>
171*1b3f573fSAndroid Build Coastguard Worker   bool operator==(const MapAllocator<X>& other) const {
172*1b3f573fSAndroid Build Coastguard Worker     return arena_ == other.arena_;
173*1b3f573fSAndroid Build Coastguard Worker   }
174*1b3f573fSAndroid Build Coastguard Worker 
175*1b3f573fSAndroid Build Coastguard Worker   template <typename X>
176*1b3f573fSAndroid Build Coastguard Worker   bool operator!=(const MapAllocator<X>& other) const {
177*1b3f573fSAndroid Build Coastguard Worker     return arena_ != other.arena_;
178*1b3f573fSAndroid Build Coastguard Worker   }
179*1b3f573fSAndroid Build Coastguard Worker 
180*1b3f573fSAndroid Build Coastguard Worker   // To support Visual Studio 2008
max_size()181*1b3f573fSAndroid Build Coastguard Worker   size_type max_size() const {
182*1b3f573fSAndroid Build Coastguard Worker     // parentheses around (std::...:max) prevents macro warning of max()
183*1b3f573fSAndroid Build Coastguard Worker     return (std::numeric_limits<size_type>::max)();
184*1b3f573fSAndroid Build Coastguard Worker   }
185*1b3f573fSAndroid Build Coastguard Worker 
186*1b3f573fSAndroid Build Coastguard Worker   // To support gcc-4.4, which does not properly
187*1b3f573fSAndroid Build Coastguard Worker   // support templated friend classes
arena()188*1b3f573fSAndroid Build Coastguard Worker   Arena* arena() const { return arena_; }
189*1b3f573fSAndroid Build Coastguard Worker 
190*1b3f573fSAndroid Build Coastguard Worker  private:
191*1b3f573fSAndroid Build Coastguard Worker   using DestructorSkippable_ = void;
192*1b3f573fSAndroid Build Coastguard Worker   Arena* arena_;
193*1b3f573fSAndroid Build Coastguard Worker };
194*1b3f573fSAndroid Build Coastguard Worker 
195*1b3f573fSAndroid Build Coastguard Worker template <typename T>
196*1b3f573fSAndroid Build Coastguard Worker using KeyForTree =
197*1b3f573fSAndroid Build Coastguard Worker     typename std::conditional<std::is_scalar<T>::value, T,
198*1b3f573fSAndroid Build Coastguard Worker                               std::reference_wrapper<const T>>::type;
199*1b3f573fSAndroid Build Coastguard Worker 
200*1b3f573fSAndroid Build Coastguard Worker // Default case: Not transparent.
201*1b3f573fSAndroid Build Coastguard Worker // We use std::hash<key_type>/std::less<key_type> and all the lookup functions
202*1b3f573fSAndroid Build Coastguard Worker // only accept `key_type`.
203*1b3f573fSAndroid Build Coastguard Worker template <typename key_type>
204*1b3f573fSAndroid Build Coastguard Worker struct TransparentSupport {
205*1b3f573fSAndroid Build Coastguard Worker   using hash = std::hash<key_type>;
206*1b3f573fSAndroid Build Coastguard Worker   using less = std::less<key_type>;
207*1b3f573fSAndroid Build Coastguard Worker 
EqualsTransparentSupport208*1b3f573fSAndroid Build Coastguard Worker   static bool Equals(const key_type& a, const key_type& b) { return a == b; }
209*1b3f573fSAndroid Build Coastguard Worker 
210*1b3f573fSAndroid Build Coastguard Worker   template <typename K>
211*1b3f573fSAndroid Build Coastguard Worker   using key_arg = key_type;
212*1b3f573fSAndroid Build Coastguard Worker };
213*1b3f573fSAndroid Build Coastguard Worker 
214*1b3f573fSAndroid Build Coastguard Worker #if defined(__cpp_lib_string_view)
215*1b3f573fSAndroid Build Coastguard Worker // If std::string_view is available, we add transparent support for std::string
216*1b3f573fSAndroid Build Coastguard Worker // keys. We use std::hash<std::string_view> as it supports the input types we
217*1b3f573fSAndroid Build Coastguard Worker // care about. The lookup functions accept arbitrary `K`. This will include any
218*1b3f573fSAndroid Build Coastguard Worker // key type that is convertible to std::string_view.
219*1b3f573fSAndroid Build Coastguard Worker template <>
220*1b3f573fSAndroid Build Coastguard Worker struct TransparentSupport<std::string> {
221*1b3f573fSAndroid Build Coastguard Worker   static std::string_view ImplicitConvert(std::string_view str) { return str; }
222*1b3f573fSAndroid Build Coastguard Worker   // If the element is not convertible to std::string_view, try to convert to
223*1b3f573fSAndroid Build Coastguard Worker   // std::string first.
224*1b3f573fSAndroid Build Coastguard Worker   // The template makes this overload lose resolution when both have the same
225*1b3f573fSAndroid Build Coastguard Worker   // rank otherwise.
226*1b3f573fSAndroid Build Coastguard Worker   template <typename = void>
227*1b3f573fSAndroid Build Coastguard Worker   static std::string_view ImplicitConvert(const std::string& str) {
228*1b3f573fSAndroid Build Coastguard Worker     return str;
229*1b3f573fSAndroid Build Coastguard Worker   }
230*1b3f573fSAndroid Build Coastguard Worker 
231*1b3f573fSAndroid Build Coastguard Worker   struct hash : private std::hash<std::string_view> {
232*1b3f573fSAndroid Build Coastguard Worker     using is_transparent = void;
233*1b3f573fSAndroid Build Coastguard Worker 
234*1b3f573fSAndroid Build Coastguard Worker     template <typename T>
235*1b3f573fSAndroid Build Coastguard Worker     size_t operator()(const T& str) const {
236*1b3f573fSAndroid Build Coastguard Worker       return base()(ImplicitConvert(str));
237*1b3f573fSAndroid Build Coastguard Worker     }
238*1b3f573fSAndroid Build Coastguard Worker 
239*1b3f573fSAndroid Build Coastguard Worker    private:
240*1b3f573fSAndroid Build Coastguard Worker     const std::hash<std::string_view>& base() const { return *this; }
241*1b3f573fSAndroid Build Coastguard Worker   };
242*1b3f573fSAndroid Build Coastguard Worker   struct less {
243*1b3f573fSAndroid Build Coastguard Worker     using is_transparent = void;
244*1b3f573fSAndroid Build Coastguard Worker 
245*1b3f573fSAndroid Build Coastguard Worker     template <typename T, typename U>
246*1b3f573fSAndroid Build Coastguard Worker     bool operator()(const T& t, const U& u) const {
247*1b3f573fSAndroid Build Coastguard Worker       return ImplicitConvert(t) < ImplicitConvert(u);
248*1b3f573fSAndroid Build Coastguard Worker     }
249*1b3f573fSAndroid Build Coastguard Worker   };
250*1b3f573fSAndroid Build Coastguard Worker 
251*1b3f573fSAndroid Build Coastguard Worker   template <typename T, typename U>
252*1b3f573fSAndroid Build Coastguard Worker   static bool Equals(const T& t, const U& u) {
253*1b3f573fSAndroid Build Coastguard Worker     return ImplicitConvert(t) == ImplicitConvert(u);
254*1b3f573fSAndroid Build Coastguard Worker   }
255*1b3f573fSAndroid Build Coastguard Worker 
256*1b3f573fSAndroid Build Coastguard Worker   template <typename K>
257*1b3f573fSAndroid Build Coastguard Worker   using key_arg = K;
258*1b3f573fSAndroid Build Coastguard Worker };
259*1b3f573fSAndroid Build Coastguard Worker #endif  // defined(__cpp_lib_string_view)
260*1b3f573fSAndroid Build Coastguard Worker 
261*1b3f573fSAndroid Build Coastguard Worker template <typename Key>
262*1b3f573fSAndroid Build Coastguard Worker using TreeForMap =
263*1b3f573fSAndroid Build Coastguard Worker     std::map<KeyForTree<Key>, void*, typename TransparentSupport<Key>::less,
264*1b3f573fSAndroid Build Coastguard Worker              MapAllocator<std::pair<const KeyForTree<Key>, void*>>>;
265*1b3f573fSAndroid Build Coastguard Worker 
266*1b3f573fSAndroid Build Coastguard Worker inline bool TableEntryIsEmpty(void* const* table, size_t b) {
267*1b3f573fSAndroid Build Coastguard Worker   return table[b] == nullptr;
268*1b3f573fSAndroid Build Coastguard Worker }
269*1b3f573fSAndroid Build Coastguard Worker inline bool TableEntryIsNonEmptyList(void* const* table, size_t b) {
270*1b3f573fSAndroid Build Coastguard Worker   return table[b] != nullptr && table[b] != table[b ^ 1];
271*1b3f573fSAndroid Build Coastguard Worker }
272*1b3f573fSAndroid Build Coastguard Worker inline bool TableEntryIsTree(void* const* table, size_t b) {
273*1b3f573fSAndroid Build Coastguard Worker   return !TableEntryIsEmpty(table, b) && !TableEntryIsNonEmptyList(table, b);
274*1b3f573fSAndroid Build Coastguard Worker }
275*1b3f573fSAndroid Build Coastguard Worker inline bool TableEntryIsList(void* const* table, size_t b) {
276*1b3f573fSAndroid Build Coastguard Worker   return !TableEntryIsTree(table, b);
277*1b3f573fSAndroid Build Coastguard Worker }
278*1b3f573fSAndroid Build Coastguard Worker 
279*1b3f573fSAndroid Build Coastguard Worker // This captures all numeric types.
280*1b3f573fSAndroid Build Coastguard Worker inline size_t MapValueSpaceUsedExcludingSelfLong(bool) { return 0; }
281*1b3f573fSAndroid Build Coastguard Worker inline size_t MapValueSpaceUsedExcludingSelfLong(const std::string& str) {
282*1b3f573fSAndroid Build Coastguard Worker   return StringSpaceUsedExcludingSelfLong(str);
283*1b3f573fSAndroid Build Coastguard Worker }
284*1b3f573fSAndroid Build Coastguard Worker template <typename T,
285*1b3f573fSAndroid Build Coastguard Worker           typename = decltype(std::declval<const T&>().SpaceUsedLong())>
286*1b3f573fSAndroid Build Coastguard Worker size_t MapValueSpaceUsedExcludingSelfLong(const T& message) {
287*1b3f573fSAndroid Build Coastguard Worker   return message.SpaceUsedLong() - sizeof(T);
288*1b3f573fSAndroid Build Coastguard Worker }
289*1b3f573fSAndroid Build Coastguard Worker 
290*1b3f573fSAndroid Build Coastguard Worker constexpr size_t kGlobalEmptyTableSize = 1;
291*1b3f573fSAndroid Build Coastguard Worker PROTOBUF_EXPORT extern void* const kGlobalEmptyTable[kGlobalEmptyTableSize];
292*1b3f573fSAndroid Build Coastguard Worker 
293*1b3f573fSAndroid Build Coastguard Worker // Space used for the table, trees, and nodes.
294*1b3f573fSAndroid Build Coastguard Worker // Does not include the indirect space used. Eg the data of a std::string.
295*1b3f573fSAndroid Build Coastguard Worker template <typename Key>
296*1b3f573fSAndroid Build Coastguard Worker PROTOBUF_NOINLINE size_t SpaceUsedInTable(void** table, size_t num_buckets,
297*1b3f573fSAndroid Build Coastguard Worker                                           size_t num_elements,
298*1b3f573fSAndroid Build Coastguard Worker                                           size_t sizeof_node) {
299*1b3f573fSAndroid Build Coastguard Worker   size_t size = 0;
300*1b3f573fSAndroid Build Coastguard Worker   // The size of the table.
301*1b3f573fSAndroid Build Coastguard Worker   size += sizeof(void*) * num_buckets;
302*1b3f573fSAndroid Build Coastguard Worker   // All the nodes.
303*1b3f573fSAndroid Build Coastguard Worker   size += sizeof_node * num_elements;
304*1b3f573fSAndroid Build Coastguard Worker   // For each tree, count the overhead of the those nodes.
305*1b3f573fSAndroid Build Coastguard Worker   // Two buckets at a time because we only care about trees.
306*1b3f573fSAndroid Build Coastguard Worker   for (size_t b = 0; b < num_buckets; b += 2) {
307*1b3f573fSAndroid Build Coastguard Worker     if (internal::TableEntryIsTree(table, b)) {
308*1b3f573fSAndroid Build Coastguard Worker       using Tree = TreeForMap<Key>;
309*1b3f573fSAndroid Build Coastguard Worker       Tree* tree = static_cast<Tree*>(table[b]);
310*1b3f573fSAndroid Build Coastguard Worker       // Estimated cost of the red-black tree nodes, 3 pointers plus a
311*1b3f573fSAndroid Build Coastguard Worker       // bool (plus alignment, so 4 pointers).
312*1b3f573fSAndroid Build Coastguard Worker       size += tree->size() *
313*1b3f573fSAndroid Build Coastguard Worker               (sizeof(typename Tree::value_type) + sizeof(void*) * 4);
314*1b3f573fSAndroid Build Coastguard Worker     }
315*1b3f573fSAndroid Build Coastguard Worker   }
316*1b3f573fSAndroid Build Coastguard Worker   return size;
317*1b3f573fSAndroid Build Coastguard Worker }
318*1b3f573fSAndroid Build Coastguard Worker 
319*1b3f573fSAndroid Build Coastguard Worker template <typename Map,
320*1b3f573fSAndroid Build Coastguard Worker           typename = typename std::enable_if<
321*1b3f573fSAndroid Build Coastguard Worker               !std::is_scalar<typename Map::key_type>::value ||
322*1b3f573fSAndroid Build Coastguard Worker               !std::is_scalar<typename Map::mapped_type>::value>::type>
323*1b3f573fSAndroid Build Coastguard Worker size_t SpaceUsedInValues(const Map* map) {
324*1b3f573fSAndroid Build Coastguard Worker   size_t size = 0;
325*1b3f573fSAndroid Build Coastguard Worker   for (const auto& v : *map) {
326*1b3f573fSAndroid Build Coastguard Worker     size += internal::MapValueSpaceUsedExcludingSelfLong(v.first) +
327*1b3f573fSAndroid Build Coastguard Worker             internal::MapValueSpaceUsedExcludingSelfLong(v.second);
328*1b3f573fSAndroid Build Coastguard Worker   }
329*1b3f573fSAndroid Build Coastguard Worker   return size;
330*1b3f573fSAndroid Build Coastguard Worker }
331*1b3f573fSAndroid Build Coastguard Worker 
332*1b3f573fSAndroid Build Coastguard Worker inline size_t SpaceUsedInValues(const void*) { return 0; }
333*1b3f573fSAndroid Build Coastguard Worker 
334*1b3f573fSAndroid Build Coastguard Worker // Multiply two numbers where overflow is expected.
335*1b3f573fSAndroid Build Coastguard Worker template <typename N>
336*1b3f573fSAndroid Build Coastguard Worker N MultiplyWithOverflow(N a, N b) {
337*1b3f573fSAndroid Build Coastguard Worker #if __has_builtin(__builtin_mul_overflow)
338*1b3f573fSAndroid Build Coastguard Worker   N res;
339*1b3f573fSAndroid Build Coastguard Worker   (void)__builtin_mul_overflow(a, b, &res);
340*1b3f573fSAndroid Build Coastguard Worker   return res;
341*1b3f573fSAndroid Build Coastguard Worker #else
342*1b3f573fSAndroid Build Coastguard Worker   return a * b;
343*1b3f573fSAndroid Build Coastguard Worker #endif
344*1b3f573fSAndroid Build Coastguard Worker }
345*1b3f573fSAndroid Build Coastguard Worker 
346*1b3f573fSAndroid Build Coastguard Worker }  // namespace internal
347*1b3f573fSAndroid Build Coastguard Worker 
348*1b3f573fSAndroid Build Coastguard Worker // This is the class for Map's internal value_type. Instead of using
349*1b3f573fSAndroid Build Coastguard Worker // std::pair as value_type, we use this class which provides us more control of
350*1b3f573fSAndroid Build Coastguard Worker // its process of construction and destruction.
351*1b3f573fSAndroid Build Coastguard Worker template <typename Key, typename T>
352*1b3f573fSAndroid Build Coastguard Worker struct PROTOBUF_ATTRIBUTE_STANDALONE_DEBUG MapPair {
353*1b3f573fSAndroid Build Coastguard Worker   using first_type = const Key;
354*1b3f573fSAndroid Build Coastguard Worker   using second_type = T;
355*1b3f573fSAndroid Build Coastguard Worker 
356*1b3f573fSAndroid Build Coastguard Worker   MapPair(const Key& other_first, const T& other_second)
357*1b3f573fSAndroid Build Coastguard Worker       : first(other_first), second(other_second) {}
358*1b3f573fSAndroid Build Coastguard Worker   explicit MapPair(const Key& other_first) : first(other_first), second() {}
359*1b3f573fSAndroid Build Coastguard Worker   explicit MapPair(Key&& other_first)
360*1b3f573fSAndroid Build Coastguard Worker       : first(std::move(other_first)), second() {}
361*1b3f573fSAndroid Build Coastguard Worker   MapPair(const MapPair& other) : first(other.first), second(other.second) {}
362*1b3f573fSAndroid Build Coastguard Worker 
363*1b3f573fSAndroid Build Coastguard Worker   ~MapPair() {}
364*1b3f573fSAndroid Build Coastguard Worker 
365*1b3f573fSAndroid Build Coastguard Worker   // Implicitly convertible to std::pair of compatible types.
366*1b3f573fSAndroid Build Coastguard Worker   template <typename T1, typename T2>
367*1b3f573fSAndroid Build Coastguard Worker   operator std::pair<T1, T2>() const {  // NOLINT(runtime/explicit)
368*1b3f573fSAndroid Build Coastguard Worker     return std::pair<T1, T2>(first, second);
369*1b3f573fSAndroid Build Coastguard Worker   }
370*1b3f573fSAndroid Build Coastguard Worker 
371*1b3f573fSAndroid Build Coastguard Worker   const Key first;
372*1b3f573fSAndroid Build Coastguard Worker   T second;
373*1b3f573fSAndroid Build Coastguard Worker 
374*1b3f573fSAndroid Build Coastguard Worker  private:
375*1b3f573fSAndroid Build Coastguard Worker   friend class Arena;
376*1b3f573fSAndroid Build Coastguard Worker   friend class Map<Key, T>;
377*1b3f573fSAndroid Build Coastguard Worker };
378*1b3f573fSAndroid Build Coastguard Worker 
379*1b3f573fSAndroid Build Coastguard Worker // Map is an associative container type used to store protobuf map
380*1b3f573fSAndroid Build Coastguard Worker // fields.  Each Map instance may or may not use a different hash function, a
381*1b3f573fSAndroid Build Coastguard Worker // different iteration order, and so on.  E.g., please don't examine
382*1b3f573fSAndroid Build Coastguard Worker // implementation details to decide if the following would work:
383*1b3f573fSAndroid Build Coastguard Worker //  Map<int, int> m0, m1;
384*1b3f573fSAndroid Build Coastguard Worker //  m0[0] = m1[0] = m0[1] = m1[1] = 0;
385*1b3f573fSAndroid Build Coastguard Worker //  assert(m0.begin()->first == m1.begin()->first);  // Bug!
386*1b3f573fSAndroid Build Coastguard Worker //
387*1b3f573fSAndroid Build Coastguard Worker // Map's interface is similar to std::unordered_map, except that Map is not
388*1b3f573fSAndroid Build Coastguard Worker // designed to play well with exceptions.
389*1b3f573fSAndroid Build Coastguard Worker template <typename Key, typename T>
390*1b3f573fSAndroid Build Coastguard Worker class Map {
391*1b3f573fSAndroid Build Coastguard Worker  public:
392*1b3f573fSAndroid Build Coastguard Worker   using key_type = Key;
393*1b3f573fSAndroid Build Coastguard Worker   using mapped_type = T;
394*1b3f573fSAndroid Build Coastguard Worker   using value_type = MapPair<Key, T>;
395*1b3f573fSAndroid Build Coastguard Worker 
396*1b3f573fSAndroid Build Coastguard Worker   using pointer = value_type*;
397*1b3f573fSAndroid Build Coastguard Worker   using const_pointer = const value_type*;
398*1b3f573fSAndroid Build Coastguard Worker   using reference = value_type&;
399*1b3f573fSAndroid Build Coastguard Worker   using const_reference = const value_type&;
400*1b3f573fSAndroid Build Coastguard Worker 
401*1b3f573fSAndroid Build Coastguard Worker   using size_type = size_t;
402*1b3f573fSAndroid Build Coastguard Worker   using hasher = typename internal::TransparentSupport<Key>::hash;
403*1b3f573fSAndroid Build Coastguard Worker 
404*1b3f573fSAndroid Build Coastguard Worker   constexpr Map() : elements_(nullptr) {}
405*1b3f573fSAndroid Build Coastguard Worker   explicit Map(Arena* arena) : elements_(arena) {}
406*1b3f573fSAndroid Build Coastguard Worker 
407*1b3f573fSAndroid Build Coastguard Worker   Map(const Map& other) : Map() { insert(other.begin(), other.end()); }
408*1b3f573fSAndroid Build Coastguard Worker 
409*1b3f573fSAndroid Build Coastguard Worker   Map(Map&& other) noexcept : Map() {
410*1b3f573fSAndroid Build Coastguard Worker     if (other.arena() != nullptr) {
411*1b3f573fSAndroid Build Coastguard Worker       *this = other;
412*1b3f573fSAndroid Build Coastguard Worker     } else {
413*1b3f573fSAndroid Build Coastguard Worker       swap(other);
414*1b3f573fSAndroid Build Coastguard Worker     }
415*1b3f573fSAndroid Build Coastguard Worker   }
416*1b3f573fSAndroid Build Coastguard Worker 
417*1b3f573fSAndroid Build Coastguard Worker   Map& operator=(Map&& other) noexcept {
418*1b3f573fSAndroid Build Coastguard Worker     if (this != &other) {
419*1b3f573fSAndroid Build Coastguard Worker       if (arena() != other.arena()) {
420*1b3f573fSAndroid Build Coastguard Worker         *this = other;
421*1b3f573fSAndroid Build Coastguard Worker       } else {
422*1b3f573fSAndroid Build Coastguard Worker         swap(other);
423*1b3f573fSAndroid Build Coastguard Worker       }
424*1b3f573fSAndroid Build Coastguard Worker     }
425*1b3f573fSAndroid Build Coastguard Worker     return *this;
426*1b3f573fSAndroid Build Coastguard Worker   }
427*1b3f573fSAndroid Build Coastguard Worker 
428*1b3f573fSAndroid Build Coastguard Worker   template <class InputIt>
429*1b3f573fSAndroid Build Coastguard Worker   Map(const InputIt& first, const InputIt& last) : Map() {
430*1b3f573fSAndroid Build Coastguard Worker     insert(first, last);
431*1b3f573fSAndroid Build Coastguard Worker   }
432*1b3f573fSAndroid Build Coastguard Worker 
433*1b3f573fSAndroid Build Coastguard Worker   ~Map() {}
434*1b3f573fSAndroid Build Coastguard Worker 
435*1b3f573fSAndroid Build Coastguard Worker  private:
436*1b3f573fSAndroid Build Coastguard Worker   using Allocator = internal::MapAllocator<void*>;
437*1b3f573fSAndroid Build Coastguard Worker 
438*1b3f573fSAndroid Build Coastguard Worker   // InnerMap is a generic hash-based map.  It doesn't contain any
439*1b3f573fSAndroid Build Coastguard Worker   // protocol-buffer-specific logic.  It is a chaining hash map with the
440*1b3f573fSAndroid Build Coastguard Worker   // additional feature that some buckets can be converted to use an ordered
441*1b3f573fSAndroid Build Coastguard Worker   // container.  This ensures O(lg n) bounds on find, insert, and erase, while
442*1b3f573fSAndroid Build Coastguard Worker   // avoiding the overheads of ordered containers most of the time.
443*1b3f573fSAndroid Build Coastguard Worker   //
444*1b3f573fSAndroid Build Coastguard Worker   // The implementation doesn't need the full generality of unordered_map,
445*1b3f573fSAndroid Build Coastguard Worker   // and it doesn't have it.  More bells and whistles can be added as needed.
446*1b3f573fSAndroid Build Coastguard Worker   // Some implementation details:
447*1b3f573fSAndroid Build Coastguard Worker   // 1. The hash function has type hasher and the equality function
448*1b3f573fSAndroid Build Coastguard Worker   //    equal_to<Key>.  We inherit from hasher to save space
449*1b3f573fSAndroid Build Coastguard Worker   //    (empty-base-class optimization).
450*1b3f573fSAndroid Build Coastguard Worker   // 2. The number of buckets is a power of two.
451*1b3f573fSAndroid Build Coastguard Worker   // 3. Buckets are converted to trees in pairs: if we convert bucket b then
452*1b3f573fSAndroid Build Coastguard Worker   //    buckets b and b^1 will share a tree.  Invariant: buckets b and b^1 have
453*1b3f573fSAndroid Build Coastguard Worker   //    the same non-null value iff they are sharing a tree.  (An alternative
454*1b3f573fSAndroid Build Coastguard Worker   //    implementation strategy would be to have a tag bit per bucket.)
455*1b3f573fSAndroid Build Coastguard Worker   // 4. As is typical for hash_map and such, the Keys and Values are always
456*1b3f573fSAndroid Build Coastguard Worker   //    stored in linked list nodes.  Pointers to elements are never invalidated
457*1b3f573fSAndroid Build Coastguard Worker   //    until the element is deleted.
458*1b3f573fSAndroid Build Coastguard Worker   // 5. The trees' payload type is pointer to linked-list node.  Tree-converting
459*1b3f573fSAndroid Build Coastguard Worker   //    a bucket doesn't copy Key-Value pairs.
460*1b3f573fSAndroid Build Coastguard Worker   // 6. Once we've tree-converted a bucket, it is never converted back. However,
461*1b3f573fSAndroid Build Coastguard Worker   //    the items a tree contains may wind up assigned to trees or lists upon a
462*1b3f573fSAndroid Build Coastguard Worker   //    rehash.
463*1b3f573fSAndroid Build Coastguard Worker   // 7. The code requires no C++ features from C++14 or later.
464*1b3f573fSAndroid Build Coastguard Worker   // 8. Mutations to a map do not invalidate the map's iterators, pointers to
465*1b3f573fSAndroid Build Coastguard Worker   //    elements, or references to elements.
466*1b3f573fSAndroid Build Coastguard Worker   // 9. Except for erase(iterator), any non-const method can reorder iterators.
467*1b3f573fSAndroid Build Coastguard Worker   // 10. InnerMap uses KeyForTree<Key> when using the Tree representation, which
468*1b3f573fSAndroid Build Coastguard Worker   //    is either `Key`, if Key is a scalar, or `reference_wrapper<const Key>`
469*1b3f573fSAndroid Build Coastguard Worker   //    otherwise. This avoids unnecessary copies of string keys, for example.
470*1b3f573fSAndroid Build Coastguard Worker   class InnerMap : private hasher {
471*1b3f573fSAndroid Build Coastguard Worker    public:
472*1b3f573fSAndroid Build Coastguard Worker     explicit constexpr InnerMap(Arena* arena)
473*1b3f573fSAndroid Build Coastguard Worker         : hasher(),
474*1b3f573fSAndroid Build Coastguard Worker           num_elements_(0),
475*1b3f573fSAndroid Build Coastguard Worker           num_buckets_(internal::kGlobalEmptyTableSize),
476*1b3f573fSAndroid Build Coastguard Worker           seed_(0),
477*1b3f573fSAndroid Build Coastguard Worker           index_of_first_non_null_(internal::kGlobalEmptyTableSize),
478*1b3f573fSAndroid Build Coastguard Worker           table_(const_cast<void**>(internal::kGlobalEmptyTable)),
479*1b3f573fSAndroid Build Coastguard Worker           alloc_(arena) {}
480*1b3f573fSAndroid Build Coastguard Worker 
481*1b3f573fSAndroid Build Coastguard Worker     ~InnerMap() {
482*1b3f573fSAndroid Build Coastguard Worker       if (alloc_.arena() == nullptr &&
483*1b3f573fSAndroid Build Coastguard Worker           num_buckets_ != internal::kGlobalEmptyTableSize) {
484*1b3f573fSAndroid Build Coastguard Worker         clear();
485*1b3f573fSAndroid Build Coastguard Worker         Dealloc<void*>(table_, num_buckets_);
486*1b3f573fSAndroid Build Coastguard Worker       }
487*1b3f573fSAndroid Build Coastguard Worker     }
488*1b3f573fSAndroid Build Coastguard Worker 
489*1b3f573fSAndroid Build Coastguard Worker    private:
490*1b3f573fSAndroid Build Coastguard Worker     enum { kMinTableSize = 8 };
491*1b3f573fSAndroid Build Coastguard Worker 
492*1b3f573fSAndroid Build Coastguard Worker     // Linked-list nodes, as one would expect for a chaining hash table.
493*1b3f573fSAndroid Build Coastguard Worker     struct Node {
494*1b3f573fSAndroid Build Coastguard Worker       value_type kv;
495*1b3f573fSAndroid Build Coastguard Worker       Node* next;
496*1b3f573fSAndroid Build Coastguard Worker     };
497*1b3f573fSAndroid Build Coastguard Worker 
498*1b3f573fSAndroid Build Coastguard Worker     // Trees. The payload type is a copy of Key, so that we can query the tree
499*1b3f573fSAndroid Build Coastguard Worker     // with Keys that are not in any particular data structure.
500*1b3f573fSAndroid Build Coastguard Worker     // The value is a void* pointing to Node. We use void* instead of Node* to
501*1b3f573fSAndroid Build Coastguard Worker     // avoid code bloat. That way there is only one instantiation of the tree
502*1b3f573fSAndroid Build Coastguard Worker     // class per key type.
503*1b3f573fSAndroid Build Coastguard Worker     using Tree = internal::TreeForMap<Key>;
504*1b3f573fSAndroid Build Coastguard Worker     using TreeIterator = typename Tree::iterator;
505*1b3f573fSAndroid Build Coastguard Worker 
506*1b3f573fSAndroid Build Coastguard Worker     static Node* NodeFromTreeIterator(TreeIterator it) {
507*1b3f573fSAndroid Build Coastguard Worker       return static_cast<Node*>(it->second);
508*1b3f573fSAndroid Build Coastguard Worker     }
509*1b3f573fSAndroid Build Coastguard Worker 
510*1b3f573fSAndroid Build Coastguard Worker     // iterator and const_iterator are instantiations of iterator_base.
511*1b3f573fSAndroid Build Coastguard Worker     template <typename KeyValueType>
512*1b3f573fSAndroid Build Coastguard Worker     class iterator_base {
513*1b3f573fSAndroid Build Coastguard Worker      public:
514*1b3f573fSAndroid Build Coastguard Worker       using reference = KeyValueType&;
515*1b3f573fSAndroid Build Coastguard Worker       using pointer = KeyValueType*;
516*1b3f573fSAndroid Build Coastguard Worker 
517*1b3f573fSAndroid Build Coastguard Worker       // Invariants:
518*1b3f573fSAndroid Build Coastguard Worker       // node_ is always correct. This is handy because the most common
519*1b3f573fSAndroid Build Coastguard Worker       // operations are operator* and operator-> and they only use node_.
520*1b3f573fSAndroid Build Coastguard Worker       // When node_ is set to a non-null value, all the other non-const fields
521*1b3f573fSAndroid Build Coastguard Worker       // are updated to be correct also, but those fields can become stale
522*1b3f573fSAndroid Build Coastguard Worker       // if the underlying map is modified.  When those fields are needed they
523*1b3f573fSAndroid Build Coastguard Worker       // are rechecked, and updated if necessary.
524*1b3f573fSAndroid Build Coastguard Worker       iterator_base() : node_(nullptr), m_(nullptr), bucket_index_(0) {}
525*1b3f573fSAndroid Build Coastguard Worker 
526*1b3f573fSAndroid Build Coastguard Worker       explicit iterator_base(const InnerMap* m) : m_(m) {
527*1b3f573fSAndroid Build Coastguard Worker         SearchFrom(m->index_of_first_non_null_);
528*1b3f573fSAndroid Build Coastguard Worker       }
529*1b3f573fSAndroid Build Coastguard Worker 
530*1b3f573fSAndroid Build Coastguard Worker       // Any iterator_base can convert to any other.  This is overkill, and we
531*1b3f573fSAndroid Build Coastguard Worker       // rely on the enclosing class to use it wisely.  The standard "iterator
532*1b3f573fSAndroid Build Coastguard Worker       // can convert to const_iterator" is OK but the reverse direction is not.
533*1b3f573fSAndroid Build Coastguard Worker       template <typename U>
534*1b3f573fSAndroid Build Coastguard Worker       explicit iterator_base(const iterator_base<U>& it)
535*1b3f573fSAndroid Build Coastguard Worker           : node_(it.node_), m_(it.m_), bucket_index_(it.bucket_index_) {}
536*1b3f573fSAndroid Build Coastguard Worker 
537*1b3f573fSAndroid Build Coastguard Worker       iterator_base(Node* n, const InnerMap* m, size_type index)
538*1b3f573fSAndroid Build Coastguard Worker           : node_(n), m_(m), bucket_index_(index) {}
539*1b3f573fSAndroid Build Coastguard Worker 
540*1b3f573fSAndroid Build Coastguard Worker       iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index)
541*1b3f573fSAndroid Build Coastguard Worker           : node_(NodeFromTreeIterator(tree_it)), m_(m), bucket_index_(index) {
542*1b3f573fSAndroid Build Coastguard Worker         // Invariant: iterators that use buckets with trees have an even
543*1b3f573fSAndroid Build Coastguard Worker         // bucket_index_.
544*1b3f573fSAndroid Build Coastguard Worker         GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0u);
545*1b3f573fSAndroid Build Coastguard Worker       }
546*1b3f573fSAndroid Build Coastguard Worker 
547*1b3f573fSAndroid Build Coastguard Worker       // Advance through buckets, looking for the first that isn't empty.
548*1b3f573fSAndroid Build Coastguard Worker       // If nothing non-empty is found then leave node_ == nullptr.
549*1b3f573fSAndroid Build Coastguard Worker       void SearchFrom(size_type start_bucket) {
550*1b3f573fSAndroid Build Coastguard Worker         GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ ||
551*1b3f573fSAndroid Build Coastguard Worker                m_->table_[m_->index_of_first_non_null_] != nullptr);
552*1b3f573fSAndroid Build Coastguard Worker         node_ = nullptr;
553*1b3f573fSAndroid Build Coastguard Worker         for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_;
554*1b3f573fSAndroid Build Coastguard Worker              bucket_index_++) {
555*1b3f573fSAndroid Build Coastguard Worker           if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
556*1b3f573fSAndroid Build Coastguard Worker             node_ = static_cast<Node*>(m_->table_[bucket_index_]);
557*1b3f573fSAndroid Build Coastguard Worker             break;
558*1b3f573fSAndroid Build Coastguard Worker           } else if (m_->TableEntryIsTree(bucket_index_)) {
559*1b3f573fSAndroid Build Coastguard Worker             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
560*1b3f573fSAndroid Build Coastguard Worker             GOOGLE_DCHECK(!tree->empty());
561*1b3f573fSAndroid Build Coastguard Worker             node_ = NodeFromTreeIterator(tree->begin());
562*1b3f573fSAndroid Build Coastguard Worker             break;
563*1b3f573fSAndroid Build Coastguard Worker           }
564*1b3f573fSAndroid Build Coastguard Worker         }
565*1b3f573fSAndroid Build Coastguard Worker       }
566*1b3f573fSAndroid Build Coastguard Worker 
567*1b3f573fSAndroid Build Coastguard Worker       reference operator*() const { return node_->kv; }
568*1b3f573fSAndroid Build Coastguard Worker       pointer operator->() const { return &(operator*()); }
569*1b3f573fSAndroid Build Coastguard Worker 
570*1b3f573fSAndroid Build Coastguard Worker       friend bool operator==(const iterator_base& a, const iterator_base& b) {
571*1b3f573fSAndroid Build Coastguard Worker         return a.node_ == b.node_;
572*1b3f573fSAndroid Build Coastguard Worker       }
573*1b3f573fSAndroid Build Coastguard Worker       friend bool operator!=(const iterator_base& a, const iterator_base& b) {
574*1b3f573fSAndroid Build Coastguard Worker         return a.node_ != b.node_;
575*1b3f573fSAndroid Build Coastguard Worker       }
576*1b3f573fSAndroid Build Coastguard Worker 
577*1b3f573fSAndroid Build Coastguard Worker       iterator_base& operator++() {
578*1b3f573fSAndroid Build Coastguard Worker         if (node_->next == nullptr) {
579*1b3f573fSAndroid Build Coastguard Worker           TreeIterator tree_it;
580*1b3f573fSAndroid Build Coastguard Worker           const bool is_list = revalidate_if_necessary(&tree_it);
581*1b3f573fSAndroid Build Coastguard Worker           if (is_list) {
582*1b3f573fSAndroid Build Coastguard Worker             SearchFrom(bucket_index_ + 1);
583*1b3f573fSAndroid Build Coastguard Worker           } else {
584*1b3f573fSAndroid Build Coastguard Worker             GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0u);
585*1b3f573fSAndroid Build Coastguard Worker             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
586*1b3f573fSAndroid Build Coastguard Worker             if (++tree_it == tree->end()) {
587*1b3f573fSAndroid Build Coastguard Worker               SearchFrom(bucket_index_ + 2);
588*1b3f573fSAndroid Build Coastguard Worker             } else {
589*1b3f573fSAndroid Build Coastguard Worker               node_ = NodeFromTreeIterator(tree_it);
590*1b3f573fSAndroid Build Coastguard Worker             }
591*1b3f573fSAndroid Build Coastguard Worker           }
592*1b3f573fSAndroid Build Coastguard Worker         } else {
593*1b3f573fSAndroid Build Coastguard Worker           node_ = node_->next;
594*1b3f573fSAndroid Build Coastguard Worker         }
595*1b3f573fSAndroid Build Coastguard Worker         return *this;
596*1b3f573fSAndroid Build Coastguard Worker       }
597*1b3f573fSAndroid Build Coastguard Worker 
598*1b3f573fSAndroid Build Coastguard Worker       iterator_base operator++(int /* unused */) {
599*1b3f573fSAndroid Build Coastguard Worker         iterator_base tmp = *this;
600*1b3f573fSAndroid Build Coastguard Worker         ++*this;
601*1b3f573fSAndroid Build Coastguard Worker         return tmp;
602*1b3f573fSAndroid Build Coastguard Worker       }
603*1b3f573fSAndroid Build Coastguard Worker 
604*1b3f573fSAndroid Build Coastguard Worker       // Assumes node_ and m_ are correct and non-null, but other fields may be
605*1b3f573fSAndroid Build Coastguard Worker       // stale.  Fix them as needed.  Then return true iff node_ points to a
606*1b3f573fSAndroid Build Coastguard Worker       // Node in a list.  If false is returned then *it is modified to be
607*1b3f573fSAndroid Build Coastguard Worker       // a valid iterator for node_.
608*1b3f573fSAndroid Build Coastguard Worker       bool revalidate_if_necessary(TreeIterator* it) {
609*1b3f573fSAndroid Build Coastguard Worker         GOOGLE_DCHECK(node_ != nullptr && m_ != nullptr);
610*1b3f573fSAndroid Build Coastguard Worker         // Force bucket_index_ to be in range.
611*1b3f573fSAndroid Build Coastguard Worker         bucket_index_ &= (m_->num_buckets_ - 1);
612*1b3f573fSAndroid Build Coastguard Worker         // Common case: the bucket we think is relevant points to node_.
613*1b3f573fSAndroid Build Coastguard Worker         if (m_->table_[bucket_index_] == static_cast<void*>(node_)) return true;
614*1b3f573fSAndroid Build Coastguard Worker         // Less common: the bucket is a linked list with node_ somewhere in it,
615*1b3f573fSAndroid Build Coastguard Worker         // but not at the head.
616*1b3f573fSAndroid Build Coastguard Worker         if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
617*1b3f573fSAndroid Build Coastguard Worker           Node* l = static_cast<Node*>(m_->table_[bucket_index_]);
618*1b3f573fSAndroid Build Coastguard Worker           while ((l = l->next) != nullptr) {
619*1b3f573fSAndroid Build Coastguard Worker             if (l == node_) {
620*1b3f573fSAndroid Build Coastguard Worker               return true;
621*1b3f573fSAndroid Build Coastguard Worker             }
622*1b3f573fSAndroid Build Coastguard Worker           }
623*1b3f573fSAndroid Build Coastguard Worker         }
624*1b3f573fSAndroid Build Coastguard Worker         // Well, bucket_index_ still might be correct, but probably
625*1b3f573fSAndroid Build Coastguard Worker         // not.  Revalidate just to be sure.  This case is rare enough that we
626*1b3f573fSAndroid Build Coastguard Worker         // don't worry about potential optimizations, such as having a custom
627*1b3f573fSAndroid Build Coastguard Worker         // find-like method that compares Node* instead of the key.
628*1b3f573fSAndroid Build Coastguard Worker         iterator_base i(m_->find(node_->kv.first, it));
629*1b3f573fSAndroid Build Coastguard Worker         bucket_index_ = i.bucket_index_;
630*1b3f573fSAndroid Build Coastguard Worker         return m_->TableEntryIsList(bucket_index_);
631*1b3f573fSAndroid Build Coastguard Worker       }
632*1b3f573fSAndroid Build Coastguard Worker 
633*1b3f573fSAndroid Build Coastguard Worker       Node* node_;
634*1b3f573fSAndroid Build Coastguard Worker       const InnerMap* m_;
635*1b3f573fSAndroid Build Coastguard Worker       size_type bucket_index_;
636*1b3f573fSAndroid Build Coastguard Worker     };
637*1b3f573fSAndroid Build Coastguard Worker 
638*1b3f573fSAndroid Build Coastguard Worker    public:
639*1b3f573fSAndroid Build Coastguard Worker     using iterator = iterator_base<value_type>;
640*1b3f573fSAndroid Build Coastguard Worker     using const_iterator = iterator_base<const value_type>;
641*1b3f573fSAndroid Build Coastguard Worker 
642*1b3f573fSAndroid Build Coastguard Worker     Arena* arena() const { return alloc_.arena(); }
643*1b3f573fSAndroid Build Coastguard Worker 
644*1b3f573fSAndroid Build Coastguard Worker     void Swap(InnerMap* other) {
645*1b3f573fSAndroid Build Coastguard Worker       std::swap(num_elements_, other->num_elements_);
646*1b3f573fSAndroid Build Coastguard Worker       std::swap(num_buckets_, other->num_buckets_);
647*1b3f573fSAndroid Build Coastguard Worker       std::swap(seed_, other->seed_);
648*1b3f573fSAndroid Build Coastguard Worker       std::swap(index_of_first_non_null_, other->index_of_first_non_null_);
649*1b3f573fSAndroid Build Coastguard Worker       std::swap(table_, other->table_);
650*1b3f573fSAndroid Build Coastguard Worker       std::swap(alloc_, other->alloc_);
651*1b3f573fSAndroid Build Coastguard Worker     }
652*1b3f573fSAndroid Build Coastguard Worker 
653*1b3f573fSAndroid Build Coastguard Worker     iterator begin() { return iterator(this); }
654*1b3f573fSAndroid Build Coastguard Worker     iterator end() { return iterator(); }
655*1b3f573fSAndroid Build Coastguard Worker     const_iterator begin() const { return const_iterator(this); }
656*1b3f573fSAndroid Build Coastguard Worker     const_iterator end() const { return const_iterator(); }
657*1b3f573fSAndroid Build Coastguard Worker 
658*1b3f573fSAndroid Build Coastguard Worker     void clear() {
659*1b3f573fSAndroid Build Coastguard Worker       for (size_type b = 0; b < num_buckets_; b++) {
660*1b3f573fSAndroid Build Coastguard Worker         if (TableEntryIsNonEmptyList(b)) {
661*1b3f573fSAndroid Build Coastguard Worker           Node* node = static_cast<Node*>(table_[b]);
662*1b3f573fSAndroid Build Coastguard Worker           table_[b] = nullptr;
663*1b3f573fSAndroid Build Coastguard Worker           do {
664*1b3f573fSAndroid Build Coastguard Worker             Node* next = node->next;
665*1b3f573fSAndroid Build Coastguard Worker             DestroyNode(node);
666*1b3f573fSAndroid Build Coastguard Worker             node = next;
667*1b3f573fSAndroid Build Coastguard Worker           } while (node != nullptr);
668*1b3f573fSAndroid Build Coastguard Worker         } else if (TableEntryIsTree(b)) {
669*1b3f573fSAndroid Build Coastguard Worker           Tree* tree = static_cast<Tree*>(table_[b]);
670*1b3f573fSAndroid Build Coastguard Worker           GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0);
671*1b3f573fSAndroid Build Coastguard Worker           table_[b] = table_[b + 1] = nullptr;
672*1b3f573fSAndroid Build Coastguard Worker           typename Tree::iterator tree_it = tree->begin();
673*1b3f573fSAndroid Build Coastguard Worker           do {
674*1b3f573fSAndroid Build Coastguard Worker             Node* node = NodeFromTreeIterator(tree_it);
675*1b3f573fSAndroid Build Coastguard Worker             typename Tree::iterator next = tree_it;
676*1b3f573fSAndroid Build Coastguard Worker             ++next;
677*1b3f573fSAndroid Build Coastguard Worker             tree->erase(tree_it);
678*1b3f573fSAndroid Build Coastguard Worker             DestroyNode(node);
679*1b3f573fSAndroid Build Coastguard Worker             tree_it = next;
680*1b3f573fSAndroid Build Coastguard Worker           } while (tree_it != tree->end());
681*1b3f573fSAndroid Build Coastguard Worker           DestroyTree(tree);
682*1b3f573fSAndroid Build Coastguard Worker           b++;
683*1b3f573fSAndroid Build Coastguard Worker         }
684*1b3f573fSAndroid Build Coastguard Worker       }
685*1b3f573fSAndroid Build Coastguard Worker       num_elements_ = 0;
686*1b3f573fSAndroid Build Coastguard Worker       index_of_first_non_null_ = num_buckets_;
687*1b3f573fSAndroid Build Coastguard Worker     }
688*1b3f573fSAndroid Build Coastguard Worker 
689*1b3f573fSAndroid Build Coastguard Worker     const hasher& hash_function() const { return *this; }
690*1b3f573fSAndroid Build Coastguard Worker 
691*1b3f573fSAndroid Build Coastguard Worker     static size_type max_size() {
692*1b3f573fSAndroid Build Coastguard Worker       return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28);
693*1b3f573fSAndroid Build Coastguard Worker     }
694*1b3f573fSAndroid Build Coastguard Worker     size_type size() const { return num_elements_; }
695*1b3f573fSAndroid Build Coastguard Worker     bool empty() const { return size() == 0; }
696*1b3f573fSAndroid Build Coastguard Worker 
697*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
698*1b3f573fSAndroid Build Coastguard Worker     iterator find(const K& k) {
699*1b3f573fSAndroid Build Coastguard Worker       return iterator(FindHelper(k).first);
700*1b3f573fSAndroid Build Coastguard Worker     }
701*1b3f573fSAndroid Build Coastguard Worker 
702*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
703*1b3f573fSAndroid Build Coastguard Worker     const_iterator find(const K& k) const {
704*1b3f573fSAndroid Build Coastguard Worker       return FindHelper(k).first;
705*1b3f573fSAndroid Build Coastguard Worker     }
706*1b3f573fSAndroid Build Coastguard Worker 
707*1b3f573fSAndroid Build Coastguard Worker     // Inserts a new element into the container if there is no element with the
708*1b3f573fSAndroid Build Coastguard Worker     // key in the container.
709*1b3f573fSAndroid Build Coastguard Worker     // The new element is:
710*1b3f573fSAndroid Build Coastguard Worker     //  (1) Constructed in-place with the given args, if mapped_type is not
711*1b3f573fSAndroid Build Coastguard Worker     //      arena constructible.
712*1b3f573fSAndroid Build Coastguard Worker     //  (2) Constructed in-place with the arena and then assigned with a
713*1b3f573fSAndroid Build Coastguard Worker     //      mapped_type temporary constructed with the given args, otherwise.
714*1b3f573fSAndroid Build Coastguard Worker     template <typename K, typename... Args>
715*1b3f573fSAndroid Build Coastguard Worker     std::pair<iterator, bool> try_emplace(K&& k, Args&&... args) {
716*1b3f573fSAndroid Build Coastguard Worker       return ArenaAwareTryEmplace(Arena::is_arena_constructable<mapped_type>(),
717*1b3f573fSAndroid Build Coastguard Worker                                   std::forward<K>(k),
718*1b3f573fSAndroid Build Coastguard Worker                                   std::forward<Args>(args)...);
719*1b3f573fSAndroid Build Coastguard Worker     }
720*1b3f573fSAndroid Build Coastguard Worker 
721*1b3f573fSAndroid Build Coastguard Worker     // Inserts the key into the map, if not present. In that case, the value
722*1b3f573fSAndroid Build Coastguard Worker     // will be value initialized.
723*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
724*1b3f573fSAndroid Build Coastguard Worker     std::pair<iterator, bool> insert(K&& k) {
725*1b3f573fSAndroid Build Coastguard Worker       return try_emplace(std::forward<K>(k));
726*1b3f573fSAndroid Build Coastguard Worker     }
727*1b3f573fSAndroid Build Coastguard Worker 
728*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
729*1b3f573fSAndroid Build Coastguard Worker     value_type& operator[](K&& k) {
730*1b3f573fSAndroid Build Coastguard Worker       return *try_emplace(std::forward<K>(k)).first;
731*1b3f573fSAndroid Build Coastguard Worker     }
732*1b3f573fSAndroid Build Coastguard Worker 
733*1b3f573fSAndroid Build Coastguard Worker     void erase(iterator it) {
734*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK_EQ(it.m_, this);
735*1b3f573fSAndroid Build Coastguard Worker       typename Tree::iterator tree_it;
736*1b3f573fSAndroid Build Coastguard Worker       const bool is_list = it.revalidate_if_necessary(&tree_it);
737*1b3f573fSAndroid Build Coastguard Worker       size_type b = it.bucket_index_;
738*1b3f573fSAndroid Build Coastguard Worker       Node* const item = it.node_;
739*1b3f573fSAndroid Build Coastguard Worker       if (is_list) {
740*1b3f573fSAndroid Build Coastguard Worker         GOOGLE_DCHECK(TableEntryIsNonEmptyList(b));
741*1b3f573fSAndroid Build Coastguard Worker         Node* head = static_cast<Node*>(table_[b]);
742*1b3f573fSAndroid Build Coastguard Worker         head = EraseFromLinkedList(item, head);
743*1b3f573fSAndroid Build Coastguard Worker         table_[b] = static_cast<void*>(head);
744*1b3f573fSAndroid Build Coastguard Worker       } else {
745*1b3f573fSAndroid Build Coastguard Worker         GOOGLE_DCHECK(TableEntryIsTree(b));
746*1b3f573fSAndroid Build Coastguard Worker         Tree* tree = static_cast<Tree*>(table_[b]);
747*1b3f573fSAndroid Build Coastguard Worker         tree->erase(tree_it);
748*1b3f573fSAndroid Build Coastguard Worker         if (tree->empty()) {
749*1b3f573fSAndroid Build Coastguard Worker           // Force b to be the minimum of b and b ^ 1.  This is important
750*1b3f573fSAndroid Build Coastguard Worker           // only because we want index_of_first_non_null_ to be correct.
751*1b3f573fSAndroid Build Coastguard Worker           b &= ~static_cast<size_type>(1);
752*1b3f573fSAndroid Build Coastguard Worker           DestroyTree(tree);
753*1b3f573fSAndroid Build Coastguard Worker           table_[b] = table_[b + 1] = nullptr;
754*1b3f573fSAndroid Build Coastguard Worker         }
755*1b3f573fSAndroid Build Coastguard Worker       }
756*1b3f573fSAndroid Build Coastguard Worker       DestroyNode(item);
757*1b3f573fSAndroid Build Coastguard Worker       --num_elements_;
758*1b3f573fSAndroid Build Coastguard Worker       if (PROTOBUF_PREDICT_FALSE(b == index_of_first_non_null_)) {
759*1b3f573fSAndroid Build Coastguard Worker         while (index_of_first_non_null_ < num_buckets_ &&
760*1b3f573fSAndroid Build Coastguard Worker                table_[index_of_first_non_null_] == nullptr) {
761*1b3f573fSAndroid Build Coastguard Worker           ++index_of_first_non_null_;
762*1b3f573fSAndroid Build Coastguard Worker         }
763*1b3f573fSAndroid Build Coastguard Worker       }
764*1b3f573fSAndroid Build Coastguard Worker     }
765*1b3f573fSAndroid Build Coastguard Worker 
766*1b3f573fSAndroid Build Coastguard Worker     size_t SpaceUsedInternal() const {
767*1b3f573fSAndroid Build Coastguard Worker       return internal::SpaceUsedInTable<Key>(table_, num_buckets_,
768*1b3f573fSAndroid Build Coastguard Worker                                              num_elements_, sizeof(Node));
769*1b3f573fSAndroid Build Coastguard Worker     }
770*1b3f573fSAndroid Build Coastguard Worker 
771*1b3f573fSAndroid Build Coastguard Worker    private:
772*1b3f573fSAndroid Build Coastguard Worker     template <typename K, typename... Args>
773*1b3f573fSAndroid Build Coastguard Worker     std::pair<iterator, bool> TryEmplaceInternal(K&& k, Args&&... args) {
774*1b3f573fSAndroid Build Coastguard Worker       std::pair<const_iterator, size_type> p = FindHelper(k);
775*1b3f573fSAndroid Build Coastguard Worker       // Case 1: key was already present.
776*1b3f573fSAndroid Build Coastguard Worker       if (p.first.node_ != nullptr)
777*1b3f573fSAndroid Build Coastguard Worker         return std::make_pair(iterator(p.first), false);
778*1b3f573fSAndroid Build Coastguard Worker       // Case 2: insert.
779*1b3f573fSAndroid Build Coastguard Worker       if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
780*1b3f573fSAndroid Build Coastguard Worker         p = FindHelper(k);
781*1b3f573fSAndroid Build Coastguard Worker       }
782*1b3f573fSAndroid Build Coastguard Worker       const size_type b = p.second;  // bucket number
783*1b3f573fSAndroid Build Coastguard Worker       // If K is not key_type, make the conversion to key_type explicit.
784*1b3f573fSAndroid Build Coastguard Worker       using TypeToInit = typename std::conditional<
785*1b3f573fSAndroid Build Coastguard Worker           std::is_same<typename std::decay<K>::type, key_type>::value, K&&,
786*1b3f573fSAndroid Build Coastguard Worker           key_type>::type;
787*1b3f573fSAndroid Build Coastguard Worker       Node* node = Alloc<Node>(1);
788*1b3f573fSAndroid Build Coastguard Worker       // Even when arena is nullptr, CreateInArenaStorage is still used to
789*1b3f573fSAndroid Build Coastguard Worker       // ensure the arena of submessage will be consistent. Otherwise,
790*1b3f573fSAndroid Build Coastguard Worker       // submessage may have its own arena when message-owned arena is enabled.
791*1b3f573fSAndroid Build Coastguard Worker       // Note: This only works if `Key` is not arena constructible.
792*1b3f573fSAndroid Build Coastguard Worker       Arena::CreateInArenaStorage(const_cast<Key*>(&node->kv.first),
793*1b3f573fSAndroid Build Coastguard Worker                                   alloc_.arena(),
794*1b3f573fSAndroid Build Coastguard Worker                                   static_cast<TypeToInit>(std::forward<K>(k)));
795*1b3f573fSAndroid Build Coastguard Worker       // Note: if `T` is arena constructible, `Args` needs to be empty.
796*1b3f573fSAndroid Build Coastguard Worker       Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena(),
797*1b3f573fSAndroid Build Coastguard Worker                                   std::forward<Args>(args)...);
798*1b3f573fSAndroid Build Coastguard Worker 
799*1b3f573fSAndroid Build Coastguard Worker       iterator result = InsertUnique(b, node);
800*1b3f573fSAndroid Build Coastguard Worker       ++num_elements_;
801*1b3f573fSAndroid Build Coastguard Worker       return std::make_pair(result, true);
802*1b3f573fSAndroid Build Coastguard Worker     }
803*1b3f573fSAndroid Build Coastguard Worker 
804*1b3f573fSAndroid Build Coastguard Worker     // A helper function to perform an assignment of `mapped_type`.
805*1b3f573fSAndroid Build Coastguard Worker     // If the first argument is true, then it is a regular assignment.
806*1b3f573fSAndroid Build Coastguard Worker     // Otherwise, we first create a temporary and then perform an assignment.
807*1b3f573fSAndroid Build Coastguard Worker     template <typename V>
808*1b3f573fSAndroid Build Coastguard Worker     static void AssignMapped(std::true_type, mapped_type& mapped, V&& v) {
809*1b3f573fSAndroid Build Coastguard Worker       mapped = std::forward<V>(v);
810*1b3f573fSAndroid Build Coastguard Worker     }
811*1b3f573fSAndroid Build Coastguard Worker     template <typename... Args>
812*1b3f573fSAndroid Build Coastguard Worker     static void AssignMapped(std::false_type, mapped_type& mapped,
813*1b3f573fSAndroid Build Coastguard Worker                              Args&&... args) {
814*1b3f573fSAndroid Build Coastguard Worker       mapped = mapped_type(std::forward<Args>(args)...);
815*1b3f573fSAndroid Build Coastguard Worker     }
816*1b3f573fSAndroid Build Coastguard Worker 
817*1b3f573fSAndroid Build Coastguard Worker     // Case 1: `mapped_type` is arena constructible. A temporary object is
818*1b3f573fSAndroid Build Coastguard Worker     // created and then (if `Args` are not empty) assigned to a mapped value
819*1b3f573fSAndroid Build Coastguard Worker     // that was created with the arena.
820*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
821*1b3f573fSAndroid Build Coastguard Worker     std::pair<iterator, bool> ArenaAwareTryEmplace(std::true_type, K&& k) {
822*1b3f573fSAndroid Build Coastguard Worker       // case 1.1: "default" constructed (e.g. from arena only).
823*1b3f573fSAndroid Build Coastguard Worker       return TryEmplaceInternal(std::forward<K>(k));
824*1b3f573fSAndroid Build Coastguard Worker     }
825*1b3f573fSAndroid Build Coastguard Worker     template <typename K, typename... Args>
826*1b3f573fSAndroid Build Coastguard Worker     std::pair<iterator, bool> ArenaAwareTryEmplace(std::true_type, K&& k,
827*1b3f573fSAndroid Build Coastguard Worker                                                    Args&&... args) {
828*1b3f573fSAndroid Build Coastguard Worker       // case 1.2: "default" constructed + copy/move assignment
829*1b3f573fSAndroid Build Coastguard Worker       auto p = TryEmplaceInternal(std::forward<K>(k));
830*1b3f573fSAndroid Build Coastguard Worker       if (p.second) {
831*1b3f573fSAndroid Build Coastguard Worker         AssignMapped(std::is_same<void(typename std::decay<Args>::type...),
832*1b3f573fSAndroid Build Coastguard Worker                                   void(mapped_type)>(),
833*1b3f573fSAndroid Build Coastguard Worker                      p.first->second, std::forward<Args>(args)...);
834*1b3f573fSAndroid Build Coastguard Worker       }
835*1b3f573fSAndroid Build Coastguard Worker       return p;
836*1b3f573fSAndroid Build Coastguard Worker     }
837*1b3f573fSAndroid Build Coastguard Worker     // Case 2: `mapped_type` is not arena constructible. Using in-place
838*1b3f573fSAndroid Build Coastguard Worker     // construction.
839*1b3f573fSAndroid Build Coastguard Worker     template <typename... Args>
840*1b3f573fSAndroid Build Coastguard Worker     std::pair<iterator, bool> ArenaAwareTryEmplace(std::false_type,
841*1b3f573fSAndroid Build Coastguard Worker                                                    Args&&... args) {
842*1b3f573fSAndroid Build Coastguard Worker       return TryEmplaceInternal(std::forward<Args>(args)...);
843*1b3f573fSAndroid Build Coastguard Worker     }
844*1b3f573fSAndroid Build Coastguard Worker 
845*1b3f573fSAndroid Build Coastguard Worker     const_iterator find(const Key& k, TreeIterator* it) const {
846*1b3f573fSAndroid Build Coastguard Worker       return FindHelper(k, it).first;
847*1b3f573fSAndroid Build Coastguard Worker     }
848*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
849*1b3f573fSAndroid Build Coastguard Worker     std::pair<const_iterator, size_type> FindHelper(const K& k) const {
850*1b3f573fSAndroid Build Coastguard Worker       return FindHelper(k, nullptr);
851*1b3f573fSAndroid Build Coastguard Worker     }
852*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
853*1b3f573fSAndroid Build Coastguard Worker     std::pair<const_iterator, size_type> FindHelper(const K& k,
854*1b3f573fSAndroid Build Coastguard Worker                                                     TreeIterator* it) const {
855*1b3f573fSAndroid Build Coastguard Worker       size_type b = BucketNumber(k);
856*1b3f573fSAndroid Build Coastguard Worker       if (TableEntryIsNonEmptyList(b)) {
857*1b3f573fSAndroid Build Coastguard Worker         Node* node = static_cast<Node*>(table_[b]);
858*1b3f573fSAndroid Build Coastguard Worker         do {
859*1b3f573fSAndroid Build Coastguard Worker           if (internal::TransparentSupport<Key>::Equals(node->kv.first, k)) {
860*1b3f573fSAndroid Build Coastguard Worker             return std::make_pair(const_iterator(node, this, b), b);
861*1b3f573fSAndroid Build Coastguard Worker           } else {
862*1b3f573fSAndroid Build Coastguard Worker             node = node->next;
863*1b3f573fSAndroid Build Coastguard Worker           }
864*1b3f573fSAndroid Build Coastguard Worker         } while (node != nullptr);
865*1b3f573fSAndroid Build Coastguard Worker       } else if (TableEntryIsTree(b)) {
866*1b3f573fSAndroid Build Coastguard Worker         GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
867*1b3f573fSAndroid Build Coastguard Worker         b &= ~static_cast<size_t>(1);
868*1b3f573fSAndroid Build Coastguard Worker         Tree* tree = static_cast<Tree*>(table_[b]);
869*1b3f573fSAndroid Build Coastguard Worker         auto tree_it = tree->find(k);
870*1b3f573fSAndroid Build Coastguard Worker         if (tree_it != tree->end()) {
871*1b3f573fSAndroid Build Coastguard Worker           if (it != nullptr) *it = tree_it;
872*1b3f573fSAndroid Build Coastguard Worker           return std::make_pair(const_iterator(tree_it, this, b), b);
873*1b3f573fSAndroid Build Coastguard Worker         }
874*1b3f573fSAndroid Build Coastguard Worker       }
875*1b3f573fSAndroid Build Coastguard Worker       return std::make_pair(end(), b);
876*1b3f573fSAndroid Build Coastguard Worker     }
877*1b3f573fSAndroid Build Coastguard Worker 
878*1b3f573fSAndroid Build Coastguard Worker     // Insert the given Node in bucket b.  If that would make bucket b too big,
879*1b3f573fSAndroid Build Coastguard Worker     // and bucket b is not a tree, create a tree for buckets b and b^1 to share.
880*1b3f573fSAndroid Build Coastguard Worker     // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct
881*1b3f573fSAndroid Build Coastguard Worker     // bucket.  num_elements_ is not modified.
882*1b3f573fSAndroid Build Coastguard Worker     iterator InsertUnique(size_type b, Node* node) {
883*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ ||
884*1b3f573fSAndroid Build Coastguard Worker              table_[index_of_first_non_null_] != nullptr);
885*1b3f573fSAndroid Build Coastguard Worker       // In practice, the code that led to this point may have already
886*1b3f573fSAndroid Build Coastguard Worker       // determined whether we are inserting into an empty list, a short list,
887*1b3f573fSAndroid Build Coastguard Worker       // or whatever.  But it's probably cheap enough to recompute that here;
888*1b3f573fSAndroid Build Coastguard Worker       // it's likely that we're inserting into an empty or short list.
889*1b3f573fSAndroid Build Coastguard Worker       iterator result;
890*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK(find(node->kv.first) == end());
891*1b3f573fSAndroid Build Coastguard Worker       if (TableEntryIsEmpty(b)) {
892*1b3f573fSAndroid Build Coastguard Worker         result = InsertUniqueInList(b, node);
893*1b3f573fSAndroid Build Coastguard Worker       } else if (TableEntryIsNonEmptyList(b)) {
894*1b3f573fSAndroid Build Coastguard Worker         if (PROTOBUF_PREDICT_FALSE(TableEntryIsTooLong(b))) {
895*1b3f573fSAndroid Build Coastguard Worker           TreeConvert(b);
896*1b3f573fSAndroid Build Coastguard Worker           result = InsertUniqueInTree(b, node);
897*1b3f573fSAndroid Build Coastguard Worker           GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast<size_type>(1));
898*1b3f573fSAndroid Build Coastguard Worker         } else {
899*1b3f573fSAndroid Build Coastguard Worker           // Insert into a pre-existing list.  This case cannot modify
900*1b3f573fSAndroid Build Coastguard Worker           // index_of_first_non_null_, so we skip the code to update it.
901*1b3f573fSAndroid Build Coastguard Worker           return InsertUniqueInList(b, node);
902*1b3f573fSAndroid Build Coastguard Worker         }
903*1b3f573fSAndroid Build Coastguard Worker       } else {
904*1b3f573fSAndroid Build Coastguard Worker         // Insert into a pre-existing tree.  This case cannot modify
905*1b3f573fSAndroid Build Coastguard Worker         // index_of_first_non_null_, so we skip the code to update it.
906*1b3f573fSAndroid Build Coastguard Worker         return InsertUniqueInTree(b, node);
907*1b3f573fSAndroid Build Coastguard Worker       }
908*1b3f573fSAndroid Build Coastguard Worker       // parentheses around (std::min) prevents macro expansion of min(...)
909*1b3f573fSAndroid Build Coastguard Worker       index_of_first_non_null_ =
910*1b3f573fSAndroid Build Coastguard Worker           (std::min)(index_of_first_non_null_, result.bucket_index_);
911*1b3f573fSAndroid Build Coastguard Worker       return result;
912*1b3f573fSAndroid Build Coastguard Worker     }
913*1b3f573fSAndroid Build Coastguard Worker 
914*1b3f573fSAndroid Build Coastguard Worker     // Returns whether we should insert after the head of the list. For
915*1b3f573fSAndroid Build Coastguard Worker     // non-optimized builds, we randomly decide whether to insert right at the
916*1b3f573fSAndroid Build Coastguard Worker     // head of the list or just after the head. This helps add a little bit of
917*1b3f573fSAndroid Build Coastguard Worker     // non-determinism to the map ordering.
918*1b3f573fSAndroid Build Coastguard Worker     bool ShouldInsertAfterHead(void* node) {
919*1b3f573fSAndroid Build Coastguard Worker #ifdef NDEBUG
920*1b3f573fSAndroid Build Coastguard Worker       (void)node;
921*1b3f573fSAndroid Build Coastguard Worker       return false;
922*1b3f573fSAndroid Build Coastguard Worker #else
923*1b3f573fSAndroid Build Coastguard Worker       // Doing modulo with a prime mixes the bits more.
924*1b3f573fSAndroid Build Coastguard Worker       return (reinterpret_cast<uintptr_t>(node) ^ seed_) % 13 > 6;
925*1b3f573fSAndroid Build Coastguard Worker #endif
926*1b3f573fSAndroid Build Coastguard Worker     }
927*1b3f573fSAndroid Build Coastguard Worker 
928*1b3f573fSAndroid Build Coastguard Worker     // Helper for InsertUnique.  Handles the case where bucket b is a
929*1b3f573fSAndroid Build Coastguard Worker     // not-too-long linked list.
930*1b3f573fSAndroid Build Coastguard Worker     iterator InsertUniqueInList(size_type b, Node* node) {
931*1b3f573fSAndroid Build Coastguard Worker       if (table_[b] != nullptr && ShouldInsertAfterHead(node)) {
932*1b3f573fSAndroid Build Coastguard Worker         Node* first = static_cast<Node*>(table_[b]);
933*1b3f573fSAndroid Build Coastguard Worker         node->next = first->next;
934*1b3f573fSAndroid Build Coastguard Worker         first->next = node;
935*1b3f573fSAndroid Build Coastguard Worker         return iterator(node, this, b);
936*1b3f573fSAndroid Build Coastguard Worker       }
937*1b3f573fSAndroid Build Coastguard Worker 
938*1b3f573fSAndroid Build Coastguard Worker       node->next = static_cast<Node*>(table_[b]);
939*1b3f573fSAndroid Build Coastguard Worker       table_[b] = static_cast<void*>(node);
940*1b3f573fSAndroid Build Coastguard Worker       return iterator(node, this, b);
941*1b3f573fSAndroid Build Coastguard Worker     }
942*1b3f573fSAndroid Build Coastguard Worker 
943*1b3f573fSAndroid Build Coastguard Worker     // Helper for InsertUnique.  Handles the case where bucket b points to a
944*1b3f573fSAndroid Build Coastguard Worker     // Tree.
945*1b3f573fSAndroid Build Coastguard Worker     iterator InsertUniqueInTree(size_type b, Node* node) {
946*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
947*1b3f573fSAndroid Build Coastguard Worker       // Maintain the invariant that node->next is null for all Nodes in Trees.
948*1b3f573fSAndroid Build Coastguard Worker       node->next = nullptr;
949*1b3f573fSAndroid Build Coastguard Worker       return iterator(
950*1b3f573fSAndroid Build Coastguard Worker           static_cast<Tree*>(table_[b])->insert({node->kv.first, node}).first,
951*1b3f573fSAndroid Build Coastguard Worker           this, b & ~static_cast<size_t>(1));
952*1b3f573fSAndroid Build Coastguard Worker     }
953*1b3f573fSAndroid Build Coastguard Worker 
954*1b3f573fSAndroid Build Coastguard Worker     // Returns whether it did resize.  Currently this is only used when
955*1b3f573fSAndroid Build Coastguard Worker     // num_elements_ increases, though it could be used in other situations.
956*1b3f573fSAndroid Build Coastguard Worker     // It checks for load too low as well as load too high: because any number
957*1b3f573fSAndroid Build Coastguard Worker     // of erases can occur between inserts, the load could be as low as 0 here.
958*1b3f573fSAndroid Build Coastguard Worker     // Resizing to a lower size is not always helpful, but failing to do so can
959*1b3f573fSAndroid Build Coastguard Worker     // destroy the expected big-O bounds for some operations. By having the
960*1b3f573fSAndroid Build Coastguard Worker     // policy that sometimes we resize down as well as up, clients can easily
961*1b3f573fSAndroid Build Coastguard Worker     // keep O(size()) = O(number of buckets) if they want that.
962*1b3f573fSAndroid Build Coastguard Worker     bool ResizeIfLoadIsOutOfRange(size_type new_size) {
963*1b3f573fSAndroid Build Coastguard Worker       const size_type kMaxMapLoadTimes16 = 12;  // controls RAM vs CPU tradeoff
964*1b3f573fSAndroid Build Coastguard Worker       const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16;
965*1b3f573fSAndroid Build Coastguard Worker       const size_type lo_cutoff = hi_cutoff / 4;
966*1b3f573fSAndroid Build Coastguard Worker       // We don't care how many elements are in trees.  If a lot are,
967*1b3f573fSAndroid Build Coastguard Worker       // we may resize even though there are many empty buckets.  In
968*1b3f573fSAndroid Build Coastguard Worker       // practice, this seems fine.
969*1b3f573fSAndroid Build Coastguard Worker       if (PROTOBUF_PREDICT_FALSE(new_size >= hi_cutoff)) {
970*1b3f573fSAndroid Build Coastguard Worker         if (num_buckets_ <= max_size() / 2) {
971*1b3f573fSAndroid Build Coastguard Worker           Resize(num_buckets_ * 2);
972*1b3f573fSAndroid Build Coastguard Worker           return true;
973*1b3f573fSAndroid Build Coastguard Worker         }
974*1b3f573fSAndroid Build Coastguard Worker       } else if (PROTOBUF_PREDICT_FALSE(new_size <= lo_cutoff &&
975*1b3f573fSAndroid Build Coastguard Worker                                         num_buckets_ > kMinTableSize)) {
976*1b3f573fSAndroid Build Coastguard Worker         size_type lg2_of_size_reduction_factor = 1;
977*1b3f573fSAndroid Build Coastguard Worker         // It's possible we want to shrink a lot here... size() could even be 0.
978*1b3f573fSAndroid Build Coastguard Worker         // So, estimate how much to shrink by making sure we don't shrink so
979*1b3f573fSAndroid Build Coastguard Worker         // much that we would need to grow the table after a few inserts.
980*1b3f573fSAndroid Build Coastguard Worker         const size_type hypothetical_size = new_size * 5 / 4 + 1;
981*1b3f573fSAndroid Build Coastguard Worker         while ((hypothetical_size << lg2_of_size_reduction_factor) <
982*1b3f573fSAndroid Build Coastguard Worker                hi_cutoff) {
983*1b3f573fSAndroid Build Coastguard Worker           ++lg2_of_size_reduction_factor;
984*1b3f573fSAndroid Build Coastguard Worker         }
985*1b3f573fSAndroid Build Coastguard Worker         size_type new_num_buckets = std::max<size_type>(
986*1b3f573fSAndroid Build Coastguard Worker             kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor);
987*1b3f573fSAndroid Build Coastguard Worker         if (new_num_buckets != num_buckets_) {
988*1b3f573fSAndroid Build Coastguard Worker           Resize(new_num_buckets);
989*1b3f573fSAndroid Build Coastguard Worker           return true;
990*1b3f573fSAndroid Build Coastguard Worker         }
991*1b3f573fSAndroid Build Coastguard Worker       }
992*1b3f573fSAndroid Build Coastguard Worker       return false;
993*1b3f573fSAndroid Build Coastguard Worker     }
994*1b3f573fSAndroid Build Coastguard Worker 
995*1b3f573fSAndroid Build Coastguard Worker     // Resize to the given number of buckets.
996*1b3f573fSAndroid Build Coastguard Worker     void Resize(size_t new_num_buckets) {
997*1b3f573fSAndroid Build Coastguard Worker       if (num_buckets_ == internal::kGlobalEmptyTableSize) {
998*1b3f573fSAndroid Build Coastguard Worker         // This is the global empty array.
999*1b3f573fSAndroid Build Coastguard Worker         // Just overwrite with a new one. No need to transfer or free anything.
1000*1b3f573fSAndroid Build Coastguard Worker         num_buckets_ = index_of_first_non_null_ = kMinTableSize;
1001*1b3f573fSAndroid Build Coastguard Worker         table_ = CreateEmptyTable(num_buckets_);
1002*1b3f573fSAndroid Build Coastguard Worker         seed_ = Seed();
1003*1b3f573fSAndroid Build Coastguard Worker         return;
1004*1b3f573fSAndroid Build Coastguard Worker       }
1005*1b3f573fSAndroid Build Coastguard Worker 
1006*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize);
1007*1b3f573fSAndroid Build Coastguard Worker       void** const old_table = table_;
1008*1b3f573fSAndroid Build Coastguard Worker       const size_type old_table_size = num_buckets_;
1009*1b3f573fSAndroid Build Coastguard Worker       num_buckets_ = new_num_buckets;
1010*1b3f573fSAndroid Build Coastguard Worker       table_ = CreateEmptyTable(num_buckets_);
1011*1b3f573fSAndroid Build Coastguard Worker       const size_type start = index_of_first_non_null_;
1012*1b3f573fSAndroid Build Coastguard Worker       index_of_first_non_null_ = num_buckets_;
1013*1b3f573fSAndroid Build Coastguard Worker       for (size_type i = start; i < old_table_size; i++) {
1014*1b3f573fSAndroid Build Coastguard Worker         if (internal::TableEntryIsNonEmptyList(old_table, i)) {
1015*1b3f573fSAndroid Build Coastguard Worker           TransferList(old_table, i);
1016*1b3f573fSAndroid Build Coastguard Worker         } else if (internal::TableEntryIsTree(old_table, i)) {
1017*1b3f573fSAndroid Build Coastguard Worker           TransferTree(old_table, i++);
1018*1b3f573fSAndroid Build Coastguard Worker         }
1019*1b3f573fSAndroid Build Coastguard Worker       }
1020*1b3f573fSAndroid Build Coastguard Worker       Dealloc<void*>(old_table, old_table_size);
1021*1b3f573fSAndroid Build Coastguard Worker     }
1022*1b3f573fSAndroid Build Coastguard Worker 
1023*1b3f573fSAndroid Build Coastguard Worker     void TransferList(void* const* table, size_type index) {
1024*1b3f573fSAndroid Build Coastguard Worker       Node* node = static_cast<Node*>(table[index]);
1025*1b3f573fSAndroid Build Coastguard Worker       do {
1026*1b3f573fSAndroid Build Coastguard Worker         Node* next = node->next;
1027*1b3f573fSAndroid Build Coastguard Worker         InsertUnique(BucketNumber(node->kv.first), node);
1028*1b3f573fSAndroid Build Coastguard Worker         node = next;
1029*1b3f573fSAndroid Build Coastguard Worker       } while (node != nullptr);
1030*1b3f573fSAndroid Build Coastguard Worker     }
1031*1b3f573fSAndroid Build Coastguard Worker 
1032*1b3f573fSAndroid Build Coastguard Worker     void TransferTree(void* const* table, size_type index) {
1033*1b3f573fSAndroid Build Coastguard Worker       Tree* tree = static_cast<Tree*>(table[index]);
1034*1b3f573fSAndroid Build Coastguard Worker       typename Tree::iterator tree_it = tree->begin();
1035*1b3f573fSAndroid Build Coastguard Worker       do {
1036*1b3f573fSAndroid Build Coastguard Worker         InsertUnique(BucketNumber(std::cref(tree_it->first).get()),
1037*1b3f573fSAndroid Build Coastguard Worker                      NodeFromTreeIterator(tree_it));
1038*1b3f573fSAndroid Build Coastguard Worker       } while (++tree_it != tree->end());
1039*1b3f573fSAndroid Build Coastguard Worker       DestroyTree(tree);
1040*1b3f573fSAndroid Build Coastguard Worker     }
1041*1b3f573fSAndroid Build Coastguard Worker 
1042*1b3f573fSAndroid Build Coastguard Worker     Node* EraseFromLinkedList(Node* item, Node* head) {
1043*1b3f573fSAndroid Build Coastguard Worker       if (head == item) {
1044*1b3f573fSAndroid Build Coastguard Worker         return head->next;
1045*1b3f573fSAndroid Build Coastguard Worker       } else {
1046*1b3f573fSAndroid Build Coastguard Worker         head->next = EraseFromLinkedList(item, head->next);
1047*1b3f573fSAndroid Build Coastguard Worker         return head;
1048*1b3f573fSAndroid Build Coastguard Worker       }
1049*1b3f573fSAndroid Build Coastguard Worker     }
1050*1b3f573fSAndroid Build Coastguard Worker 
1051*1b3f573fSAndroid Build Coastguard Worker     bool TableEntryIsEmpty(size_type b) const {
1052*1b3f573fSAndroid Build Coastguard Worker       return internal::TableEntryIsEmpty(table_, b);
1053*1b3f573fSAndroid Build Coastguard Worker     }
1054*1b3f573fSAndroid Build Coastguard Worker     bool TableEntryIsNonEmptyList(size_type b) const {
1055*1b3f573fSAndroid Build Coastguard Worker       return internal::TableEntryIsNonEmptyList(table_, b);
1056*1b3f573fSAndroid Build Coastguard Worker     }
1057*1b3f573fSAndroid Build Coastguard Worker     bool TableEntryIsTree(size_type b) const {
1058*1b3f573fSAndroid Build Coastguard Worker       return internal::TableEntryIsTree(table_, b);
1059*1b3f573fSAndroid Build Coastguard Worker     }
1060*1b3f573fSAndroid Build Coastguard Worker     bool TableEntryIsList(size_type b) const {
1061*1b3f573fSAndroid Build Coastguard Worker       return internal::TableEntryIsList(table_, b);
1062*1b3f573fSAndroid Build Coastguard Worker     }
1063*1b3f573fSAndroid Build Coastguard Worker 
1064*1b3f573fSAndroid Build Coastguard Worker     void TreeConvert(size_type b) {
1065*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1));
1066*1b3f573fSAndroid Build Coastguard Worker       Tree* tree =
1067*1b3f573fSAndroid Build Coastguard Worker           Arena::Create<Tree>(alloc_.arena(), typename Tree::key_compare(),
1068*1b3f573fSAndroid Build Coastguard Worker                               typename Tree::allocator_type(alloc_));
1069*1b3f573fSAndroid Build Coastguard Worker       size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree);
1070*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK_EQ(count, tree->size());
1071*1b3f573fSAndroid Build Coastguard Worker       table_[b] = table_[b ^ 1] = static_cast<void*>(tree);
1072*1b3f573fSAndroid Build Coastguard Worker     }
1073*1b3f573fSAndroid Build Coastguard Worker 
1074*1b3f573fSAndroid Build Coastguard Worker     // Copy a linked list in the given bucket to a tree.
1075*1b3f573fSAndroid Build Coastguard Worker     // Returns the number of things it copied.
1076*1b3f573fSAndroid Build Coastguard Worker     size_type CopyListToTree(size_type b, Tree* tree) {
1077*1b3f573fSAndroid Build Coastguard Worker       size_type count = 0;
1078*1b3f573fSAndroid Build Coastguard Worker       Node* node = static_cast<Node*>(table_[b]);
1079*1b3f573fSAndroid Build Coastguard Worker       while (node != nullptr) {
1080*1b3f573fSAndroid Build Coastguard Worker         tree->insert({node->kv.first, node});
1081*1b3f573fSAndroid Build Coastguard Worker         ++count;
1082*1b3f573fSAndroid Build Coastguard Worker         Node* next = node->next;
1083*1b3f573fSAndroid Build Coastguard Worker         node->next = nullptr;
1084*1b3f573fSAndroid Build Coastguard Worker         node = next;
1085*1b3f573fSAndroid Build Coastguard Worker       }
1086*1b3f573fSAndroid Build Coastguard Worker       return count;
1087*1b3f573fSAndroid Build Coastguard Worker     }
1088*1b3f573fSAndroid Build Coastguard Worker 
1089*1b3f573fSAndroid Build Coastguard Worker     // Return whether table_[b] is a linked list that seems awfully long.
1090*1b3f573fSAndroid Build Coastguard Worker     // Requires table_[b] to point to a non-empty linked list.
1091*1b3f573fSAndroid Build Coastguard Worker     bool TableEntryIsTooLong(size_type b) {
1092*1b3f573fSAndroid Build Coastguard Worker       const size_type kMaxLength = 8;
1093*1b3f573fSAndroid Build Coastguard Worker       size_type count = 0;
1094*1b3f573fSAndroid Build Coastguard Worker       Node* node = static_cast<Node*>(table_[b]);
1095*1b3f573fSAndroid Build Coastguard Worker       do {
1096*1b3f573fSAndroid Build Coastguard Worker         ++count;
1097*1b3f573fSAndroid Build Coastguard Worker         node = node->next;
1098*1b3f573fSAndroid Build Coastguard Worker       } while (node != nullptr);
1099*1b3f573fSAndroid Build Coastguard Worker       // Invariant: no linked list ever is more than kMaxLength in length.
1100*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK_LE(count, kMaxLength);
1101*1b3f573fSAndroid Build Coastguard Worker       return count >= kMaxLength;
1102*1b3f573fSAndroid Build Coastguard Worker     }
1103*1b3f573fSAndroid Build Coastguard Worker 
1104*1b3f573fSAndroid Build Coastguard Worker     template <typename K>
1105*1b3f573fSAndroid Build Coastguard Worker     size_type BucketNumber(const K& k) const {
1106*1b3f573fSAndroid Build Coastguard Worker       // We xor the hash value against the random seed so that we effectively
1107*1b3f573fSAndroid Build Coastguard Worker       // have a random hash function.
1108*1b3f573fSAndroid Build Coastguard Worker       uint64_t h = hash_function()(k) ^ seed_;
1109*1b3f573fSAndroid Build Coastguard Worker 
1110*1b3f573fSAndroid Build Coastguard Worker       // We use the multiplication method to determine the bucket number from
1111*1b3f573fSAndroid Build Coastguard Worker       // the hash value. The constant kPhi (suggested by Knuth) is roughly
1112*1b3f573fSAndroid Build Coastguard Worker       // (sqrt(5) - 1) / 2 * 2^64.
1113*1b3f573fSAndroid Build Coastguard Worker       constexpr uint64_t kPhi = uint64_t{0x9e3779b97f4a7c15};
1114*1b3f573fSAndroid Build Coastguard Worker       return (internal::MultiplyWithOverflow(kPhi, h) >> 32) &
1115*1b3f573fSAndroid Build Coastguard Worker             (num_buckets_ - 1);
1116*1b3f573fSAndroid Build Coastguard Worker     }
1117*1b3f573fSAndroid Build Coastguard Worker 
1118*1b3f573fSAndroid Build Coastguard Worker     // Return a power of two no less than max(kMinTableSize, n).
1119*1b3f573fSAndroid Build Coastguard Worker     // Assumes either n < kMinTableSize or n is a power of two.
1120*1b3f573fSAndroid Build Coastguard Worker     size_type TableSize(size_type n) {
1121*1b3f573fSAndroid Build Coastguard Worker       return n < static_cast<size_type>(kMinTableSize)
1122*1b3f573fSAndroid Build Coastguard Worker                  ? static_cast<size_type>(kMinTableSize)
1123*1b3f573fSAndroid Build Coastguard Worker                  : n;
1124*1b3f573fSAndroid Build Coastguard Worker     }
1125*1b3f573fSAndroid Build Coastguard Worker 
1126*1b3f573fSAndroid Build Coastguard Worker     // Use alloc_ to allocate an array of n objects of type U.
1127*1b3f573fSAndroid Build Coastguard Worker     template <typename U>
1128*1b3f573fSAndroid Build Coastguard Worker     U* Alloc(size_type n) {
1129*1b3f573fSAndroid Build Coastguard Worker       using alloc_type = typename Allocator::template rebind<U>::other;
1130*1b3f573fSAndroid Build Coastguard Worker       return alloc_type(alloc_).allocate(n);
1131*1b3f573fSAndroid Build Coastguard Worker     }
1132*1b3f573fSAndroid Build Coastguard Worker 
1133*1b3f573fSAndroid Build Coastguard Worker     // Use alloc_ to deallocate an array of n objects of type U.
1134*1b3f573fSAndroid Build Coastguard Worker     template <typename U>
1135*1b3f573fSAndroid Build Coastguard Worker     void Dealloc(U* t, size_type n) {
1136*1b3f573fSAndroid Build Coastguard Worker       using alloc_type = typename Allocator::template rebind<U>::other;
1137*1b3f573fSAndroid Build Coastguard Worker       alloc_type(alloc_).deallocate(t, n);
1138*1b3f573fSAndroid Build Coastguard Worker     }
1139*1b3f573fSAndroid Build Coastguard Worker 
1140*1b3f573fSAndroid Build Coastguard Worker     void DestroyNode(Node* node) {
1141*1b3f573fSAndroid Build Coastguard Worker       if (alloc_.arena() == nullptr) {
1142*1b3f573fSAndroid Build Coastguard Worker         delete node;
1143*1b3f573fSAndroid Build Coastguard Worker       }
1144*1b3f573fSAndroid Build Coastguard Worker     }
1145*1b3f573fSAndroid Build Coastguard Worker 
1146*1b3f573fSAndroid Build Coastguard Worker     void DestroyTree(Tree* tree) {
1147*1b3f573fSAndroid Build Coastguard Worker       if (alloc_.arena() == nullptr) {
1148*1b3f573fSAndroid Build Coastguard Worker         delete tree;
1149*1b3f573fSAndroid Build Coastguard Worker       }
1150*1b3f573fSAndroid Build Coastguard Worker     }
1151*1b3f573fSAndroid Build Coastguard Worker 
1152*1b3f573fSAndroid Build Coastguard Worker     void** CreateEmptyTable(size_type n) {
1153*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK(n >= kMinTableSize);
1154*1b3f573fSAndroid Build Coastguard Worker       GOOGLE_DCHECK_EQ(n & (n - 1), 0u);
1155*1b3f573fSAndroid Build Coastguard Worker       void** result = Alloc<void*>(n);
1156*1b3f573fSAndroid Build Coastguard Worker       memset(result, 0, n * sizeof(result[0]));
1157*1b3f573fSAndroid Build Coastguard Worker       return result;
1158*1b3f573fSAndroid Build Coastguard Worker     }
1159*1b3f573fSAndroid Build Coastguard Worker 
1160*1b3f573fSAndroid Build Coastguard Worker     // Return a randomish value.
1161*1b3f573fSAndroid Build Coastguard Worker     size_type Seed() const {
1162*1b3f573fSAndroid Build Coastguard Worker       // We get a little bit of randomness from the address of the map. The
1163*1b3f573fSAndroid Build Coastguard Worker       // lower bits are not very random, due to alignment, so we discard them
1164*1b3f573fSAndroid Build Coastguard Worker       // and shift the higher bits into their place.
1165*1b3f573fSAndroid Build Coastguard Worker       size_type s = reinterpret_cast<uintptr_t>(this) >> 4;
1166*1b3f573fSAndroid Build Coastguard Worker #if !defined(GOOGLE_PROTOBUF_NO_RDTSC)
1167*1b3f573fSAndroid Build Coastguard Worker #if defined(__APPLE__)
1168*1b3f573fSAndroid Build Coastguard Worker       // Use a commpage-based fast time function on Apple environments (MacOS,
1169*1b3f573fSAndroid Build Coastguard Worker       // iOS, tvOS, watchOS, etc).
1170*1b3f573fSAndroid Build Coastguard Worker       s += mach_absolute_time();
1171*1b3f573fSAndroid Build Coastguard Worker #elif defined(__x86_64__) && defined(__GNUC__)
1172*1b3f573fSAndroid Build Coastguard Worker       uint32_t hi, lo;
1173*1b3f573fSAndroid Build Coastguard Worker       asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
1174*1b3f573fSAndroid Build Coastguard Worker       s += ((static_cast<uint64_t>(hi) << 32) | lo);
1175*1b3f573fSAndroid Build Coastguard Worker #elif defined(__aarch64__) && defined(__GNUC__)
1176*1b3f573fSAndroid Build Coastguard Worker       // There is no rdtsc on ARMv8. CNTVCT_EL0 is the virtual counter of the
1177*1b3f573fSAndroid Build Coastguard Worker       // system timer. It runs at a different frequency than the CPU's, but is
1178*1b3f573fSAndroid Build Coastguard Worker       // the best source of time-based entropy we get.
1179*1b3f573fSAndroid Build Coastguard Worker       uint64_t virtual_timer_value;
1180*1b3f573fSAndroid Build Coastguard Worker       asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
1181*1b3f573fSAndroid Build Coastguard Worker       s += virtual_timer_value;
1182*1b3f573fSAndroid Build Coastguard Worker #endif
1183*1b3f573fSAndroid Build Coastguard Worker #endif  // !defined(GOOGLE_PROTOBUF_NO_RDTSC)
1184*1b3f573fSAndroid Build Coastguard Worker       return s;
1185*1b3f573fSAndroid Build Coastguard Worker     }
1186*1b3f573fSAndroid Build Coastguard Worker 
1187*1b3f573fSAndroid Build Coastguard Worker     friend class Arena;
1188*1b3f573fSAndroid Build Coastguard Worker     using InternalArenaConstructable_ = void;
1189*1b3f573fSAndroid Build Coastguard Worker     using DestructorSkippable_ = void;
1190*1b3f573fSAndroid Build Coastguard Worker 
1191*1b3f573fSAndroid Build Coastguard Worker     size_type num_elements_;
1192*1b3f573fSAndroid Build Coastguard Worker     size_type num_buckets_;
1193*1b3f573fSAndroid Build Coastguard Worker     size_type seed_;
1194*1b3f573fSAndroid Build Coastguard Worker     size_type index_of_first_non_null_;
1195*1b3f573fSAndroid Build Coastguard Worker     void** table_;  // an array with num_buckets_ entries
1196*1b3f573fSAndroid Build Coastguard Worker     Allocator alloc_;
1197*1b3f573fSAndroid Build Coastguard Worker     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap);
1198*1b3f573fSAndroid Build Coastguard Worker   };  // end of class InnerMap
1199*1b3f573fSAndroid Build Coastguard Worker 
1200*1b3f573fSAndroid Build Coastguard Worker   template <typename LookupKey>
1201*1b3f573fSAndroid Build Coastguard Worker   using key_arg = typename internal::TransparentSupport<
1202*1b3f573fSAndroid Build Coastguard Worker       key_type>::template key_arg<LookupKey>;
1203*1b3f573fSAndroid Build Coastguard Worker 
1204*1b3f573fSAndroid Build Coastguard Worker  public:
1205*1b3f573fSAndroid Build Coastguard Worker   // Iterators
1206*1b3f573fSAndroid Build Coastguard Worker   class const_iterator {
1207*1b3f573fSAndroid Build Coastguard Worker     using InnerIt = typename InnerMap::const_iterator;
1208*1b3f573fSAndroid Build Coastguard Worker 
1209*1b3f573fSAndroid Build Coastguard Worker    public:
1210*1b3f573fSAndroid Build Coastguard Worker     using iterator_category = std::forward_iterator_tag;
1211*1b3f573fSAndroid Build Coastguard Worker     using value_type = typename Map::value_type;
1212*1b3f573fSAndroid Build Coastguard Worker     using difference_type = ptrdiff_t;
1213*1b3f573fSAndroid Build Coastguard Worker     using pointer = const value_type*;
1214*1b3f573fSAndroid Build Coastguard Worker     using reference = const value_type&;
1215*1b3f573fSAndroid Build Coastguard Worker 
1216*1b3f573fSAndroid Build Coastguard Worker     const_iterator() {}
1217*1b3f573fSAndroid Build Coastguard Worker     explicit const_iterator(const InnerIt& it) : it_(it) {}
1218*1b3f573fSAndroid Build Coastguard Worker 
1219*1b3f573fSAndroid Build Coastguard Worker     const_reference operator*() const { return *it_; }
1220*1b3f573fSAndroid Build Coastguard Worker     const_pointer operator->() const { return &(operator*()); }
1221*1b3f573fSAndroid Build Coastguard Worker 
1222*1b3f573fSAndroid Build Coastguard Worker     const_iterator& operator++() {
1223*1b3f573fSAndroid Build Coastguard Worker       ++it_;
1224*1b3f573fSAndroid Build Coastguard Worker       return *this;
1225*1b3f573fSAndroid Build Coastguard Worker     }
1226*1b3f573fSAndroid Build Coastguard Worker     const_iterator operator++(int) { return const_iterator(it_++); }
1227*1b3f573fSAndroid Build Coastguard Worker 
1228*1b3f573fSAndroid Build Coastguard Worker     friend bool operator==(const const_iterator& a, const const_iterator& b) {
1229*1b3f573fSAndroid Build Coastguard Worker       return a.it_ == b.it_;
1230*1b3f573fSAndroid Build Coastguard Worker     }
1231*1b3f573fSAndroid Build Coastguard Worker     friend bool operator!=(const const_iterator& a, const const_iterator& b) {
1232*1b3f573fSAndroid Build Coastguard Worker       return !(a == b);
1233*1b3f573fSAndroid Build Coastguard Worker     }
1234*1b3f573fSAndroid Build Coastguard Worker 
1235*1b3f573fSAndroid Build Coastguard Worker    private:
1236*1b3f573fSAndroid Build Coastguard Worker     InnerIt it_;
1237*1b3f573fSAndroid Build Coastguard Worker   };
1238*1b3f573fSAndroid Build Coastguard Worker 
1239*1b3f573fSAndroid Build Coastguard Worker   class iterator {
1240*1b3f573fSAndroid Build Coastguard Worker     using InnerIt = typename InnerMap::iterator;
1241*1b3f573fSAndroid Build Coastguard Worker 
1242*1b3f573fSAndroid Build Coastguard Worker    public:
1243*1b3f573fSAndroid Build Coastguard Worker     using iterator_category = std::forward_iterator_tag;
1244*1b3f573fSAndroid Build Coastguard Worker     using value_type = typename Map::value_type;
1245*1b3f573fSAndroid Build Coastguard Worker     using difference_type = ptrdiff_t;
1246*1b3f573fSAndroid Build Coastguard Worker     using pointer = value_type*;
1247*1b3f573fSAndroid Build Coastguard Worker     using reference = value_type&;
1248*1b3f573fSAndroid Build Coastguard Worker 
1249*1b3f573fSAndroid Build Coastguard Worker     iterator() {}
1250*1b3f573fSAndroid Build Coastguard Worker     explicit iterator(const InnerIt& it) : it_(it) {}
1251*1b3f573fSAndroid Build Coastguard Worker 
1252*1b3f573fSAndroid Build Coastguard Worker     reference operator*() const { return *it_; }
1253*1b3f573fSAndroid Build Coastguard Worker     pointer operator->() const { return &(operator*()); }
1254*1b3f573fSAndroid Build Coastguard Worker 
1255*1b3f573fSAndroid Build Coastguard Worker     iterator& operator++() {
1256*1b3f573fSAndroid Build Coastguard Worker       ++it_;
1257*1b3f573fSAndroid Build Coastguard Worker       return *this;
1258*1b3f573fSAndroid Build Coastguard Worker     }
1259*1b3f573fSAndroid Build Coastguard Worker     iterator operator++(int) { return iterator(it_++); }
1260*1b3f573fSAndroid Build Coastguard Worker 
1261*1b3f573fSAndroid Build Coastguard Worker     // Allow implicit conversion to const_iterator.
1262*1b3f573fSAndroid Build Coastguard Worker     operator const_iterator() const {  // NOLINT(runtime/explicit)
1263*1b3f573fSAndroid Build Coastguard Worker       return const_iterator(typename InnerMap::const_iterator(it_));
1264*1b3f573fSAndroid Build Coastguard Worker     }
1265*1b3f573fSAndroid Build Coastguard Worker 
1266*1b3f573fSAndroid Build Coastguard Worker     friend bool operator==(const iterator& a, const iterator& b) {
1267*1b3f573fSAndroid Build Coastguard Worker       return a.it_ == b.it_;
1268*1b3f573fSAndroid Build Coastguard Worker     }
1269*1b3f573fSAndroid Build Coastguard Worker     friend bool operator!=(const iterator& a, const iterator& b) {
1270*1b3f573fSAndroid Build Coastguard Worker       return !(a == b);
1271*1b3f573fSAndroid Build Coastguard Worker     }
1272*1b3f573fSAndroid Build Coastguard Worker 
1273*1b3f573fSAndroid Build Coastguard Worker    private:
1274*1b3f573fSAndroid Build Coastguard Worker     friend class Map;
1275*1b3f573fSAndroid Build Coastguard Worker 
1276*1b3f573fSAndroid Build Coastguard Worker     InnerIt it_;
1277*1b3f573fSAndroid Build Coastguard Worker   };
1278*1b3f573fSAndroid Build Coastguard Worker 
1279*1b3f573fSAndroid Build Coastguard Worker   iterator begin() { return iterator(elements_.begin()); }
1280*1b3f573fSAndroid Build Coastguard Worker   iterator end() { return iterator(elements_.end()); }
1281*1b3f573fSAndroid Build Coastguard Worker   const_iterator begin() const { return const_iterator(elements_.begin()); }
1282*1b3f573fSAndroid Build Coastguard Worker   const_iterator end() const { return const_iterator(elements_.end()); }
1283*1b3f573fSAndroid Build Coastguard Worker   const_iterator cbegin() const { return begin(); }
1284*1b3f573fSAndroid Build Coastguard Worker   const_iterator cend() const { return end(); }
1285*1b3f573fSAndroid Build Coastguard Worker 
1286*1b3f573fSAndroid Build Coastguard Worker   // Capacity
1287*1b3f573fSAndroid Build Coastguard Worker   size_type size() const { return elements_.size(); }
1288*1b3f573fSAndroid Build Coastguard Worker   bool empty() const { return size() == 0; }
1289*1b3f573fSAndroid Build Coastguard Worker 
1290*1b3f573fSAndroid Build Coastguard Worker   // Element access
1291*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1292*1b3f573fSAndroid Build Coastguard Worker   T& operator[](const key_arg<K>& key) {
1293*1b3f573fSAndroid Build Coastguard Worker     return elements_[key].second;
1294*1b3f573fSAndroid Build Coastguard Worker   }
1295*1b3f573fSAndroid Build Coastguard Worker   template <
1296*1b3f573fSAndroid Build Coastguard Worker       typename K = key_type,
1297*1b3f573fSAndroid Build Coastguard Worker       // Disable for integral types to reduce code bloat.
1298*1b3f573fSAndroid Build Coastguard Worker       typename = typename std::enable_if<!std::is_integral<K>::value>::type>
1299*1b3f573fSAndroid Build Coastguard Worker   T& operator[](key_arg<K>&& key) {
1300*1b3f573fSAndroid Build Coastguard Worker     return elements_[std::forward<K>(key)].second;
1301*1b3f573fSAndroid Build Coastguard Worker   }
1302*1b3f573fSAndroid Build Coastguard Worker 
1303*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1304*1b3f573fSAndroid Build Coastguard Worker   const T& at(const key_arg<K>& key) const {
1305*1b3f573fSAndroid Build Coastguard Worker     const_iterator it = find(key);
1306*1b3f573fSAndroid Build Coastguard Worker     GOOGLE_CHECK(it != end()) << "key not found: " << static_cast<Key>(key);
1307*1b3f573fSAndroid Build Coastguard Worker     return it->second;
1308*1b3f573fSAndroid Build Coastguard Worker   }
1309*1b3f573fSAndroid Build Coastguard Worker 
1310*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1311*1b3f573fSAndroid Build Coastguard Worker   T& at(const key_arg<K>& key) {
1312*1b3f573fSAndroid Build Coastguard Worker     iterator it = find(key);
1313*1b3f573fSAndroid Build Coastguard Worker     GOOGLE_CHECK(it != end()) << "key not found: " << static_cast<Key>(key);
1314*1b3f573fSAndroid Build Coastguard Worker     return it->second;
1315*1b3f573fSAndroid Build Coastguard Worker   }
1316*1b3f573fSAndroid Build Coastguard Worker 
1317*1b3f573fSAndroid Build Coastguard Worker   // Lookup
1318*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1319*1b3f573fSAndroid Build Coastguard Worker   size_type count(const key_arg<K>& key) const {
1320*1b3f573fSAndroid Build Coastguard Worker     return find(key) == end() ? 0 : 1;
1321*1b3f573fSAndroid Build Coastguard Worker   }
1322*1b3f573fSAndroid Build Coastguard Worker 
1323*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1324*1b3f573fSAndroid Build Coastguard Worker   const_iterator find(const key_arg<K>& key) const {
1325*1b3f573fSAndroid Build Coastguard Worker     return const_iterator(elements_.find(key));
1326*1b3f573fSAndroid Build Coastguard Worker   }
1327*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1328*1b3f573fSAndroid Build Coastguard Worker   iterator find(const key_arg<K>& key) {
1329*1b3f573fSAndroid Build Coastguard Worker     return iterator(elements_.find(key));
1330*1b3f573fSAndroid Build Coastguard Worker   }
1331*1b3f573fSAndroid Build Coastguard Worker 
1332*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1333*1b3f573fSAndroid Build Coastguard Worker   bool contains(const key_arg<K>& key) const {
1334*1b3f573fSAndroid Build Coastguard Worker     return find(key) != end();
1335*1b3f573fSAndroid Build Coastguard Worker   }
1336*1b3f573fSAndroid Build Coastguard Worker 
1337*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1338*1b3f573fSAndroid Build Coastguard Worker   std::pair<const_iterator, const_iterator> equal_range(
1339*1b3f573fSAndroid Build Coastguard Worker       const key_arg<K>& key) const {
1340*1b3f573fSAndroid Build Coastguard Worker     const_iterator it = find(key);
1341*1b3f573fSAndroid Build Coastguard Worker     if (it == end()) {
1342*1b3f573fSAndroid Build Coastguard Worker       return std::pair<const_iterator, const_iterator>(it, it);
1343*1b3f573fSAndroid Build Coastguard Worker     } else {
1344*1b3f573fSAndroid Build Coastguard Worker       const_iterator begin = it++;
1345*1b3f573fSAndroid Build Coastguard Worker       return std::pair<const_iterator, const_iterator>(begin, it);
1346*1b3f573fSAndroid Build Coastguard Worker     }
1347*1b3f573fSAndroid Build Coastguard Worker   }
1348*1b3f573fSAndroid Build Coastguard Worker 
1349*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1350*1b3f573fSAndroid Build Coastguard Worker   std::pair<iterator, iterator> equal_range(const key_arg<K>& key) {
1351*1b3f573fSAndroid Build Coastguard Worker     iterator it = find(key);
1352*1b3f573fSAndroid Build Coastguard Worker     if (it == end()) {
1353*1b3f573fSAndroid Build Coastguard Worker       return std::pair<iterator, iterator>(it, it);
1354*1b3f573fSAndroid Build Coastguard Worker     } else {
1355*1b3f573fSAndroid Build Coastguard Worker       iterator begin = it++;
1356*1b3f573fSAndroid Build Coastguard Worker       return std::pair<iterator, iterator>(begin, it);
1357*1b3f573fSAndroid Build Coastguard Worker     }
1358*1b3f573fSAndroid Build Coastguard Worker   }
1359*1b3f573fSAndroid Build Coastguard Worker 
1360*1b3f573fSAndroid Build Coastguard Worker   // insert
1361*1b3f573fSAndroid Build Coastguard Worker   template <typename K, typename... Args>
1362*1b3f573fSAndroid Build Coastguard Worker   std::pair<iterator, bool> try_emplace(K&& k, Args&&... args) {
1363*1b3f573fSAndroid Build Coastguard Worker     auto p =
1364*1b3f573fSAndroid Build Coastguard Worker         elements_.try_emplace(std::forward<K>(k), std::forward<Args>(args)...);
1365*1b3f573fSAndroid Build Coastguard Worker     return std::pair<iterator, bool>(iterator(p.first), p.second);
1366*1b3f573fSAndroid Build Coastguard Worker   }
1367*1b3f573fSAndroid Build Coastguard Worker   std::pair<iterator, bool> insert(const value_type& value) {
1368*1b3f573fSAndroid Build Coastguard Worker     return try_emplace(value.first, value.second);
1369*1b3f573fSAndroid Build Coastguard Worker   }
1370*1b3f573fSAndroid Build Coastguard Worker   std::pair<iterator, bool> insert(value_type&& value) {
1371*1b3f573fSAndroid Build Coastguard Worker     return try_emplace(value.first, std::move(value.second));
1372*1b3f573fSAndroid Build Coastguard Worker   }
1373*1b3f573fSAndroid Build Coastguard Worker   template <typename... Args>
1374*1b3f573fSAndroid Build Coastguard Worker   std::pair<iterator, bool> emplace(Args&&... args) {
1375*1b3f573fSAndroid Build Coastguard Worker     return insert(value_type(std::forward<Args>(args)...));
1376*1b3f573fSAndroid Build Coastguard Worker   }
1377*1b3f573fSAndroid Build Coastguard Worker   template <class InputIt>
1378*1b3f573fSAndroid Build Coastguard Worker   void insert(InputIt first, InputIt last) {
1379*1b3f573fSAndroid Build Coastguard Worker     for (; first != last; ++first) {
1380*1b3f573fSAndroid Build Coastguard Worker       try_emplace(first->first, first->second);
1381*1b3f573fSAndroid Build Coastguard Worker     }
1382*1b3f573fSAndroid Build Coastguard Worker   }
1383*1b3f573fSAndroid Build Coastguard Worker   void insert(std::initializer_list<value_type> values) {
1384*1b3f573fSAndroid Build Coastguard Worker     insert(values.begin(), values.end());
1385*1b3f573fSAndroid Build Coastguard Worker   }
1386*1b3f573fSAndroid Build Coastguard Worker 
1387*1b3f573fSAndroid Build Coastguard Worker   // Erase and clear
1388*1b3f573fSAndroid Build Coastguard Worker   template <typename K = key_type>
1389*1b3f573fSAndroid Build Coastguard Worker   size_type erase(const key_arg<K>& key) {
1390*1b3f573fSAndroid Build Coastguard Worker     iterator it = find(key);
1391*1b3f573fSAndroid Build Coastguard Worker     if (it == end()) {
1392*1b3f573fSAndroid Build Coastguard Worker       return 0;
1393*1b3f573fSAndroid Build Coastguard Worker     } else {
1394*1b3f573fSAndroid Build Coastguard Worker       erase(it);
1395*1b3f573fSAndroid Build Coastguard Worker       return 1;
1396*1b3f573fSAndroid Build Coastguard Worker     }
1397*1b3f573fSAndroid Build Coastguard Worker   }
1398*1b3f573fSAndroid Build Coastguard Worker   iterator erase(iterator pos) {
1399*1b3f573fSAndroid Build Coastguard Worker     iterator i = pos++;
1400*1b3f573fSAndroid Build Coastguard Worker     elements_.erase(i.it_);
1401*1b3f573fSAndroid Build Coastguard Worker     return pos;
1402*1b3f573fSAndroid Build Coastguard Worker   }
1403*1b3f573fSAndroid Build Coastguard Worker   void erase(iterator first, iterator last) {
1404*1b3f573fSAndroid Build Coastguard Worker     while (first != last) {
1405*1b3f573fSAndroid Build Coastguard Worker       first = erase(first);
1406*1b3f573fSAndroid Build Coastguard Worker     }
1407*1b3f573fSAndroid Build Coastguard Worker   }
1408*1b3f573fSAndroid Build Coastguard Worker   void clear() { elements_.clear(); }
1409*1b3f573fSAndroid Build Coastguard Worker 
1410*1b3f573fSAndroid Build Coastguard Worker   // Assign
1411*1b3f573fSAndroid Build Coastguard Worker   Map& operator=(const Map& other) {
1412*1b3f573fSAndroid Build Coastguard Worker     if (this != &other) {
1413*1b3f573fSAndroid Build Coastguard Worker       clear();
1414*1b3f573fSAndroid Build Coastguard Worker       insert(other.begin(), other.end());
1415*1b3f573fSAndroid Build Coastguard Worker     }
1416*1b3f573fSAndroid Build Coastguard Worker     return *this;
1417*1b3f573fSAndroid Build Coastguard Worker   }
1418*1b3f573fSAndroid Build Coastguard Worker 
1419*1b3f573fSAndroid Build Coastguard Worker   void swap(Map& other) {
1420*1b3f573fSAndroid Build Coastguard Worker     if (arena() == other.arena()) {
1421*1b3f573fSAndroid Build Coastguard Worker       InternalSwap(other);
1422*1b3f573fSAndroid Build Coastguard Worker     } else {
1423*1b3f573fSAndroid Build Coastguard Worker       // TODO(zuguang): optimize this. The temporary copy can be allocated
1424*1b3f573fSAndroid Build Coastguard Worker       // in the same arena as the other message, and the "other = copy" can
1425*1b3f573fSAndroid Build Coastguard Worker       // be replaced with the fast-path swap above.
1426*1b3f573fSAndroid Build Coastguard Worker       Map copy = *this;
1427*1b3f573fSAndroid Build Coastguard Worker       *this = other;
1428*1b3f573fSAndroid Build Coastguard Worker       other = copy;
1429*1b3f573fSAndroid Build Coastguard Worker     }
1430*1b3f573fSAndroid Build Coastguard Worker   }
1431*1b3f573fSAndroid Build Coastguard Worker 
1432*1b3f573fSAndroid Build Coastguard Worker   void InternalSwap(Map& other) { elements_.Swap(&other.elements_); }
1433*1b3f573fSAndroid Build Coastguard Worker 
1434*1b3f573fSAndroid Build Coastguard Worker   // Access to hasher.  Currently this returns a copy, but it may
1435*1b3f573fSAndroid Build Coastguard Worker   // be modified to return a const reference in the future.
1436*1b3f573fSAndroid Build Coastguard Worker   hasher hash_function() const { return elements_.hash_function(); }
1437*1b3f573fSAndroid Build Coastguard Worker 
1438*1b3f573fSAndroid Build Coastguard Worker   size_t SpaceUsedExcludingSelfLong() const {
1439*1b3f573fSAndroid Build Coastguard Worker     if (empty()) return 0;
1440*1b3f573fSAndroid Build Coastguard Worker     return elements_.SpaceUsedInternal() + internal::SpaceUsedInValues(this);
1441*1b3f573fSAndroid Build Coastguard Worker   }
1442*1b3f573fSAndroid Build Coastguard Worker 
1443*1b3f573fSAndroid Build Coastguard Worker  private:
1444*1b3f573fSAndroid Build Coastguard Worker   Arena* arena() const { return elements_.arena(); }
1445*1b3f573fSAndroid Build Coastguard Worker   InnerMap elements_;
1446*1b3f573fSAndroid Build Coastguard Worker 
1447*1b3f573fSAndroid Build Coastguard Worker   friend class Arena;
1448*1b3f573fSAndroid Build Coastguard Worker   using InternalArenaConstructable_ = void;
1449*1b3f573fSAndroid Build Coastguard Worker   using DestructorSkippable_ = void;
1450*1b3f573fSAndroid Build Coastguard Worker   template <typename Derived, typename K, typename V,
1451*1b3f573fSAndroid Build Coastguard Worker             internal::WireFormatLite::FieldType key_wire_type,
1452*1b3f573fSAndroid Build Coastguard Worker             internal::WireFormatLite::FieldType value_wire_type>
1453*1b3f573fSAndroid Build Coastguard Worker   friend class internal::MapFieldLite;
1454*1b3f573fSAndroid Build Coastguard Worker };
1455*1b3f573fSAndroid Build Coastguard Worker 
1456*1b3f573fSAndroid Build Coastguard Worker }  // namespace protobuf
1457*1b3f573fSAndroid Build Coastguard Worker }  // namespace google
1458*1b3f573fSAndroid Build Coastguard Worker 
1459*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/port_undef.inc>
1460*1b3f573fSAndroid Build Coastguard Worker 
1461*1b3f573fSAndroid Build Coastguard Worker #endif  // GOOGLE_PROTOBUF_MAP_H__
1462