diff options
author | Chris Kennelly <ckennelly@google.com> | 2016-12-15 16:17:17 -0800 |
---|---|---|
committer | Chris Kennelly <ckennelly@google.com> | 2016-12-16 13:50:14 -0800 |
commit | 183d31cbdb5197b1a014893a91198e970379f656 (patch) | |
tree | 1dcb6e66e200a91724895185b4561aec8dc9552b /src/google/protobuf/compiler/cpp | |
parent | a95e38ce8dec20d327692f4f5c2b0d37d6776696 (diff) |
Add rvalue setters for non-arena strings on C++11.
Diffstat (limited to 'src/google/protobuf/compiler/cpp')
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_string_field.cc | 32 | ||||
-rw-r--r-- | src/google/protobuf/compiler/cpp/cpp_unittest.cc | 46 |
2 files changed, 77 insertions, 1 deletions
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index a9505e3d..2874de7d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -141,7 +141,16 @@ GenerateAccessorDeclarations(io::Printer* printer) const { printer->Print(variables_, "$deprecated_attr$const ::std::string& $name$() const;\n" - "$deprecated_attr$void set_$name$(const ::std::string& value);\n" + "$deprecated_attr$void set_$name$(const ::std::string& value);\n"); + + if (!SupportsArenas(descriptor_)) { + printer->Print(variables_, + "#if LANG_CXX11\n" + "$deprecated_attr$void set_$name$(::std::string&& value);\n" + "#endif\n"); + } + + printer->Print(variables_, "$deprecated_attr$void set_$name$(const char* value);\n" "$deprecated_attr$void set_$name$(const $pointer_type$* value, size_t size)" ";\n" @@ -249,6 +258,14 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " $name$_.SetNoArena($default_variable$, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" + "#if LANG_CXX11\n" + "$inline$void $classname$::set_$name$(::std::string&& value) {\n" + " $set_hasbit$\n" + " $name$_.SetNoArena(\n" + " $default_variable$, ::std::move(value));\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "#endif\n" "$inline$void $classname$::set_$name$(const char* value) {\n" " $set_hasbit$\n" " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n" @@ -633,6 +650,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " $oneof_prefix$$name$_.SetNoArena($default_variable$, value);\n" " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" + "#if LANG_CXX11\n" + "$inline$void $classname$::set_$name$(::std::string&& value) {\n" + " // @@protoc_insertion_point(field_set:$full_name$)\n" + " if (!has_$name$()) {\n" + " clear_$oneof_name$();\n" + " set_has_$name$();\n" + " $oneof_prefix$$name$_.UnsafeSetDefault($default_variable$);\n" + " }\n" + " $oneof_prefix$$name$_.SetNoArena(\n" + " $default_variable$, ::std::move(value));\n" + " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" + "}\n" + "#endif\n" "$inline$void $classname$::set_$name$(const char* value) {\n" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index 8eaddb87..686c70a9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -53,6 +53,7 @@ #include <vector> #include <google/protobuf/unittest.pb.h> +#include <google/protobuf/unittest_no_arena.pb.h> #include <google/protobuf/unittest_optimize_for.pb.h> #include <google/protobuf/unittest_embed_optimize_for.pb.h> #if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER) @@ -420,6 +421,51 @@ TEST(GeneratedMessageTest, StringCharStarLength) { EXPECT_EQ("wx", message.repeated_string(0)); } +#if LANG_CXX11 +TEST(GeneratedMessageTest, StringMove) { + // Verify that we trigger the move behavior on a scalar setter. + protobuf_unittest_no_arena::TestAllTypes message; + { + string tmp(32, 'a'); + + const char* old_data = tmp.data(); + message.set_optional_string(std::move(tmp)); + const char* new_data = message.optional_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'a'), message.optional_string()); + + string tmp2(32, 'b'); + old_data = tmp2.data(); + message.set_optional_string(std::move(tmp2)); + new_data = message.optional_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'b'), message.optional_string()); + } + + // Verify that we trigger the move behavior on a oneof setter. + { + string tmp(32, 'a'); + + const char* old_data = tmp.data(); + message.set_oneof_string(std::move(tmp)); + const char* new_data = message.oneof_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'a'), message.oneof_string()); + + string tmp2(32, 'b'); + old_data = tmp2.data(); + message.set_oneof_string(std::move(tmp2)); + new_data = message.oneof_string().data(); + + EXPECT_EQ(old_data, new_data); + EXPECT_EQ(string(32, 'b'), message.oneof_string()); + } +} +#endif + TEST(GeneratedMessageTest, CopyFrom) { unittest::TestAllTypes message1, message2; |