Skip to content

Commit

Permalink
ICU-22651 Refactor U_DEFINE_LOCAL_OPEN_POINTER into a template.
Browse files Browse the repository at this point in the history
  • Loading branch information
roubert committed Feb 5, 2024
1 parent b827157 commit 6fa113e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 44 deletions.
84 changes: 45 additions & 39 deletions icu4c/source/common/unicode/localpointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,46 +548,52 @@ class LocalArray : public LocalPointerBase<T> {
* @stable ICU 4.4
*/
#define U_DEFINE_LOCAL_OPEN_POINTER(LocalPointerClassName, Type, closeFunction) \
class LocalPointerClassName : public LocalPointerBase<Type> { \
public: \
using LocalPointerBase<Type>::operator*; \
using LocalPointerBase<Type>::operator->; \
explicit LocalPointerClassName(Type *p=nullptr) : LocalPointerBase<Type>(p) {} \
LocalPointerClassName(LocalPointerClassName &&src) noexcept \
: LocalPointerBase<Type>(src.ptr) { \
src.ptr=nullptr; \
} \
/* 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 != nullptr) { closeFunction(ptr); } } \
LocalPointerClassName &operator=(LocalPointerClassName &&src) noexcept { \
if (ptr != nullptr) { closeFunction(ptr); } \
LocalPointerBase<Type>::ptr=src.ptr; \
src.ptr=nullptr; \
return *this; \
} \
/* 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; \
} \
void swap(LocalPointerClassName &other) noexcept { \
Type *temp=LocalPointerBase<Type>::ptr; \
LocalPointerBase<Type>::ptr=other.ptr; \
other.ptr=temp; \
} \
friend inline void swap(LocalPointerClassName &p1, LocalPointerClassName &p2) noexcept { \
p1.swap(p2); \
} \
void adoptInstead(Type *p) { \
if (ptr != nullptr) { closeFunction(ptr); } \
ptr=p; \
} \
operator std::unique_ptr<Type, decltype(&closeFunction)> () && { \
return std::unique_ptr<Type, decltype(&closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction); \
} \
using LocalPointerClassName = LocalOpenPointer<Type, closeFunction>

#ifndef U_IN_DOXYGEN
template <typename Type, auto closeFunction>
class LocalOpenPointer : public LocalPointerBase<Type> {
using LocalPointerBase<Type>::ptr;
public:
using LocalPointerBase<Type>::operator*;
using LocalPointerBase<Type>::operator->;
explicit LocalOpenPointer(Type *p=nullptr) : LocalPointerBase<Type>(p) {}
LocalOpenPointer(LocalOpenPointer &&src) noexcept
: LocalPointerBase<Type>(src.ptr) {
src.ptr=nullptr;
}
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */
explicit LocalOpenPointer(std::unique_ptr<Type, decltype(closeFunction)> &&p)
: LocalPointerBase<Type>(p.release()) {}
~LocalOpenPointer() { if (ptr != nullptr) { closeFunction(ptr); } }
LocalOpenPointer &operator=(LocalOpenPointer &&src) noexcept {
if (ptr != nullptr) { closeFunction(ptr); }
LocalPointerBase<Type>::ptr=src.ptr;
src.ptr=nullptr;
return *this;
}
/* TODO: Be agnostic of the deleter function signature from the user-provided std::unique_ptr? */
LocalOpenPointer &operator=(std::unique_ptr<Type, decltype(closeFunction)> &&p) {
adoptInstead(p.release());
return *this;
}
void swap(LocalOpenPointer &other) noexcept {
Type *temp=LocalPointerBase<Type>::ptr;
LocalPointerBase<Type>::ptr=other.ptr;
other.ptr=temp;
}
friend inline void swap(LocalOpenPointer &p1, LocalOpenPointer &p2) noexcept {
p1.swap(p2);
}
void adoptInstead(Type *p) {
if (ptr != nullptr) { closeFunction(ptr); }
ptr=p;
}
operator std::unique_ptr<Type, decltype(closeFunction)> () && {
return std::unique_ptr<Type, decltype(closeFunction)>(LocalPointerBase<Type>::orphan(), closeFunction);
}
};
#endif

U_NAMESPACE_END

Expand Down
8 changes: 3 additions & 5 deletions icu4c/source/tools/pkgdata/pkgdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,9 @@ U_CDECL_BEGIN
U_CDECL_END

#if U_HAVE_POPEN

using icu::LocalPointerBase;

U_NAMESPACE_BEGIN
U_DEFINE_LOCAL_OPEN_POINTER(LocalPipeFilePointer, FILE, pclose);

U_NAMESPACE_END
#endif

using icu::LocalMemory;
Expand Down Expand Up @@ -2184,7 +2182,7 @@ static void loadLists(UPKGOptions *o, UErrorCode *status)
static UBool getPkgDataPath(const char *cmd, UBool verbose, char *buf, size_t items) {
icu::CharString cmdBuf;
UErrorCode status = U_ZERO_ERROR;
LocalPipeFilePointer p;
icu::LocalPipeFilePointer p;
size_t n;

cmdBuf.append(cmd, status);
Expand Down

0 comments on commit 6fa113e

Please sign in to comment.