ArrayView: Also accept const references when doing implicit conversions
This allows us to bind to temporaries. Bug: none Change-Id: Ic84ad378f344776bef38f9dc81a6fe0dee74400f Reviewed-on: https://webrtc-review.googlesource.com/c/120901 Commit-Queue: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/master@{#26530}
This commit is contained in:
parent
ee61f9440a
commit
30abc36444
@ -231,6 +231,12 @@ class ArrayView final : public impl::ArrayViewBase<T, Size> {
|
|||||||
HasDataAndSize<U, T>::value>::type* = nullptr>
|
HasDataAndSize<U, T>::value>::type* = nullptr>
|
||||||
ArrayView(U& u) // NOLINT
|
ArrayView(U& u) // NOLINT
|
||||||
: ArrayView(u.data(), u.size()) {}
|
: ArrayView(u.data(), u.size()) {}
|
||||||
|
template <
|
||||||
|
typename U,
|
||||||
|
typename std::enable_if<Size == impl::kArrayViewVarSize &&
|
||||||
|
HasDataAndSize<U, T>::value>::type* = nullptr>
|
||||||
|
ArrayView(const U& u) // NOLINT(runtime/explicit)
|
||||||
|
: ArrayView(u.data(), u.size()) {}
|
||||||
|
|
||||||
// Indexing and iteration. These allow mutation even if the ArrayView is
|
// Indexing and iteration. These allow mutation even if the ArrayView is
|
||||||
// const, because the ArrayView doesn't own the array. (To prevent mutation,
|
// const, because the ArrayView doesn't own the array. (To prevent mutation,
|
||||||
|
|||||||
@ -28,16 +28,21 @@ using ::testing::ElementsAre;
|
|||||||
using ::testing::IsEmpty;
|
using ::testing::IsEmpty;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Call(ArrayView<T>) {}
|
size_t Call(ArrayView<T> av) {
|
||||||
|
return av.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, size_t N>
|
||||||
|
void CallFixed(ArrayView<T, N> av) {}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST(ArrayViewTest, TestConstructFromPtrAndArray) {
|
TEST(ArrayViewTest, TestConstructFromPtrAndArray) {
|
||||||
char arr[] = "Arrr!";
|
char arr[] = "Arrr!";
|
||||||
const char carr[] = "Carrr!";
|
const char carr[] = "Carrr!";
|
||||||
Call<const char>(arr);
|
EXPECT_EQ(6u, Call<const char>(arr));
|
||||||
Call<const char>(carr);
|
EXPECT_EQ(7u, Call<const char>(carr));
|
||||||
Call<char>(arr);
|
EXPECT_EQ(6u, Call<char>(arr));
|
||||||
// Call<char>(carr); // Compile error, because can't drop const.
|
// Call<char>(carr); // Compile error, because can't drop const.
|
||||||
// Call<int>(arr); // Compile error, because incompatible types.
|
// Call<int>(arr); // Compile error, because incompatible types.
|
||||||
ArrayView<int*> x;
|
ArrayView<int*> x;
|
||||||
@ -182,6 +187,8 @@ TEST(ArrayViewTest, TestCopyAssignmentFixed) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArrayViewTest, TestStdArray) {
|
TEST(ArrayViewTest, TestStdArray) {
|
||||||
|
EXPECT_EQ(4u, Call<const int>(std::array<int, 4>{1, 2, 3, 4}));
|
||||||
|
CallFixed<const int, 3>(std::array<int, 3>{2, 3, 4});
|
||||||
constexpr size_t size = 5;
|
constexpr size_t size = 5;
|
||||||
std::array<float, size> arr{};
|
std::array<float, size> arr{};
|
||||||
// Fixed size view.
|
// Fixed size view.
|
||||||
@ -214,11 +221,12 @@ TEST(ArrayViewTest, TestConstStdArray) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(ArrayViewTest, TestStdVector) {
|
TEST(ArrayViewTest, TestStdVector) {
|
||||||
|
EXPECT_EQ(3u, Call<const int>(std::vector<int>{4, 5, 6}));
|
||||||
std::vector<int> v;
|
std::vector<int> v;
|
||||||
v.push_back(3);
|
v.push_back(3);
|
||||||
v.push_back(11);
|
v.push_back(11);
|
||||||
Call<const int>(v);
|
EXPECT_EQ(2u, Call<const int>(v));
|
||||||
Call<int>(v);
|
EXPECT_EQ(2u, Call<int>(v));
|
||||||
// Call<unsigned int>(v); // Compile error, because incompatible types.
|
// Call<unsigned int>(v); // Compile error, because incompatible types.
|
||||||
ArrayView<int> x = v;
|
ArrayView<int> x = v;
|
||||||
EXPECT_EQ(2u, x.size());
|
EXPECT_EQ(2u, x.size());
|
||||||
@ -229,7 +237,7 @@ TEST(ArrayViewTest, TestStdVector) {
|
|||||||
EXPECT_EQ(v.data(), y.data());
|
EXPECT_EQ(v.data(), y.data());
|
||||||
// ArrayView<double> d = v; // Compile error, because incompatible types.
|
// ArrayView<double> d = v; // Compile error, because incompatible types.
|
||||||
const std::vector<int> cv;
|
const std::vector<int> cv;
|
||||||
Call<const int>(cv);
|
EXPECT_EQ(0u, Call<const int>(cv));
|
||||||
// Call<int>(cv); // Compile error, because can't drop const.
|
// Call<int>(cv); // Compile error, because can't drop const.
|
||||||
ArrayView<const int> z = cv;
|
ArrayView<const int> z = cv;
|
||||||
EXPECT_EQ(0u, z.size());
|
EXPECT_EQ(0u, z.size());
|
||||||
@ -239,8 +247,8 @@ TEST(ArrayViewTest, TestStdVector) {
|
|||||||
|
|
||||||
TEST(ArrayViewTest, TestRtcBuffer) {
|
TEST(ArrayViewTest, TestRtcBuffer) {
|
||||||
rtc::Buffer b = "so buffer";
|
rtc::Buffer b = "so buffer";
|
||||||
Call<const uint8_t>(b);
|
EXPECT_EQ(10u, Call<const uint8_t>(b));
|
||||||
Call<uint8_t>(b);
|
EXPECT_EQ(10u, Call<uint8_t>(b));
|
||||||
// Call<int8_t>(b); // Compile error, because incompatible types.
|
// Call<int8_t>(b); // Compile error, because incompatible types.
|
||||||
ArrayView<uint8_t> x = b;
|
ArrayView<uint8_t> x = b;
|
||||||
EXPECT_EQ(10u, x.size());
|
EXPECT_EQ(10u, x.size());
|
||||||
@ -251,7 +259,7 @@ TEST(ArrayViewTest, TestRtcBuffer) {
|
|||||||
EXPECT_EQ(b.data(), y.data());
|
EXPECT_EQ(b.data(), y.data());
|
||||||
// ArrayView<char> d = b; // Compile error, because incompatible types.
|
// ArrayView<char> d = b; // Compile error, because incompatible types.
|
||||||
const rtc::Buffer cb = "very const";
|
const rtc::Buffer cb = "very const";
|
||||||
Call<const uint8_t>(cb);
|
EXPECT_EQ(11u, Call<const uint8_t>(cb));
|
||||||
// Call<uint8_t>(cb); // Compile error, because can't drop const.
|
// Call<uint8_t>(cb); // Compile error, because can't drop const.
|
||||||
ArrayView<const uint8_t> z = cb;
|
ArrayView<const uint8_t> z = cb;
|
||||||
EXPECT_EQ(11u, z.size());
|
EXPECT_EQ(11u, z.size());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user