diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h --- a/llvm/include/llvm/ADT/ArrayRef.h +++ b/llvm/include/llvm/ADT/ArrayRef.h @@ -540,6 +540,41 @@ return MutableArrayRef(data, length); } + /// Construct a MutableArrayRef from a SmallVector. + template + MutableArrayRef makeMutableArrayRef(SmallVectorImpl &Vec) { + return Vec; + } + + template + MutableArrayRef makeMutableArrayRef(SmallVector &Vec) { + return Vec; + } + + /// Construct a MutableArrayRef from a std::vector. + template + MutableArrayRef makeMutableArrayRef(std::vector &Vec) { + return Vec; + } + + /// Construct a MutableArrayRef from a std::array. + template + MutableArrayRef makeMutableArrayRef(std::array &Arr) { + return Arr; + } + + /// Construct a MutableArrayRef from a MutableArrayRef (no-op) (const) + template + MutableArrayRef makeMutableArrayRef(const MutableArrayRef &Vec) { + return Vec; + } + + /// Construct a MutableArrayRef from a C array. + template + MutableArrayRef makeMutableArrayRef(T (&Arr)[N]) { + return MutableArrayRef(Arr); + } + /// @} /// @name ArrayRef Comparison Operators /// @{ diff --git a/llvm/unittests/ADT/CMakeLists.txt b/llvm/unittests/ADT/CMakeLists.txt --- a/llvm/unittests/ADT/CMakeLists.txt +++ b/llvm/unittests/ADT/CMakeLists.txt @@ -45,6 +45,7 @@ IteratorTest.cpp MappedIteratorTest.cpp MapVectorTest.cpp + MutableArrayRefTest.cpp OptionalTest.cpp PackedVectorTest.cpp PointerEmbeddedIntTest.cpp diff --git a/llvm/unittests/ADT/MutableArrayRefTest.cpp b/llvm/unittests/ADT/MutableArrayRefTest.cpp new file mode 100644 --- /dev/null +++ b/llvm/unittests/ADT/MutableArrayRefTest.cpp @@ -0,0 +1,55 @@ +//===- llvm/unittest/ADT/MutableArrayRefTest.cpp --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "gtest/gtest.h" +#include + +using namespace llvm; + +namespace { + +// Test that makeArrayRef works on ArrayRef (no-op) +TEST(MutableArrayRefTest, makeMutableArrayRef) { + int A; + auto AR = makeMutableArrayRef(A); + EXPECT_EQ(AR.data(), &A); + EXPECT_EQ(AR.size(), (size_t)1); + + int B[] = {0, 1, 2, 3}; + auto BR1 = makeMutableArrayRef(&B[0], 4); + auto BR2 = makeMutableArrayRef(B); + EXPECT_EQ(BR1.data(), &B[0]); + EXPECT_EQ(BR1.size(), (size_t)4); + EXPECT_EQ(BR2.data(), &B[0]); + EXPECT_EQ(BR2.size(), (size_t)4); + + SmallVector C1; + SmallVectorImpl &C2 = C1; + C1.resize(5); + auto CR1 = makeMutableArrayRef(C1); + auto CR2 = makeMutableArrayRef(C2); + EXPECT_EQ(CR1.data(), C1.data()); + EXPECT_EQ(CR1.size(), C1.size()); + EXPECT_EQ(CR2.data(), C2.data()); + EXPECT_EQ(CR2.size(), C2.size()); + + std::vector D; + D.resize(5); + auto DR = makeMutableArrayRef(D); + EXPECT_EQ(DR.data(), D.data()); + EXPECT_EQ(DR.size(), D.size()); + + std::array E; + auto ER = makeMutableArrayRef(E); + EXPECT_EQ(ER.data(), E.data()); + EXPECT_EQ(ER.size(), E.size()); +} + +} // end anonymous namespace