diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index eb515fd4583..e6215e4ae5b 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -382,6 +382,11 @@ struct build_index_impl<0, I...> : index_sequence {}; template struct index_sequence_for : build_index_impl {}; +/// Utility type to build an inheritance chain that makes it easy to rank +/// overload candidates. +template struct rank : rank {}; +template <> struct rank<0> {}; + //===----------------------------------------------------------------------===// // Extra additions for arrays //===----------------------------------------------------------------------===// diff --git a/unittests/ADT/CMakeLists.txt b/unittests/ADT/CMakeLists.txt index 83d6eb53d83..72d0c00a450 100644 --- a/unittests/ADT/CMakeLists.txt +++ b/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/unittests/ADT/STLExtrasTest.cpp b/unittests/ADT/STLExtrasTest.cpp new file mode 100644 index 00000000000..dc62b03741c --- /dev/null +++ b/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>())); +} + +}