Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit d319716

Browse files
committed
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279197 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 84c33c6 commit d319716

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

include/llvm/ADT/STLExtras.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ struct build_index_impl<0, I...> : index_sequence<I...> {};
382382
template <class... Ts>
383383
struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
384384

385+
/// Utility type to build an inheritance chain that makes it easy to rank
386+
/// overload candidates.
387+
template <int N> struct rank : rank<N - 1> {};
388+
template <> struct rank<0> {};
389+
385390
//===----------------------------------------------------------------------===//
386391
// Extra additions for arrays
387392
//===----------------------------------------------------------------------===//

unittests/ADT/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ set(ADTSources
3434
PriorityWorklistTest.cpp
3535
RangeAdapterTest.cpp
3636
SCCIteratorTest.cpp
37+
STLExtrasTest.cpp
3738
ScopeExitTest.cpp
3839
SequenceTest.cpp
3940
SetVectorTest.cpp

unittests/ADT/STLExtrasTest.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//===- STLExtrasTest.cpp - Unit tests for STL extras ----------------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "llvm/ADT/STLExtras.h"
11+
#include "gtest/gtest.h"
12+
13+
using namespace llvm;
14+
15+
namespace {
16+
17+
int f(rank<0>) { return 0; }
18+
int f(rank<1>) { return 1; }
19+
int f(rank<2>) { return 2; }
20+
int f(rank<4>) { return 4; }
21+
22+
TEST(STLExtrasTest, Rank) {
23+
// We shouldn't get ambiguities and should select the overload of the same
24+
// rank as the argument.
25+
EXPECT_EQ(0, f(rank<0>()));
26+
EXPECT_EQ(1, f(rank<1>()));
27+
EXPECT_EQ(2, f(rank<2>()));
28+
29+
// This overload is missing so we end up back at 2.
30+
EXPECT_EQ(2, f(rank<3>()));
31+
32+
// But going past 3 should work fine.
33+
EXPECT_EQ(4, f(rank<4>()));
34+
35+
// And we can even go higher and just fall back to the last overload.
36+
EXPECT_EQ(4, f(rank<5>()));
37+
EXPECT_EQ(4, f(rank<6>()));
38+
}
39+
40+
}

0 commit comments

Comments
 (0)