ICU-13585 Adding std::move operators to CharString and MaybeStackArray.
X-SVN-Rev: 40904
This commit is contained in:
parent
1ed7deaa8c
commit
fb26c75df0
@ -23,6 +23,18 @@
|
|||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
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) {
|
CharString &CharString::copyFrom(const CharString &s, UErrorCode &errorCode) {
|
||||||
if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) {
|
if(U_SUCCESS(errorCode) && this!=&s && ensureCapacity(s.len+1, 0, errorCode)) {
|
||||||
len=s.len;
|
len=s.len;
|
||||||
|
@ -55,6 +55,18 @@ public:
|
|||||||
}
|
}
|
||||||
~CharString() {}
|
~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.
|
* Replaces this string's contents with the other string's contents.
|
||||||
* CharString does not support the standard copy constructor nor
|
* CharString does not support the standard copy constructor nor
|
||||||
|
@ -299,6 +299,14 @@ public:
|
|||||||
* Destructor deletes the array (if owned).
|
* Destructor deletes the array (if owned).
|
||||||
*/
|
*/
|
||||||
~MaybeStackArray() { releaseArray(); }
|
~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).
|
* Returns the array capacity (number of T items).
|
||||||
* @return array capacity
|
* @return array capacity
|
||||||
@ -376,6 +384,11 @@ private:
|
|||||||
uprv_free(ptr);
|
uprv_free(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void resetToStackArray() {
|
||||||
|
ptr=stackArray;
|
||||||
|
capacity=stackCapacity;
|
||||||
|
needToRelease=FALSE;
|
||||||
|
}
|
||||||
/* No comparison operators with other MaybeStackArray's. */
|
/* No comparison operators with other MaybeStackArray's. */
|
||||||
bool operator==(const MaybeStackArray & /*other*/) {return FALSE;}
|
bool operator==(const MaybeStackArray & /*other*/) {return FALSE;}
|
||||||
bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;}
|
bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;}
|
||||||
@ -398,6 +411,34 @@ private:
|
|||||||
#endif
|
#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>
|
template<typename T, int32_t stackCapacity>
|
||||||
inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) {
|
inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) {
|
||||||
if(newCapacity>0) {
|
if(newCapacity>0) {
|
||||||
@ -447,9 +488,7 @@ inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32
|
|||||||
uprv_memcpy(p, ptr, (size_t)length*sizeof(T));
|
uprv_memcpy(p, ptr, (size_t)length*sizeof(T));
|
||||||
}
|
}
|
||||||
resultCapacity=length;
|
resultCapacity=length;
|
||||||
ptr=stackArray;
|
resetToStackArray();
|
||||||
capacity=stackCapacity;
|
|
||||||
needToRelease=FALSE;
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1892,7 +1892,7 @@ public:
|
|||||||
UnicodeString &fastCopyFrom(const UnicodeString &src);
|
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.
|
* 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.
|
* The behavior is undefined if *this and src are the same object.
|
||||||
* @param src source string
|
* @param src source string
|
||||||
@ -1905,7 +1905,7 @@ public:
|
|||||||
|
|
||||||
// do not use #ifndef U_HIDE_DRAFT_API for moveFrom, needed by non-draft API
|
// 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.
|
* 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.
|
* The behavior is undefined if *this and src are the same object.
|
||||||
*
|
*
|
||||||
@ -3350,7 +3350,7 @@ public:
|
|||||||
UnicodeString(const UnicodeString& that);
|
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.
|
* This string will have the same contents and state that the source string had.
|
||||||
* @param src source string
|
* @param src source string
|
||||||
* @stable ICU 56
|
* @stable ICU 56
|
||||||
|
@ -551,6 +551,28 @@ StringTest::TestCharString() {
|
|||||||
if (chStr.length() != 0) {
|
if (chStr.length() != 0) {
|
||||||
errln("%s:%d expected length() = 0, got %d", __FILE__, __LINE__, chStr.length());
|
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
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user