U_NAMESPACE_BEGIN
+CharString::CharString(CharString&& src) U_NOEXCEPT
+ : buffer(std::move(src.buffer)), len(src.len) {
+ src.len = 0; // not strictly necessary because we make no guarantees on the source string
+}
+
+CharString& CharString::operator=(CharString&& src) U_NOEXCEPT {
+ buffer = std::move(src.buffer);
+ len = src.len;
+ src.len = 0; // not strictly necessary because we make no guarantees on the source string
+ return *this;
+}
+
CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) {
len=s.len;
}
~CharString() {}
+ /**
+ * Move constructor; might leave src in an undefined state.
+ * This string will have the same contents and state that the source string had.
+ */
+ CharString(CharString &&src) U_NOEXCEPT;
+ /**
+ * Move assignment operator; might leave src in an undefined state.
+ * This string will have the same contents and state that the source string had.
+ * The behavior is undefined if *this and src are the same object.
+ */
+ CharString &operator=(CharString &&src) U_NOEXCEPT;
+
/**
* Replaces this string's contents with the other string's contents.
* CharString does not support the standard copy constructor nor
* Destructor deletes the array (if owned).
*/
~MaybeStackArray() { releaseArray(); }
+ /**
+ * Move constructor: transfers ownership or copies the stack array.
+ */
+ MaybeStackArray(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT;
+ /**
+ * Move assignment: transfers ownership or copies the stack array.
+ */
+ MaybeStackArray<T, stackCapacity> &operator=(MaybeStackArray<T, stackCapacity> &&src) U_NOEXCEPT;
/**
* Returns the array capacity (number of T items).
* @return array capacity
uprv_free(ptr);
}
}
+ void resetToStackArray() {
+ ptr=stackArray;
+ capacity=stackCapacity;
+ needToRelease=FALSE;
+ }
/* No comparison operators with other MaybeStackArray's. */
bool operator==(const MaybeStackArray & /*other*/) {return FALSE;}
bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;}
#endif
};
+template<typename T, int32_t stackCapacity>
+icu::MaybeStackArray<T, stackCapacity>::MaybeStackArray(
+ MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT
+ : ptr(src.ptr), capacity(src.capacity), needToRelease(src.needToRelease) {
+ if (src.ptr == src.stackArray) {
+ ptr = stackArray;
+ uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity);
+ } else {
+ src.resetToStackArray(); // take ownership away from src
+ }
+}
+
+template<typename T, int32_t stackCapacity>
+inline MaybeStackArray <T, stackCapacity>&
+MaybeStackArray<T, stackCapacity>::operator=(MaybeStackArray <T, stackCapacity>&& src) U_NOEXCEPT {
+ releaseArray(); // in case this instance had its own memory allocated
+ capacity = src.capacity;
+ needToRelease = src.needToRelease;
+ if (src.ptr == src.stackArray) {
+ ptr = stackArray;
+ uprv_memcpy(stackArray, src.stackArray, sizeof(T) * src.capacity);
+ } else {
+ ptr = src.ptr;
+ src.resetToStackArray(); // take ownership away from src
+ }
+ return *this;
+}
+
template<typename T, int32_t stackCapacity>
inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) {
if(newCapacity>0) {
uprv_memcpy(p, ptr, (size_t)length*sizeof(T));
}
resultCapacity=length;
- ptr=stackArray;
- capacity=stackCapacity;
- needToRelease=FALSE;
+ resetToStackArray();
return p;
}
UnicodeString &fastCopyFrom(const UnicodeString &src);
/**
- * Move assignment operator, might leave src in bogus state.
+ * Move assignment operator; might leave src in bogus state.
* This string will have the same contents and state that the source string had.
* The behavior is undefined if *this and src are the same object.
* @param src source string
// do not use #ifndef U_HIDE_DRAFT_API for moveFrom, needed by non-draft API
/**
- * Move assignment, might leave src in bogus state.
+ * Move assignment; might leave src in bogus state.
* This string will have the same contents and state that the source string had.
* The behavior is undefined if *this and src are the same object.
*
UnicodeString(const UnicodeString& that);
/**
- * Move constructor, might leave src in bogus state.
+ * Move constructor; might leave src in bogus state.
* This string will have the same contents and state that the source string had.
* @param src source string
* @stable ICU 56
if (chStr.length() != 0) {
errln("%s:%d expected length() = 0, got %d", __FILE__, __LINE__, chStr.length());
}
+
+ {
+ CharString s1("Short string", errorCode);
+ CharString s2(std::move(s1));
+ assertEquals("s2 should have content of s1", "Short string", s2.data());
+ CharString s3("Dummy", errorCode);
+ s3 = std::move(s2);
+ assertEquals("s3 should have content of s2", "Short string", s3.data());
+ }
+
+ {
+ CharString s1("Long string over 40 characters to trigger heap allocation", errorCode);
+ CharString s2(std::move(s1));
+ assertEquals("s2 should have content of s1",
+ "Long string over 40 characters to trigger heap allocation",
+ s2.data());
+ CharString s3("Dummy string with over 40 characters to trigger heap allocation", errorCode);
+ s3 = std::move(s2);
+ assertEquals("s3 should have content of s2",
+ "Long string over 40 characters to trigger heap allocation",
+ s3.data());
+ }
}
void