Home | History | Annotate | Download | only in protobuf
      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 
     50 namespace google {
     51 namespace 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.
     56 template <typename Key, typename T>
     57 class Map;
     58 
     59 class MapIterator;
     60 
     61 template <typename Enum> struct is_proto_enum;
     62 
     63 namespace internal {
     64 template <typename Key, typename T,
     65           WireFormatLite::FieldType key_wire_type,
     66           WireFormatLite::FieldType value_wire_type,
     67           int default_enum_value>
     68 class MapFieldLite;
     69 
     70 template <typename Key, typename T,
     71           WireFormatLite::FieldType key_wire_type,
     72           WireFormatLite::FieldType value_wire_type,
     73           int default_enum_value>
     74 class MapField;
     75 
     76 template <typename Key, typename T>
     77 class TypeDefinedMapFieldBase;
     78 
     79 class DynamicMapField;
     80 
     81 class 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.
     97 class 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.
    297 class 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.
    470 template <typename Key, typename T>
    471 class 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.
    508 template <typename Key, typename T>
    509 class 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    private:
    654     typedef void DestructorSkippable_;
    655     Arena* const arena_;
    656 
    657     template <typename X>
    658     friend class MapAllocator;
    659   };
    660 
    661   // InnerMap's key type is Key and its value type is value_type*.  We use a
    662   // custom class here and for Node, below, to ensure that k_ is at offset 0,
    663   // allowing safe conversion from pointer to Node to pointer to Key, and vice
    664   // versa when appropriate.
    665   class KeyValuePair {
    666    public:
    667     KeyValuePair(const Key& k, value_type* v) : k_(k), v_(v) {}
    668 
    669     const Key& key() const { return k_; }
    670     Key& key() { return k_; }
    671     value_type* const value() const { return v_; }
    672     value_type*& value() { return v_; }
    673 
    674    private:
    675     Key k_;
    676     value_type* v_;
    677   };
    678 
    679   typedef MapAllocator<KeyValuePair> Allocator;
    680 
    681   // InnerMap is a generic hash-based map.  It doesn't contain any
    682   // protocol-buffer-specific logic.  It is a chaining hash map with the
    683   // additional feature that some buckets can be converted to use an ordered
    684   // container.  This ensures O(lg n) bounds on find, insert, and erase, while
    685   // avoiding the overheads of ordered containers most of the time.
    686   //
    687   // The implementation doesn't need the full generality of unordered_map,
    688   // and it doesn't have it.  More bells and whistles can be added as needed.
    689   // Some implementation details:
    690   // 1. The hash function has type hasher and the equality function
    691   //    equal_to<Key>.  We inherit from hasher to save space
    692   //    (empty-base-class optimization).
    693   // 2. The number of buckets is a power of two.
    694   // 3. Buckets are converted to trees in pairs: if we convert bucket b then
    695   //    buckets b and b^1 will share a tree.  Invariant: buckets b and b^1 have
    696   //    the same non-NULL value iff they are sharing a tree.  (An alternative
    697   //    implementation strategy would be to have a tag bit per bucket.)
    698   // 4. As is typical for hash_map and such, the Keys and Values are always
    699   //    stored in linked list nodes.  Pointers to elements are never invalidated
    700   //    until the element is deleted.
    701   // 5. The trees' payload type is pointer to linked-list node.  Tree-converting
    702   //    a bucket doesn't copy Key-Value pairs.
    703   // 6. Once we've tree-converted a bucket, it is never converted back. However,
    704   //    the items a tree contains may wind up assigned to trees or lists upon a
    705   //    rehash.
    706   // 7. The code requires no C++ features from C++11 or later.
    707   // 8. Mutations to a map do not invalidate the map's iterators, pointers to
    708   //    elements, or references to elements.
    709   // 9. Except for erase(iterator), any non-const method can reorder iterators.
    710   class InnerMap : private hasher {
    711    public:
    712     typedef value_type* Value;
    713 
    714     InnerMap(size_type n, hasher h, Allocator alloc)
    715         : hasher(h),
    716           num_elements_(0),
    717           seed_(Seed()),
    718           table_(NULL),
    719           alloc_(alloc) {
    720       n = TableSize(n);
    721       table_ = CreateEmptyTable(n);
    722       num_buckets_ = index_of_first_non_null_ = n;
    723     }
    724 
    725     ~InnerMap() {
    726       if (table_ != NULL) {
    727         clear();
    728         Dealloc<void*>(table_, num_buckets_);
    729       }
    730     }
    731 
    732    private:
    733     enum { kMinTableSize = 8 };
    734 
    735     // Linked-list nodes, as one would expect for a chaining hash table.
    736     struct Node {
    737       KeyValuePair kv;
    738       Node* next;
    739     };
    740 
    741     // This is safe only if the given pointer is known to point to a Key that is
    742     // part of a Node.
    743     static Node* NodePtrFromKeyPtr(Key* k) {
    744       return reinterpret_cast<Node*>(k);
    745     }
    746 
    747     static Key* KeyPtrFromNodePtr(Node* node) { return &node->kv.key(); }
    748 
    749     // Trees.  The payload type is pointer to Key, so that we can query the tree
    750     // with Keys that are not in any particular data structure.  When we insert,
    751     // though, the pointer is always pointing to a Key that is inside a Node.
    752     struct KeyCompare {
    753       bool operator()(const Key* n0, const Key* n1) const { return *n0 < *n1; }
    754     };
    755     typedef typename Allocator::template rebind<Key*>::other KeyPtrAllocator;
    756     typedef std::set<Key*, KeyCompare, KeyPtrAllocator> Tree;
    757 
    758     // iterator and const_iterator are instantiations of iterator_base.
    759     template <typename KeyValueType>
    760     class iterator_base {
    761      public:
    762       typedef KeyValueType& reference;
    763       typedef KeyValueType* pointer;
    764       typedef typename Tree::iterator TreeIterator;
    765 
    766       // Invariants:
    767       // node_ is always correct. This is handy because the most common
    768       // operations are operator* and operator-> and they only use node_.
    769       // When node_ is set to a non-NULL value, all the other non-const fields
    770       // are updated to be correct also, but those fields can become stale
    771       // if the underlying map is modified.  When those fields are needed they
    772       // are rechecked, and updated if necessary.
    773       iterator_base() : node_(NULL) {}
    774 
    775       explicit iterator_base(const InnerMap* m) : m_(m) {
    776         SearchFrom(m->index_of_first_non_null_);
    777       }
    778 
    779       // Any iterator_base can convert to any other.  This is overkill, and we
    780       // rely on the enclosing class to use it wisely.  The standard "iterator
    781       // can convert to const_iterator" is OK but the reverse direction is not.
    782       template <typename U>
    783       explicit iterator_base(const iterator_base<U>& it)
    784           : node_(it.node_),
    785             m_(it.m_),
    786             bucket_index_(it.bucket_index_),
    787             tree_it_(it.tree_it_) {}
    788 
    789       iterator_base(Node* n, const InnerMap* m, size_type index)
    790           : node_(n),
    791             m_(m),
    792             bucket_index_(index) {}
    793 
    794       iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index)
    795           : node_(NodePtrFromKeyPtr(*tree_it)),
    796             m_(m),
    797             bucket_index_(index),
    798             tree_it_(tree_it) {
    799         // Invariant: iterators that use tree_it_ have an even bucket_index_.
    800         GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0);
    801       }
    802 
    803       // Advance through buckets, looking for the first that isn't empty.
    804       // If nothing non-empty is found then leave node_ == NULL.
    805       void SearchFrom(size_type start_bucket) {
    806         GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ ||
    807                m_->table_[m_->index_of_first_non_null_] != NULL);
    808         node_ = NULL;
    809         for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_;
    810              bucket_index_++) {
    811           if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
    812             node_ = static_cast<Node*>(m_->table_[bucket_index_]);
    813             break;
    814           } else if (m_->TableEntryIsTree(bucket_index_)) {
    815             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
    816             GOOGLE_DCHECK(!tree->empty());
    817             tree_it_ = tree->begin();
    818             node_ = NodePtrFromKeyPtr(*tree_it_);
    819             break;
    820           }
    821         }
    822       }
    823 
    824       reference operator*() const { return node_->kv; }
    825       pointer operator->() const { return &(operator*()); }
    826 
    827       friend bool operator==(const iterator_base& a, const iterator_base& b) {
    828         return a.node_ == b.node_;
    829       }
    830       friend bool operator!=(const iterator_base& a, const iterator_base& b) {
    831         return a.node_ != b.node_;
    832       }
    833 
    834       iterator_base& operator++() {
    835         if (node_->next == NULL) {
    836           const bool is_list = revalidate_if_necessary();
    837           if (is_list) {
    838             SearchFrom(bucket_index_ + 1);
    839           } else {
    840             GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0);
    841             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
    842             if (++tree_it_ == tree->end()) {
    843               SearchFrom(bucket_index_ + 2);
    844             } else {
    845               node_ = NodePtrFromKeyPtr(*tree_it_);
    846             }
    847           }
    848         } else {
    849           node_ = node_->next;
    850         }
    851         return *this;
    852       }
    853 
    854       iterator_base operator++(int /* unused */) {
    855         iterator_base tmp = *this;
    856         ++*this;
    857         return tmp;
    858       }
    859 
    860       // Assumes node_ and m_ are correct and non-NULL, but other fields may be
    861       // stale.  Fix them as needed.  Then return true iff node_ points to a
    862       // Node in a list.
    863       bool revalidate_if_necessary() {
    864         GOOGLE_DCHECK(node_ != NULL && m_ != NULL);
    865         // Force bucket_index_ to be in range.
    866         bucket_index_ &= (m_->num_buckets_ - 1);
    867         // Common case: the bucket we think is relevant points to node_.
    868         if (m_->table_[bucket_index_] == static_cast<void*>(node_))
    869           return true;
    870         // Less common: the bucket is a linked list with node_ somewhere in it,
    871         // but not at the head.
    872         if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
    873           Node* l = static_cast<Node*>(m_->table_[bucket_index_]);
    874           while ((l = l->next) != NULL) {
    875             if (l == node_) {
    876               return true;
    877             }
    878           }
    879         }
    880         // Well, bucket_index_ still might be correct, but probably
    881         // not.  Revalidate just to be sure.  This case is rare enough that we
    882         // don't worry about potential optimizations, such as having a custom
    883         // find-like method that compares Node* instead of const Key&.
    884         iterator_base i(m_->find(*KeyPtrFromNodePtr(node_)));
    885         bucket_index_ = i.bucket_index_;
    886         tree_it_ = i.tree_it_;
    887         return m_->TableEntryIsList(bucket_index_);
    888       }
    889 
    890       Node* node_;
    891       const InnerMap* m_;
    892       size_type bucket_index_;
    893       TreeIterator tree_it_;
    894     };
    895 
    896    public:
    897     typedef iterator_base<KeyValuePair> iterator;
    898     typedef iterator_base<const KeyValuePair> const_iterator;
    899 
    900     iterator begin() { return iterator(this); }
    901     iterator end() { return iterator(); }
    902     const_iterator begin() const { return const_iterator(this); }
    903     const_iterator end() const { return const_iterator(); }
    904 
    905     void clear() {
    906       for (size_type b = 0; b < num_buckets_; b++) {
    907         if (TableEntryIsNonEmptyList(b)) {
    908           Node* node = static_cast<Node*>(table_[b]);
    909           table_[b] = NULL;
    910           do {
    911             Node* next = node->next;
    912             DestroyNode(node);
    913             node = next;
    914           } while (node != NULL);
    915         } else if (TableEntryIsTree(b)) {
    916           Tree* tree = static_cast<Tree*>(table_[b]);
    917           GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0);
    918           table_[b] = table_[b + 1] = NULL;
    919           typename Tree::iterator tree_it = tree->begin();
    920           do {
    921             Node* node = NodePtrFromKeyPtr(*tree_it);
    922             typename Tree::iterator next = tree_it;
    923             ++next;
    924             tree->erase(tree_it);
    925             DestroyNode(node);
    926             tree_it = next;
    927           } while (tree_it != tree->end());
    928           DestroyTree(tree);
    929           b++;
    930         }
    931       }
    932       num_elements_ = 0;
    933       index_of_first_non_null_ = num_buckets_;
    934     }
    935 
    936     const hasher& hash_function() const { return *this; }
    937 
    938     static size_type max_size() {
    939       return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28);
    940     }
    941     size_type size() const { return num_elements_; }
    942     bool empty() const { return size() == 0; }
    943 
    944     iterator find(const Key& k) { return iterator(FindHelper(k).first); }
    945     const_iterator find(const Key& k) const { return FindHelper(k).first; }
    946 
    947     // In traditional C++ style, this performs "insert if not present."
    948     std::pair<iterator, bool> insert(const KeyValuePair& kv) {
    949       std::pair<const_iterator, size_type> p = FindHelper(kv.key());
    950       // Case 1: key was already present.
    951       if (p.first.node_ != NULL)
    952         return std::make_pair(iterator(p.first), false);
    953       // Case 2: insert.
    954       if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
    955         p = FindHelper(kv.key());
    956       }
    957       const size_type b = p.second;  // bucket number
    958       Node* node = Alloc<Node>(1);
    959       alloc_.construct(&node->kv, kv);
    960       iterator result = InsertUnique(b, node);
    961       ++num_elements_;
    962       return std::make_pair(result, true);
    963     }
    964 
    965     // The same, but if an insertion is necessary then the value portion of the
    966     // inserted key-value pair is left uninitialized.
    967     std::pair<iterator, bool> insert(const Key& k) {
    968       std::pair<const_iterator, size_type> p = FindHelper(k);
    969       // Case 1: key was already present.
    970       if (p.first.node_ != NULL)
    971         return std::make_pair(iterator(p.first), false);
    972       // Case 2: insert.
    973       if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
    974         p = FindHelper(k);
    975       }
    976       const size_type b = p.second;  // bucket number
    977       Node* node = Alloc<Node>(1);
    978       typedef typename Allocator::template rebind<Key>::other KeyAllocator;
    979       KeyAllocator(alloc_).construct(&node->kv.key(), k);
    980       iterator result = InsertUnique(b, node);
    981       ++num_elements_;
    982       return std::make_pair(result, true);
    983     }
    984 
    985     Value& operator[](const Key& k) {
    986       KeyValuePair kv(k, Value());
    987       return insert(kv).first->value();
    988     }
    989 
    990     void erase(iterator it) {
    991       GOOGLE_DCHECK_EQ(it.m_, this);
    992       const bool is_list = it.revalidate_if_necessary();
    993       size_type b = it.bucket_index_;
    994       Node* const item = it.node_;
    995       if (is_list) {
    996         GOOGLE_DCHECK(TableEntryIsNonEmptyList(b));
    997         Node* head = static_cast<Node*>(table_[b]);
    998         head = EraseFromLinkedList(item, head);
    999         table_[b] = static_cast<void*>(head);
   1000       } else {
   1001         GOOGLE_DCHECK(TableEntryIsTree(b));
   1002         Tree* tree = static_cast<Tree*>(table_[b]);
   1003         tree->erase(it.tree_it_);
   1004         if (tree->empty()) {
   1005           // Force b to be the minimum of b and b ^ 1.  This is important
   1006           // only because we want index_of_first_non_null_ to be correct.
   1007           b &= ~static_cast<size_type>(1);
   1008           DestroyTree(tree);
   1009           table_[b] = table_[b + 1] = NULL;
   1010         }
   1011       }
   1012       DestroyNode(item);
   1013       --num_elements_;
   1014       if (GOOGLE_PREDICT_FALSE(b == index_of_first_non_null_)) {
   1015         while (index_of_first_non_null_ < num_buckets_ &&
   1016                table_[index_of_first_non_null_] == NULL) {
   1017           ++index_of_first_non_null_;
   1018         }
   1019       }
   1020     }
   1021 
   1022    private:
   1023     std::pair<const_iterator, size_type> FindHelper(const Key& k) const {
   1024       size_type b = BucketNumber(k);
   1025       if (TableEntryIsNonEmptyList(b)) {
   1026         Node* node = static_cast<Node*>(table_[b]);
   1027         do {
   1028           if (IsMatch(*KeyPtrFromNodePtr(node), k)) {
   1029             return std::make_pair(const_iterator(node, this, b), b);
   1030           } else {
   1031             node = node->next;
   1032           }
   1033         } while (node != NULL);
   1034       } else if (TableEntryIsTree(b)) {
   1035         GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
   1036         b &= ~static_cast<size_t>(1);
   1037         Tree* tree = static_cast<Tree*>(table_[b]);
   1038         Key* key = const_cast<Key*>(&k);
   1039         typename Tree::iterator tree_it = tree->find(key);
   1040         if (tree_it != tree->end()) {
   1041           return std::make_pair(const_iterator(tree_it, this, b), b);
   1042         }
   1043       }
   1044       return std::make_pair(end(), b);
   1045     }
   1046 
   1047     // Insert the given Node in bucket b.  If that would make bucket b too big,
   1048     // and bucket b is not a tree, create a tree for buckets b and b^1 to share.
   1049     // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct
   1050     // bucket.  num_elements_ is not modified.
   1051     iterator InsertUnique(size_type b, Node* node) {
   1052       GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ ||
   1053              table_[index_of_first_non_null_] != NULL);
   1054       // In practice, the code that led to this point may have already
   1055       // determined whether we are inserting into an empty list, a short list,
   1056       // or whatever.  But it's probably cheap enough to recompute that here;
   1057       // it's likely that we're inserting into an empty or short list.
   1058       iterator result;
   1059       GOOGLE_DCHECK(find(*KeyPtrFromNodePtr(node)) == end());
   1060       if (TableEntryIsEmpty(b)) {
   1061         result = InsertUniqueInList(b, node);
   1062       } else if (TableEntryIsNonEmptyList(b)) {
   1063         if (GOOGLE_PREDICT_FALSE(TableEntryIsTooLong(b))) {
   1064           TreeConvert(b);
   1065           result = InsertUniqueInTree(b, node);
   1066           GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast<size_type>(1));
   1067         } else {
   1068           // Insert into a pre-existing list.  This case cannot modify
   1069           // index_of_first_non_null_, so we skip the code to update it.
   1070           return InsertUniqueInList(b, node);
   1071         }
   1072       } else {
   1073         // Insert into a pre-existing tree.  This case cannot modify
   1074         // index_of_first_non_null_, so we skip the code to update it.
   1075         return InsertUniqueInTree(b, node);
   1076       }
   1077       index_of_first_non_null_ =
   1078           std::min(index_of_first_non_null_, result.bucket_index_);
   1079       return result;
   1080     }
   1081 
   1082     // Helper for InsertUnique.  Handles the case where bucket b is a
   1083     // not-too-long linked list.
   1084     iterator InsertUniqueInList(size_type b, Node* node) {
   1085       node->next = static_cast<Node*>(table_[b]);
   1086       table_[b] = static_cast<void*>(node);
   1087       return iterator(node, this, b);
   1088     }
   1089 
   1090     // Helper for InsertUnique.  Handles the case where bucket b points to a
   1091     // Tree.
   1092     iterator InsertUniqueInTree(size_type b, Node* node) {
   1093       GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
   1094       // Maintain the invariant that node->next is NULL for all Nodes in Trees.
   1095       node->next = NULL;
   1096       return iterator(static_cast<Tree*>(table_[b])
   1097                       ->insert(KeyPtrFromNodePtr(node))
   1098                       .first,
   1099                       this, b & ~static_cast<size_t>(1));
   1100     }
   1101 
   1102     // Returns whether it did resize.  Currently this is only used when
   1103     // num_elements_ increases, though it could be used in other situations.
   1104     // It checks for load too low as well as load too high: because any number
   1105     // of erases can occur between inserts, the load could be as low as 0 here.
   1106     // Resizing to a lower size is not always helpful, but failing to do so can
   1107     // destroy the expected big-O bounds for some operations. By having the
   1108     // policy that sometimes we resize down as well as up, clients can easily
   1109     // keep O(size()) = O(number of buckets) if they want that.
   1110     bool ResizeIfLoadIsOutOfRange(size_type new_size) {
   1111       const size_type kMaxMapLoadTimes16 = 12;  // controls RAM vs CPU tradeoff
   1112       const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16;
   1113       const size_type lo_cutoff = hi_cutoff / 4;
   1114       // We don't care how many elements are in trees.  If a lot are,
   1115       // we may resize even though there are many empty buckets.  In
   1116       // practice, this seems fine.
   1117       if (GOOGLE_PREDICT_FALSE(new_size >= hi_cutoff)) {
   1118         if (num_buckets_ <= max_size() / 2) {
   1119           Resize(num_buckets_ * 2);
   1120           return true;
   1121         }
   1122       } else if (GOOGLE_PREDICT_FALSE(new_size <= lo_cutoff &&
   1123                                num_buckets_ > kMinTableSize)) {
   1124         size_type lg2_of_size_reduction_factor = 1;
   1125         // It's possible we want to shrink a lot here... size() could even be 0.
   1126         // So, estimate how much to shrink by making sure we don't shrink so
   1127         // much that we would need to grow the table after a few inserts.
   1128         const size_type hypothetical_size = new_size * 5 / 4 + 1;
   1129         while ((hypothetical_size << lg2_of_size_reduction_factor) <
   1130                hi_cutoff) {
   1131           ++lg2_of_size_reduction_factor;
   1132         }
   1133         size_type new_num_buckets = std::max<size_type>(
   1134             kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor);
   1135         if (new_num_buckets != num_buckets_) {
   1136           Resize(new_num_buckets);
   1137           return true;
   1138         }
   1139       }
   1140       return false;
   1141     }
   1142 
   1143     // Resize to the given number of buckets.
   1144     void Resize(size_t new_num_buckets) {
   1145       GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize);
   1146       void** const old_table = table_;
   1147       const size_type old_table_size = num_buckets_;
   1148       num_buckets_ = new_num_buckets;
   1149       table_ = CreateEmptyTable(num_buckets_);
   1150       const size_type start = index_of_first_non_null_;
   1151       index_of_first_non_null_ = num_buckets_;
   1152       for (size_type i = start; i < old_table_size; i++) {
   1153         if (TableEntryIsNonEmptyList(old_table, i)) {
   1154           TransferList(old_table, i);
   1155         } else if (TableEntryIsTree(old_table, i)) {
   1156           TransferTree(old_table, i++);
   1157         }
   1158       }
   1159       Dealloc<void*>(old_table, old_table_size);
   1160     }
   1161 
   1162     void TransferList(void* const* table, size_type index) {
   1163       Node* node = static_cast<Node*>(table[index]);
   1164       do {
   1165         Node* next = node->next;
   1166         InsertUnique(BucketNumber(*KeyPtrFromNodePtr(node)), node);
   1167         node = next;
   1168       } while (node != NULL);
   1169     }
   1170 
   1171     void TransferTree(void* const* table, size_type index) {
   1172       Tree* tree = static_cast<Tree*>(table[index]);
   1173       typename Tree::iterator tree_it = tree->begin();
   1174       do {
   1175         Node* node = NodePtrFromKeyPtr(*tree_it);
   1176         InsertUnique(BucketNumber(**tree_it), node);
   1177       } while (++tree_it != tree->end());
   1178       DestroyTree(tree);
   1179     }
   1180 
   1181     Node* EraseFromLinkedList(Node* item, Node* head) {
   1182       if (head == item) {
   1183         return head->next;
   1184       } else {
   1185         head->next = EraseFromLinkedList(item, head->next);
   1186         return head;
   1187       }
   1188     }
   1189 
   1190     bool TableEntryIsEmpty(size_type b) const {
   1191       return TableEntryIsEmpty(table_, b);
   1192     }
   1193     bool TableEntryIsNonEmptyList(size_type b) const {
   1194       return TableEntryIsNonEmptyList(table_, b);
   1195     }
   1196     bool TableEntryIsTree(size_type b) const {
   1197       return TableEntryIsTree(table_, b);
   1198     }
   1199     bool TableEntryIsList(size_type b) const {
   1200       return TableEntryIsList(table_, b);
   1201     }
   1202     static bool TableEntryIsEmpty(void* const* table, size_type b) {
   1203       return table[b] == NULL;
   1204     }
   1205     static bool TableEntryIsNonEmptyList(void* const* table, size_type b) {
   1206       return table[b] != NULL && table[b] != table[b ^ 1];
   1207     }
   1208     static bool TableEntryIsTree(void* const* table, size_type b) {
   1209       return !TableEntryIsEmpty(table, b) &&
   1210           !TableEntryIsNonEmptyList(table, b);
   1211     }
   1212     static bool TableEntryIsList(void* const* table, size_type b) {
   1213       return !TableEntryIsTree(table, b);
   1214     }
   1215 
   1216     void TreeConvert(size_type b) {
   1217       GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1));
   1218       typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
   1219       Tree* tree = tree_allocator.allocate(1);
   1220       // We want to use the three-arg form of construct, if it exists, but we
   1221       // create a temporary and use the two-arg construct that's known to exist.
   1222       // It's clunky, but the compiler should be able to generate more-or-less
   1223       // the same code.
   1224       tree_allocator.construct(tree,
   1225                                Tree(KeyCompare(), KeyPtrAllocator(alloc_)));
   1226       // Now the tree is ready to use.
   1227       size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree);
   1228       GOOGLE_DCHECK_EQ(count, tree->size());
   1229       table_[b] = table_[b ^ 1] = static_cast<void*>(tree);
   1230     }
   1231 
   1232     // Copy a linked list in the given bucket to a tree.
   1233     // Returns the number of things it copied.
   1234     size_type CopyListToTree(size_type b, Tree* tree) {
   1235       size_type count = 0;
   1236       Node* node = static_cast<Node*>(table_[b]);
   1237       while (node != NULL) {
   1238         tree->insert(KeyPtrFromNodePtr(node));
   1239         ++count;
   1240         Node* next = node->next;
   1241         node->next = NULL;
   1242         node = next;
   1243       }
   1244       return count;
   1245     }
   1246 
   1247     // Return whether table_[b] is a linked list that seems awfully long.
   1248     // Requires table_[b] to point to a non-empty linked list.
   1249     bool TableEntryIsTooLong(size_type b) {
   1250       const int kMaxLength = 8;
   1251       size_type count = 0;
   1252       Node* node = static_cast<Node*>(table_[b]);
   1253       do {
   1254         ++count;
   1255         node = node->next;
   1256       } while (node != NULL);
   1257       // Invariant: no linked list ever is more than kMaxLength in length.
   1258       GOOGLE_DCHECK_LE(count, kMaxLength);
   1259       return count >= kMaxLength;
   1260     }
   1261 
   1262     size_type BucketNumber(const Key& k) const {
   1263       // We inherit from hasher, so one-arg operator() provides a hash function.
   1264       size_type h = (*const_cast<InnerMap*>(this))(k);
   1265       // To help prevent people from making assumptions about the hash function,
   1266       // we use the seed differently depending on NDEBUG.  The default hash
   1267       // function, the seeding, etc., are all likely to change in the future.
   1268 #ifndef NDEBUG
   1269       return (h * (seed_ | 1)) & (num_buckets_ - 1);
   1270 #else
   1271       return (h + seed_) & (num_buckets_ - 1);
   1272 #endif
   1273     }
   1274 
   1275     bool IsMatch(const Key& k0, const Key& k1) const {
   1276       return std::equal_to<Key>()(k0, k1);
   1277     }
   1278 
   1279     // Return a power of two no less than max(kMinTableSize, n).
   1280     // Assumes either n < kMinTableSize or n is a power of two.
   1281     size_type TableSize(size_type n) {
   1282       return n < kMinTableSize ? kMinTableSize : n;
   1283     }
   1284 
   1285     // Use alloc_ to allocate an array of n objects of type U.
   1286     template <typename U>
   1287     U* Alloc(size_type n) {
   1288       typedef typename Allocator::template rebind<U>::other alloc_type;
   1289       return alloc_type(alloc_).allocate(n);
   1290     }
   1291 
   1292     // Use alloc_ to deallocate an array of n objects of type U.
   1293     template <typename U>
   1294     void Dealloc(U* t, size_type n) {
   1295       typedef typename Allocator::template rebind<U>::other alloc_type;
   1296       alloc_type(alloc_).deallocate(t, n);
   1297     }
   1298 
   1299     void DestroyNode(Node* node) {
   1300       alloc_.destroy(&node->kv);
   1301       Dealloc<Node>(node, 1);
   1302     }
   1303 
   1304     void DestroyTree(Tree* tree) {
   1305       typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
   1306       tree_allocator.destroy(tree);
   1307       tree_allocator.deallocate(tree, 1);
   1308     }
   1309 
   1310     void** CreateEmptyTable(size_type n) {
   1311       GOOGLE_DCHECK(n >= kMinTableSize);
   1312       GOOGLE_DCHECK_EQ(n & (n - 1), 0);
   1313       void** result = Alloc<void*>(n);
   1314       memset(result, 0, n * sizeof(result[0]));
   1315       return result;
   1316     }
   1317 
   1318     // Return a randomish value.
   1319     size_type Seed() const {
   1320       // random_device can throw, so avoid it unless we are compiling with
   1321       // exceptions enabled.
   1322 #if __cpp_exceptions && LANG_CXX11
   1323       try {
   1324         std::random_device rd;
   1325         std::knuth_b knuth(rd());
   1326         std::uniform_int_distribution<size_type> u;
   1327         return u(knuth);
   1328       } catch (...) { }
   1329 #endif
   1330       size_type s = static_cast<size_type>(reinterpret_cast<uintptr_t>(this));
   1331 #if defined(__x86_64__) && defined(__GNUC__)
   1332       uint32 hi, lo;
   1333       asm("rdtsc" : "=a" (lo), "=d" (hi));
   1334       s += ((static_cast<uint64>(hi) << 32) | lo);
   1335 #endif
   1336       return s;
   1337     }
   1338 
   1339     size_type num_elements_;
   1340     size_type num_buckets_;
   1341     size_type seed_;
   1342     size_type index_of_first_non_null_;
   1343     void** table_;  // an array with num_buckets_ entries
   1344     Allocator alloc_;
   1345     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap);
   1346   };  // end of class InnerMap
   1347 
   1348   typedef hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
   1349                    MapAllocator<std::pair<const Key, MapPair<Key, T>*> > >
   1350       DeprecatedInnerMap;
   1351 
   1352  public:
   1353   // Iterators
   1354   class iterator_base {
   1355    public:
   1356     // We support "old style" and "new style" iterators for now. This is
   1357     // temporary.  Also, for "iterator()" we have an unknown category.
   1358     // TODO(gpike): get rid of this.
   1359     enum IteratorStyle { kUnknown, kOld, kNew };
   1360     explicit iterator_base(IteratorStyle style) : iterator_style_(style) {}
   1361 
   1362     bool OldStyle() const {
   1363       GOOGLE_DCHECK_NE(iterator_style_, kUnknown);
   1364       return iterator_style_ == kOld;
   1365     }
   1366     bool UnknownStyle() const {
   1367       return iterator_style_ == kUnknown;
   1368     }
   1369     bool SameStyle(const iterator_base& other) const {
   1370       return iterator_style_ == other.iterator_style_;
   1371     }
   1372 
   1373    private:
   1374     IteratorStyle iterator_style_;
   1375   };
   1376 
   1377   class const_iterator
   1378       : private iterator_base,
   1379         public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
   1380                              const value_type*, const value_type&> {
   1381     typedef typename InnerMap::const_iterator InnerIt;
   1382     typedef typename DeprecatedInnerMap::const_iterator DeprecatedInnerIt;
   1383 
   1384    public:
   1385     const_iterator() : iterator_base(iterator_base::kUnknown) {}
   1386     explicit const_iterator(const DeprecatedInnerIt& dit)
   1387         : iterator_base(iterator_base::kOld), dit_(dit) {}
   1388     explicit const_iterator(const InnerIt& it)
   1389         : iterator_base(iterator_base::kNew), it_(it) {}
   1390 
   1391     const_iterator(const const_iterator& other)
   1392         : iterator_base(other), it_(other.it_), dit_(other.dit_) {}
   1393 
   1394     const_reference operator*() const {
   1395       return this->OldStyle() ? *dit_->second : *it_->value();
   1396     }
   1397     const_pointer operator->() const { return &(operator*()); }
   1398 
   1399     const_iterator& operator++() {
   1400       if (this->OldStyle())
   1401         ++dit_;
   1402       else
   1403         ++it_;
   1404       return *this;
   1405     }
   1406     const_iterator operator++(int) {
   1407       return this->OldStyle() ? const_iterator(dit_++) : const_iterator(it_++);
   1408     }
   1409 
   1410     friend bool operator==(const const_iterator& a, const const_iterator& b) {
   1411       if (!a.SameStyle(b)) return false;
   1412       if (a.UnknownStyle()) return true;
   1413       return a.OldStyle() ? (a.dit_ == b.dit_) : (a.it_ == b.it_);
   1414     }
   1415     friend bool operator!=(const const_iterator& a, const const_iterator& b) {
   1416       return !(a == b);
   1417     }
   1418 
   1419    private:
   1420     InnerIt it_;
   1421     DeprecatedInnerIt dit_;
   1422   };
   1423 
   1424   class iterator : private iterator_base,
   1425                    public std::iterator<std::forward_iterator_tag, value_type> {
   1426     typedef typename InnerMap::iterator InnerIt;
   1427     typedef typename DeprecatedInnerMap::iterator DeprecatedInnerIt;
   1428 
   1429    public:
   1430     iterator() : iterator_base(iterator_base::kUnknown) {}
   1431     explicit iterator(const DeprecatedInnerIt& dit)
   1432         : iterator_base(iterator_base::kOld), dit_(dit) {}
   1433     explicit iterator(const InnerIt& it)
   1434         : iterator_base(iterator_base::kNew), it_(it) {}
   1435 
   1436     reference operator*() const {
   1437       return this->OldStyle() ? *dit_->second : *it_->value();
   1438     }
   1439     pointer operator->() const { return &(operator*()); }
   1440 
   1441     iterator& operator++() {
   1442       if (this->OldStyle())
   1443         ++dit_;
   1444       else
   1445         ++it_;
   1446       return *this;
   1447     }
   1448     iterator operator++(int) {
   1449       return this->OldStyle() ? iterator(dit_++) : iterator(it_++);
   1450     }
   1451 
   1452     // Allow implicit conversion to const_iterator.
   1453     operator const_iterator() const {
   1454       return this->OldStyle() ?
   1455           const_iterator(typename DeprecatedInnerMap::const_iterator(dit_)) :
   1456           const_iterator(typename InnerMap::const_iterator(it_));
   1457     }
   1458 
   1459     friend bool operator==(const iterator& a, const iterator& b) {
   1460       if (!a.SameStyle(b)) return false;
   1461       if (a.UnknownStyle()) return true;
   1462       return a.OldStyle() ? a.dit_ == b.dit_ : a.it_ == b.it_;
   1463     }
   1464     friend bool operator!=(const iterator& a, const iterator& b) {
   1465       return !(a == b);
   1466     }
   1467 
   1468    private:
   1469     friend class Map;
   1470 
   1471     InnerIt it_;
   1472     DeprecatedInnerIt dit_;
   1473   };
   1474 
   1475   iterator begin() {
   1476     return old_style_ ? iterator(deprecated_elements_->begin())
   1477                       : iterator(elements_->begin());
   1478   }
   1479   iterator end() {
   1480     return old_style_ ? iterator(deprecated_elements_->end())
   1481                       : iterator(elements_->end());
   1482   }
   1483   const_iterator begin() const {
   1484     return old_style_ ? const_iterator(deprecated_elements_->begin())
   1485                       : const_iterator(iterator(elements_->begin()));
   1486   }
   1487   const_iterator end() const {
   1488     return old_style_ ? const_iterator(deprecated_elements_->end())
   1489                       : const_iterator(iterator(elements_->end()));
   1490   }
   1491   const_iterator cbegin() const { return begin(); }
   1492   const_iterator cend() const { return end(); }
   1493 
   1494   // Capacity
   1495   size_type size() const {
   1496     return old_style_ ? deprecated_elements_->size() : elements_->size();
   1497   }
   1498   bool empty() const { return size() == 0; }
   1499 
   1500   // Element access
   1501   T& operator[](const key_type& key) {
   1502     value_type** value =
   1503         old_style_ ? &(*deprecated_elements_)[key] : &(*elements_)[key];
   1504     if (*value == NULL) {
   1505       *value = CreateValueTypeInternal(key);
   1506       internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
   1507                                     T>::Initialize((*value)->second,
   1508                                                    default_enum_value_);
   1509     }
   1510     return (*value)->second;
   1511   }
   1512   const T& at(const key_type& key) const {
   1513     const_iterator it = find(key);
   1514     GOOGLE_CHECK(it != end());
   1515     return it->second;
   1516   }
   1517   T& at(const key_type& key) {
   1518     iterator it = find(key);
   1519     GOOGLE_CHECK(it != end());
   1520     return it->second;
   1521   }
   1522 
   1523   // Lookup
   1524   size_type count(const key_type& key) const {
   1525     if (find(key) != end()) assert(key == find(key)->first);
   1526     return find(key) == end() ? 0 : 1;
   1527   }
   1528   const_iterator find(const key_type& key) const {
   1529     return old_style_ ? const_iterator(deprecated_elements_->find(key))
   1530         : const_iterator(iterator(elements_->find(key)));
   1531   }
   1532   iterator find(const key_type& key) {
   1533     return old_style_ ? iterator(deprecated_elements_->find(key))
   1534                       : iterator(elements_->find(key));
   1535   }
   1536   std::pair<const_iterator, const_iterator> equal_range(
   1537       const key_type& key) const {
   1538     const_iterator it = find(key);
   1539     if (it == end()) {
   1540       return std::pair<const_iterator, const_iterator>(it, it);
   1541     } else {
   1542       const_iterator begin = it++;
   1543       return std::pair<const_iterator, const_iterator>(begin, it);
   1544     }
   1545   }
   1546   std::pair<iterator, iterator> equal_range(const key_type& key) {
   1547     iterator it = find(key);
   1548     if (it == end()) {
   1549       return std::pair<iterator, iterator>(it, it);
   1550     } else {
   1551       iterator begin = it++;
   1552       return std::pair<iterator, iterator>(begin, it);
   1553     }
   1554   }
   1555 
   1556   // insert
   1557   std::pair<iterator, bool> insert(const value_type& value) {
   1558     if (old_style_) {
   1559       iterator it = find(value.first);
   1560       if (it != end()) {
   1561         return std::pair<iterator, bool>(it, false);
   1562       } else {
   1563         return std::pair<iterator, bool>(
   1564             iterator(deprecated_elements_->insert(std::pair<Key, value_type*>(
   1565                 value.first, CreateValueTypeInternal(value))).first), true);
   1566       }
   1567     } else {
   1568       std::pair<typename InnerMap::iterator, bool> p =
   1569           elements_->insert(value.first);
   1570       if (p.second) {
   1571         p.first->value() = CreateValueTypeInternal(value);
   1572       }
   1573       return std::pair<iterator, bool>(iterator(p.first), p.second);
   1574     }
   1575   }
   1576   template <class InputIt>
   1577   void insert(InputIt first, InputIt last) {
   1578     for (InputIt it = first; it != last; ++it) {
   1579       iterator exist_it = find(it->first);
   1580       if (exist_it == end()) {
   1581         operator[](it->first) = it->second;
   1582       }
   1583     }
   1584   }
   1585 
   1586   // Erase and clear
   1587   size_type erase(const key_type& key) {
   1588     iterator it = find(key);
   1589     if (it == end()) {
   1590       return 0;
   1591     } else {
   1592       erase(it);
   1593       return 1;
   1594     }
   1595   }
   1596   iterator erase(iterator pos) {
   1597     if (arena_ == NULL) delete pos.operator->();
   1598     iterator i = pos++;
   1599     if (old_style_)
   1600       deprecated_elements_->erase(i.dit_);
   1601     else
   1602       elements_->erase(i.it_);
   1603     return pos;
   1604   }
   1605   void erase(iterator first, iterator last) {
   1606     while (first != last) {
   1607       first = erase(first);
   1608     }
   1609   }
   1610   void clear() { erase(begin(), end()); }
   1611 
   1612   // Assign
   1613   Map& operator=(const Map& other) {
   1614     if (this != &other) {
   1615       clear();
   1616       insert(other.begin(), other.end());
   1617     }
   1618     return *this;
   1619   }
   1620 
   1621   // Access to hasher.  Currently this returns a copy, but it may
   1622   // be modified to return a const reference in the future.
   1623   hasher hash_function() const {
   1624     return old_style_ ? deprecated_elements_->hash_function()
   1625                       : elements_->hash_function();
   1626   }
   1627 
   1628  private:
   1629   // Set default enum value only for proto2 map field whose value is enum type.
   1630   void SetDefaultEnumValue(int default_enum_value) {
   1631     default_enum_value_ = default_enum_value;
   1632   }
   1633 
   1634   value_type* CreateValueTypeInternal(const Key& key) {
   1635     if (arena_ == NULL) {
   1636       return new value_type(key);
   1637     } else {
   1638       value_type* value = reinterpret_cast<value_type*>(
   1639           Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
   1640       Arena::CreateInArenaStorage(const_cast<Key*>(&value->first), arena_);
   1641       Arena::CreateInArenaStorage(&value->second, arena_);
   1642       const_cast<Key&>(value->first) = key;
   1643       return value;
   1644     }
   1645   }
   1646 
   1647   value_type* CreateValueTypeInternal(const value_type& value) {
   1648     if (arena_ == NULL) {
   1649       return new value_type(value);
   1650     } else {
   1651       value_type* p = reinterpret_cast<value_type*>(
   1652           Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
   1653       Arena::CreateInArenaStorage(const_cast<Key*>(&p->first), arena_);
   1654       Arena::CreateInArenaStorage(&p->second, arena_);
   1655       const_cast<Key&>(p->first) = value.first;
   1656       p->second = value.second;
   1657       return p;
   1658     }
   1659   }
   1660 
   1661   Arena* arena_;
   1662   int default_enum_value_;
   1663   // The following is a tagged union because we support two map styles
   1664   // for now.
   1665   // TODO(gpike): get rid of the old style.
   1666   const bool old_style_;
   1667   union {
   1668     InnerMap* elements_;
   1669     DeprecatedInnerMap* deprecated_elements_;
   1670   };
   1671 
   1672   friend class ::google::protobuf::Arena;
   1673   typedef void InternalArenaConstructable_;
   1674   typedef void DestructorSkippable_;
   1675   template <typename K, typename V,
   1676             internal::WireFormatLite::FieldType key_wire_type,
   1677             internal::WireFormatLite::FieldType value_wire_type,
   1678             int default_enum_value>
   1679   friend class internal::MapFieldLite;
   1680 };
   1681 
   1682 }  // namespace protobuf
   1683 }  // namespace google
   1684 
   1685 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
   1686 template<>
   1687 struct hash<google::protobuf::MapKey> {
   1688   size_t
   1689   operator()(const google::protobuf::MapKey& map_key) const {
   1690     switch (map_key.type()) {
   1691       case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
   1692       case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
   1693       case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
   1694       case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
   1695         GOOGLE_LOG(FATAL) << "Unsupported";
   1696         break;
   1697       case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
   1698         return hash<string>()(map_key.GetStringValue());
   1699       case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
   1700         return hash< ::google::protobuf::int64>()(map_key.GetInt64Value());
   1701       case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
   1702         return hash< ::google::protobuf::int32>()(map_key.GetInt32Value());
   1703       case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
   1704         return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value());
   1705       case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
   1706         return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
   1707       case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
   1708         return hash<bool>()(map_key.GetBoolValue());
   1709     }
   1710     GOOGLE_LOG(FATAL) << "Can't get here.";
   1711     return 0;
   1712   }
   1713   bool
   1714   operator()(const google::protobuf::MapKey& map_key1,
   1715              const google::protobuf::MapKey& map_key2) const {
   1716     return map_key1 < map_key2;
   1717   }
   1718 };
   1719 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
   1720 
   1721 #endif  // GOOGLE_PROTOBUF_MAP_H__
   1722