summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2016-08-19 02:07:51 +0000
committerChandler Carruth <chandlerc@gmail.com>2016-08-19 02:07:51 +0000
commite8529c28f1c109e0c5f7be3ff96b17248c69b9bb (patch)
treed5e054158235e407952a82c9283d3b1a97c770be
parent964cc53d9a7411bc2d7ecc2bf7958ac5c65da32e (diff)
downloadbcm5719-llvm-e8529c28f1c109e0c5f7be3ff96b17248c69b9bb.tar.gz
bcm5719-llvm-e8529c28f1c109e0c5f7be3ff96b17248c69b9bb.zip
[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. llvm-svn: 279197
-rw-r--r--llvm/include/llvm/ADT/STLExtras.h5
-rw-r--r--llvm/unittests/ADT/CMakeLists.txt1
-rw-r--r--llvm/unittests/ADT/STLExtrasTest.cpp40
3 files changed, 46 insertions, 0 deletions
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index eb515fd4583..e6215e4ae5b 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -382,6 +382,11 @@ struct build_index_impl<0, I...> : index_sequence<I...> {};
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
//===----------------------------------------------------------------------===//
diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt
index 83d6eb53d83..72d0c00a450 100644
--- a/llvm/unittests/ADT/CMakeLists.txt
+++ b/llvm/unittests/ADT/CMakeLists.txt
@@ -34,6 +34,7 @@ set(ADTSources
PriorityWorklistTest.cpp
RangeAdapterTest.cpp
SCCIteratorTest.cpp
+ STLExtrasTest.cpp
ScopeExitTest.cpp
SequenceTest.cpp
SetVectorTest.cpp
diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
new file mode 100644
index 00000000000..dc62b03741c
--- /dev/null
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -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>()));
+}
+
+}
OpenPOWER on IntegriCloud