diff --git a/api/array_view.h b/api/array_view.h index efc642d6fc..bf91484a24 100644 --- a/api/array_view.h +++ b/api/array_view.h @@ -231,6 +231,12 @@ class ArrayView final : public impl::ArrayViewBase { HasDataAndSize::value>::type* = nullptr> ArrayView(U& u) // NOLINT : ArrayView(u.data(), u.size()) {} + template < + typename U, + typename std::enable_if::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 // const, because the ArrayView doesn't own the array. (To prevent mutation, diff --git a/api/array_view_unittest.cc b/api/array_view_unittest.cc index 694ed0b008..62b51c0811 100644 --- a/api/array_view_unittest.cc +++ b/api/array_view_unittest.cc @@ -28,16 +28,21 @@ using ::testing::ElementsAre; using ::testing::IsEmpty; template -void Call(ArrayView) {} +size_t Call(ArrayView av) { + return av.size(); +} + +template +void CallFixed(ArrayView av) {} } // namespace TEST(ArrayViewTest, TestConstructFromPtrAndArray) { char arr[] = "Arrr!"; const char carr[] = "Carrr!"; - Call(arr); - Call(carr); - Call(arr); + EXPECT_EQ(6u, Call(arr)); + EXPECT_EQ(7u, Call(carr)); + EXPECT_EQ(6u, Call(arr)); // Call(carr); // Compile error, because can't drop const. // Call(arr); // Compile error, because incompatible types. ArrayView x; @@ -182,6 +187,8 @@ TEST(ArrayViewTest, TestCopyAssignmentFixed) { } TEST(ArrayViewTest, TestStdArray) { + EXPECT_EQ(4u, Call(std::array{1, 2, 3, 4})); + CallFixed(std::array{2, 3, 4}); constexpr size_t size = 5; std::array arr{}; // Fixed size view. @@ -214,11 +221,12 @@ TEST(ArrayViewTest, TestConstStdArray) { } TEST(ArrayViewTest, TestStdVector) { + EXPECT_EQ(3u, Call(std::vector{4, 5, 6})); std::vector v; v.push_back(3); v.push_back(11); - Call(v); - Call(v); + EXPECT_EQ(2u, Call(v)); + EXPECT_EQ(2u, Call(v)); // Call(v); // Compile error, because incompatible types. ArrayView x = v; EXPECT_EQ(2u, x.size()); @@ -229,7 +237,7 @@ TEST(ArrayViewTest, TestStdVector) { EXPECT_EQ(v.data(), y.data()); // ArrayView d = v; // Compile error, because incompatible types. const std::vector cv; - Call(cv); + EXPECT_EQ(0u, Call(cv)); // Call(cv); // Compile error, because can't drop const. ArrayView z = cv; EXPECT_EQ(0u, z.size()); @@ -239,8 +247,8 @@ TEST(ArrayViewTest, TestStdVector) { TEST(ArrayViewTest, TestRtcBuffer) { rtc::Buffer b = "so buffer"; - Call(b); - Call(b); + EXPECT_EQ(10u, Call(b)); + EXPECT_EQ(10u, Call(b)); // Call(b); // Compile error, because incompatible types. ArrayView x = b; EXPECT_EQ(10u, x.size()); @@ -251,7 +259,7 @@ TEST(ArrayViewTest, TestRtcBuffer) { EXPECT_EQ(b.data(), y.data()); // ArrayView d = b; // Compile error, because incompatible types. const rtc::Buffer cb = "very const"; - Call(cb); + EXPECT_EQ(11u, Call(cb)); // Call(cb); // Compile error, because can't drop const. ArrayView z = cb; EXPECT_EQ(11u, z.size());