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__
|