Browse Source

Expose rvalue setters for repeated string fields.

rvalue setters for scalar string fields were added in #2506.
Chris Kennelly 8 năm trước cách đây
mục cha
commit
0026dff9f6

+ 23 - 0
src/google/protobuf/arena.h

@@ -322,6 +322,17 @@ class LIBPROTOBUF_EXPORT Arena {
                                       arg);
     }
   }
+#if LANG_CXX11
+  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+  static T* Create(::google::protobuf::Arena* arena, Arg&& arg) {
+    if (arena == NULL) {
+      return new T(std::move(arg));
+    } else {
+      return arena->CreateInternal<T>(google::protobuf::internal::has_trivial_destructor<T>::value,
+                                      std::move(arg));
+    }
+  }
+#endif
 
   // Version of the above with two constructor arguments for the created object.
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
@@ -662,6 +673,18 @@ class LIBPROTOBUF_EXPORT Arena {
     return t;
   }
 
+#if LANG_CXX11
+  template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+  T* CreateInternal(bool skip_explicit_ownership, Arg&& arg) {
+    T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(
+        std::move(arg));
+    if (!skip_explicit_ownership) {
+      AddListNode(t, &internal::arena_destruct_object<T>);
+    }
+    return t;
+  }
+#endif
+
   template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
   T* CreateInternal(
       bool skip_explicit_ownership, const Arg1& arg1, const Arg2& arg2) {

+ 18 - 0
src/google/protobuf/compiler/cpp/cpp_string_field.cc

@@ -830,12 +830,18 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
     "$deprecated_attr$const ::std::string& $name$(int index) const;\n"
     "$deprecated_attr$::std::string* mutable_$name$(int index);\n"
     "$deprecated_attr$void set_$name$(int index, const ::std::string& value);\n"
+    "#if LANG_CXX11\n"
+    "$deprecated_attr$void set_$name$(int index, ::std::string&& value);\n"
+    "#endif\n"
     "$deprecated_attr$void set_$name$(int index, const char* value);\n"
     ""
     "$deprecated_attr$void set_$name$("
                  "int index, const $pointer_type$* value, size_t size);\n"
     "$deprecated_attr$::std::string* add_$name$();\n"
     "$deprecated_attr$void add_$name$(const ::std::string& value);\n"
+    "#if LANG_CXX11\n"
+    "$deprecated_attr$void add_$name$(::std::string&& value);\n"
+    "#endif\n"
     "$deprecated_attr$void add_$name$(const char* value);\n"
     "$deprecated_attr$void add_$name$(const $pointer_type$* value, size_t size)"
                  ";\n"
@@ -869,6 +875,12 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
     "  // @@protoc_insertion_point(field_set:$full_name$)\n"
     "  $name$_.Mutable(index)->assign(value);\n"
     "}\n"
+    "#if LANG_CXX11\n"
+    "$inline$void $classname$::set_$name$(int index, ::std::string&& value) {\n"
+    "  // @@protoc_insertion_point(field_set:$full_name$)\n"
+    "  $name$_.Mutable(index)->assign(std::move(value));\n"
+    "}\n"
+    "#endif\n"
     "$inline$void $classname$::set_$name$(int index, const char* value) {\n"
     "  $name$_.Mutable(index)->assign(value);\n"
     "  // @@protoc_insertion_point(field_set_char:$full_name$)\n"
@@ -888,6 +900,12 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
     "  $name$_.Add()->assign(value);\n"
     "  // @@protoc_insertion_point(field_add:$full_name$)\n"
     "}\n"
+    "#if LANG_CXX11\n"
+    "$inline$void $classname$::add_$name$(::std::string&& value) {\n"
+    "  $name$_.Add()->assign(std::move(value));\n"
+    "  // @@protoc_insertion_point(field_add:$full_name$)\n"
+    "}\n"
+    "#endif\n"
     "$inline$void $classname$::add_$name$(const char* value) {\n"
     "  $name$_.Add()->assign(value);\n"
     "  // @@protoc_insertion_point(field_add_char:$full_name$)\n"

+ 20 - 0
src/google/protobuf/compiler/cpp/cpp_unittest.cc

@@ -463,6 +463,26 @@ TEST(GeneratedMessageTest, StringMove) {
     EXPECT_EQ(old_data, new_data);
     EXPECT_EQ(string(32, 'b'), message.oneof_string());
   }
+
+  // Verify that we trigger the move behavior on a repeated setter.
+  {
+    string tmp(32, 'a');
+
+    const char* old_data = tmp.data();
+    message.add_repeated_string(std::move(tmp));
+    const char* new_data = message.repeated_string(0).data();
+
+    EXPECT_EQ(old_data, new_data);
+    EXPECT_EQ(string(32, 'a'), message.repeated_string(0));
+
+    string tmp2(32, 'b');
+    old_data = tmp2.data();
+    message.set_repeated_string(0, std::move(tmp2));
+    new_data = message.repeated_string(0).data();
+
+    EXPECT_EQ(old_data, new_data);
+    EXPECT_EQ(string(32, 'b'), message.repeated_string(0));
+  }
 }
 #endif
 

+ 12 - 0
src/google/protobuf/compiler/plugin.pb.cc

@@ -1107,6 +1107,12 @@ void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::string&
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
   file_to_generate_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+void CodeGeneratorRequest::set_file_to_generate(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  file_to_generate_.Mutable(index)->assign(std::move(value));
+}
+#endif
 void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
   file_to_generate_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
@@ -1124,6 +1130,12 @@ void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) {
   file_to_generate_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
+#if LANG_CXX11
+void CodeGeneratorRequest::add_file_to_generate(::std::string&& value) {
+  file_to_generate_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+#endif
 void CodeGeneratorRequest::add_file_to_generate(const char* value) {
   file_to_generate_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)

+ 18 - 0
src/google/protobuf/compiler/plugin.pb.h

@@ -356,10 +356,16 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
   const ::std::string& file_to_generate(int index) const;
   ::std::string* mutable_file_to_generate(int index);
   void set_file_to_generate(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_file_to_generate(int index, ::std::string&& value);
+  #endif
   void set_file_to_generate(int index, const char* value);
   void set_file_to_generate(int index, const char* value, size_t size);
   ::std::string* add_file_to_generate();
   void add_file_to_generate(const ::std::string& value);
+  #if LANG_CXX11
+  void add_file_to_generate(::std::string&& value);
+  #endif
   void add_file_to_generate(const char* value);
   void add_file_to_generate(const char* value, size_t size);
   const ::google::protobuf::RepeatedPtrField< ::std::string>& file_to_generate() const;
@@ -839,6 +845,12 @@ inline void CodeGeneratorRequest::set_file_to_generate(int index, const ::std::s
   // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
   file_to_generate_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+inline void CodeGeneratorRequest::set_file_to_generate(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+  file_to_generate_.Mutable(index)->assign(std::move(value));
+}
+#endif
 inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) {
   file_to_generate_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
@@ -856,6 +868,12 @@ inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& valu
   file_to_generate_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
 }
+#if LANG_CXX11
+inline void CodeGeneratorRequest::add_file_to_generate(::std::string&& value) {
+  file_to_generate_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)
+}
+#endif
 inline void CodeGeneratorRequest::add_file_to_generate(const char* value) {
   file_to_generate_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate)

+ 36 - 0
src/google/protobuf/descriptor.pb.cc

@@ -2113,6 +2113,12 @@ void FileDescriptorProto::set_dependency(int index, const ::std::string& value)
   // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
   dependency_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+void FileDescriptorProto::set_dependency(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
+  dependency_.Mutable(index)->assign(std::move(value));
+}
+#endif
 void FileDescriptorProto::set_dependency(int index, const char* value) {
   dependency_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
@@ -2130,6 +2136,12 @@ void FileDescriptorProto::add_dependency(const ::std::string& value) {
   dependency_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
 }
+#if LANG_CXX11
+void FileDescriptorProto::add_dependency(::std::string&& value) {
+  dependency_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
+}
+#endif
 void FileDescriptorProto::add_dependency(const char* value) {
   dependency_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
@@ -4120,6 +4132,12 @@ void DescriptorProto::set_reserved_name(int index, const ::std::string& value) {
   // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
   reserved_name_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+void DescriptorProto::set_reserved_name(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
+  reserved_name_.Mutable(index)->assign(std::move(value));
+}
+#endif
 void DescriptorProto::set_reserved_name(int index, const char* value) {
   reserved_name_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name)
@@ -4137,6 +4155,12 @@ void DescriptorProto::add_reserved_name(const ::std::string& value) {
   reserved_name_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
 }
+#if LANG_CXX11
+void DescriptorProto::add_reserved_name(::std::string&& value) {
+  reserved_name_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
+}
+#endif
 void DescriptorProto::add_reserved_name(const char* value) {
   reserved_name_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name)
@@ -14438,6 +14462,12 @@ void SourceCodeInfo_Location::set_leading_detached_comments(int index, const ::s
   // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
   leading_detached_comments_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+void SourceCodeInfo_Location::set_leading_detached_comments(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  leading_detached_comments_.Mutable(index)->assign(std::move(value));
+}
+#endif
 void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
   leading_detached_comments_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
@@ -14455,6 +14485,12 @@ void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string&
   leading_detached_comments_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
+#if LANG_CXX11
+void SourceCodeInfo_Location::add_leading_detached_comments(::std::string&& value) {
+  leading_detached_comments_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+#endif
 void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
   leading_detached_comments_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)

+ 54 - 0
src/google/protobuf/descriptor.pb.h

@@ -441,10 +441,16 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
   const ::std::string& dependency(int index) const;
   ::std::string* mutable_dependency(int index);
   void set_dependency(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_dependency(int index, ::std::string&& value);
+  #endif
   void set_dependency(int index, const char* value);
   void set_dependency(int index, const char* value, size_t size);
   ::std::string* add_dependency();
   void add_dependency(const ::std::string& value);
+  #if LANG_CXX11
+  void add_dependency(::std::string&& value);
+  #endif
   void add_dependency(const char* value);
   void add_dependency(const char* value, size_t size);
   const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const;
@@ -996,10 +1002,16 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /*
   const ::std::string& reserved_name(int index) const;
   ::std::string* mutable_reserved_name(int index);
   void set_reserved_name(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_reserved_name(int index, ::std::string&& value);
+  #endif
   void set_reserved_name(int index, const char* value);
   void set_reserved_name(int index, const char* value, size_t size);
   ::std::string* add_reserved_name();
   void add_reserved_name(const ::std::string& value);
+  #if LANG_CXX11
+  void add_reserved_name(::std::string&& value);
+  #endif
   void add_reserved_name(const char* value);
   void add_reserved_name(const char* value, size_t size);
   const ::google::protobuf::RepeatedPtrField< ::std::string>& reserved_name() const;
@@ -3717,10 +3729,16 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me
   const ::std::string& leading_detached_comments(int index) const;
   ::std::string* mutable_leading_detached_comments(int index);
   void set_leading_detached_comments(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_leading_detached_comments(int index, ::std::string&& value);
+  #endif
   void set_leading_detached_comments(int index, const char* value);
   void set_leading_detached_comments(int index, const char* value, size_t size);
   ::std::string* add_leading_detached_comments();
   void add_leading_detached_comments(const ::std::string& value);
+  #if LANG_CXX11
+  void add_leading_detached_comments(::std::string&& value);
+  #endif
   void add_leading_detached_comments(const char* value);
   void add_leading_detached_comments(const char* value, size_t size);
   const ::google::protobuf::RepeatedPtrField< ::std::string>& leading_detached_comments() const;
@@ -4297,6 +4315,12 @@ inline void FileDescriptorProto::set_dependency(int index, const ::std::string&
   // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
   dependency_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+inline void FileDescriptorProto::set_dependency(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.FileDescriptorProto.dependency)
+  dependency_.Mutable(index)->assign(std::move(value));
+}
+#endif
 inline void FileDescriptorProto::set_dependency(int index, const char* value) {
   dependency_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency)
@@ -4314,6 +4338,12 @@ inline void FileDescriptorProto::add_dependency(const ::std::string& value) {
   dependency_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
 }
+#if LANG_CXX11
+inline void FileDescriptorProto::add_dependency(::std::string&& value) {
+  dependency_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency)
+}
+#endif
 inline void FileDescriptorProto::add_dependency(const char* value) {
   dependency_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency)
@@ -5109,6 +5139,12 @@ inline void DescriptorProto::set_reserved_name(int index, const ::std::string& v
   // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
   reserved_name_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+inline void DescriptorProto::set_reserved_name(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.DescriptorProto.reserved_name)
+  reserved_name_.Mutable(index)->assign(std::move(value));
+}
+#endif
 inline void DescriptorProto::set_reserved_name(int index, const char* value) {
   reserved_name_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name)
@@ -5126,6 +5162,12 @@ inline void DescriptorProto::add_reserved_name(const ::std::string& value) {
   reserved_name_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
 }
+#if LANG_CXX11
+inline void DescriptorProto::add_reserved_name(::std::string&& value) {
+  reserved_name_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name)
+}
+#endif
 inline void DescriptorProto::add_reserved_name(const char* value) {
   reserved_name_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name)
@@ -8250,6 +8292,12 @@ inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, co
   // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
   leading_detached_comments_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+  leading_detached_comments_.Mutable(index)->assign(std::move(value));
+}
+#endif
 inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) {
   leading_detached_comments_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
@@ -8267,6 +8315,12 @@ inline void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::
   leading_detached_comments_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
 }
+#if LANG_CXX11
+inline void SourceCodeInfo_Location::add_leading_detached_comments(::std::string&& value) {
+  leading_detached_comments_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)
+}
+#endif
 inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) {
   leading_detached_comments_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments)

+ 12 - 0
src/google/protobuf/field_mask.pb.cc

@@ -356,6 +356,12 @@ void FieldMask::set_paths(int index, const ::std::string& value) {
   // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
   paths_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+void FieldMask::set_paths(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
+  paths_.Mutable(index)->assign(std::move(value));
+}
+#endif
 void FieldMask::set_paths(int index, const char* value) {
   paths_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths)
@@ -373,6 +379,12 @@ void FieldMask::add_paths(const ::std::string& value) {
   paths_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
 }
+#if LANG_CXX11
+void FieldMask::add_paths(::std::string&& value) {
+  paths_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
+}
+#endif
 void FieldMask::add_paths(const char* value) {
   paths_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths)

+ 18 - 0
src/google/protobuf/field_mask.pb.h

@@ -127,10 +127,16 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro
   const ::std::string& paths(int index) const;
   ::std::string* mutable_paths(int index);
   void set_paths(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_paths(int index, ::std::string&& value);
+  #endif
   void set_paths(int index, const char* value);
   void set_paths(int index, const char* value, size_t size);
   ::std::string* add_paths();
   void add_paths(const ::std::string& value);
+  #if LANG_CXX11
+  void add_paths(::std::string&& value);
+  #endif
   void add_paths(const char* value);
   void add_paths(const char* value, size_t size);
   const ::google::protobuf::RepeatedPtrField< ::std::string>& paths() const;
@@ -171,6 +177,12 @@ inline void FieldMask::set_paths(int index, const ::std::string& value) {
   // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
   paths_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+inline void FieldMask::set_paths(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.FieldMask.paths)
+  paths_.Mutable(index)->assign(std::move(value));
+}
+#endif
 inline void FieldMask::set_paths(int index, const char* value) {
   paths_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths)
@@ -188,6 +200,12 @@ inline void FieldMask::add_paths(const ::std::string& value) {
   paths_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
 }
+#if LANG_CXX11
+inline void FieldMask::add_paths(::std::string&& value) {
+  paths_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths)
+}
+#endif
 inline void FieldMask::add_paths(const char* value) {
   paths_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths)

+ 47 - 0
src/google/protobuf/repeated_field.h

@@ -423,6 +423,11 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
   void Delete(int index);
   template <typename TypeHandler>
   typename TypeHandler::Type* Add(typename TypeHandler::Type* prototype = NULL);
+#if LANG_CXX11
+  template <typename TypeHandler>
+  void Add(typename TypeHandler::Type&& value,
+           std::enable_if<TypeHandler::Moveable>* dummy = NULL);
+#endif
 
   template <typename TypeHandler>
   void RemoveLast();
@@ -575,6 +580,9 @@ template <typename GenericType>
 class GenericTypeHandler {
  public:
   typedef GenericType Type;
+#if LANG_CXX11
+  static const bool Moveable = false;
+#endif
   static inline GenericType* New(Arena* arena) {
     return ::google::protobuf::Arena::CreateMaybeMessage<Type>(
         arena, static_cast<GenericType*>(0));
@@ -690,10 +698,20 @@ inline const Message& GenericTypeHandler<Message>::default_instance() {
 class StringTypeHandler {
  public:
   typedef string Type;
+#if LANG_CXX11
+  static const bool Moveable =
+      std::is_move_constructible<Type>::value &&
+      std::is_move_assignable<Type>::value;
+#endif
 
   static inline string* New(Arena* arena) {
     return Arena::Create<string>(arena);
   }
+#if LANG_CXX11
+  static inline string* New(Arena* arena, std::string&& value) {
+    return Arena::Create<string>(arena, std::move(value));
+  }
+#endif
   static inline string* NewFromPrototype(const string*,
                                          ::google::protobuf::Arena* arena) {
     return New(arena);
@@ -743,6 +761,9 @@ class RepeatedPtrField PROTOBUF_FINAL : public internal::RepeatedPtrFieldBase {
   const Element& Get(int index) const;
   Element* Mutable(int index);
   Element* Add();
+#if LANG_CXX11
+  void Add(Element&& value);
+#endif
 
   const Element& operator[](int index) const { return Get(index); }
   Element& operator[](int index) { return *Mutable(index); }
@@ -1451,6 +1472,25 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add(
   return result;
 }
 
+#if LANG_CXX11
+template <typename TypeHandler>
+inline void RepeatedPtrFieldBase::Add(
+    typename TypeHandler::Type&& value,
+    std::enable_if<TypeHandler::Moveable>*) {
+  if (rep_ != NULL && current_size_ < rep_->allocated_size) {
+    cast<TypeHandler>(rep_->elements[current_size_++]) = std::move(value);
+  }
+  if (!rep_ || rep_->allocated_size == total_size_) {
+    Reserve(total_size_ + 1);
+  }
+  ++rep_->allocated_size;
+  typename TypeHandler::Type* result =
+      TypeHandler::New(arena_, std::move(value));
+  rep_->elements[current_size_++] = result;
+  return result;
+}
+#endif
+
 template <typename TypeHandler>
 inline void RepeatedPtrFieldBase::RemoveLast() {
   GOOGLE_DCHECK_GT(current_size_, 0);
@@ -1848,6 +1888,13 @@ inline Element* RepeatedPtrField<Element>::Add() {
   return RepeatedPtrFieldBase::Add<TypeHandler>();
 }
 
+#if LANG_CXX11
+template <typename Element>
+inline void RepeatedPtrField<Element>::Add(Element&& value) {
+  RepeatedPtrFieldBase::Add<TypeHandler>(std::move(value));
+}
+#endif
+
 template <typename Element>
 inline void RepeatedPtrField<Element>::RemoveLast() {
   RepeatedPtrFieldBase::RemoveLast<TypeHandler>();

+ 12 - 0
src/google/protobuf/type.pb.cc

@@ -957,6 +957,12 @@ void Type::set_oneofs(int index, const ::std::string& value) {
   // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
   oneofs_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+void Type::set_oneofs(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
+  oneofs_.Mutable(index)->assign(std::move(value));
+}
+#endif
 void Type::set_oneofs(int index, const char* value) {
   oneofs_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs)
@@ -974,6 +980,12 @@ void Type::add_oneofs(const ::std::string& value) {
   oneofs_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
 }
+#if LANG_CXX11
+void Type::add_oneofs(::std::string&& value) {
+  oneofs_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
+}
+#endif
 void Type::add_oneofs(const char* value) {
   oneofs_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs)

+ 18 - 0
src/google/protobuf/type.pb.h

@@ -254,10 +254,16 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i
   const ::std::string& oneofs(int index) const;
   ::std::string* mutable_oneofs(int index);
   void set_oneofs(int index, const ::std::string& value);
+  #if LANG_CXX11
+  void set_oneofs(int index, ::std::string&& value);
+  #endif
   void set_oneofs(int index, const char* value);
   void set_oneofs(int index, const char* value, size_t size);
   ::std::string* add_oneofs();
   void add_oneofs(const ::std::string& value);
+  #if LANG_CXX11
+  void add_oneofs(::std::string&& value);
+  #endif
   void add_oneofs(const char* value);
   void add_oneofs(const char* value, size_t size);
   const ::google::protobuf::RepeatedPtrField< ::std::string>& oneofs() const;
@@ -1144,6 +1150,12 @@ inline void Type::set_oneofs(int index, const ::std::string& value) {
   // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
   oneofs_.Mutable(index)->assign(value);
 }
+#if LANG_CXX11
+inline void Type::set_oneofs(int index, ::std::string&& value) {
+  // @@protoc_insertion_point(field_set:google.protobuf.Type.oneofs)
+  oneofs_.Mutable(index)->assign(std::move(value));
+}
+#endif
 inline void Type::set_oneofs(int index, const char* value) {
   oneofs_.Mutable(index)->assign(value);
   // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs)
@@ -1161,6 +1173,12 @@ inline void Type::add_oneofs(const ::std::string& value) {
   oneofs_.Add()->assign(value);
   // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
 }
+#if LANG_CXX11
+inline void Type::add_oneofs(::std::string&& value) {
+  oneofs_.Add()->assign(std::move(value));
+  // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs)
+}
+#endif
 inline void Type::add_oneofs(const char* value) {
   oneofs_.Add()->assign(value);
   // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs)