ICU-20357 Adding LocalPointer conversion methods to/from std::unique_ptr
- Requires the right side to be an rvalue reference. - Includes move constructor, move operator, and conversion operator.
This commit is contained in:
parent
4104d33501
commit
b7a3571b21
@ -42,6 +42,8 @@
|
||||
|
||||
#if U_SHOW_CPLUSPLUS_API
|
||||
|
||||
#include <memory>
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
@ -222,6 +224,17 @@ public:
|
||||
LocalPointer(LocalPointer<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
|
||||
src.ptr=NULL;
|
||||
}
|
||||
/**
|
||||
* Constructs a LocalPointer from a C++11 std::unique_ptr.
|
||||
* The LocalPointer steals the object owned by the std::unique_ptr.
|
||||
*
|
||||
* This constructor works via move semantics. If your std::unique_ptr is
|
||||
* in a local variable, you must use std::move.
|
||||
*
|
||||
* @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()) {}
|
||||
/**
|
||||
* Destructor deletes the object it owns.
|
||||
* @stable ICU 4.4
|
||||
@ -239,6 +252,18 @@ public:
|
||||
LocalPointer<T> &operator=(LocalPointer<T> &&src) U_NOEXCEPT {
|
||||
return moveFrom(src);
|
||||
}
|
||||
/**
|
||||
* Move-assign from an std::unique_ptr to this LocalPointer.
|
||||
* Steals the pointer from the std::unique_ptr.
|
||||
*
|
||||
* @param p The std::unique_ptr from which the pointer will be stolen.
|
||||
* @return *this
|
||||
* @draft ICU 64
|
||||
*/
|
||||
LocalPointer<T> &operator=(std::unique_ptr<T> &&p) U_NOEXCEPT {
|
||||
adoptInstead(p.release());
|
||||
return *this;
|
||||
}
|
||||
// do not use #ifndef U_HIDE_DRAFT_API for moveFrom, needed by non-draft API
|
||||
/**
|
||||
* Move assignment, leaves src with isNull().
|
||||
@ -310,6 +335,20 @@ public:
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Conversion operator to a C++11 std::unique_ptr.
|
||||
* Disowns the object and gives it to the returned std::unique_ptr.
|
||||
*
|
||||
* This operator works via move semantics. If your LocalPointer is
|
||||
* in a local variable, you must use std::move.
|
||||
*
|
||||
* @return An std::unique_ptr owning the pointer previously owned by this
|
||||
* icu::LocalPointer.
|
||||
* @draft ICU 64
|
||||
*/
|
||||
operator std::unique_ptr<T> () && {
|
||||
return std::unique_ptr<T>(LocalPointerBase<T>::orphan());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -367,6 +406,17 @@ public:
|
||||
LocalArray(LocalArray<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
|
||||
src.ptr=NULL;
|
||||
}
|
||||
/**
|
||||
* Constructs a LocalArray from a C++11 std::unique_ptr of an array type.
|
||||
* The LocalPointer steals the array owned by the std::unique_ptr.
|
||||
*
|
||||
* This constructor works via move semantics. If your std::unique_ptr is
|
||||
* in a local variable, you must use std::move.
|
||||
*
|
||||
* @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()) {}
|
||||
/**
|
||||
* Destructor deletes the array it owns.
|
||||
* @stable ICU 4.4
|
||||
@ -384,6 +434,18 @@ public:
|
||||
LocalArray<T> &operator=(LocalArray<T> &&src) U_NOEXCEPT {
|
||||
return moveFrom(src);
|
||||
}
|
||||
/**
|
||||
* Move-assign from an std::unique_ptr to this LocalPointer.
|
||||
* Steals the array from the std::unique_ptr.
|
||||
*
|
||||
* @param p The std::unique_ptr from which the array will be stolen.
|
||||
* @return *this
|
||||
* @draft ICU 64
|
||||
*/
|
||||
LocalArray<T> &operator=(std::unique_ptr<T[]> &&p) U_NOEXCEPT {
|
||||
adoptInstead(p.release());
|
||||
return *this;
|
||||
}
|
||||
// do not use #ifndef U_HIDE_DRAFT_API for moveFrom, needed by non-draft API
|
||||
/**
|
||||
* Move assignment, leaves src with isNull().
|
||||
@ -463,6 +525,20 @@ public:
|
||||
* @stable ICU 4.4
|
||||
*/
|
||||
T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
|
||||
/**
|
||||
* Conversion operator to a C++11 std::unique_ptr.
|
||||
* Disowns the object and gives it to the returned std::unique_ptr.
|
||||
*
|
||||
* This operator works via move semantics. If your LocalPointer is
|
||||
* in a local variable, you must use std::move.
|
||||
*
|
||||
* @return An std::unique_ptr owning the pointer previously owned by this
|
||||
* icu::LocalPointer.
|
||||
* @draft ICU 64
|
||||
*/
|
||||
operator std::unique_ptr<T[]> () && {
|
||||
return std::unique_ptr<T[]>(LocalPointerBase<T>::orphan());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -385,8 +385,10 @@ public:
|
||||
|
||||
void TestLocalPointer();
|
||||
void TestLocalPointerMoveSwap();
|
||||
void TestLocalPointerStdUniquePtr();
|
||||
void TestLocalArray();
|
||||
void TestLocalArrayMoveSwap();
|
||||
void TestLocalArrayStdUniquePtr();
|
||||
void TestLocalXyzPointer();
|
||||
void TestLocalXyzPointerMoveSwap();
|
||||
void TestLocalXyzPointerNull();
|
||||
@ -403,8 +405,10 @@ void LocalPointerTest::runIndexedTest(int32_t index, UBool exec, const char *&na
|
||||
TESTCASE_AUTO_BEGIN;
|
||||
TESTCASE_AUTO(TestLocalPointer);
|
||||
TESTCASE_AUTO(TestLocalPointerMoveSwap);
|
||||
TESTCASE_AUTO(TestLocalPointerStdUniquePtr);
|
||||
TESTCASE_AUTO(TestLocalArray);
|
||||
TESTCASE_AUTO(TestLocalArrayMoveSwap);
|
||||
TESTCASE_AUTO(TestLocalArrayStdUniquePtr);
|
||||
TESTCASE_AUTO(TestLocalXyzPointer);
|
||||
TESTCASE_AUTO(TestLocalXyzPointerMoveSwap);
|
||||
TESTCASE_AUTO(TestLocalXyzPointerNull);
|
||||
@ -514,6 +518,17 @@ void LocalPointerTest::TestLocalPointerMoveSwap() {
|
||||
s3.moveFrom(s3);
|
||||
}
|
||||
|
||||
void LocalPointerTest::TestLocalPointerStdUniquePtr() {
|
||||
// Implicit conversion operator
|
||||
std::unique_ptr<UnicodeString> s = LocalPointer<UnicodeString>(new UnicodeString((UChar32)0x50005));
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Exercise almost every LocalArray method (but not LocalPointerBase).
|
||||
void LocalPointerTest::TestLocalArray() {
|
||||
// constructor
|
||||
@ -607,6 +622,17 @@ void LocalPointerTest::TestLocalArrayMoveSwap() {
|
||||
a3.moveFrom(a3);
|
||||
}
|
||||
|
||||
void LocalPointerTest::TestLocalArrayStdUniquePtr() {
|
||||
// Implicit conversion operator
|
||||
std::unique_ptr<UnicodeString[]> a = LocalArray<UnicodeString>(new UnicodeString[2]);
|
||||
// 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);
|
||||
}
|
||||
|
||||
#include "unicode/ucnvsel.h"
|
||||
#include "unicode/ucal.h"
|
||||
#include "unicode/udatpg.h"
|
||||
|
Loading…
Reference in New Issue
Block a user