aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Feng Xiao <xfxyjwf@gmail.com>2014-11-25 14:01:44 -0800
committerGravatar Feng Xiao <xfxyjwf@gmail.com>2014-11-25 14:01:44 -0800
commit6ae3bde73dd9090712e22986afe866229e61d305 (patch)
tree91175cad07b13034c3a9b574ca19182093a26653
parent7f3a25bebdcf732d7f43518c9b03a5a92b4be9e1 (diff)
Fix issue 99.
-rw-r--r--src/google/protobuf/map.h13
-rw-r--r--src/google/protobuf/map_field.h7
-rw-r--r--src/google/protobuf/map_field_inl.h9
-rw-r--r--src/google/protobuf/map_test.cc21
-rw-r--r--src/google/protobuf/map_unittest.proto5
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;
+}