hidl_vec: move elements on resize am: dfbedb8ffb
am: 06ef1e772a
Change-Id: Id3ea3f7b7b38e568da9c00b3dff34727693600c0
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 4c133c1..5be02b5 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -512,7 +512,7 @@
T* newBuffer = new T[size]();
for (size_t i = 0; i < std::min(static_cast<uint32_t>(size), mSize); ++i) {
- newBuffer[i] = mBuffer[i];
+ newBuffer[i] = std::move(mBuffer[i]);
}
if (mOwnsBuffer) {
@@ -733,6 +733,8 @@
using std_array_type = typename details::std_array<T, SIZE1, SIZES...>::type;
hidl_array() = default;
+ hidl_array(const hidl_array&) noexcept = default;
+ hidl_array(hidl_array&&) noexcept = default;
// Copies the data from source, using T::operator=(const T &).
hidl_array(const T *source) {
@@ -747,6 +749,9 @@
modifier = array;
}
+ hidl_array& operator=(const hidl_array&) noexcept = default;
+ hidl_array& operator=(hidl_array&&) noexcept = default;
+
T *data() { return mBuffer; }
const T *data() const { return mBuffer; }
@@ -799,6 +804,8 @@
using std_array_type = typename details::std_array<T, SIZE1>::type;
hidl_array() = default;
+ hidl_array(const hidl_array&) noexcept = default;
+ hidl_array(hidl_array&&) noexcept = default;
// Copies the data from source, using T::operator=(const T &).
hidl_array(const T *source) {
@@ -810,6 +817,9 @@
// Copies the data from the given std::array, using T::operator=(const T &).
hidl_array(const std_array_type &array) : hidl_array(array.data()) {}
+ hidl_array& operator=(const hidl_array&) noexcept = default;
+ hidl_array& operator=(hidl_array&&) noexcept = default;
+
T *data() { return mBuffer; }
const T *data() const { return mBuffer; }
diff --git a/test_main.cpp b/test_main.cpp
index 2b9f52c..6e96a42 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -319,6 +319,37 @@
EXPECT_EQ(sum, 1 + 2 + 3);
}
+struct FailsIfCopied {
+ FailsIfCopied() {}
+
+ // add failure if copied since in general this can be expensive
+ FailsIfCopied(const FailsIfCopied& o) { *this = o; }
+ FailsIfCopied& operator=(const FailsIfCopied&) {
+ ADD_FAILURE() << "FailsIfCopied copied";
+ return *this;
+ }
+
+ // fine to move this type since in general this is cheaper
+ FailsIfCopied(FailsIfCopied&& o) = default;
+ FailsIfCopied& operator=(FailsIfCopied&&) = default;
+};
+
+TEST_F(LibHidlTest, VecResizeNoCopy) {
+ using android::hardware::hidl_vec;
+
+ hidl_vec<FailsIfCopied> noCopies;
+ noCopies.resize(3); // instantiates three elements
+
+ FailsIfCopied* oldPointer = noCopies.data();
+
+ noCopies.resize(6); // should move three elements, not copy
+
+ // oldPointer should be invalidated at this point.
+ // hidl_vec doesn't currently try to realloc but if it ever switches
+ // to an implementation that does, this test wouldn't do anything.
+ EXPECT_NE(oldPointer, noCopies.data());
+}
+
TEST_F(LibHidlTest, ArrayTest) {
using android::hardware::hidl_array;
int32_t array[] = {5, 6, 7};