+TEST(IOBuf, move) {
+ // Default allocate an IOBuf on the stack
+ IOBuf outerBuf;
+ char data[] = "foobar";
+ uint32_t length = sizeof(data);
+ uint32_t actualCapacity{0};
+ const void* ptr{nullptr};
+
+ {
+ // Create a small IOBuf on the stack.
+ // Note that IOBufs created on the stack always use an external buffer.
+ IOBuf b1(IOBuf::CREATE, 10);
+ actualCapacity = b1.capacity();
+ EXPECT_GE(actualCapacity, 10);
+ EXPECT_EQ(0, b1.length());
+ EXPECT_FALSE(b1.isShared());
+ ptr = b1.data();
+ ASSERT_TRUE(ptr != nullptr);
+ memcpy(b1.writableTail(), data, length);
+ b1.append(length);
+ EXPECT_EQ(length, b1.length());
+
+ // Use the move constructor
+ IOBuf b2(std::move(b1));
+ EXPECT_EQ(ptr, b2.data());
+ EXPECT_EQ(length, b2.length());
+ EXPECT_EQ(actualCapacity, b2.capacity());
+ EXPECT_FALSE(b2.isShared());
+
+ // Use the move assignment operator
+ outerBuf = std::move(b2);
+ // Close scope, destroying b1 and b2
+ // (which are both be invalid now anyway after moving out of them)
+ }
+
+ EXPECT_EQ(ptr, outerBuf.data());
+ EXPECT_EQ(length, outerBuf.length());
+ EXPECT_EQ(actualCapacity, outerBuf.capacity());
+ EXPECT_FALSE(outerBuf.isShared());
+}
+