Skip to content

Commit 75e8b95

Browse files
[llvm][ADT] Add getSingleElement helper
1 parent d781ac1 commit 75e8b95

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

llvm/include/llvm/ADT/STLExtras.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,14 @@ template <typename ContainerTy> bool hasSingleElement(ContainerTy &&C) {
325325
return B != E && std::next(B) == E;
326326
}
327327

328+
/// Asserts that the given container has a single element and returns that
329+
/// element.
330+
template <typename ContainerTy>
331+
decltype(auto) getSingleElement(ContainerTy &&C) {
332+
assert(hasSingleElement(C) && "expected container with single element");
333+
return *adl_begin(C);
334+
}
335+
328336
/// Return a range covering \p RangeOrContainer with the first N elements
329337
/// excluded.
330338
template <typename T> auto drop_begin(T &&RangeOrContainer, size_t N = 1) {

llvm/unittests/ADT/STLExtrasTest.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,30 @@ TEST(STLExtrasTest, hasSingleElement) {
10161016
EXPECT_FALSE(hasSingleElement(S));
10171017
}
10181018

1019+
TEST(STLExtrasTest, getSingleElement) {
1020+
// Note: Asserting behavior of getSingleElement cannot be tested because the
1021+
// program would crash.
1022+
const std::vector<int> V1 = {7};
1023+
EXPECT_EQ(getSingleElement(V1), 7);
1024+
1025+
std::vector<int> V2 = {8};
1026+
EXPECT_EQ(getSingleElement(V2), 8);
1027+
1028+
SmallVector<int> V3 {9};
1029+
EXPECT_EQ(getSingleElement(V3), 9);
1030+
getSingleElement(V3) = 11;
1031+
EXPECT_EQ(V3[0], 11);
1032+
1033+
std::list<int> L1 = {10};
1034+
EXPECT_EQ(getSingleElement(L1), 10);
1035+
1036+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
1037+
// using ADL.
1038+
some_namespace::some_struct S;
1039+
S.data = V2;
1040+
EXPECT_EQ(getSingleElement(S), 8);
1041+
}
1042+
10191043
TEST(STLExtrasTest, hasNItems) {
10201044
const std::list<int> V0 = {}, V1 = {1}, V2 = {1, 2};
10211045
const std::list<int> V3 = {1, 3, 5};

0 commit comments

Comments
 (0)