diff options
author | Feng Xiao <xfxyjwf@gmail.com> | 2014-11-25 14:01:44 -0800 |
---|---|---|
committer | Feng Xiao <xfxyjwf@gmail.com> | 2014-11-25 14:01:44 -0800 |
commit | 6ae3bde73dd9090712e22986afe866229e61d305 (patch) | |
tree | 91175cad07b13034c3a9b574ca19182093a26653 | |
parent | 7f3a25bebdcf732d7f43518c9b03a5a92b4be9e1 (diff) |
Fix issue 99.
-rw-r--r-- | src/google/protobuf/map.h | 13 | ||||
-rw-r--r-- | src/google/protobuf/map_field.h | 7 | ||||
-rw-r--r-- | src/google/protobuf/map_field_inl.h | 9 | ||||
-rw-r--r-- | src/google/protobuf/map_test.cc | 21 | ||||
-rw-r--r-- | src/google/protobuf/map_unittest.proto | 5 |
5 files changed, 48 insertions, 7 deletions
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index e55a6d43..f6ae3e52 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -56,7 +56,7 @@ class MapField; template <typename Key, typename T> class MapPair { public: - typedef Key first_type; + typedef const Key first_type; typedef T second_type; MapPair(const Key& other_first, const T& other_second) @@ -67,14 +67,13 @@ class MapPair { MapPair(const MapPair& other) : first(other.first), second(other.second) {} - MapPair& operator=(const MapPair& other) { - first = other.first; - second = other.second; - return *this; - } - ~MapPair() {} + // Implicitly convertible to std::pair. + operator std::pair<const Key, T>() const { + return std::pair<const Key, T>(first, second); + } + const Key first; T second; diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 4ceaf4a0..0fad1351 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -213,6 +213,13 @@ class LIBPROTOBUF_EXPORT MapField : public MapFieldBase { mutable const EntryType* default_entry_; }; +// True if IsInitialized() is true for value field in all elements of t. T is +// expected to be message. It's useful to have this helper here to keep the +// protobuf compiler from ever having to emit loops in IsInitialized() methods. +// We want the C++ compiler to inline this or not as it sees fit. +template <typename Key, typename T> +bool AllAreInitialized(const Map<Key, T>& t); + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h index 6f17df95..79302e48 100644 --- a/src/google/protobuf/map_field_inl.h +++ b/src/google/protobuf/map_field_inl.h @@ -262,6 +262,15 @@ void MapField<Key, T, KeyProto, ValueProto, } } +template <typename Key, typename T> +bool AllAreInitialized(const Map<Key, T>& t) { + for (typename Map<Key, T>::const_iterator it = t.begin(); it != t.end(); + ++it) { + if (!it->second.IsInitialized()) return false; + } + return true; +} + } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index f9544efb..c680ccb2 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -544,6 +544,13 @@ TEST_F(MapImplTest, EqualRange) { EXPECT_TRUE(const_map_.end() == const_range.second); } +TEST_F(MapImplTest, ConvertToStdMap) { + map_[100] = 101; + std::map<int32, int32> std_map(map_.begin(), map_.end()); + EXPECT_EQ(1, std_map.size()); + EXPECT_EQ(101, std_map[100]); +} + // Map Field Reflection Test ======================================== static int Func(int i, int j) { @@ -1740,6 +1747,20 @@ TEST(GeneratedMapFieldTest, MessageLiteMap) { EXPECT_EQ(1, to.map_field().at(1)); } +TEST(GeneratedMapFieldTest, IsInitialized) { + unittest::TestRequiredMessageMap map_message; + + // Add an uninitialized message. + (*map_message.mutable_map_field())[0]; + EXPECT_FALSE(map_message.IsInitialized()); + + // Initialize uninitialized message + (*map_message.mutable_map_field())[0].set_a(0); + (*map_message.mutable_map_field())[0].set_b(0); + (*map_message.mutable_map_field())[0].set_c(0); + EXPECT_TRUE(map_message.IsInitialized()); +} + // Generated Message Reflection Test ================================ TEST(GeneratedMapFieldReflectionTest, SpaceUsed) { diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto index 54bc4486..9232d58f 100644 --- a/src/google/protobuf/map_unittest.proto +++ b/src/google/protobuf/map_unittest.proto @@ -75,3 +75,8 @@ enum MapEnum { MAP_ENUM_BAR = 1; MAP_ENUM_BAZ = 2; } + +// Test embeded message with required fields +message TestRequiredMessageMap { + map<int32, TestRequired> map_field = 1; +} |