[llvm] r279197 - [ADT] Add the worlds simplest STL extra. Or at least close to it.

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 18 19:07:52 PDT 2016


Author: chandlerc
Date: Thu Aug 18 21:07:51 2016
New Revision: 279197

URL: http://llvm.org/viewvc/llvm-project?rev=279197&view=rev
Log:
[ADT] Add the worlds simplest STL extra. Or at least close to it.

This is a little class template that just builds an inheritance chain of
empty classes. Despite how simple this is, it can be used to really
nicely create ranked overload sets. I've added a unittest as much to
document this as test it. You can pass an object of this type as an
argument to a function overload set an it will call the first viable and
enabled candidate at or below the rank of the object.

I'm planning to use this in a subsequent commit to more clearly rank
overload candidates used for SFINAE. All credit for this technique and
both lines of code here to Richard Smith who was helping me rewrite the
SFINAE check in question to much more effectively capture the intended
set of checks.

Added:
    llvm/trunk/unittests/ADT/STLExtrasTest.cpp
Modified:
    llvm/trunk/include/llvm/ADT/STLExtras.h
    llvm/trunk/unittests/ADT/CMakeLists.txt

Modified: llvm/trunk/include/llvm/ADT/STLExtras.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/STLExtras.h?rev=279197&r1=279196&r2=279197&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/STLExtras.h (original)
+++ llvm/trunk/include/llvm/ADT/STLExtras.h Thu Aug 18 21:07:51 2016
@@ -382,6 +382,11 @@ struct build_index_impl<0, I...> : index
 template <class... Ts>
 struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
 
+/// Utility type to build an inheritance chain that makes it easy to rank
+/// overload candidates.
+template <int N> struct rank : rank<N - 1> {};
+template <> struct rank<0> {};
+
 //===----------------------------------------------------------------------===//
 //     Extra additions for arrays
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/unittests/ADT/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/CMakeLists.txt?rev=279197&r1=279196&r2=279197&view=diff
==============================================================================
--- llvm/trunk/unittests/ADT/CMakeLists.txt (original)
+++ llvm/trunk/unittests/ADT/CMakeLists.txt Thu Aug 18 21:07:51 2016
@@ -34,6 +34,7 @@ set(ADTSources
   PriorityWorklistTest.cpp
   RangeAdapterTest.cpp
   SCCIteratorTest.cpp
+  STLExtrasTest.cpp
   ScopeExitTest.cpp
   SequenceTest.cpp
   SetVectorTest.cpp

Added: llvm/trunk/unittests/ADT/STLExtrasTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/STLExtrasTest.cpp?rev=279197&view=auto
==============================================================================
--- llvm/trunk/unittests/ADT/STLExtrasTest.cpp (added)
+++ llvm/trunk/unittests/ADT/STLExtrasTest.cpp Thu Aug 18 21:07:51 2016
@@ -0,0 +1,40 @@
+//===- STLExtrasTest.cpp - Unit tests for STL extras ----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+int f(rank<0>) { return 0; }
+int f(rank<1>) { return 1; }
+int f(rank<2>) { return 2; }
+int f(rank<4>) { return 4; }
+
+TEST(STLExtrasTest, Rank) {
+  // We shouldn't get ambiguities and should select the overload of the same
+  // rank as the argument.
+  EXPECT_EQ(0, f(rank<0>()));
+  EXPECT_EQ(1, f(rank<1>()));
+  EXPECT_EQ(2, f(rank<2>()));
+
+  // This overload is missing so we end up back at 2.
+  EXPECT_EQ(2, f(rank<3>()));
+
+  // But going past 3 should work fine.
+  EXPECT_EQ(4, f(rank<4>()));
+
+  // And we can even go higher and just fall back to the last overload.
+  EXPECT_EQ(4, f(rank<5>()));
+  EXPECT_EQ(4, f(rank<6>()));
+}
+
+}




More information about the llvm-commits mailing list