Fix issue 99.

This commit is contained in:
Feng Xiao 2014-11-25 14:01:44 -08:00
parent 7f3a25bebd
commit 6ae3bde73d
5 changed files with 48 additions and 7 deletions

View File

@ -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;

View File

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

View File

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

View File

@ -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) {

View File

@ -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;
}