cpp_move_unittest.cc 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #include <google/protobuf/stubs/common.h>
  31. #include <google/protobuf/test_util.h>
  32. #include <google/protobuf/unittest.pb.h>
  33. #include <gtest/gtest.h>
  34. #if LANG_CXX11
  35. #include <type_traits>
  36. #endif
  37. namespace google {
  38. namespace protobuf {
  39. namespace compiler {
  40. namespace cpp {
  41. // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
  42. namespace cpp_unittest {
  43. // Moves are enabled only when compiling with a C++11 compiler or newer.
  44. #if LANG_CXX11
  45. TEST(MovableMessageTest, MoveConstructor) {
  46. protobuf_unittest::TestAllTypes message1;
  47. TestUtil::SetAllFields(&message1);
  48. const auto* nested = &message1.optional_nested_message();
  49. protobuf_unittest::TestAllTypes message2(std::move(message1));
  50. TestUtil::ExpectAllFieldsSet(message2);
  51. // Check if the optional_nested_message was actually moved (and not just
  52. // copied).
  53. EXPECT_EQ(nested, &message2.optional_nested_message());
  54. EXPECT_NE(nested, &message1.optional_nested_message());
  55. }
  56. TEST(MovableMessageTest, MoveAssignmentOperator) {
  57. protobuf_unittest::TestAllTypes message1;
  58. TestUtil::SetAllFields(&message1);
  59. const auto* nested = &message1.optional_nested_message();
  60. protobuf_unittest::TestAllTypes message2;
  61. message2 = std::move(message1);
  62. TestUtil::ExpectAllFieldsSet(message2);
  63. // Check if the optional_nested_message was actually moved (and not just
  64. // copied).
  65. EXPECT_EQ(nested, &message2.optional_nested_message());
  66. EXPECT_NE(nested, &message1.optional_nested_message());
  67. }
  68. TEST(MovableMessageTest, SelfMoveAssignment) {
  69. // The `self` reference is necessary to defeat -Wself-move.
  70. protobuf_unittest::TestAllTypes message, &self = message;
  71. TestUtil::SetAllFields(&message);
  72. message = std::move(self);
  73. TestUtil::ExpectAllFieldsSet(message);
  74. }
  75. TEST(MovableMessageTest, MoveSameArena) {
  76. Arena arena;
  77. auto* message1_on_arena =
  78. Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
  79. TestUtil::SetAllFields(message1_on_arena);
  80. const auto* nested = &message1_on_arena->optional_nested_message();
  81. auto* message2_on_arena =
  82. Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
  83. // Moving messages on the same arena should lead to swapped pointers.
  84. *message2_on_arena = std::move(*message1_on_arena);
  85. EXPECT_EQ(nested, &message2_on_arena->optional_nested_message());
  86. }
  87. TEST(MovableMessageTest, MoveDifferentArenas) {
  88. Arena arena1, arena2;
  89. auto* message1_on_arena =
  90. Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena1);
  91. TestUtil::SetAllFields(message1_on_arena);
  92. const auto* nested = &message1_on_arena->optional_nested_message();
  93. auto* message2_on_arena =
  94. Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena2);
  95. // Moving messages on two different arenas should lead to a copy.
  96. *message2_on_arena = std::move(*message1_on_arena);
  97. EXPECT_NE(nested, &message2_on_arena->optional_nested_message());
  98. TestUtil::ExpectAllFieldsSet(*message1_on_arena);
  99. TestUtil::ExpectAllFieldsSet(*message2_on_arena);
  100. }
  101. TEST(MovableMessageTest, MoveFromArena) {
  102. Arena arena;
  103. auto* message1_on_arena =
  104. Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
  105. TestUtil::SetAllFields(message1_on_arena);
  106. const auto* nested = &message1_on_arena->optional_nested_message();
  107. protobuf_unittest::TestAllTypes message2;
  108. // Moving from a message on the arena should lead to a copy.
  109. message2 = std::move(*message1_on_arena);
  110. EXPECT_NE(nested, &message2.optional_nested_message());
  111. TestUtil::ExpectAllFieldsSet(*message1_on_arena);
  112. TestUtil::ExpectAllFieldsSet(message2);
  113. }
  114. TEST(MovableMessageTest, MoveToArena) {
  115. Arena arena;
  116. protobuf_unittest::TestAllTypes message1;
  117. TestUtil::SetAllFields(&message1);
  118. const auto* nested = &message1.optional_nested_message();
  119. auto* message2_on_arena =
  120. Arena::CreateMessage<protobuf_unittest::TestAllTypes>(&arena);
  121. // Moving to a message on the arena should lead to a copy.
  122. *message2_on_arena = std::move(message1);
  123. EXPECT_NE(nested, &message2_on_arena->optional_nested_message());
  124. TestUtil::ExpectAllFieldsSet(message1);
  125. TestUtil::ExpectAllFieldsSet(*message2_on_arena);
  126. }
  127. TEST(MovableMessageTest, Noexcept) {
  128. EXPECT_TRUE(
  129. std::is_nothrow_move_constructible<protobuf_unittest::TestAllTypes>());
  130. EXPECT_TRUE(std::is_nothrow_move_assignable<protobuf_unittest::TestAllTypes>());
  131. }
  132. #endif // LANG_CXX11
  133. } // namespace cpp_unittest
  134. } // namespace cpp
  135. } // namespace compiler
  136. } // namespace protobuf
  137. } // namespace google