Skip to content

Commit 65159c4

Browse files
[llvm][ADT] Add getSingleElement helper
1 parent d781ac1 commit 65159c4

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-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: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,35 @@ 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+
1023+
// Test const and non-const containers.
1024+
const std::vector<int> V1 = {7};
1025+
EXPECT_EQ(getSingleElement(V1), 7);
1026+
std::vector<int> V2 = {8};
1027+
EXPECT_EQ(getSingleElement(V2), 8);
1028+
1029+
// Test LLVM container.
1030+
SmallVector<int> V3 {9};
1031+
EXPECT_EQ(getSingleElement(V3), 9);
1032+
1033+
// Test that the returned element is a reference.
1034+
getSingleElement(V3) = 11;
1035+
EXPECT_EQ(V3[0], 11);
1036+
1037+
// Test non-random access container.
1038+
std::list<int> L1 = {10};
1039+
EXPECT_EQ(getSingleElement(L1), 10);
1040+
1041+
// Make sure that we use the `begin`/`end` functions from `some_namespace`,
1042+
// using ADL.
1043+
some_namespace::some_struct S;
1044+
S.data = V2;
1045+
EXPECT_EQ(getSingleElement(S), 8);
1046+
}
1047+
10191048
TEST(STLExtrasTest, hasNItems) {
10201049
const std::list<int> V0 = {}, V1 = {1}, V2 = {1, 2};
10211050
const std::list<int> V3 = {1, 3, 5};

0 commit comments

Comments
 (0)