diff options
| -rw-r--r-- | llvm/include/llvm/ADT/ilist.h | 35 | ||||
| -rw-r--r-- | llvm/unittests/ADT/ilistTest.cpp | 17 |
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 |

