LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - map.h (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 203 0.0 %
Date: 2015-10-10 Functions: 0 32 0.0 %

          Line data    Source code
       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 <iterator>
      35             : #include <google/protobuf/stubs/hash.h>
      36             : #include <limits>  // To support Visual Studio 2008
      37             : 
      38             : #include <google/protobuf/stubs/common.h>
      39             : #include <google/protobuf/arena.h>
      40             : #include <google/protobuf/generated_enum_util.h>
      41             : #include <google/protobuf/map_type_handler.h>
      42             : #include <google/protobuf/message.h>
      43             : #include <google/protobuf/descriptor.h>
      44             : 
      45             : namespace google {
      46             : namespace protobuf {
      47             : 
      48             : template <typename Key, typename T>
      49             : class Map;
      50             : 
      51             : template <typename Enum> struct is_proto_enum;
      52             : 
      53             : class MapIterator;
      54             : 
      55             : namespace internal {
      56             : template <typename Key, typename T,
      57             :           WireFormatLite::FieldType key_wire_type,
      58             :           WireFormatLite::FieldType value_wire_type,
      59             :           int default_enum_value>
      60             : class MapFieldLite;
      61             : 
      62             : template <typename Key, typename T,
      63             :           WireFormatLite::FieldType key_wire_type,
      64             :           WireFormatLite::FieldType value_wire_type,
      65             :           int default_enum_value>
      66             : class MapField;
      67             : 
      68             : template <typename Key, typename T>
      69             : class TypeDefinedMapFieldBase;
      70             : 
      71             : class DynamicMapField;
      72             : 
      73             : class GeneratedMessageReflection;
      74             : }  // namespace internal
      75             : 
      76             : #define TYPE_CHECK(EXPECTEDTYPE, METHOD)                                \
      77             :   if (type() != EXPECTEDTYPE) {                                         \
      78             :     GOOGLE_LOG(FATAL)                                                          \
      79             :         << "Protocol Buffer map usage error:\n"                         \
      80             :         << METHOD << " type does not match\n"                           \
      81             :         << "  Expected : "                                              \
      82             :         << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n"           \
      83             :         << "  Actual   : "                                              \
      84             :         << FieldDescriptor::CppTypeName(type());                        \
      85             :   }
      86             : 
      87             : // MapKey is an union type for representing any possible
      88             : // map key.
      89             : class LIBPROTOBUF_EXPORT MapKey {
      90             :  public:
      91           0 :   MapKey() : type_(0) {
      92             :   }
      93           0 :   MapKey(const MapKey& other) : type_(0) {
      94           0 :     CopyFrom(other);
      95             :   }
      96             : 
      97           0 :   ~MapKey() {
      98           0 :     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
      99           0 :       delete val_.string_value_;
     100             :     }
     101           0 :   }
     102             : 
     103           0 :   FieldDescriptor::CppType type() const {
     104           0 :     if (type_ == 0) {
     105           0 :       GOOGLE_LOG(FATAL)
     106           0 :           << "Protocol Buffer map usage error:\n"
     107           0 :           << "MapKey::type MapKey is not initialized. "
     108           0 :           << "Call set methods to initialize MapKey.";
     109             :     }
     110           0 :     return (FieldDescriptor::CppType)type_;
     111             :   }
     112             : 
     113             :   void SetInt64Value(int64 value) {
     114           0 :     SetType(FieldDescriptor::CPPTYPE_INT64);
     115           0 :     val_.int64_value_ = value;
     116             :   }
     117             :   void SetUInt64Value(uint64 value) {
     118           0 :     SetType(FieldDescriptor::CPPTYPE_UINT64);
     119           0 :     val_.uint64_value_ = value;
     120             :   }
     121             :   void SetInt32Value(int32 value) {
     122           0 :     SetType(FieldDescriptor::CPPTYPE_INT32);
     123           0 :     val_.int32_value_ = value;
     124             :   }
     125             :   void SetUInt32Value(uint32 value) {
     126           0 :     SetType(FieldDescriptor::CPPTYPE_UINT32);
     127           0 :     val_.uint32_value_ = value;
     128             :   }
     129             :   void SetBoolValue(bool value) {
     130           0 :     SetType(FieldDescriptor::CPPTYPE_BOOL);
     131           0 :     val_.bool_value_ = value;
     132             :   }
     133           0 :   void SetStringValue(const string& val) {
     134           0 :     SetType(FieldDescriptor::CPPTYPE_STRING);
     135           0 :     *val_.string_value_ = val;
     136           0 :   }
     137             : 
     138           0 :   int64 GetInt64Value() const {
     139           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
     140             :                "MapKey::GetInt64Value");
     141           0 :     return val_.int64_value_;
     142             :   }
     143           0 :   uint64 GetUInt64Value() const {
     144           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
     145             :                "MapKey::GetUInt64Value");
     146           0 :     return val_.uint64_value_;
     147             :   }
     148           0 :   int32 GetInt32Value() const {
     149           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
     150             :                "MapKey::GetInt32Value");
     151           0 :     return val_.int32_value_;
     152             :   }
     153           0 :   uint32 GetUInt32Value() const {
     154           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
     155             :                "MapKey::GetUInt32Value");
     156           0 :     return val_.uint32_value_;
     157             :   }
     158           0 :   int32 GetBoolValue() const {
     159           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
     160             :                "MapKey::GetBoolValue");
     161           0 :     return val_.bool_value_;
     162             :   }
     163           0 :   const string& GetStringValue() const {
     164           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
     165             :                "MapKey::GetStringValue");
     166           0 :     return *val_.string_value_;
     167             :   }
     168             : 
     169           0 :   bool operator==(const MapKey& other) const {
     170           0 :     if (type_ != other.type_) {
     171             :       return false;
     172             :     }
     173           0 :     switch (type()) {
     174             :       case FieldDescriptor::CPPTYPE_STRING:
     175           0 :         return *val_.string_value_ == *other.val_.string_value_;
     176             :       case FieldDescriptor::CPPTYPE_INT64:
     177           0 :         return val_.int64_value_ == other.val_.int64_value_;
     178             :       case FieldDescriptor::CPPTYPE_INT32:
     179           0 :         return val_.int32_value_ == other.val_.int32_value_;
     180             :       case FieldDescriptor::CPPTYPE_UINT64:
     181           0 :         return val_.uint64_value_ == other.val_.uint64_value_;
     182             :       case FieldDescriptor::CPPTYPE_UINT32:
     183           0 :         return val_.uint32_value_ == other.val_.uint32_value_;
     184             :       case FieldDescriptor::CPPTYPE_BOOL:
     185           0 :         return val_.bool_value_ == other.val_.bool_value_;
     186             :       case FieldDescriptor::CPPTYPE_DOUBLE:
     187             :       case FieldDescriptor::CPPTYPE_FLOAT:
     188             :       case FieldDescriptor::CPPTYPE_ENUM:
     189             :       case FieldDescriptor::CPPTYPE_MESSAGE:
     190           0 :         GOOGLE_LOG(FATAL) << "Can't get here.";
     191           0 :         return false;
     192             :     }
     193           0 :   }
     194             : 
     195           0 :   void CopyFrom(const MapKey& other) {
     196           0 :     SetType(other.type());
     197           0 :     switch (type_) {
     198             :       case FieldDescriptor::CPPTYPE_STRING:
     199           0 :         *val_.string_value_ = *other.val_.string_value_;
     200             :         break;
     201             :       case FieldDescriptor::CPPTYPE_INT64:
     202           0 :         val_.int64_value_ = other.val_.int64_value_;
     203           0 :         break;
     204             :       case FieldDescriptor::CPPTYPE_INT32:
     205           0 :         val_.int32_value_ = other.val_.int32_value_;
     206           0 :         break;
     207             :       case FieldDescriptor::CPPTYPE_UINT64:
     208           0 :         val_.uint64_value_ = other.val_.uint64_value_;
     209           0 :         break;
     210             :       case FieldDescriptor::CPPTYPE_UINT32:
     211           0 :         val_.uint32_value_ = other.val_.uint32_value_;
     212           0 :         break;
     213             :       case FieldDescriptor::CPPTYPE_BOOL:
     214           0 :         val_.bool_value_ = other.val_.bool_value_;
     215           0 :         break;
     216             :       case FieldDescriptor::CPPTYPE_DOUBLE:
     217             :       case FieldDescriptor::CPPTYPE_FLOAT:
     218             :       case FieldDescriptor::CPPTYPE_ENUM:
     219             :       case FieldDescriptor::CPPTYPE_MESSAGE:
     220           0 :         GOOGLE_LOG(FATAL) << "Can't get here.";
     221           0 :         break;
     222             :     }
     223           0 :   }
     224             : 
     225             :  private:
     226             :   template <typename K, typename V>
     227             :   friend class internal::TypeDefinedMapFieldBase;
     228             :   friend class MapIterator;
     229             :   friend class internal::DynamicMapField;
     230             : 
     231             :   union KeyValue {
     232             :     KeyValue() {}
     233             :     string* string_value_;
     234             :     int64 int64_value_;
     235             :     int32 int32_value_;
     236             :     uint64 uint64_value_;
     237             :     uint32 uint32_value_;
     238             :     bool bool_value_;
     239             :   } val_;
     240             : 
     241           0 :   void SetType(FieldDescriptor::CppType type) {
     242           0 :     if (type_ == type) return;
     243           0 :     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
     244           0 :       delete val_.string_value_;
     245             :     }
     246           0 :     type_ = type;
     247           0 :     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
     248           0 :       val_.string_value_ = new string;
     249             :     }
     250             :   }
     251             : 
     252             :   // type_ is 0 or a valid FieldDescriptor::CppType.
     253             :   int type_;
     254             : };
     255             : 
     256             : // MapValueRef points to a map value.
     257             : class LIBPROTOBUF_EXPORT MapValueRef {
     258             :  public:
     259           0 :   MapValueRef() : data_(NULL), type_(0) {}
     260             : 
     261             :   void SetInt64Value(int64 value) {
     262             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
     263             :                "MapValueRef::SetInt64Value");
     264             :     *reinterpret_cast<int64*>(data_) = value;
     265             :   }
     266             :   void SetUInt64Value(uint64 value) {
     267             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
     268             :                "MapValueRef::SetUInt64Value");
     269             :     *reinterpret_cast<uint64*>(data_) = value;
     270             :   }
     271             :   void SetInt32Value(int32 value) {
     272             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
     273             :                "MapValueRef::SetInt32Value");
     274             :     *reinterpret_cast<int32*>(data_) = value;
     275             :   }
     276             :   void SetUInt32Value(uint64 value) {
     277             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
     278             :                "MapValueRef::SetUInt32Value");
     279             :     *reinterpret_cast<uint32*>(data_) = value;
     280             :   }
     281             :   void SetBoolValue(bool value) {
     282             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
     283             :                "MapValueRef::SetBoolValue");
     284             :     *reinterpret_cast<bool*>(data_) = value;
     285             :   }
     286             :   // TODO(jieluo) - Checks that enum is member.
     287             :   void SetEnumValue(int value) {
     288             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
     289             :                "MapValueRef::SetEnumValue");
     290             :     *reinterpret_cast<int*>(data_) = value;
     291             :   }
     292             :   void SetStringValue(const string& value) {
     293             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
     294             :                "MapValueRef::SetStringValue");
     295             :     *reinterpret_cast<string*>(data_) = value;
     296             :   }
     297             :   void SetFloatValue(float value) {
     298             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
     299             :                "MapValueRef::SetFloatValue");
     300             :     *reinterpret_cast<float*>(data_) = value;
     301             :   }
     302             :   void SetDoubleValue(double value) {
     303             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
     304             :                "MapValueRef::SetDoubleValue");
     305             :     *reinterpret_cast<double*>(data_) = value;
     306             :   }
     307             : 
     308           0 :   int64 GetInt64Value() const {
     309           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
     310             :                "MapValueRef::GetInt64Value");
     311           0 :     return *reinterpret_cast<int64*>(data_);
     312             :   }
     313           0 :   uint64 GetUInt64Value() const {
     314           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
     315             :                "MapValueRef::GetUInt64Value");
     316           0 :     return *reinterpret_cast<uint64*>(data_);
     317             :   }
     318           0 :   int32 GetInt32Value() const {
     319           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
     320             :                "MapValueRef::GetInt32Value");
     321           0 :     return *reinterpret_cast<int32*>(data_);
     322             :   }
     323           0 :   uint32 GetUInt32Value() const {
     324           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
     325             :                "MapValueRef::GetUInt32Value");
     326           0 :     return *reinterpret_cast<uint32*>(data_);
     327             :   }
     328           0 :   bool GetBoolValue() const {
     329           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
     330             :                "MapValueRef::GetBoolValue");
     331           0 :     return *reinterpret_cast<bool*>(data_);
     332             :   }
     333           0 :   int GetEnumValue() const {
     334           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
     335             :                "MapValueRef::GetEnumValue");
     336           0 :     return *reinterpret_cast<int*>(data_);
     337             :   }
     338           0 :   const string& GetStringValue() const {
     339           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
     340             :                "MapValueRef::GetStringValue");
     341           0 :     return *reinterpret_cast<string*>(data_);
     342             :   }
     343           0 :   float GetFloatValue() const {
     344           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
     345             :                "MapValueRef::GetFloatValue");
     346           0 :     return *reinterpret_cast<float*>(data_);
     347             :   }
     348           0 :   double GetDoubleValue() const {
     349           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
     350             :                "MapValueRef::GetDoubleValue");
     351           0 :     return *reinterpret_cast<double*>(data_);
     352             :   }
     353             : 
     354           0 :   const Message& GetMessageValue() const {
     355           0 :     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
     356             :                "MapValueRef::GetMessageValue");
     357           0 :     return *reinterpret_cast<Message*>(data_);
     358             :   }
     359             : 
     360             :   Message* MutableMessageValue() {
     361             :     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
     362             :                "MapValueRef::MutableMessageValue");
     363             :     return reinterpret_cast<Message*>(data_);
     364             :   }
     365             : 
     366             :  private:
     367             :   template <typename K, typename V,
     368             :             internal::WireFormatLite::FieldType key_wire_type,
     369             :             internal::WireFormatLite::FieldType value_wire_type,
     370             :             int default_enum_value>
     371             :   friend class internal::MapField;
     372             :   template <typename K, typename V>
     373             :   friend class internal::TypeDefinedMapFieldBase;
     374             :   friend class MapIterator;
     375             :   friend class internal::GeneratedMessageReflection;
     376             :   friend class internal::DynamicMapField;
     377             : 
     378             :   void SetType(FieldDescriptor::CppType type) {
     379           0 :     type_ = type;
     380             :   }
     381             : 
     382           0 :   FieldDescriptor::CppType type() const {
     383           0 :     if (type_ == 0 || data_ == NULL) {
     384           0 :       GOOGLE_LOG(FATAL)
     385           0 :           << "Protocol Buffer map usage error:\n"
     386           0 :           << "MapValueRef::type MapValueRef is not initialized.";
     387             :     }
     388           0 :     return (FieldDescriptor::CppType)type_;
     389             :   }
     390             :   void SetValue(const void* val) {
     391           0 :     data_ = const_cast<void*>(val);
     392             :   }
     393             :   void CopyFrom(const MapValueRef& other) {
     394           0 :     type_ = other.type_;
     395           0 :     data_ = other.data_;
     396             :   }
     397             :   // Only used in DynamicMapField
     398           0 :   void DeleteData() {
     399           0 :     switch (type_) {
     400             : #define HANDLE_TYPE(CPPTYPE, TYPE)                              \
     401             :       case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
     402             :         delete reinterpret_cast<TYPE*>(data_);                  \
     403             :         break;                                                  \
     404             :       }
     405           0 :       HANDLE_TYPE(INT32, int32);
     406           0 :       HANDLE_TYPE(INT64, int64);
     407           0 :       HANDLE_TYPE(UINT32, uint32);
     408           0 :       HANDLE_TYPE(UINT64, uint64);
     409           0 :       HANDLE_TYPE(DOUBLE, double);
     410           0 :       HANDLE_TYPE(FLOAT, float);
     411           0 :       HANDLE_TYPE(BOOL, bool);
     412           0 :       HANDLE_TYPE(STRING, string);
     413           0 :       HANDLE_TYPE(ENUM, int32);
     414           0 :       HANDLE_TYPE(MESSAGE, Message);
     415             : #undef HANDLE_TYPE
     416             :     }
     417           0 :   }
     418             :   // data_ point to a map value. MapValueRef does not
     419             :   // own this value.
     420             :   void* data_;
     421             :   // type_ is 0 or a valid FieldDescriptor::CppType.
     422             :   int type_;
     423             : };
     424             : 
     425             : #undef TYPE_CHECK
     426             : 
     427             : // This is the class for google::protobuf::Map's internal value_type. Instead of using
     428             : // std::pair as value_type, we use this class which provides us more control of
     429             : // its process of construction and destruction.
     430             : template <typename Key, typename T>
     431             : class MapPair {
     432             :  public:
     433             :   typedef const Key first_type;
     434             :   typedef T second_type;
     435             : 
     436             :   MapPair(const Key& other_first, const T& other_second)
     437             :       : first(other_first), second(other_second) {}
     438           0 :   explicit MapPair(const Key& other_first) : first(other_first), second() {}
     439             :   MapPair(const MapPair& other)
     440             :       : first(other.first), second(other.second) {}
     441             : 
     442           0 :   ~MapPair() {}
     443             : 
     444             :   // Implicitly convertible to std::pair of compatible types.
     445             :   template <typename T1, typename T2>
     446             :   operator std::pair<T1, T2>() const {
     447             :     return std::pair<T1, T2>(first, second);
     448             :   }
     449             : 
     450             :   const Key first;
     451             :   T second;
     452             : 
     453             :  private:
     454             :   friend class ::google::protobuf::Arena;
     455             :   friend class Map<Key, T>;
     456             : };
     457             : 
     458             : // google::protobuf::Map is an associative container type used to store protobuf map
     459             : // fields. Its interface is similar to std::unordered_map. Users should use this
     460             : // interface directly to visit or change map fields.
     461             : template <typename Key, typename T>
     462             : class Map {
     463             :  public:
     464             :   typedef Key key_type;
     465             :   typedef T mapped_type;
     466             :   typedef MapPair<Key, T> value_type;
     467             : 
     468             :   typedef value_type* pointer;
     469             :   typedef const value_type* const_pointer;
     470             :   typedef value_type& reference;
     471             :   typedef const value_type& const_reference;
     472             : 
     473             :   typedef size_t size_type;
     474             :   typedef hash<Key> hasher;
     475             :   typedef equal_to<Key> key_equal;
     476             : 
     477           0 :   Map()
     478             :       : arena_(NULL),
     479             :         allocator_(arena_),
     480             :         elements_(0, hasher(), key_equal(), allocator_),
     481           0 :         default_enum_value_(0) {}
     482             :   explicit Map(Arena* arena)
     483             :       : arena_(arena),
     484             :         allocator_(arena_),
     485             :         elements_(0, hasher(), key_equal(), allocator_),
     486             :         default_enum_value_(0) {
     487             :     arena_->OwnDestructor(&elements_);
     488             :   }
     489             : 
     490             :   Map(const Map& other)
     491             :       : arena_(NULL),
     492             :         allocator_(arena_),
     493             :         elements_(0, hasher(), key_equal(), allocator_),
     494             :         default_enum_value_(other.default_enum_value_) {
     495             :     insert(other.begin(), other.end());
     496             :   }
     497             :   template <class InputIt>
     498             :   explicit Map(const InputIt& first, const InputIt& last)
     499             :       : arena_(NULL),
     500             :         allocator_(arena_),
     501             :         elements_(0, hasher(), key_equal(), allocator_),
     502             :         default_enum_value_(0) {
     503             :     insert(first, last);
     504             :   }
     505             : 
     506           0 :   ~Map() { clear(); }
     507             : 
     508             :  private:
     509             :   // re-implement std::allocator to use arena allocator for memory allocation.
     510             :   // Used for google::protobuf::Map implementation. Users should not use this class
     511             :   // directly.
     512             :   template <typename U>
     513             :   class MapAllocator {
     514             :    public:
     515             :     typedef U value_type;
     516             :     typedef value_type* pointer;
     517             :     typedef const value_type* const_pointer;
     518             :     typedef value_type& reference;
     519             :     typedef const value_type& const_reference;
     520             :     typedef size_t size_type;
     521             :     typedef ptrdiff_t difference_type;
     522             : 
     523             :     MapAllocator() : arena_(NULL) {}
     524           0 :     explicit MapAllocator(Arena* arena) : arena_(arena) {}
     525             :     template <typename X>
     526             :     MapAllocator(const MapAllocator<X>& allocator)
     527           0 :         : arena_(allocator.arena_) {}
     528             : 
     529           0 :     pointer allocate(size_type n, const_pointer hint = 0) {
     530             :       // If arena is not given, malloc needs to be called which doesn't
     531             :       // construct element object.
     532           0 :       if (arena_ == NULL) {
     533           0 :         return reinterpret_cast<pointer>(malloc(n * sizeof(value_type)));
     534             :       } else {
     535             :         return reinterpret_cast<pointer>(
     536           0 :             Arena::CreateArray<uint8>(arena_, n * sizeof(value_type)));
     537             :       }
     538             :     }
     539             : 
     540             :     void deallocate(pointer p, size_type n) {
     541           0 :       if (arena_ == NULL) {
     542           0 :         free(p);
     543             :       }
     544             :     }
     545             : 
     546             : #if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) && \
     547             :     !defined(GOOGLE_PROTOBUF_OS_NACL) && !defined(GOOGLE_PROTOBUF_OS_ANDROID)
     548             :     template<class NodeType, class... Args>
     549             :     void construct(NodeType* p, Args&&... args) {
     550             :       new (static_cast<void*>(p)) NodeType(std::forward<Args>(args)...);
     551             :     }
     552             : 
     553             :     template<class NodeType>
     554             :     void destroy(NodeType* p) {
     555             :       p->~NodeType();
     556             :     }
     557             : #else
     558           0 :     void construct(pointer p, const_reference t) { new (p) value_type(t); }
     559             : 
     560             :     void destroy(pointer p) { p->~value_type(); }
     561             : #endif
     562             : 
     563             :     template <typename X>
     564             :     struct rebind {
     565             :       typedef MapAllocator<X> other;
     566             :     };
     567             : 
     568             :     template <typename X>
     569             :     bool operator==(const MapAllocator<X>& other) const {
     570             :       return arena_ == other.arena_;
     571             :     }
     572             : 
     573             :     template <typename X>
     574             :     bool operator!=(const MapAllocator<X>& other) const {
     575             :       return arena_ != other.arena_;
     576             :     }
     577             : 
     578             :     // To support Visual Studio 2008
     579             :     size_type max_size() const {
     580             :       return std::numeric_limits<size_type>::max();
     581             :     }
     582             : 
     583             :    private:
     584             :     typedef void DestructorSkippable_;
     585             :     Arena* arena_;
     586             : 
     587             :     template <typename X>
     588             :     friend class MapAllocator;
     589             :   };
     590             : 
     591             :  public:
     592             :   typedef MapAllocator<std::pair<const Key, MapPair<Key, T>*> > Allocator;
     593             : 
     594             :   // Iterators
     595             :   class const_iterator
     596             :       : public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
     597             :                              const value_type*, const value_type&> {
     598             :     typedef typename hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
     599             :                               Allocator>::const_iterator InnerIt;
     600             : 
     601             :    public:
     602           0 :     const_iterator() {}
     603           0 :     explicit const_iterator(const InnerIt& it) : it_(it) {}
     604             : 
     605             :     const_reference operator*() const { return *it_->second; }
     606           0 :     const_pointer operator->() const { return it_->second; }
     607             : 
     608             :     const_iterator& operator++() {
     609           0 :       ++it_;
     610             :       return *this;
     611             :     }
     612             :     const_iterator operator++(int) { return const_iterator(it_++); }
     613             : 
     614             :     friend bool operator==(const const_iterator& a, const const_iterator& b) {
     615           0 :       return a.it_ == b.it_;
     616             :     }
     617             :     friend bool operator!=(const const_iterator& a, const const_iterator& b) {
     618           0 :       return a.it_ != b.it_;
     619             :     }
     620             : 
     621             :    private:
     622             :     InnerIt it_;
     623             :   };
     624             : 
     625             :   class iterator : public std::iterator<std::forward_iterator_tag, value_type> {
     626             :     typedef typename hash_map<Key, value_type*, hasher, equal_to<Key>,
     627             :                               Allocator>::iterator InnerIt;
     628             : 
     629             :    public:
     630             :     iterator() {}
     631           0 :     explicit iterator(const InnerIt& it) : it_(it) {}
     632             : 
     633             :     reference operator*() const { return *it_->second; }
     634           0 :     pointer operator->() const { return it_->second; }
     635             : 
     636             :     iterator& operator++() {
     637           0 :       ++it_;
     638             :       return *this;
     639             :     }
     640             :     iterator operator++(int) { return iterator(it_++); }
     641             : 
     642             :     // Implicitly convertible to const_iterator.
     643             :     operator const_iterator() const { return const_iterator(it_); }
     644             : 
     645             :     friend bool operator==(const iterator& a, const iterator& b) {
     646           0 :       return a.it_ == b.it_;
     647             :     }
     648             :     friend bool operator!=(const iterator& a, const iterator& b) {
     649           0 :       return a.it_ != b.it_;
     650             :     }
     651             : 
     652             :    private:
     653             :     friend class Map;
     654             :     InnerIt it_;
     655             :   };
     656             : 
     657           0 :   iterator begin() { return iterator(elements_.begin()); }
     658           0 :   iterator end() { return iterator(elements_.end()); }
     659           0 :   const_iterator begin() const { return const_iterator(elements_.begin()); }
     660           0 :   const_iterator end() const { return const_iterator(elements_.end()); }
     661             :   const_iterator cbegin() const { return begin(); }
     662             :   const_iterator cend() const { return end(); }
     663             : 
     664             :   // Capacity
     665           0 :   size_type size() const { return elements_.size(); }
     666             :   bool empty() const { return elements_.empty(); }
     667             : 
     668             :   // Element access
     669           0 :   T& operator[](const key_type& key) {
     670           0 :     value_type** value = &elements_[key];
     671           0 :     if (*value == NULL) {
     672           0 :       *value = CreateValueTypeInternal(key);
     673           0 :       internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
     674             :                                     T>::Initialize((*value)->second,
     675           0 :                                                    default_enum_value_);
     676             :     }
     677           0 :     return (*value)->second;
     678             :   }
     679             :   const T& at(const key_type& key) const {
     680             :     const_iterator it = find(key);
     681             :     GOOGLE_CHECK(it != end());
     682             :     return it->second;
     683             :   }
     684             :   T& at(const key_type& key) {
     685             :     iterator it = find(key);
     686             :     GOOGLE_CHECK(it != end());
     687             :     return it->second;
     688             :   }
     689             : 
     690             :   // Lookup
     691             :   size_type count(const key_type& key) const {
     692             :     return elements_.count(key);
     693             :   }
     694             :   const_iterator find(const key_type& key) const {
     695           0 :     return const_iterator(elements_.find(key));
     696             :   }
     697             :   iterator find(const key_type& key) {
     698           0 :     return iterator(elements_.find(key));
     699             :   }
     700             :   std::pair<const_iterator, const_iterator> equal_range(
     701             :       const key_type& key) const {
     702             :     const_iterator it = find(key);
     703             :     if (it == end()) {
     704             :       return std::pair<const_iterator, const_iterator>(it, it);
     705             :     } else {
     706             :       const_iterator begin = it++;
     707             :       return std::pair<const_iterator, const_iterator>(begin, it);
     708             :     }
     709             :   }
     710             :   std::pair<iterator, iterator> equal_range(const key_type& key) {
     711             :     iterator it = find(key);
     712             :     if (it == end()) {
     713             :       return std::pair<iterator, iterator>(it, it);
     714             :     } else {
     715             :       iterator begin = it++;
     716             :       return std::pair<iterator, iterator>(begin, it);
     717             :     }
     718             :   }
     719             : 
     720             :   // insert
     721             :   std::pair<iterator, bool> insert(const value_type& value) {
     722             :     iterator it = find(value.first);
     723             :     if (it != end()) {
     724             :       return std::pair<iterator, bool>(it, false);
     725             :     } else {
     726             :       return std::pair<iterator, bool>(
     727             :           iterator(elements_.insert(std::pair<Key, value_type*>(
     728             :               value.first, CreateValueTypeInternal(value))).first), true);
     729             :     }
     730             :   }
     731             :   template <class InputIt>
     732             :   void insert(InputIt first, InputIt last) {
     733             :     for (InputIt it = first; it != last; ++it) {
     734             :       iterator exist_it = find(it->first);
     735             :       if (exist_it == end()) {
     736             :         operator[](it->first) = it->second;
     737             :       }
     738             :     }
     739             :   }
     740             : 
     741             :   // Erase
     742             :   size_type erase(const key_type& key) {
     743             :     typename hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
     744             :                       Allocator>::iterator it = elements_.find(key);
     745             :     if (it == elements_.end()) {
     746             :       return 0;
     747             :     } else {
     748             :       if (arena_ == NULL) delete it->second;
     749             :       elements_.erase(it);
     750             :       return 1;
     751             :     }
     752             :   }
     753           0 :   void erase(iterator pos) {
     754           0 :     if (arena_ == NULL) delete pos.it_->second;
     755           0 :     elements_.erase(pos.it_);
     756           0 :   }
     757             :   void erase(iterator first, iterator last) {
     758             :     for (iterator it = first; it != last;) {
     759             :       if (arena_ == NULL) delete it.it_->second;
     760             :       elements_.erase((it++).it_);
     761             :     }
     762             :   }
     763           0 :   void clear() {
     764           0 :     for (iterator it = begin(); it != end(); ++it) {
     765           0 :       if (arena_ == NULL) delete it.it_->second;
     766             :     }
     767           0 :     elements_.clear();
     768           0 :   }
     769             : 
     770             :   // Assign
     771             :   Map& operator=(const Map& other) {
     772             :     if (this != &other) {
     773             :       clear();
     774             :       insert(other.begin(), other.end());
     775             :     }
     776             :     return *this;
     777             :   }
     778             : 
     779             :  private:
     780             :   // Set default enum value only for proto2 map field whose value is enum type.
     781             :   void SetDefaultEnumValue(int default_enum_value) {
     782             :     default_enum_value_ = default_enum_value;
     783             :   }
     784             : 
     785           0 :   value_type* CreateValueTypeInternal(const Key& key) {
     786           0 :     if (arena_ == NULL) {
     787           0 :       return new value_type(key);
     788             :     } else {
     789             :       value_type* value = reinterpret_cast<value_type*>(
     790           0 :           Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
     791           0 :       Arena::CreateInArenaStorage(const_cast<Key*>(&value->first), arena_);
     792           0 :       Arena::CreateInArenaStorage(&value->second, arena_);
     793           0 :       const_cast<Key&>(value->first) = key;
     794           0 :       return value;
     795             :     }
     796             :   }
     797             : 
     798             :   value_type* CreateValueTypeInternal(const value_type& value) {
     799             :     if (arena_ == NULL) {
     800             :       return new value_type(value);
     801             :     } else {
     802             :       value_type* p = reinterpret_cast<value_type*>(
     803             :           Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
     804             :       Arena::CreateInArenaStorage(const_cast<Key*>(&p->first), arena_);
     805             :       Arena::CreateInArenaStorage(&p->second, arena_);
     806             :       const_cast<Key&>(p->first) = value.first;
     807             :       p->second = value.second;
     808             :       return p;
     809             :     }
     810             :   }
     811             : 
     812             :   Arena* arena_;
     813             :   Allocator allocator_;
     814             :   hash_map<Key, value_type*, hash<Key>, equal_to<Key>, Allocator> elements_;
     815             :   int default_enum_value_;
     816             : 
     817             :   friend class ::google::protobuf::Arena;
     818             :   typedef void InternalArenaConstructable_;
     819             :   typedef void DestructorSkippable_;
     820             :   template <typename K, typename V,
     821             :             internal::WireFormatLite::FieldType key_wire_type,
     822             :             internal::WireFormatLite::FieldType value_wire_type,
     823             :             int default_enum_value>
     824             :   friend class internal::MapFieldLite;
     825             : };
     826             : 
     827             : }  // namespace protobuf
     828             : }  // namespace google
     829             : 
     830             : GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
     831             : template<>
     832             : struct hash<google::protobuf::MapKey> {
     833             :   size_t
     834           0 :   operator()(const google::protobuf::MapKey& map_key) const {
     835           0 :     switch (map_key.type()) {
     836             :       case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
     837           0 :         return hash<string>()(map_key.GetStringValue());
     838             :       case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
     839           0 :         return hash< ::google::protobuf::int64>()(map_key.GetInt64Value());
     840             :       case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
     841           0 :         return hash< ::google::protobuf::int32>()(map_key.GetInt32Value());
     842             :       case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
     843           0 :         return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value());
     844             :       case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
     845           0 :         return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
     846             :       case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
     847           0 :         return hash<bool>()(map_key.GetBoolValue());
     848             :       case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
     849             :       case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
     850             :       case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
     851             :       case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
     852           0 :         GOOGLE_LOG(FATAL) << "Can't get here.";
     853           0 :         return 0;
     854             :     }
     855           0 :   }
     856             :   bool
     857             :   operator()(const google::protobuf::MapKey& map_key1,
     858             :              const google::protobuf::MapKey& map_key2) const {
     859             :     switch (map_key1.type()) {
     860             : #define COMPARE_CPPTYPE(CPPTYPE, CPPTYPE_METHOD)             \
     861             :       case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
     862             :         return map_key1.Get##CPPTYPE_METHOD##Value() <           \
     863             :                map_key2.Get##CPPTYPE_METHOD##Value();
     864             :       COMPARE_CPPTYPE(STRING, String)
     865             :       COMPARE_CPPTYPE(INT64,  Int64)
     866             :       COMPARE_CPPTYPE(INT32,  Int32)
     867             :       COMPARE_CPPTYPE(UINT64, UInt64)
     868             :       COMPARE_CPPTYPE(UINT32, UInt32)
     869             :       COMPARE_CPPTYPE(BOOL,   Bool)
     870             : #undef COMPARE_CPPTYPE
     871             :       case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
     872             :       case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
     873             :       case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
     874             :       case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
     875             :         GOOGLE_LOG(FATAL) << "Can't get here.";
     876             :         return true;
     877             :     }
     878             :   }
     879             : };
     880             : GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
     881             : 
     882             : #endif  // GOOGLE_PROTOBUF_MAP_H__

Generated by: LCOV version 1.10