diff --git a/webrtc/base/array_view.h b/webrtc/base/array_view.h index 783e717b7b..725a2d79d6 100644 --- a/webrtc/base/array_view.h +++ b/webrtc/base/array_view.h @@ -11,10 +11,37 @@ #ifndef WEBRTC_BASE_ARRAY_VIEW_H_ #define WEBRTC_BASE_ARRAY_VIEW_H_ +#include + #include "webrtc/base/checks.h" namespace rtc { +namespace internal { + +// (Internal; please don't use outside this file.) Determines if the given +// class has zero-argument .data() and .size() methods whose return values are +// convertible to T* and size_t, respectively. +template +class HasDataAndSize { + private: + template < + typename C, + typename std::enable_if< + std::is_convertible().data()), T*>::value && + std::is_convertible().size()), + size_t>::value>::type* = nullptr> + static int Test(int); + + template + static char Test(...); + + public: + static constexpr bool value = std::is_same(0)), int>::value; +}; + +} // namespace internal + // Many functions read from or write to arrays. The obvious way to do this is // to use two arguments, a pointer to the first element and an element count: // @@ -95,7 +122,9 @@ class ArrayView final { // or ArrayView, const std::vector to ArrayView, and // rtc::Buffer to ArrayView (with the same const behavior as // std::vector). - template + template ::value>::type* = nullptr> ArrayView(U& u) : ArrayView(u.data(), u.size()) {} // Indexing, size, and iteration. These allow mutation even if the ArrayView diff --git a/webrtc/base/array_view_unittest.cc b/webrtc/base/array_view_unittest.cc index 8bb1bcc4c6..9d5e1afc60 100644 --- a/webrtc/base/array_view_unittest.cc +++ b/webrtc/base/array_view_unittest.cc @@ -20,8 +20,45 @@ namespace rtc { namespace { + +namespace test_has_data_and_size { + +template +using DS = internal::HasDataAndSize; + +template +struct Test1 { + DR data(); + SR size(); +}; +static_assert(DS, int>::value, ""); +static_assert(DS, const int>::value, ""); +static_assert(DS, const int>::value, ""); +static_assert(!DS, int>::value, ""); // Wrong const. +static_assert(!DS, int>::value, ""); // Wrong ptr type. + +struct Test2 { + int* data; + size_t size; +}; +static_assert(!DS::value, ""); // Because they aren't methods. + +struct Test3 { + int* data(); +}; +static_assert(!DS::value, ""); // Because .size() is missing. + +class Test4 { + int* data(); + size_t size(); +}; +static_assert(!DS::value, ""); // Because methods are private. + +} // namespace test_has_data_and_size + template void Call(ArrayView) {} + } // namespace TEST(ArrayViewTest, TestConstructFromPtrAndArray) {