[llvm] r279012 - ADT: Tidy up ilist_traits static asserts, NFC

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 17 16:47:57 PDT 2016


Author: dexonsmith
Date: Wed Aug 17 18:47:56 2016
New Revision: 279012

URL: http://llvm.org/viewvc/llvm-project?rev=279012&view=rev
Log:
ADT: Tidy up ilist_traits static asserts, NFC

Change the ilist traits to use decltype instead of sizeof, and add
HasObsoleteCustomization so that additions to this list don't need to be
added in two places.

I suspect this will now work with MSVC, since the trait tested in
r278991 seems to work.  If for some reason it continues to fail on
Windows I'll follow up by adding back the #ifndef _MSC_VER.

Modified:
    llvm/trunk/include/llvm/ADT/ilist.h
    llvm/trunk/unittests/ADT/ilistTest.cpp

Modified: llvm/trunk/include/llvm/ADT/ilist.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist.h?rev=279012&r1=279011&r2=279012&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/ilist.h (original)
+++ llvm/trunk/include/llvm/ADT/ilist.h Wed Aug 17 18:47:56 2016
@@ -83,34 +83,37 @@ 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> struct HasGetNext {
+template <class TraitsT, class NodeT> class HasGetNext {
   typedef char Yes[1];
   typedef char No[2];
   template <size_t N> struct SFINAE {};
 
   template <class U>
-  static Yes &hasGetNext(
-      SFINAE<sizeof(static_cast<NodeT *>(make<U>().getNext(&make<NodeT>())))>
-          * = 0);
-  template <class U> static No &hasGetNext(...);
+  static Yes &test(U *I, decltype(I->getNext(&make<NodeT>())) * = 0);
+  template <class> static No &test(...);
 
-  static const bool value = sizeof(hasGetNext<TraitsT>(nullptr)) == sizeof(Yes);
+public:
+  static const bool value = sizeof(test<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> struct HasCreateSentinel {
+template <class TraitsT> class HasCreateSentinel {
   typedef char Yes[1];
   typedef char No[2];
   template <size_t N> struct SFINAE {};
 
   template <class U>
-  static Yes &
-  hasCreateSentinel(SFINAE<sizeof(make<U>().createSentinel())> * = 0);
-  template <class U> static No &hasCreateSentinel(...);
+  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);
+};
 
+template <class TraitsT, class NodeT> struct HasObsoleteCustomization {
   static const bool value =
-      sizeof(hasCreateSentinel<TraitsT>(nullptr)) == sizeof(Yes);
+      HasGetNext<TraitsT, NodeT>::value || HasCreateSentinel<TraitsT>::value;
 };
 
 } // end namespace ilist_detail
@@ -287,14 +290,8 @@ template <typename NodeTy, typename Trai
 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).
-#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
+  static_assert(!ilist_detail::HasObsoleteCustomization<Traits, NodeTy>::value,
+                "ilist customization points have changed!");
 
   ilist_sentinel<NodeTy> Sentinel;
 

Modified: llvm/trunk/unittests/ADT/ilistTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/ilistTest.cpp?rev=279012&r1=279011&r2=279012&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/ilistTest.cpp (original)
+++ llvm/trunk/unittests/ADT/ilistTest.cpp Wed Aug 17 18:47:56 2016
@@ -190,4 +190,21 @@ 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




More information about the llvm-commits mailing list