[PATCH] D95498: ADT: Add SFINAE to the generic IntrusiveRefCntPtr constructors
Duncan P. N. Exon Smith via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 26 19:58:39 PST 2021
dexonsmith created this revision.
dexonsmith added a reviewer: dblaikie.
Herald added a subscriber: ributzka.
dexonsmith requested review of this revision.
Herald added a project: LLVM.
Add an `enable_if` to the generic `IntrusiveRefCntPtr` constructors so
that std::is_convertible gives an honest answer when the underlying
pointers cannot be converted.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D95498
Files:
llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
Index: llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
===================================================================
--- llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
+++ llvm/unittests/ADT/IntrusiveRefCntPtrTest.cpp
@@ -96,4 +96,46 @@
EXPECT_TRUE(Retained);
}
+TEST(IntrusiveRefCntPtr, ConstructorSFINAE) {
+ struct X {};
+ struct Y : X {};
+ struct Z {};
+ static_assert(std::is_convertible<IntrusiveRefCntPtr<X> &&,
+ IntrusiveRefCntPtr<X>>::value,
+ "X -> X is okay");
+ static_assert(std::is_convertible<const IntrusiveRefCntPtr<X> &,
+ IntrusiveRefCntPtr<X>>::value,
+ "X -> X is okay");
+ static_assert(
+ std::is_convertible<std::unique_ptr<X>, IntrusiveRefCntPtr<X>>::value,
+ "X -> X is okay");
+ static_assert(std::is_convertible<IntrusiveRefCntPtr<Y> &&,
+ IntrusiveRefCntPtr<X>>::value,
+ "Y -> X is okay");
+ static_assert(std::is_convertible<const IntrusiveRefCntPtr<Y> &,
+ IntrusiveRefCntPtr<X>>::value,
+ "Y -> X is okay");
+ static_assert(
+ std::is_convertible<std::unique_ptr<Y>, IntrusiveRefCntPtr<X>>::value,
+ "Y -> X is okay");
+ static_assert(!std::is_convertible<IntrusiveRefCntPtr<X> &&,
+ IntrusiveRefCntPtr<Y>>::value,
+ "X -> Y should be rejected with SFINAE");
+ static_assert(!std::is_convertible<const IntrusiveRefCntPtr<X> &,
+ IntrusiveRefCntPtr<Y>>::value,
+ "X -> Y should be rejected with SFINAE");
+ static_assert(
+ !std::is_convertible<std::unique_ptr<X>, IntrusiveRefCntPtr<Y>>::value,
+ "X -> Y should be rejected with SFINAE");
+ static_assert(!std::is_convertible<IntrusiveRefCntPtr<X> &&,
+ IntrusiveRefCntPtr<Z>>::value,
+ "X -> Z should be rejected with SFINAE");
+ static_assert(!std::is_convertible<const IntrusiveRefCntPtr<X> &,
+ IntrusiveRefCntPtr<Z>>::value,
+ "X -> Z should be rejected with SFINAE");
+ static_assert(
+ !std::is_convertible<std::unique_ptr<X>, IntrusiveRefCntPtr<Z>>::value,
+ "X -> Z should be rejected with SFINAE");
+}
+
} // end namespace llvm
Index: llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
===================================================================
--- llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ llvm/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -171,17 +171,20 @@
IntrusiveRefCntPtr(const IntrusiveRefCntPtr &S) : Obj(S.Obj) { retain(); }
IntrusiveRefCntPtr(IntrusiveRefCntPtr &&S) : Obj(S.Obj) { S.Obj = nullptr; }
- template <class X>
+ template <class X,
+ std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true>
IntrusiveRefCntPtr(IntrusiveRefCntPtr<X> &&S) : Obj(S.get()) {
S.Obj = nullptr;
}
- template <class X>
+ template <class X,
+ std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true>
IntrusiveRefCntPtr(std::unique_ptr<X> S) : Obj(S.release()) {
retain();
}
- template <class X>
+ template <class X,
+ std::enable_if_t<std::is_convertible<X *, T *>::value, bool> = true>
IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X> &S) : Obj(S.get()) {
retain();
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95498.319452.patch
Type: text/x-patch
Size: 3437 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210127/606839be/attachment.bin>
More information about the llvm-commits
mailing list