summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/ADT/ilist.h35
-rw-r--r--llvm/unittests/ADT/ilistTest.cpp17
2 files changed, 19 insertions, 33 deletions
diff --git a/llvm/include/llvm/ADT/ilist.h b/llvm/include/llvm/ADT/ilist.h
index c77730c99a3..10ff088dcd6 100644
--- a/llvm/include/llvm/ADT/ilist.h
+++ b/llvm/include/llvm/ADT/ilist.h
@@ -83,37 +83,34 @@ template <class T> T &make();
/// Type trait to check for a traits class that has a getNext member (as a
/// canary for any of the ilist_nextprev_traits API).
-template <class TraitsT, class NodeT> class HasGetNext {
+template <class TraitsT, class NodeT> struct HasGetNext {
typedef char Yes[1];
typedef char No[2];
template <size_t N> struct SFINAE {};
template <class U>
- static Yes &test(U *I, decltype(I->getNext(&make<NodeT>())) * = 0);
- template <class> static No &test(...);
+ static Yes &hasGetNext(
+ SFINAE<sizeof(static_cast<NodeT *>(make<U>().getNext(&make<NodeT>())))>
+ * = 0);
+ template <class U> static No &hasGetNext(...);
-public:
- static const bool value = sizeof(test<TraitsT>(nullptr)) == sizeof(Yes);
+ static const bool value = sizeof(hasGetNext<TraitsT>(nullptr)) == sizeof(Yes);
};
/// Type trait to check for a traits class that has a createSentinel member (as
/// a canary for any of the ilist_sentinel_traits API).
-template <class TraitsT> class HasCreateSentinel {
+template <class TraitsT> struct HasCreateSentinel {
typedef char Yes[1];
typedef char No[2];
template <size_t N> struct SFINAE {};
template <class U>
- static Yes &test(U *I, decltype(I->createSentinel()) * = 0);
- template <class U> static No &test(...);
-
-public:
- static const bool value = sizeof(test<TraitsT>(nullptr)) == sizeof(Yes);
-};
+ static Yes &
+ hasCreateSentinel(SFINAE<sizeof(make<U>().createSentinel())> * = 0);
+ template <class U> static No &hasCreateSentinel(...);
-template <class TraitsT, class NodeT> struct HasObsoleteCustomization {
static const bool value =
- HasGetNext<TraitsT, NodeT>::value || HasCreateSentinel<TraitsT>::value;
+ sizeof(hasCreateSentinel<TraitsT>(nullptr)) == sizeof(Yes);
};
} // end namespace ilist_detail
@@ -290,8 +287,14 @@ template <typename NodeTy, typename Traits = ilist_traits<NodeTy>>
class iplist : public Traits, ilist_node_access {
// TODO: Drop these assertions anytime after 4.0 is branched (keep them for
// one release to help out-of-tree code update).
- static_assert(!ilist_detail::HasObsoleteCustomization<Traits, NodeTy>::value,
- "ilist customization points have changed!");
+#if !defined(_MSC_VER)
+ // FIXME: This fails in MSVC, but it's worth keeping around to help
+ // non-Windows users root out bugs in their ilist_traits.
+ static_assert(!ilist_detail::HasGetNext<Traits, NodeTy>::value,
+ "ilist next and prev links are not customizable!");
+ static_assert(!ilist_detail::HasCreateSentinel<Traits>::value,
+ "ilist sentinel is not customizable!");
+#endif
ilist_sentinel<NodeTy> Sentinel;
diff --git a/llvm/unittests/ADT/ilistTest.cpp b/llvm/unittests/ADT/ilistTest.cpp
index 57cdd584ec1..a8ea63ed464 100644
--- a/llvm/unittests/ADT/ilistTest.cpp
+++ b/llvm/unittests/ADT/ilistTest.cpp
@@ -190,21 +190,4 @@ TEST(ilistTest, privateNode) {
L2.remove(&N);
}
-struct GetNext {
- Node *getNext(Node *);
-};
-TEST(ilistTest, HasGetNextTrait) {
- EXPECT_TRUE((ilist_detail::HasGetNext<GetNext, Node>::value));
- EXPECT_TRUE((ilist_detail::HasObsoleteCustomization<GetNext, Node>::value));
-}
-
-struct CreateSentinel {
- Node *createSentinel();
-};
-TEST(ilistTest, HasCreateSentinel) {
- EXPECT_TRUE((ilist_detail::HasCreateSentinel<CreateSentinel>::value));
- EXPECT_TRUE(
- (ilist_detail::HasObsoleteCustomization<CreateSentinel, Node>::value));
-}
-
} // end namespace
OpenPOWER on IntegriCloud