1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9//     * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11//     * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15//     * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#ifndef GOOGLE_PROTOBUF_MAP_H__
32#define GOOGLE_PROTOBUF_MAP_H__
33
34#include <google/protobuf/stubs/hash.h>
35#include <iterator>
36#include <limits>  // To support Visual Studio 2008
37#include <set>
38#include <utility>
39
40#include <google/protobuf/stubs/common.h>
41#include <google/protobuf/arena.h>
42#include <google/protobuf/generated_enum_util.h>
43#include <google/protobuf/map_type_handler.h>
44#include <google/protobuf/message.h>
45#include <google/protobuf/descriptor.h>
46#if __cpp_exceptions && LANG_CXX11
47#include <random>
48#endif
49
50namespace google {
51namespace protobuf {
52
53// The Map and MapIterator types are provided by this header file.
54// Please avoid using other types defined here, unless they are public
55// types within Map or MapIterator, such as Map::value_type.
56template <typename Key, typename T>
57class Map;
58
59class MapIterator;
60
61template <typename Enum> struct is_proto_enum;
62
63namespace internal {
64template <typename Key, typename T,
65          WireFormatLite::FieldType key_wire_type,
66          WireFormatLite::FieldType value_wire_type,
67          int default_enum_value>
68class MapFieldLite;
69
70template <typename Key, typename T,
71          WireFormatLite::FieldType key_wire_type,
72          WireFormatLite::FieldType value_wire_type,
73          int default_enum_value>
74class MapField;
75
76template <typename Key, typename T>
77class TypeDefinedMapFieldBase;
78
79class DynamicMapField;
80
81class GeneratedMessageReflection;
82}  // namespace internal
83
84#define TYPE_CHECK(EXPECTEDTYPE, METHOD)                        \
85  if (type() != EXPECTEDTYPE) {                                 \
86    GOOGLE_LOG(FATAL)                                                  \
87        << "Protocol Buffer map usage error:\n"                 \
88        << METHOD << " type does not match\n"                   \
89        << "  Expected : "                                      \
90        << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n"   \
91        << "  Actual   : "                                      \
92        << FieldDescriptor::CppTypeName(type());                \
93  }
94
95// MapKey is an union type for representing any possible
96// map key.
97class LIBPROTOBUF_EXPORT MapKey {
98 public:
99  MapKey() : type_(0) {
100  }
101  MapKey(const MapKey& other) : type_(0) {
102    CopyFrom(other);
103  }
104
105  ~MapKey() {
106    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
107      delete val_.string_value_;
108    }
109  }
110
111  FieldDescriptor::CppType type() const {
112    if (type_ == 0) {
113      GOOGLE_LOG(FATAL)
114          << "Protocol Buffer map usage error:\n"
115          << "MapKey::type MapKey is not initialized. "
116          << "Call set methods to initialize MapKey.";
117    }
118    return (FieldDescriptor::CppType)type_;
119  }
120
121  void SetInt64Value(int64 value) {
122    SetType(FieldDescriptor::CPPTYPE_INT64);
123    val_.int64_value_ = value;
124  }
125  void SetUInt64Value(uint64 value) {
126    SetType(FieldDescriptor::CPPTYPE_UINT64);
127    val_.uint64_value_ = value;
128  }
129  void SetInt32Value(int32 value) {
130    SetType(FieldDescriptor::CPPTYPE_INT32);
131    val_.int32_value_ = value;
132  }
133  void SetUInt32Value(uint32 value) {
134    SetType(FieldDescriptor::CPPTYPE_UINT32);
135    val_.uint32_value_ = value;
136  }
137  void SetBoolValue(bool value) {
138    SetType(FieldDescriptor::CPPTYPE_BOOL);
139    val_.bool_value_ = value;
140  }
141  void SetStringValue(const string& val) {
142    SetType(FieldDescriptor::CPPTYPE_STRING);
143    *val_.string_value_ = val;
144  }
145
146  int64 GetInt64Value() const {
147    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
148               "MapKey::GetInt64Value");
149    return val_.int64_value_;
150  }
151  uint64 GetUInt64Value() const {
152    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
153               "MapKey::GetUInt64Value");
154    return val_.uint64_value_;
155  }
156  int32 GetInt32Value() const {
157    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
158               "MapKey::GetInt32Value");
159    return val_.int32_value_;
160  }
161  uint32 GetUInt32Value() const {
162    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
163               "MapKey::GetUInt32Value");
164    return val_.uint32_value_;
165  }
166  bool GetBoolValue() const {
167    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
168               "MapKey::GetBoolValue");
169    return val_.bool_value_;
170  }
171  const string& GetStringValue() const {
172    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
173               "MapKey::GetStringValue");
174    return *val_.string_value_;
175  }
176
177  bool operator<(const MapKey& other) const {
178    if (type_ != other.type_) {
179      // We could define a total order that handles this case, but
180      // there currently no need.  So, for now, fail.
181      GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
182    }
183    switch (type()) {
184      case FieldDescriptor::CPPTYPE_DOUBLE:
185      case FieldDescriptor::CPPTYPE_FLOAT:
186      case FieldDescriptor::CPPTYPE_ENUM:
187      case FieldDescriptor::CPPTYPE_MESSAGE:
188        GOOGLE_LOG(FATAL) << "Unsupported";
189        return false;
190      case FieldDescriptor::CPPTYPE_STRING:
191        return *val_.string_value_ < *other.val_.string_value_;
192      case FieldDescriptor::CPPTYPE_INT64:
193        return val_.int64_value_ < other.val_.int64_value_;
194      case FieldDescriptor::CPPTYPE_INT32:
195        return val_.int32_value_ < other.val_.int32_value_;
196      case FieldDescriptor::CPPTYPE_UINT64:
197        return val_.uint64_value_ < other.val_.uint64_value_;
198      case FieldDescriptor::CPPTYPE_UINT32:
199        return val_.uint32_value_ < other.val_.uint32_value_;
200      case FieldDescriptor::CPPTYPE_BOOL:
201        return val_.bool_value_ < other.val_.bool_value_;
202    }
203    return false;
204  }
205
206  bool operator==(const MapKey& other) const {
207    if (type_ != other.type_) {
208      // To be consistent with operator<, we don't allow this either.
209      GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
210    }
211    switch (type()) {
212      case FieldDescriptor::CPPTYPE_DOUBLE:
213      case FieldDescriptor::CPPTYPE_FLOAT:
214      case FieldDescriptor::CPPTYPE_ENUM:
215      case FieldDescriptor::CPPTYPE_MESSAGE:
216        GOOGLE_LOG(FATAL) << "Unsupported";
217        break;
218      case FieldDescriptor::CPPTYPE_STRING:
219        return *val_.string_value_ == *other.val_.string_value_;
220      case FieldDescriptor::CPPTYPE_INT64:
221        return val_.int64_value_ == other.val_.int64_value_;
222      case FieldDescriptor::CPPTYPE_INT32:
223        return val_.int32_value_ == other.val_.int32_value_;
224      case FieldDescriptor::CPPTYPE_UINT64:
225        return val_.uint64_value_ == other.val_.uint64_value_;
226      case FieldDescriptor::CPPTYPE_UINT32:
227        return val_.uint32_value_ == other.val_.uint32_value_;
228      case FieldDescriptor::CPPTYPE_BOOL:
229        return val_.bool_value_ == other.val_.bool_value_;
230    }
231    GOOGLE_LOG(FATAL) << "Can't get here.";
232    return false;
233  }
234
235  void CopyFrom(const MapKey& other) {
236    SetType(other.type());
237    switch (type_) {
238      case FieldDescriptor::CPPTYPE_DOUBLE:
239      case FieldDescriptor::CPPTYPE_FLOAT:
240      case FieldDescriptor::CPPTYPE_ENUM:
241      case FieldDescriptor::CPPTYPE_MESSAGE:
242        GOOGLE_LOG(FATAL) << "Unsupported";
243        break;
244      case FieldDescriptor::CPPTYPE_STRING:
245        *val_.string_value_ = *other.val_.string_value_;
246        break;
247      case FieldDescriptor::CPPTYPE_INT64:
248        val_.int64_value_ = other.val_.int64_value_;
249        break;
250      case FieldDescriptor::CPPTYPE_INT32:
251        val_.int32_value_ = other.val_.int32_value_;
252        break;
253      case FieldDescriptor::CPPTYPE_UINT64:
254        val_.uint64_value_ = other.val_.uint64_value_;
255        break;
256      case FieldDescriptor::CPPTYPE_UINT32:
257        val_.uint32_value_ = other.val_.uint32_value_;
258        break;
259      case FieldDescriptor::CPPTYPE_BOOL:
260        val_.bool_value_ = other.val_.bool_value_;
261        break;
262    }
263  }
264
265 private:
266  template <typename K, typename V>
267  friend class internal::TypeDefinedMapFieldBase;
268  friend class MapIterator;
269  friend class internal::DynamicMapField;
270
271  union KeyValue {
272    KeyValue() {}
273    string* string_value_;
274    int64 int64_value_;
275    int32 int32_value_;
276    uint64 uint64_value_;
277    uint32 uint32_value_;
278    bool bool_value_;
279  } val_;
280
281  void SetType(FieldDescriptor::CppType type) {
282    if (type_ == type) return;
283    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
284      delete val_.string_value_;
285    }
286    type_ = type;
287    if (type_ == FieldDescriptor::CPPTYPE_STRING) {
288      val_.string_value_ = new string;
289    }
290  }
291
292  // type_ is 0 or a valid FieldDescriptor::CppType.
293  int type_;
294};
295
296// MapValueRef points to a map value.
297class LIBPROTOBUF_EXPORT MapValueRef {
298 public:
299  MapValueRef() : data_(NULL), type_(0) {}
300
301  void SetInt64Value(int64 value) {
302    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
303               "MapValueRef::SetInt64Value");
304    *reinterpret_cast<int64*>(data_) = value;
305  }
306  void SetUInt64Value(uint64 value) {
307    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
308               "MapValueRef::SetUInt64Value");
309    *reinterpret_cast<uint64*>(data_) = value;
310  }
311  void SetInt32Value(int32 value) {
312    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
313               "MapValueRef::SetInt32Value");
314    *reinterpret_cast<int32*>(data_) = value;
315  }
316  void SetUInt32Value(uint32 value) {
317    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
318               "MapValueRef::SetUInt32Value");
319    *reinterpret_cast<uint32*>(data_) = value;
320  }
321  void SetBoolValue(bool value) {
322    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
323               "MapValueRef::SetBoolValue");
324    *reinterpret_cast<bool*>(data_) = value;
325  }
326  // TODO(jieluo) - Checks that enum is member.
327  void SetEnumValue(int value) {
328    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
329               "MapValueRef::SetEnumValue");
330    *reinterpret_cast<int*>(data_) = value;
331  }
332  void SetStringValue(const string& value) {
333    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
334               "MapValueRef::SetStringValue");
335    *reinterpret_cast<string*>(data_) = value;
336  }
337  void SetFloatValue(float value) {
338    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
339               "MapValueRef::SetFloatValue");
340    *reinterpret_cast<float*>(data_) = value;
341  }
342  void SetDoubleValue(double value) {
343    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
344               "MapValueRef::SetDoubleValue");
345    *reinterpret_cast<double*>(data_) = value;
346  }
347
348  int64 GetInt64Value() const {
349    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
350               "MapValueRef::GetInt64Value");
351    return *reinterpret_cast<int64*>(data_);
352  }
353  uint64 GetUInt64Value() const {
354    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
355               "MapValueRef::GetUInt64Value");
356    return *reinterpret_cast<uint64*>(data_);
357  }
358  int32 GetInt32Value() const {
359    TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
360               "MapValueRef::GetInt32Value");
361    return *reinterpret_cast<int32*>(data_);
362  }
363  uint32 GetUInt32Value() const {
364    TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
365               "MapValueRef::GetUInt32Value");
366    return *reinterpret_cast<uint32*>(data_);
367  }
368  bool GetBoolValue() const {
369    TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
370               "MapValueRef::GetBoolValue");
371    return *reinterpret_cast<bool*>(data_);
372  }
373  int GetEnumValue() const {
374    TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
375               "MapValueRef::GetEnumValue");
376    return *reinterpret_cast<int*>(data_);
377  }
378  const string& GetStringValue() const {
379    TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
380               "MapValueRef::GetStringValue");
381    return *reinterpret_cast<string*>(data_);
382  }
383  float GetFloatValue() const {
384    TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
385               "MapValueRef::GetFloatValue");
386    return *reinterpret_cast<float*>(data_);
387  }
388  double GetDoubleValue() const {
389    TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
390               "MapValueRef::GetDoubleValue");
391    return *reinterpret_cast<double*>(data_);
392  }
393
394  const Message& GetMessageValue() const {
395    TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
396               "MapValueRef::GetMessageValue");
397    return *reinterpret_cast<Message*>(data_);
398  }
399
400  Message* MutableMessageValue() {
401    TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
402               "MapValueRef::MutableMessageValue");
403    return reinterpret_cast<Message*>(data_);
404  }
405
406 private:
407  template <typename K, typename V,
408            internal::WireFormatLite::FieldType key_wire_type,
409            internal::WireFormatLite::FieldType value_wire_type,
410            int default_enum_value>
411  friend class internal::MapField;
412  template <typename K, typename V>
413  friend class internal::TypeDefinedMapFieldBase;
414  friend class MapIterator;
415  friend class internal::GeneratedMessageReflection;
416  friend class internal::DynamicMapField;
417
418  void SetType(FieldDescriptor::CppType type) {
419    type_ = type;
420  }
421
422  FieldDescriptor::CppType type() const {
423    if (type_ == 0 || data_ == NULL) {
424      GOOGLE_LOG(FATAL)
425          << "Protocol Buffer map usage error:\n"
426          << "MapValueRef::type MapValueRef is not initialized.";
427    }
428    return (FieldDescriptor::CppType)type_;
429  }
430  void SetValue(const void* val) {
431    data_ = const_cast<void*>(val);
432  }
433  void CopyFrom(const MapValueRef& other) {
434    type_ = other.type_;
435    data_ = other.data_;
436  }
437  // Only used in DynamicMapField
438  void DeleteData() {
439    switch (type_) {
440#define HANDLE_TYPE(CPPTYPE, TYPE)                              \
441      case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
442        delete reinterpret_cast<TYPE*>(data_);                  \
443        break;                                                  \
444      }
445      HANDLE_TYPE(INT32, int32);
446      HANDLE_TYPE(INT64, int64);
447      HANDLE_TYPE(UINT32, uint32);
448      HANDLE_TYPE(UINT64, uint64);
449      HANDLE_TYPE(DOUBLE, double);
450      HANDLE_TYPE(FLOAT, float);
451      HANDLE_TYPE(BOOL, bool);
452      HANDLE_TYPE(STRING, string);
453      HANDLE_TYPE(ENUM, int32);
454      HANDLE_TYPE(MESSAGE, Message);
455#undef HANDLE_TYPE
456    }
457  }
458  // data_ point to a map value. MapValueRef does not
459  // own this value.
460  void* data_;
461  // type_ is 0 or a valid FieldDescriptor::CppType.
462  int type_;
463};
464
465#undef TYPE_CHECK
466
467// This is the class for google::protobuf::Map's internal value_type. Instead of using
468// std::pair as value_type, we use this class which provides us more control of
469// its process of construction and destruction.
470template <typename Key, typename T>
471class MapPair {
472 public:
473  typedef const Key first_type;
474  typedef T second_type;
475
476  MapPair(const Key& other_first, const T& other_second)
477      : first(other_first), second(other_second) {}
478  explicit MapPair(const Key& other_first) : first(other_first), second() {}
479  MapPair(const MapPair& other)
480      : first(other.first), second(other.second) {}
481
482  ~MapPair() {}
483
484  // Implicitly convertible to std::pair of compatible types.
485  template <typename T1, typename T2>
486  operator std::pair<T1, T2>() const {
487    return std::pair<T1, T2>(first, second);
488  }
489
490  const Key first;
491  T second;
492
493 private:
494  friend class ::google::protobuf::Arena;
495  friend class Map<Key, T>;
496};
497
498// google::protobuf::Map is an associative container type used to store protobuf map
499// fields.  Each Map instance may or may not use a different hash function, a
500// different iteration order, and so on.  E.g., please don't examine
501// implementation details to decide if the following would work:
502//  Map<int, int> m0, m1;
503//  m0[0] = m1[0] = m0[1] = m1[1] = 0;
504//  assert(m0.begin()->first == m1.begin()->first);  // Bug!
505//
506// Map's interface is similar to std::unordered_map, except that Map is not
507// designed to play well with exceptions.
508template <typename Key, typename T>
509class Map {
510 public:
511  typedef Key key_type;
512  typedef T mapped_type;
513  typedef MapPair<Key, T> value_type;
514
515  typedef value_type* pointer;
516  typedef const value_type* const_pointer;
517  typedef value_type& reference;
518  typedef const value_type& const_reference;
519
520  typedef size_t size_type;
521  typedef hash<Key> hasher;
522
523  Map(bool old_style = true)
524      : arena_(NULL),
525        default_enum_value_(0),
526        old_style_(old_style) {
527    Init();
528  }
529  explicit Map(Arena* arena, bool old_style = true)
530      : arena_(arena),
531        default_enum_value_(0),
532        old_style_(old_style) {
533    Init();
534  }
535  Map(const Map& other)
536      : arena_(NULL),
537        default_enum_value_(other.default_enum_value_),
538        old_style_(other.old_style_) {
539    Init();
540    insert(other.begin(), other.end());
541  }
542  template <class InputIt>
543  Map(const InputIt& first, const InputIt& last, bool old_style = true)
544      : arena_(NULL),
545        default_enum_value_(0),
546        old_style_(old_style) {
547    Init();
548    insert(first, last);
549  }
550
551  ~Map() {
552    clear();
553    if (arena_ == NULL) {
554      if (old_style_)
555        delete deprecated_elements_;
556      else
557        delete elements_;
558    }
559  }
560
561 private:
562  void Init() {
563    if (old_style_)
564      deprecated_elements_ = Arena::Create<DeprecatedInnerMap>(
565          arena_, 0, hasher(), equal_to<Key>(),
566          MapAllocator<std::pair<const Key, MapPair<Key, T>*> >(arena_));
567    else
568      elements_ =
569          Arena::Create<InnerMap>(arena_, 0, hasher(), Allocator(arena_));
570  }
571
572  // re-implement std::allocator to use arena allocator for memory allocation.
573  // Used for google::protobuf::Map implementation. Users should not use this class
574  // directly.
575  template <typename U>
576  class MapAllocator {
577   public:
578    typedef U value_type;
579    typedef value_type* pointer;
580    typedef const value_type* const_pointer;
581    typedef value_type& reference;
582    typedef const value_type& const_reference;
583    typedef size_t size_type;
584    typedef ptrdiff_t difference_type;
585
586    MapAllocator() : arena_(NULL) {}
587    explicit MapAllocator(Arena* arena) : arena_(arena) {}
588    template <typename X>
589    MapAllocator(const MapAllocator<X>& allocator)
590        : arena_(allocator.arena()) {}
591
592    pointer allocate(size_type n, const_pointer hint = 0) {
593      // If arena is not given, malloc needs to be called which doesn't
594      // construct element object.
595      if (arena_ == NULL) {
596        return reinterpret_cast<pointer>(malloc(n * sizeof(value_type)));
597      } else {
598        return reinterpret_cast<pointer>(
599            Arena::CreateArray<uint8>(arena_, n * sizeof(value_type)));
600      }
601    }
602
603    void deallocate(pointer p, size_type n) {
604      if (arena_ == NULL) {
605        free(p);
606      }
607    }
608
609#if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) && \
610    !defined(GOOGLE_PROTOBUF_OS_NACL) &&                            \
611    !defined(GOOGLE_PROTOBUF_OS_ANDROID) &&                         \
612    !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN)
613    template<class NodeType, class... Args>
614    void construct(NodeType* p, Args&&... args) {
615      // Clang 3.6 doesn't compile static casting to void* directly. (Issue
616      // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall
617      // not cast away constness". So first the maybe const pointer is casted to
618      // const void* and after the const void* is const casted.
619      new (const_cast<void*>(static_cast<const void*>(p)))
620          NodeType(std::forward<Args>(args)...);
621    }
622
623    template<class NodeType>
624    void destroy(NodeType* p) {
625      p->~NodeType();
626    }
627#else
628    void construct(pointer p, const_reference t) { new (p) value_type(t); }
629
630    void destroy(pointer p) { p->~value_type(); }
631#endif
632
633    template <typename X>
634    struct rebind {
635      typedef MapAllocator<X> other;
636    };
637
638    template <typename X>
639    bool operator==(const MapAllocator<X>& other) const {
640      return arena_ == other.arena_;
641    }
642
643    template <typename X>
644    bool operator!=(const MapAllocator<X>& other) const {
645      return arena_ != other.arena_;
646    }
647
648    // To support Visual Studio 2008
649    size_type max_size() const {
650      return std::numeric_limits<size_type>::max();
651    }
652
653    // To support gcc-4.4, which does not properly
654    // support templated friend classes
655    Arena* arena() const {
656      return arena_;
657    }
658
659   private:
660    typedef void DestructorSkippable_;
661    Arena* const arena_;
662  };
663
664  // InnerMap's key type is Key and its value type is value_type*.  We use a
665  // custom class here and for Node, below, to ensure that k_ is at offset 0,
666  // allowing safe conversion from pointer to Node to pointer to Key, and vice
667  // versa when appropriate.
668  class KeyValuePair {
669   public:
670    KeyValuePair(const Key& k, value_type* v) : k_(k), v_(v) {}
671
672    const Key& key() const { return k_; }
673    Key& key() { return k_; }
674    value_type* const value() const { return v_; }
675    value_type*& value() { return v_; }
676
677   private:
678    Key k_;
679    value_type* v_;
680  };
681
682  typedef MapAllocator<KeyValuePair> Allocator;
683
684  // InnerMap is a generic hash-based map.  It doesn't contain any
685  // protocol-buffer-specific logic.  It is a chaining hash map with the
686  // additional feature that some buckets can be converted to use an ordered
687  // container.  This ensures O(lg n) bounds on find, insert, and erase, while
688  // avoiding the overheads of ordered containers most of the time.
689  //
690  // The implementation doesn't need the full generality of unordered_map,
691  // and it doesn't have it.  More bells and whistles can be added as needed.
692  // Some implementation details:
693  // 1. The hash function has type hasher and the equality function
694  //    equal_to<Key>.  We inherit from hasher to save space
695  //    (empty-base-class optimization).
696  // 2. The number of buckets is a power of two.
697  // 3. Buckets are converted to trees in pairs: if we convert bucket b then
698  //    buckets b and b^1 will share a tree.  Invariant: buckets b and b^1 have
699  //    the same non-NULL value iff they are sharing a tree.  (An alternative
700  //    implementation strategy would be to have a tag bit per bucket.)
701  // 4. As is typical for hash_map and such, the Keys and Values are always
702  //    stored in linked list nodes.  Pointers to elements are never invalidated
703  //    until the element is deleted.
704  // 5. The trees' payload type is pointer to linked-list node.  Tree-converting
705  //    a bucket doesn't copy Key-Value pairs.
706  // 6. Once we've tree-converted a bucket, it is never converted back. However,
707  //    the items a tree contains may wind up assigned to trees or lists upon a
708  //    rehash.
709  // 7. The code requires no C++ features from C++11 or later.
710  // 8. Mutations to a map do not invalidate the map's iterators, pointers to
711  //    elements, or references to elements.
712  // 9. Except for erase(iterator), any non-const method can reorder iterators.
713  class InnerMap : private hasher {
714   public:
715    typedef value_type* Value;
716
717    InnerMap(size_type n, hasher h, Allocator alloc)
718        : hasher(h),
719          num_elements_(0),
720          seed_(Seed()),
721          table_(NULL),
722          alloc_(alloc) {
723      n = TableSize(n);
724      table_ = CreateEmptyTable(n);
725      num_buckets_ = index_of_first_non_null_ = n;
726    }
727
728    ~InnerMap() {
729      if (table_ != NULL) {
730        clear();
731        Dealloc<void*>(table_, num_buckets_);
732      }
733    }
734
735   private:
736    enum { kMinTableSize = 8 };
737
738    // Linked-list nodes, as one would expect for a chaining hash table.
739    struct Node {
740      KeyValuePair kv;
741      Node* next;
742    };
743
744    // This is safe only if the given pointer is known to point to a Key that is
745    // part of a Node.
746    static Node* NodePtrFromKeyPtr(Key* k) {
747      return reinterpret_cast<Node*>(k);
748    }
749
750    static Key* KeyPtrFromNodePtr(Node* node) { return &node->kv.key(); }
751
752    // Trees.  The payload type is pointer to Key, so that we can query the tree
753    // with Keys that are not in any particular data structure.  When we insert,
754    // though, the pointer is always pointing to a Key that is inside a Node.
755    struct KeyCompare {
756      bool operator()(const Key* n0, const Key* n1) const { return *n0 < *n1; }
757    };
758    typedef typename Allocator::template rebind<Key*>::other KeyPtrAllocator;
759    typedef std::set<Key*, KeyCompare, KeyPtrAllocator> Tree;
760
761    // iterator and const_iterator are instantiations of iterator_base.
762    template <typename KeyValueType>
763    class iterator_base {
764     public:
765      typedef KeyValueType& reference;
766      typedef KeyValueType* pointer;
767      typedef typename Tree::iterator TreeIterator;
768
769      // Invariants:
770      // node_ is always correct. This is handy because the most common
771      // operations are operator* and operator-> and they only use node_.
772      // When node_ is set to a non-NULL value, all the other non-const fields
773      // are updated to be correct also, but those fields can become stale
774      // if the underlying map is modified.  When those fields are needed they
775      // are rechecked, and updated if necessary.
776      iterator_base() : node_(NULL) {}
777
778      explicit iterator_base(const InnerMap* m) : m_(m) {
779        SearchFrom(m->index_of_first_non_null_);
780      }
781
782      // Any iterator_base can convert to any other.  This is overkill, and we
783      // rely on the enclosing class to use it wisely.  The standard "iterator
784      // can convert to const_iterator" is OK but the reverse direction is not.
785      template <typename U>
786      explicit iterator_base(const iterator_base<U>& it)
787          : node_(it.node_),
788            m_(it.m_),
789            bucket_index_(it.bucket_index_),
790            tree_it_(it.tree_it_) {}
791
792      iterator_base(Node* n, const InnerMap* m, size_type index)
793          : node_(n),
794            m_(m),
795            bucket_index_(index) {}
796
797      iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index)
798          : node_(NodePtrFromKeyPtr(*tree_it)),
799            m_(m),
800            bucket_index_(index),
801            tree_it_(tree_it) {
802        // Invariant: iterators that use tree_it_ have an even bucket_index_.
803        GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0);
804      }
805
806      // Advance through buckets, looking for the first that isn't empty.
807      // If nothing non-empty is found then leave node_ == NULL.
808      void SearchFrom(size_type start_bucket) {
809        GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ ||
810               m_->table_[m_->index_of_first_non_null_] != NULL);
811        node_ = NULL;
812        for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_;
813             bucket_index_++) {
814          if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
815            node_ = static_cast<Node*>(m_->table_[bucket_index_]);
816            break;
817          } else if (m_->TableEntryIsTree(bucket_index_)) {
818            Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
819            GOOGLE_DCHECK(!tree->empty());
820            tree_it_ = tree->begin();
821            node_ = NodePtrFromKeyPtr(*tree_it_);
822            break;
823          }
824        }
825      }
826
827      reference operator*() const { return node_->kv; }
828      pointer operator->() const { return &(operator*()); }
829
830      friend bool operator==(const iterator_base& a, const iterator_base& b) {
831        return a.node_ == b.node_;
832      }
833      friend bool operator!=(const iterator_base& a, const iterator_base& b) {
834        return a.node_ != b.node_;
835      }
836
837      iterator_base& operator++() {
838        if (node_->next == NULL) {
839          const bool is_list = revalidate_if_necessary();
840          if (is_list) {
841            SearchFrom(bucket_index_ + 1);
842          } else {
843            GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0);
844            Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
845            if (++tree_it_ == tree->end()) {
846              SearchFrom(bucket_index_ + 2);
847            } else {
848              node_ = NodePtrFromKeyPtr(*tree_it_);
849            }
850          }
851        } else {
852          node_ = node_->next;
853        }
854        return *this;
855      }
856
857      iterator_base operator++(int /* unused */) {
858        iterator_base tmp = *this;
859        ++*this;
860        return tmp;
861      }
862
863      // Assumes node_ and m_ are correct and non-NULL, but other fields may be
864      // stale.  Fix them as needed.  Then return true iff node_ points to a
865      // Node in a list.
866      bool revalidate_if_necessary() {
867        GOOGLE_DCHECK(node_ != NULL && m_ != NULL);
868        // Force bucket_index_ to be in range.
869        bucket_index_ &= (m_->num_buckets_ - 1);
870        // Common case: the bucket we think is relevant points to node_.
871        if (m_->table_[bucket_index_] == static_cast<void*>(node_))
872          return true;
873        // Less common: the bucket is a linked list with node_ somewhere in it,
874        // but not at the head.
875        if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
876          Node* l = static_cast<Node*>(m_->table_[bucket_index_]);
877          while ((l = l->next) != NULL) {
878            if (l == node_) {
879              return true;
880            }
881          }
882        }
883        // Well, bucket_index_ still might be correct, but probably
884        // not.  Revalidate just to be sure.  This case is rare enough that we
885        // don't worry about potential optimizations, such as having a custom
886        // find-like method that compares Node* instead of const Key&.
887        iterator_base i(m_->find(*KeyPtrFromNodePtr(node_)));
888        bucket_index_ = i.bucket_index_;
889        tree_it_ = i.tree_it_;
890        return m_->TableEntryIsList(bucket_index_);
891      }
892
893      Node* node_;
894      const InnerMap* m_;
895      size_type bucket_index_;
896      TreeIterator tree_it_;
897    };
898
899   public:
900    typedef iterator_base<KeyValuePair> iterator;
901    typedef iterator_base<const KeyValuePair> const_iterator;
902
903    iterator begin() { return iterator(this); }
904    iterator end() { return iterator(); }
905    const_iterator begin() const { return const_iterator(this); }
906    const_iterator end() const { return const_iterator(); }
907
908    void clear() {
909      for (size_type b = 0; b < num_buckets_; b++) {
910        if (TableEntryIsNonEmptyList(b)) {
911          Node* node = static_cast<Node*>(table_[b]);
912          table_[b] = NULL;
913          do {
914            Node* next = node->next;
915            DestroyNode(node);
916            node = next;
917          } while (node != NULL);
918        } else if (TableEntryIsTree(b)) {
919          Tree* tree = static_cast<Tree*>(table_[b]);
920          GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0);
921          table_[b] = table_[b + 1] = NULL;
922          typename Tree::iterator tree_it = tree->begin();
923          do {
924            Node* node = NodePtrFromKeyPtr(*tree_it);
925            typename Tree::iterator next = tree_it;
926            ++next;
927            tree->erase(tree_it);
928            DestroyNode(node);
929            tree_it = next;
930          } while (tree_it != tree->end());
931          DestroyTree(tree);
932          b++;
933        }
934      }
935      num_elements_ = 0;
936      index_of_first_non_null_ = num_buckets_;
937    }
938
939    const hasher& hash_function() const { return *this; }
940
941    static size_type max_size() {
942      return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28);
943    }
944    size_type size() const { return num_elements_; }
945    bool empty() const { return size() == 0; }
946
947    iterator find(const Key& k) { return iterator(FindHelper(k).first); }
948    const_iterator find(const Key& k) const { return FindHelper(k).first; }
949
950    // In traditional C++ style, this performs "insert if not present."
951    std::pair<iterator, bool> insert(const KeyValuePair& kv) {
952      std::pair<const_iterator, size_type> p = FindHelper(kv.key());
953      // Case 1: key was already present.
954      if (p.first.node_ != NULL)
955        return std::make_pair(iterator(p.first), false);
956      // Case 2: insert.
957      if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
958        p = FindHelper(kv.key());
959      }
960      const size_type b = p.second;  // bucket number
961      Node* node = Alloc<Node>(1);
962      alloc_.construct(&node->kv, kv);
963      iterator result = InsertUnique(b, node);
964      ++num_elements_;
965      return std::make_pair(result, true);
966    }
967
968    // The same, but if an insertion is necessary then the value portion of the
969    // inserted key-value pair is left uninitialized.
970    std::pair<iterator, bool> insert(const Key& k) {
971      std::pair<const_iterator, size_type> p = FindHelper(k);
972      // Case 1: key was already present.
973      if (p.first.node_ != NULL)
974        return std::make_pair(iterator(p.first), false);
975      // Case 2: insert.
976      if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
977        p = FindHelper(k);
978      }
979      const size_type b = p.second;  // bucket number
980      Node* node = Alloc<Node>(1);
981      typedef typename Allocator::template rebind<Key>::other KeyAllocator;
982      KeyAllocator(alloc_).construct(&node->kv.key(), k);
983      iterator result = InsertUnique(b, node);
984      ++num_elements_;
985      return std::make_pair(result, true);
986    }
987
988    Value& operator[](const Key& k) {
989      KeyValuePair kv(k, Value());
990      return insert(kv).first->value();
991    }
992
993    void erase(iterator it) {
994      GOOGLE_DCHECK_EQ(it.m_, this);
995      const bool is_list = it.revalidate_if_necessary();
996      size_type b = it.bucket_index_;
997      Node* const item = it.node_;
998      if (is_list) {
999        GOOGLE_DCHECK(TableEntryIsNonEmptyList(b));
1000        Node* head = static_cast<Node*>(table_[b]);
1001        head = EraseFromLinkedList(item, head);
1002        table_[b] = static_cast<void*>(head);
1003      } else {
1004        GOOGLE_DCHECK(TableEntryIsTree(b));
1005        Tree* tree = static_cast<Tree*>(table_[b]);
1006        tree->erase(it.tree_it_);
1007        if (tree->empty()) {
1008          // Force b to be the minimum of b and b ^ 1.  This is important
1009          // only because we want index_of_first_non_null_ to be correct.
1010          b &= ~static_cast<size_type>(1);
1011          DestroyTree(tree);
1012          table_[b] = table_[b + 1] = NULL;
1013        }
1014      }
1015      DestroyNode(item);
1016      --num_elements_;
1017      if (GOOGLE_PREDICT_FALSE(b == index_of_first_non_null_)) {
1018        while (index_of_first_non_null_ < num_buckets_ &&
1019               table_[index_of_first_non_null_] == NULL) {
1020          ++index_of_first_non_null_;
1021        }
1022      }
1023    }
1024
1025   private:
1026    std::pair<const_iterator, size_type> FindHelper(const Key& k) const {
1027      size_type b = BucketNumber(k);
1028      if (TableEntryIsNonEmptyList(b)) {
1029        Node* node = static_cast<Node*>(table_[b]);
1030        do {
1031          if (IsMatch(*KeyPtrFromNodePtr(node), k)) {
1032            return std::make_pair(const_iterator(node, this, b), b);
1033          } else {
1034            node = node->next;
1035          }
1036        } while (node != NULL);
1037      } else if (TableEntryIsTree(b)) {
1038        GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
1039        b &= ~static_cast<size_t>(1);
1040        Tree* tree = static_cast<Tree*>(table_[b]);
1041        Key* key = const_cast<Key*>(&k);
1042        typename Tree::iterator tree_it = tree->find(key);
1043        if (tree_it != tree->end()) {
1044          return std::make_pair(const_iterator(tree_it, this, b), b);
1045        }
1046      }
1047      return std::make_pair(end(), b);
1048    }
1049
1050    // Insert the given Node in bucket b.  If that would make bucket b too big,
1051    // and bucket b is not a tree, create a tree for buckets b and b^1 to share.
1052    // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct
1053    // bucket.  num_elements_ is not modified.
1054    iterator InsertUnique(size_type b, Node* node) {
1055      GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ ||
1056             table_[index_of_first_non_null_] != NULL);
1057      // In practice, the code that led to this point may have already
1058      // determined whether we are inserting into an empty list, a short list,
1059      // or whatever.  But it's probably cheap enough to recompute that here;
1060      // it's likely that we're inserting into an empty or short list.
1061      iterator result;
1062      GOOGLE_DCHECK(find(*KeyPtrFromNodePtr(node)) == end());
1063      if (TableEntryIsEmpty(b)) {
1064        result = InsertUniqueInList(b, node);
1065      } else if (TableEntryIsNonEmptyList(b)) {
1066        if (GOOGLE_PREDICT_FALSE(TableEntryIsTooLong(b))) {
1067          TreeConvert(b);
1068          result = InsertUniqueInTree(b, node);
1069          GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast<size_type>(1));
1070        } else {
1071          // Insert into a pre-existing list.  This case cannot modify
1072          // index_of_first_non_null_, so we skip the code to update it.
1073          return InsertUniqueInList(b, node);
1074        }
1075      } else {
1076        // Insert into a pre-existing tree.  This case cannot modify
1077        // index_of_first_non_null_, so we skip the code to update it.
1078        return InsertUniqueInTree(b, node);
1079      }
1080      index_of_first_non_null_ =
1081          std::min(index_of_first_non_null_, result.bucket_index_);
1082      return result;
1083    }
1084
1085    // Helper for InsertUnique.  Handles the case where bucket b is a
1086    // not-too-long linked list.
1087    iterator InsertUniqueInList(size_type b, Node* node) {
1088      node->next = static_cast<Node*>(table_[b]);
1089      table_[b] = static_cast<void*>(node);
1090      return iterator(node, this, b);
1091    }
1092
1093    // Helper for InsertUnique.  Handles the case where bucket b points to a
1094    // Tree.
1095    iterator InsertUniqueInTree(size_type b, Node* node) {
1096      GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
1097      // Maintain the invariant that node->next is NULL for all Nodes in Trees.
1098      node->next = NULL;
1099      return iterator(static_cast<Tree*>(table_[b])
1100                      ->insert(KeyPtrFromNodePtr(node))
1101                      .first,
1102                      this, b & ~static_cast<size_t>(1));
1103    }
1104
1105    // Returns whether it did resize.  Currently this is only used when
1106    // num_elements_ increases, though it could be used in other situations.
1107    // It checks for load too low as well as load too high: because any number
1108    // of erases can occur between inserts, the load could be as low as 0 here.
1109    // Resizing to a lower size is not always helpful, but failing to do so can
1110    // destroy the expected big-O bounds for some operations. By having the
1111    // policy that sometimes we resize down as well as up, clients can easily
1112    // keep O(size()) = O(number of buckets) if they want that.
1113    bool ResizeIfLoadIsOutOfRange(size_type new_size) {
1114      const size_type kMaxMapLoadTimes16 = 12;  // controls RAM vs CPU tradeoff
1115      const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16;
1116      const size_type lo_cutoff = hi_cutoff / 4;
1117      // We don't care how many elements are in trees.  If a lot are,
1118      // we may resize even though there are many empty buckets.  In
1119      // practice, this seems fine.
1120      if (GOOGLE_PREDICT_FALSE(new_size >= hi_cutoff)) {
1121        if (num_buckets_ <= max_size() / 2) {
1122          Resize(num_buckets_ * 2);
1123          return true;
1124        }
1125      } else if (GOOGLE_PREDICT_FALSE(new_size <= lo_cutoff &&
1126                               num_buckets_ > kMinTableSize)) {
1127        size_type lg2_of_size_reduction_factor = 1;
1128        // It's possible we want to shrink a lot here... size() could even be 0.
1129        // So, estimate how much to shrink by making sure we don't shrink so
1130        // much that we would need to grow the table after a few inserts.
1131        const size_type hypothetical_size = new_size * 5 / 4 + 1;
1132        while ((hypothetical_size << lg2_of_size_reduction_factor) <
1133               hi_cutoff) {
1134          ++lg2_of_size_reduction_factor;
1135        }
1136        size_type new_num_buckets = std::max<size_type>(
1137            kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor);
1138        if (new_num_buckets != num_buckets_) {
1139          Resize(new_num_buckets);
1140          return true;
1141        }
1142      }
1143      return false;
1144    }
1145
1146    // Resize to the given number of buckets.
1147    void Resize(size_t new_num_buckets) {
1148      GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize);
1149      void** const old_table = table_;
1150      const size_type old_table_size = num_buckets_;
1151      num_buckets_ = new_num_buckets;
1152      table_ = CreateEmptyTable(num_buckets_);
1153      const size_type start = index_of_first_non_null_;
1154      index_of_first_non_null_ = num_buckets_;
1155      for (size_type i = start; i < old_table_size; i++) {
1156        if (TableEntryIsNonEmptyList(old_table, i)) {
1157          TransferList(old_table, i);
1158        } else if (TableEntryIsTree(old_table, i)) {
1159          TransferTree(old_table, i++);
1160        }
1161      }
1162      Dealloc<void*>(old_table, old_table_size);
1163    }
1164
1165    void TransferList(void* const* table, size_type index) {
1166      Node* node = static_cast<Node*>(table[index]);
1167      do {
1168        Node* next = node->next;
1169        InsertUnique(BucketNumber(*KeyPtrFromNodePtr(node)), node);
1170        node = next;
1171      } while (node != NULL);
1172    }
1173
1174    void TransferTree(void* const* table, size_type index) {
1175      Tree* tree = static_cast<Tree*>(table[index]);
1176      typename Tree::iterator tree_it = tree->begin();
1177      do {
1178        Node* node = NodePtrFromKeyPtr(*tree_it);
1179        InsertUnique(BucketNumber(**tree_it), node);
1180      } while (++tree_it != tree->end());
1181      DestroyTree(tree);
1182    }
1183
1184    Node* EraseFromLinkedList(Node* item, Node* head) {
1185      if (head == item) {
1186        return head->next;
1187      } else {
1188        head->next = EraseFromLinkedList(item, head->next);
1189        return head;
1190      }
1191    }
1192
1193    bool TableEntryIsEmpty(size_type b) const {
1194      return TableEntryIsEmpty(table_, b);
1195    }
1196    bool TableEntryIsNonEmptyList(size_type b) const {
1197      return TableEntryIsNonEmptyList(table_, b);
1198    }
1199    bool TableEntryIsTree(size_type b) const {
1200      return TableEntryIsTree(table_, b);
1201    }
1202    bool TableEntryIsList(size_type b) const {
1203      return TableEntryIsList(table_, b);
1204    }
1205    static bool TableEntryIsEmpty(void* const* table, size_type b) {
1206      return table[b] == NULL;
1207    }
1208    static bool TableEntryIsNonEmptyList(void* const* table, size_type b) {
1209      return table[b] != NULL && table[b] != table[b ^ 1];
1210    }
1211    static bool TableEntryIsTree(void* const* table, size_type b) {
1212      return !TableEntryIsEmpty(table, b) &&
1213          !TableEntryIsNonEmptyList(table, b);
1214    }
1215    static bool TableEntryIsList(void* const* table, size_type b) {
1216      return !TableEntryIsTree(table, b);
1217    }
1218
1219    void TreeConvert(size_type b) {
1220      GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1));
1221      typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
1222      Tree* tree = tree_allocator.allocate(1);
1223      // We want to use the three-arg form of construct, if it exists, but we
1224      // create a temporary and use the two-arg construct that's known to exist.
1225      // It's clunky, but the compiler should be able to generate more-or-less
1226      // the same code.
1227      tree_allocator.construct(tree,
1228                               Tree(KeyCompare(), KeyPtrAllocator(alloc_)));
1229      // Now the tree is ready to use.
1230      size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree);
1231      GOOGLE_DCHECK_EQ(count, tree->size());
1232      table_[b] = table_[b ^ 1] = static_cast<void*>(tree);
1233    }
1234
1235    // Copy a linked list in the given bucket to a tree.
1236    // Returns the number of things it copied.
1237    size_type CopyListToTree(size_type b, Tree* tree) {
1238      size_type count = 0;
1239      Node* node = static_cast<Node*>(table_[b]);
1240      while (node != NULL) {
1241        tree->insert(KeyPtrFromNodePtr(node));
1242        ++count;
1243        Node* next = node->next;
1244        node->next = NULL;
1245        node = next;
1246      }
1247      return count;
1248    }
1249
1250    // Return whether table_[b] is a linked list that seems awfully long.
1251    // Requires table_[b] to point to a non-empty linked list.
1252    bool TableEntryIsTooLong(size_type b) {
1253      const int kMaxLength = 8;
1254      size_type count = 0;
1255      Node* node = static_cast<Node*>(table_[b]);
1256      do {
1257        ++count;
1258        node = node->next;
1259      } while (node != NULL);
1260      // Invariant: no linked list ever is more than kMaxLength in length.
1261      GOOGLE_DCHECK_LE(count, kMaxLength);
1262      return count >= kMaxLength;
1263    }
1264
1265    size_type BucketNumber(const Key& k) const {
1266      // We inherit from hasher, so one-arg operator() provides a hash function.
1267      size_type h = (*const_cast<InnerMap*>(this))(k);
1268      // To help prevent people from making assumptions about the hash function,
1269      // we use the seed differently depending on NDEBUG.  The default hash
1270      // function, the seeding, etc., are all likely to change in the future.
1271#ifndef NDEBUG
1272      return (h * (seed_ | 1)) & (num_buckets_ - 1);
1273#else
1274      return (h + seed_) & (num_buckets_ - 1);
1275#endif
1276    }
1277
1278    bool IsMatch(const Key& k0, const Key& k1) const {
1279      return std::equal_to<Key>()(k0, k1);
1280    }
1281
1282    // Return a power of two no less than max(kMinTableSize, n).
1283    // Assumes either n < kMinTableSize or n is a power of two.
1284    size_type TableSize(size_type n) {
1285      return n < kMinTableSize ? kMinTableSize : n;
1286    }
1287
1288    // Use alloc_ to allocate an array of n objects of type U.
1289    template <typename U>
1290    U* Alloc(size_type n) {
1291      typedef typename Allocator::template rebind<U>::other alloc_type;
1292      return alloc_type(alloc_).allocate(n);
1293    }
1294
1295    // Use alloc_ to deallocate an array of n objects of type U.
1296    template <typename U>
1297    void Dealloc(U* t, size_type n) {
1298      typedef typename Allocator::template rebind<U>::other alloc_type;
1299      alloc_type(alloc_).deallocate(t, n);
1300    }
1301
1302    void DestroyNode(Node* node) {
1303      alloc_.destroy(&node->kv);
1304      Dealloc<Node>(node, 1);
1305    }
1306
1307    void DestroyTree(Tree* tree) {
1308      typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
1309      tree_allocator.destroy(tree);
1310      tree_allocator.deallocate(tree, 1);
1311    }
1312
1313    void** CreateEmptyTable(size_type n) {
1314      GOOGLE_DCHECK(n >= kMinTableSize);
1315      GOOGLE_DCHECK_EQ(n & (n - 1), 0);
1316      void** result = Alloc<void*>(n);
1317      memset(result, 0, n * sizeof(result[0]));
1318      return result;
1319    }
1320
1321    // Return a randomish value.
1322    size_type Seed() const {
1323      // random_device can throw, so avoid it unless we are compiling with
1324      // exceptions enabled.
1325#if __cpp_exceptions && LANG_CXX11
1326      try {
1327        std::random_device rd;
1328        std::knuth_b knuth(rd());
1329        std::uniform_int_distribution<size_type> u;
1330        return u(knuth);
1331      } catch (...) { }
1332#endif
1333      size_type s = static_cast<size_type>(reinterpret_cast<uintptr_t>(this));
1334#if defined(__x86_64__) && defined(__GNUC__)
1335      uint32 hi, lo;
1336      asm("rdtsc" : "=a" (lo), "=d" (hi));
1337      s += ((static_cast<uint64>(hi) << 32) | lo);
1338#endif
1339      return s;
1340    }
1341
1342    size_type num_elements_;
1343    size_type num_buckets_;
1344    size_type seed_;
1345    size_type index_of_first_non_null_;
1346    void** table_;  // an array with num_buckets_ entries
1347    Allocator alloc_;
1348    GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap);
1349  };  // end of class InnerMap
1350
1351  typedef hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
1352                   MapAllocator<std::pair<const Key, MapPair<Key, T>*> > >
1353      DeprecatedInnerMap;
1354
1355 public:
1356  // Iterators
1357  class iterator_base {
1358   public:
1359    // We support "old style" and "new style" iterators for now. This is
1360    // temporary.  Also, for "iterator()" we have an unknown category.
1361    // TODO(gpike): get rid of this.
1362    enum IteratorStyle { kUnknown, kOld, kNew };
1363    explicit iterator_base(IteratorStyle style) : iterator_style_(style) {}
1364
1365    bool OldStyle() const {
1366      GOOGLE_DCHECK_NE(iterator_style_, kUnknown);
1367      return iterator_style_ == kOld;
1368    }
1369    bool UnknownStyle() const {
1370      return iterator_style_ == kUnknown;
1371    }
1372    bool SameStyle(const iterator_base& other) const {
1373      return iterator_style_ == other.iterator_style_;
1374    }
1375
1376   private:
1377    IteratorStyle iterator_style_;
1378  };
1379
1380  class const_iterator
1381      : private iterator_base,
1382        public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
1383                             const value_type*, const value_type&> {
1384    typedef typename InnerMap::const_iterator InnerIt;
1385    typedef typename DeprecatedInnerMap::const_iterator DeprecatedInnerIt;
1386
1387   public:
1388    const_iterator() : iterator_base(iterator_base::kUnknown) {}
1389    explicit const_iterator(const DeprecatedInnerIt& dit)
1390        : iterator_base(iterator_base::kOld), dit_(dit) {}
1391    explicit const_iterator(const InnerIt& it)
1392        : iterator_base(iterator_base::kNew), it_(it) {}
1393
1394    const_iterator(const const_iterator& other)
1395        : iterator_base(other), it_(other.it_), dit_(other.dit_) {}
1396
1397    const_reference operator*() const {
1398      return this->OldStyle() ? *dit_->second : *it_->value();
1399    }
1400    const_pointer operator->() const { return &(operator*()); }
1401
1402    const_iterator& operator++() {
1403      if (this->OldStyle())
1404        ++dit_;
1405      else
1406        ++it_;
1407      return *this;
1408    }
1409    const_iterator operator++(int) {
1410      return this->OldStyle() ? const_iterator(dit_++) : const_iterator(it_++);
1411    }
1412
1413    friend bool operator==(const const_iterator& a, const const_iterator& b) {
1414      if (!a.SameStyle(b)) return false;
1415      if (a.UnknownStyle()) return true;
1416      return a.OldStyle() ? (a.dit_ == b.dit_) : (a.it_ == b.it_);
1417    }
1418    friend bool operator!=(const const_iterator& a, const const_iterator& b) {
1419      return !(a == b);
1420    }
1421
1422   private:
1423    InnerIt it_;
1424    DeprecatedInnerIt dit_;
1425  };
1426
1427  class iterator : private iterator_base,
1428                   public std::iterator<std::forward_iterator_tag, value_type> {
1429    typedef typename InnerMap::iterator InnerIt;
1430    typedef typename DeprecatedInnerMap::iterator DeprecatedInnerIt;
1431
1432   public:
1433    iterator() : iterator_base(iterator_base::kUnknown) {}
1434    explicit iterator(const DeprecatedInnerIt& dit)
1435        : iterator_base(iterator_base::kOld), dit_(dit) {}
1436    explicit iterator(const InnerIt& it)
1437        : iterator_base(iterator_base::kNew), it_(it) {}
1438
1439    reference operator*() const {
1440      return this->OldStyle() ? *dit_->second : *it_->value();
1441    }
1442    pointer operator->() const { return &(operator*()); }
1443
1444    iterator& operator++() {
1445      if (this->OldStyle())
1446        ++dit_;
1447      else
1448        ++it_;
1449      return *this;
1450    }
1451    iterator operator++(int) {
1452      return this->OldStyle() ? iterator(dit_++) : iterator(it_++);
1453    }
1454
1455    // Allow implicit conversion to const_iterator.
1456    operator const_iterator() const {
1457      return this->OldStyle() ?
1458          const_iterator(typename DeprecatedInnerMap::const_iterator(dit_)) :
1459          const_iterator(typename InnerMap::const_iterator(it_));
1460    }
1461
1462    friend bool operator==(const iterator& a, const iterator& b) {
1463      if (!a.SameStyle(b)) return false;
1464      if (a.UnknownStyle()) return true;
1465      return a.OldStyle() ? a.dit_ == b.dit_ : a.it_ == b.it_;
1466    }
1467    friend bool operator!=(const iterator& a, const iterator& b) {
1468      return !(a == b);
1469    }
1470
1471   private:
1472    friend class Map;
1473
1474    InnerIt it_;
1475    DeprecatedInnerIt dit_;
1476  };
1477
1478  iterator begin() {
1479    return old_style_ ? iterator(deprecated_elements_->begin())
1480                      : iterator(elements_->begin());
1481  }
1482  iterator end() {
1483    return old_style_ ? iterator(deprecated_elements_->end())
1484                      : iterator(elements_->end());
1485  }
1486  const_iterator begin() const {
1487    return old_style_ ? const_iterator(deprecated_elements_->begin())
1488                      : const_iterator(iterator(elements_->begin()));
1489  }
1490  const_iterator end() const {
1491    return old_style_ ? const_iterator(deprecated_elements_->end())
1492                      : const_iterator(iterator(elements_->end()));
1493  }
1494  const_iterator cbegin() const { return begin(); }
1495  const_iterator cend() const { return end(); }
1496
1497  // Capacity
1498  size_type size() const {
1499    return old_style_ ? deprecated_elements_->size() : elements_->size();
1500  }
1501  bool empty() const { return size() == 0; }
1502
1503  // Element access
1504  T& operator[](const key_type& key) {
1505    value_type** value =
1506        old_style_ ? &(*deprecated_elements_)[key] : &(*elements_)[key];
1507    if (*value == NULL) {
1508      *value = CreateValueTypeInternal(key);
1509      internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
1510                                    T>::Initialize((*value)->second,
1511                                                   default_enum_value_);
1512    }
1513    return (*value)->second;
1514  }
1515  const T& at(const key_type& key) const {
1516    const_iterator it = find(key);
1517    GOOGLE_CHECK(it != end());
1518    return it->second;
1519  }
1520  T& at(const key_type& key) {
1521    iterator it = find(key);
1522    GOOGLE_CHECK(it != end());
1523    return it->second;
1524  }
1525
1526  // Lookup
1527  size_type count(const key_type& key) const {
1528    if (find(key) != end()) assert(key == find(key)->first);
1529    return find(key) == end() ? 0 : 1;
1530  }
1531  const_iterator find(const key_type& key) const {
1532    return old_style_ ? const_iterator(deprecated_elements_->find(key))
1533        : const_iterator(iterator(elements_->find(key)));
1534  }
1535  iterator find(const key_type& key) {
1536    return old_style_ ? iterator(deprecated_elements_->find(key))
1537                      : iterator(elements_->find(key));
1538  }
1539  std::pair<const_iterator, const_iterator> equal_range(
1540      const key_type& key) const {
1541    const_iterator it = find(key);
1542    if (it == end()) {
1543      return std::pair<const_iterator, const_iterator>(it, it);
1544    } else {
1545      const_iterator begin = it++;
1546      return std::pair<const_iterator, const_iterator>(begin, it);
1547    }
1548  }
1549  std::pair<iterator, iterator> equal_range(const key_type& key) {
1550    iterator it = find(key);
1551    if (it == end()) {
1552      return std::pair<iterator, iterator>(it, it);
1553    } else {
1554      iterator begin = it++;
1555      return std::pair<iterator, iterator>(begin, it);
1556    }
1557  }
1558
1559  // insert
1560  std::pair<iterator, bool> insert(const value_type& value) {
1561    if (old_style_) {
1562      iterator it = find(value.first);
1563      if (it != end()) {
1564        return std::pair<iterator, bool>(it, false);
1565      } else {
1566        return std::pair<iterator, bool>(
1567            iterator(deprecated_elements_->insert(std::pair<Key, value_type*>(
1568                value.first, CreateValueTypeInternal(value))).first), true);
1569      }
1570    } else {
1571      std::pair<typename InnerMap::iterator, bool> p =
1572          elements_->insert(value.first);
1573      if (p.second) {
1574        p.first->value() = CreateValueTypeInternal(value);
1575      }
1576      return std::pair<iterator, bool>(iterator(p.first), p.second);
1577    }
1578  }
1579  template <class InputIt>
1580  void insert(InputIt first, InputIt last) {
1581    for (InputIt it = first; it != last; ++it) {
1582      iterator exist_it = find(it->first);
1583      if (exist_it == end()) {
1584        operator[](it->first) = it->second;
1585      }
1586    }
1587  }
1588
1589  // Erase and clear
1590  size_type erase(const key_type& key) {
1591    iterator it = find(key);
1592    if (it == end()) {
1593      return 0;
1594    } else {
1595      erase(it);
1596      return 1;
1597    }
1598  }
1599  iterator erase(iterator pos) {
1600    if (arena_ == NULL) delete pos.operator->();
1601    iterator i = pos++;
1602    if (old_style_)
1603      deprecated_elements_->erase(i.dit_);
1604    else
1605      elements_->erase(i.it_);
1606    return pos;
1607  }
1608  void erase(iterator first, iterator last) {
1609    while (first != last) {
1610      first = erase(first);
1611    }
1612  }
1613  void clear() { erase(begin(), end()); }
1614
1615  // Assign
1616  Map& operator=(const Map& other) {
1617    if (this != &other) {
1618      clear();
1619      insert(other.begin(), other.end());
1620    }
1621    return *this;
1622  }
1623
1624  // Access to hasher.  Currently this returns a copy, but it may
1625  // be modified to return a const reference in the future.
1626  hasher hash_function() const {
1627    return old_style_ ? deprecated_elements_->hash_function()
1628                      : elements_->hash_function();
1629  }
1630
1631 private:
1632  // Set default enum value only for proto2 map field whose value is enum type.
1633  void SetDefaultEnumValue(int default_enum_value) {
1634    default_enum_value_ = default_enum_value;
1635  }
1636
1637  value_type* CreateValueTypeInternal(const Key& key) {
1638    if (arena_ == NULL) {
1639      return new value_type(key);
1640    } else {
1641      value_type* value = reinterpret_cast<value_type*>(
1642          Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
1643      Arena::CreateInArenaStorage(const_cast<Key*>(&value->first), arena_);
1644      Arena::CreateInArenaStorage(&value->second, arena_);
1645      const_cast<Key&>(value->first) = key;
1646      return value;
1647    }
1648  }
1649
1650  value_type* CreateValueTypeInternal(const value_type& value) {
1651    if (arena_ == NULL) {
1652      return new value_type(value);
1653    } else {
1654      value_type* p = reinterpret_cast<value_type*>(
1655          Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
1656      Arena::CreateInArenaStorage(const_cast<Key*>(&p->first), arena_);
1657      Arena::CreateInArenaStorage(&p->second, arena_);
1658      const_cast<Key&>(p->first) = value.first;
1659      p->second = value.second;
1660      return p;
1661    }
1662  }
1663
1664  Arena* arena_;
1665  int default_enum_value_;
1666  // The following is a tagged union because we support two map styles
1667  // for now.
1668  // TODO(gpike): get rid of the old style.
1669  const bool old_style_;
1670  union {
1671    InnerMap* elements_;
1672    DeprecatedInnerMap* deprecated_elements_;
1673  };
1674
1675  friend class ::google::protobuf::Arena;
1676  typedef void InternalArenaConstructable_;
1677  typedef void DestructorSkippable_;
1678  template <typename K, typename V,
1679            internal::WireFormatLite::FieldType key_wire_type,
1680            internal::WireFormatLite::FieldType value_wire_type,
1681            int default_enum_value>
1682  friend class internal::MapFieldLite;
1683};
1684
1685}  // namespace protobuf
1686}  // namespace google
1687
1688GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
1689template<>
1690struct hash<google::protobuf::MapKey> {
1691  size_t
1692  operator()(const google::protobuf::MapKey& map_key) const {
1693    switch (map_key.type()) {
1694      case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1695      case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1696      case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1697      case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1698        GOOGLE_LOG(FATAL) << "Unsupported";
1699        break;
1700      case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1701        return hash<string>()(map_key.GetStringValue());
1702      case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
1703        return hash< ::google::protobuf::int64>()(map_key.GetInt64Value());
1704      case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
1705        return hash< ::google::protobuf::int32>()(map_key.GetInt32Value());
1706      case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
1707        return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value());
1708      case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
1709        return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
1710      case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1711        return hash<bool>()(map_key.GetBoolValue());
1712    }
1713    GOOGLE_LOG(FATAL) << "Can't get here.";
1714    return 0;
1715  }
1716  bool
1717  operator()(const google::protobuf::MapKey& map_key1,
1718             const google::protobuf::MapKey& map_key2) const {
1719    return map_key1 < map_key2;
1720  }
1721};
1722GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
1723
1724#endif  // GOOGLE_PROTOBUF_MAP_H__
1725