diff --git a/icu4c/source/common/cmemory.h b/icu4c/source/common/cmemory.h index f997d9224f8..3041b56d1a1 100644 --- a/icu4c/source/common/cmemory.h +++ b/icu4c/source/common/cmemory.h @@ -207,6 +207,14 @@ public: LocalPointerBase::ptr=other.ptr; other.ptr=temp; } + /** + * Non-member LocalMemory swap function. + * @param p1 will get p2's pointer + * @param p2 will get p1's pointer + */ + friend inline void swap(LocalMemory &p1, LocalMemory &p2) U_NOEXCEPT { + p1.swap(p2); + } /** * Deletes the array it owns, * and adopts (takes ownership of) the one passed in. @@ -246,16 +254,6 @@ public: T &operator[](ptrdiff_t i) const { return LocalPointerBase::ptr[i]; } }; -/** - * Non-member LocalMemory swap function. - * @param p1 will get p2's pointer - * @param p2 will get p1's pointer - */ -template -inline void swap(LocalMemory &p1, LocalMemory &p2) U_NOEXCEPT { - p1.swap(p2); -} - template inline T *LocalMemory::allocateInsteadAndReset(int32_t newCapacity) { if(newCapacity>0) { diff --git a/icu4c/source/common/unicode/localpointer.h b/icu4c/source/common/unicode/localpointer.h index a46a0d25d5f..fff986b67fa 100644 --- a/icu4c/source/common/unicode/localpointer.h +++ b/icu4c/source/common/unicode/localpointer.h @@ -266,6 +266,15 @@ public: LocalPointerBase::ptr=other.ptr; other.ptr=temp; } + /** + * Non-member LocalPointer swap function. + * @param p1 will get p2's pointer + * @param p2 will get p1's pointer + * @draft ICU 56 + */ + friend inline void swap(LocalPointer &p1, LocalPointer &p2) U_NOEXCEPT { + p1.swap(p2); + } #endif /* U_HIDE_DRAFT_API */ /** * Deletes the object it owns, @@ -307,19 +316,6 @@ public: #endif /* U_HIDE_DRAFT_API */ }; -#ifndef U_HIDE_DRAFT_API -/** - * Non-member LocalPointer swap function. - * @param p1 will get p2's pointer - * @param p2 will get p1's pointer - * @draft ICU 56 - */ -template -inline void swap(LocalPointer &p1, LocalPointer &p2) U_NOEXCEPT { - p1.swap(p2); -} -#endif /* U_HIDE_DRAFT_API */ - /** * "Smart pointer" class, deletes objects via the C++ array delete[] operator. * For most methods see the LocalPointerBase base class. @@ -422,6 +418,15 @@ public: LocalPointerBase::ptr=other.ptr; other.ptr=temp; } + /** + * Non-member LocalArray swap function. + * @param p1 will get p2's pointer + * @param p2 will get p1's pointer + * @draft ICU 56 + */ + friend inline void swap(LocalArray &p1, LocalArray &p2) U_NOEXCEPT { + p1.swap(p2); + } #endif /* U_HIDE_DRAFT_API */ /** * Deletes the array it owns, @@ -471,19 +476,6 @@ public: T &operator[](ptrdiff_t i) const { return LocalPointerBase::ptr[i]; } }; -#ifndef U_HIDE_DRAFT_API -/** - * Non-member LocalArray swap function. - * @param p1 will get p2's pointer - * @param p2 will get p1's pointer - * @draft ICU 56 - */ -template -inline void swap(LocalArray &p1, LocalArray &p2) U_NOEXCEPT { - p1.swap(p2); -} -#endif /* U_HIDE_DRAFT_API */ - /** * \def U_DEFINE_LOCAL_OPEN_POINTER * "Smart pointer" definition macro, deletes objects via the closeFunction. @@ -531,15 +523,14 @@ inline void swap(LocalArray &p1, LocalArray &p2) U_NOEXCEPT { LocalPointerBase::ptr=other.ptr; \ other.ptr=temp; \ } \ + friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ + p1.swap(p2); \ + } \ void adoptInstead(Type *p) { \ closeFunction(ptr); \ ptr=p; \ } \ - }; \ - inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ - p1.swap(p2); \ - } \ - class LocalPointerClassName + } #else #define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \ class LocalPointerClassName : public LocalPointerBase { \ @@ -557,19 +548,15 @@ inline void swap(LocalArray &p1, LocalArray &p2) U_NOEXCEPT { LocalPointerBase::ptr=other.ptr; \ other.ptr=temp; \ } \ + friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ + p1.swap(p2); \ + } \ void adoptInstead(Type *p) { \ closeFunction(ptr); \ ptr=p; \ } \ - }; \ - inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) U_NOEXCEPT { \ - p1.swap(p2); \ - } \ - class LocalPointerClassName + } #endif -// The trailing class forward declaration at the end of U_DEFINE_LOCAL_OPEN_POINTER -// prevents a warning or error from -pedantic compilation -// due to an extra ';' after the non-member swap function definition. U_NAMESPACE_END diff --git a/icu4c/source/common/unicode/unistr.h b/icu4c/source/common/unicode/unistr.h index 179b9c2666b..dfcc8def2fc 100644 --- a/icu4c/source/common/unicode/unistr.h +++ b/icu4c/source/common/unicode/unistr.h @@ -1909,6 +1909,17 @@ public: * @draft ICU 56 */ void swap(UnicodeString &other) U_NOEXCEPT; + + /** + * Non-member UnicodeString swap function. + * @param s1 will get s2's contents and state + * @param s2 will get s1's contents and state + * @draft ICU 56 + */ + friend U_COMMON_API inline void U_EXPORT2 + swap(UnicodeString &s1, UnicodeString &s2) U_NOEXCEPT { + s1.swap(s2); + } #endif /* U_HIDE_DRAFT_API */ /** @@ -3668,19 +3679,6 @@ private: U_COMMON_API UnicodeString U_EXPORT2 operator+ (const UnicodeString &s1, const UnicodeString &s2); -#ifndef U_HIDE_DRAFT_API -/** - * Non-member UnicodeString swap function. - * @param s1 will get s2's contents and state - * @param s2 will get s1's contents and state - * @draft ICU 56 - */ -U_COMMON_API inline void U_EXPORT2 -swap(UnicodeString &s1, UnicodeString &s2) U_NOEXCEPT { - s1.swap(s2); -} -#endif /* U_HIDE_DRAFT_API */ - //======================================== // Inline members //======================================== diff --git a/icu4c/source/common/unistr.cpp b/icu4c/source/common/unistr.cpp index bd53c5a77c5..4b4a53eafba 100644 --- a/icu4c/source/common/unistr.cpp +++ b/icu4c/source/common/unistr.cpp @@ -556,8 +556,12 @@ void UnicodeString::copyFieldsFrom(UnicodeString &src, UBool setSrcToBogus) U_NO int16_t lengthAndFlags = fUnion.fFields.fLengthAndFlags = src.fUnion.fFields.fLengthAndFlags; if(lengthAndFlags & kUsingStackBuffer) { // Short string using the stack buffer, copy the contents. - uprv_memcpy(fUnion.fStackFields.fBuffer, src.fUnion.fStackFields.fBuffer, - getShortLength() * U_SIZEOF_UCHAR); + // Check for self assignment to prevent "overlap in memcpy" warnings, + // although it should be harmless to copy a buffer to itself exactly. + if(this != &src) { + uprv_memcpy(fUnion.fStackFields.fBuffer, src.fUnion.fStackFields.fBuffer, + getShortLength() * U_SIZEOF_UCHAR); + } } else { // In all other cases, copy all fields. fUnion.fFields.fArray = src.fUnion.fFields.fArray;