ICU-20357 Adding std::unique_ptr conversions to LocalXyzPointer macro.

This commit is contained in:
Shane F. Carr 2019-01-28 01:04:48 -08:00
parent b4fef640cf
commit 19407640f8
2 changed files with 41 additions and 4 deletions

View file

@ -234,7 +234,8 @@ public:
* @param p The std::unique_ptr from which the pointer will be stolen.
* @draft ICU 64
*/
explicit LocalPointer(std::unique_ptr<T> &&p) : LocalPointerBase<T>(p.release()) {}
explicit LocalPointer(std::unique_ptr<T> &&p)
: LocalPointerBase<T>(p.release()) {}
/**
* Destructor deletes the object it owns.
* @stable ICU 4.4
@ -416,7 +417,8 @@ public:
* @param p The std::unique_ptr from which the array will be stolen.
* @draft ICU 64
*/
explicit LocalArray(std::unique_ptr<T[]> &&p) : LocalPointerBase<T>(p.release()) {}
explicit LocalArray(std::unique_ptr<T[]> &&p)
: LocalPointerBase<T>(p.release()) {}
/**
* Destructor deletes the array it owns.
* @stable ICU 4.4
@ -571,10 +573,18 @@ public:
: LocalPointerBase<Type>(src.ptr) { \
src.ptr=NULL; \
} \
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
explicit LocalPointerClassName(std::unique_ptr<Type, decltype(&closeFunction)> &&p) \
: LocalPointerBase<Type>(p.release()) {} \
~LocalPointerClassName() { if (ptr != NULL) { closeFunction(ptr); } } \
LocalPointerClassName &operator=(LocalPointerClassName &&src) U_NOEXCEPT { \
return moveFrom(src); \
} \
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */ \
LocalPointerClassName &operator=(std::unique_ptr<Type, decltype(&closeFunction)> &&p) { \
adoptInstead(p.release()); \
return *this; \
} \
LocalPointerClassName &moveFrom(LocalPointerClassName &src) U_NOEXCEPT { \
if (ptr != NULL) { closeFunction(ptr); } \
LocalPointerBase<Type>::ptr=src.ptr; \
@ -593,6 +603,9 @@ public:
if (ptr != NULL) { closeFunction(ptr); } \
ptr=p; \
} \
operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \
return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \
} \
}
U_NAMESPACE_END

View file

@ -392,6 +392,7 @@ public:
void TestLocalXyzPointer();
void TestLocalXyzPointerMoveSwap();
void TestLocalXyzPointerNull();
void TestLocalXyzStdUniquePtr();
};
static IntlTest *createLocalPointerTest() {
@ -412,6 +413,7 @@ void LocalPointerTest::runIndexedTest(int32_t index, UBool exec, const char *&na
TESTCASE_AUTO(TestLocalXyzPointer);
TESTCASE_AUTO(TestLocalXyzPointerMoveSwap);
TESTCASE_AUTO(TestLocalXyzPointerNull);
TESTCASE_AUTO(TestLocalXyzStdUniquePtr);
TESTCASE_AUTO_END;
}
@ -519,14 +521,16 @@ void LocalPointerTest::TestLocalPointerMoveSwap() {
}
void LocalPointerTest::TestLocalPointerStdUniquePtr() {
auto* ptr = new UnicodeString((UChar32)0x50005);
// Implicit conversion operator
std::unique_ptr<UnicodeString> s = LocalPointer<UnicodeString>(new UnicodeString((UChar32)0x50005));
std::unique_ptr<UnicodeString> s = LocalPointer<UnicodeString>(ptr);
// Explicit move constructor
LocalPointer<UnicodeString> s2(std::move(s));
// Conversion operator should also work with std::move
s = std::move(s2);
// Back again with move assignment
s2 = std::move(s);
assertTrue("Pointer should remain the same", ptr == s2.getAlias());
}
// Exercise almost every LocalArray method (but not LocalPointerBase).
@ -623,14 +627,16 @@ void LocalPointerTest::TestLocalArrayMoveSwap() {
}
void LocalPointerTest::TestLocalArrayStdUniquePtr() {
auto* ptr = new UnicodeString[2];
// Implicit conversion operator
std::unique_ptr<UnicodeString[]> a = LocalArray<UnicodeString>(new UnicodeString[2]);
std::unique_ptr<UnicodeString[]> a = LocalArray<UnicodeString>(ptr);
// Explicit move constructor
LocalArray<UnicodeString> a2(std::move(a));
// Conversion operator should also work with std::move
a = std::move(a2);
// Back again with move assignment
a2 = std::move(a);
assertTrue("Pointer should remain the same", ptr == a2.getAlias());
}
#include "unicode/ucnvsel.h"
@ -642,6 +648,7 @@ void LocalPointerTest::TestLocalArrayStdUniquePtr() {
#include "unicode/unorm2.h"
#include "unicode/uregex.h"
#include "unicode/utrans.h"
#include "unicode/uformattedvalue.h"
// Use LocalXyzPointer types that are not covered elsewhere in the intltest suite.
void LocalPointerTest::TestLocalXyzPointer() {
@ -864,6 +871,23 @@ void LocalPointerTest::TestLocalXyzPointerNull() {
}
void LocalPointerTest::TestLocalXyzStdUniquePtr() {
IcuTestErrorCode status(*this, "TestLocalXyzStdUniquePtr");
#if !UCONFIG_NO_FORMATTING
auto* ptr = ucfpos_open(status);
// Implicit conversion operator
std::unique_ptr<UConstrainedFieldPosition, void(*)(UConstrainedFieldPosition*)> a =
LocalUConstrainedFieldPositionPointer(ptr);
// Explicit move constructor
LocalUConstrainedFieldPositionPointer a2(std::move(a));
// Conversion operator should also work with std::move
a = std::move(a2);
// Back again with move assignment
a2 = std::move(a);
assertTrue("Pointer should remain the same", ptr == a2.getAlias());
#endif // UCONFIG_NO_FORMATTING
}
/** EnumSet test **/
#include "unicode/enumset.h"