Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #ifndef WEBRTC_RTC_BASE_ARRAY_VIEW_H_ | 11 #ifndef WEBRTC_API_ARRAY_VIEW_H_ |
| 12 #define WEBRTC_RTC_BASE_ARRAY_VIEW_H_ | 12 #define WEBRTC_API_ARRAY_VIEW_H_ |
| 13 | |
| 14 #include <algorithm> | |
| 13 | 15 |
| 14 #include "webrtc/rtc_base/checks.h" | 16 #include "webrtc/rtc_base/checks.h" |
| 15 #include "webrtc/rtc_base/type_traits.h" | 17 #include "webrtc/rtc_base/type_traits.h" |
|
nisse-webrtc
2017/09/01 07:07:44
In a different cl, you preferred <type_traits>. Bu
kwiberg-webrtc
2017/09/01 08:45:31
Yes. rtc_base/type_traits.h currently defines just
| |
| 16 | 18 |
| 17 namespace rtc { | 19 namespace rtc { |
| 18 | 20 |
| 19 // Many functions read from or write to arrays. The obvious way to do this is | 21 // Many functions read from or write to arrays. The obvious way to do this is |
|
nisse-webrtc
2017/09/01 07:07:44
Maybe refer to related upcoming standard classes,
kwiberg-webrtc
2017/09/01 08:45:31
Hmm. There's a proposal for adding it (under the n
| |
| 20 // to use two arguments, a pointer to the first element and an element count: | 22 // to use two arguments, a pointer to the first element and an element count: |
| 21 // | 23 // |
| 22 // bool Contains17(const int* arr, size_t size) { | 24 // bool Contains17(const int* arr, size_t size) { |
| 23 // for (size_t i = 0; i < size; ++i) { | 25 // for (size_t i = 0; i < size; ++i) { |
| 24 // if (arr[i] == 17) | 26 // if (arr[i] == 17) |
| 25 // return true; | 27 // return true; |
| 26 // } | 28 // } |
| 27 // return false; | 29 // return false; |
| 28 // } | 30 // } |
| 29 // | 31 // |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 : impl::ArrayViewBase<T, Size>::ArrayViewBase(data, size) { | 150 : impl::ArrayViewBase<T, Size>::ArrayViewBase(data, size) { |
| 149 RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data()); | 151 RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data()); |
| 150 RTC_DCHECK_EQ(size, this->size()); | 152 RTC_DCHECK_EQ(size, this->size()); |
| 151 RTC_DCHECK_EQ(!this->data(), | 153 RTC_DCHECK_EQ(!this->data(), |
| 152 this->size() == 0); // data is null iff size == 0. | 154 this->size() == 0); // data is null iff size == 0. |
| 153 } | 155 } |
| 154 | 156 |
| 155 // Construct an empty ArrayView. Note that fixed-size ArrayViews of size > 0 | 157 // Construct an empty ArrayView. Note that fixed-size ArrayViews of size > 0 |
| 156 // cannot be empty. | 158 // cannot be empty. |
| 157 ArrayView() : ArrayView(nullptr, 0) {} | 159 ArrayView() : ArrayView(nullptr, 0) {} |
| 158 ArrayView(std::nullptr_t) : ArrayView() {} | 160 ArrayView(std::nullptr_t) // NOLINT |
| 161 : ArrayView() {} | |
| 159 ArrayView(std::nullptr_t, size_t size) | 162 ArrayView(std::nullptr_t, size_t size) |
| 160 : ArrayView(static_cast<T*>(nullptr), size) { | 163 : ArrayView(static_cast<T*>(nullptr), size) { |
| 161 static_assert(Size == 0 || Size == impl::kArrayViewVarSize, ""); | 164 static_assert(Size == 0 || Size == impl::kArrayViewVarSize, ""); |
| 162 RTC_DCHECK_EQ(0, size); | 165 RTC_DCHECK_EQ(0, size); |
| 163 } | 166 } |
| 164 | 167 |
| 165 // Construct an ArrayView from an array. | 168 // Construct an ArrayView from an array. |
| 166 template <typename U, size_t N> | 169 template <typename U, size_t N> |
| 167 ArrayView(U (&array)[N]) : ArrayView(array, N) { | 170 ArrayView(U (&array)[N]) // NOLINT |
| 171 : ArrayView(array, N) { | |
| 168 static_assert(Size == N || Size == impl::kArrayViewVarSize, | 172 static_assert(Size == N || Size == impl::kArrayViewVarSize, |
| 169 "Array size must match ArrayView size"); | 173 "Array size must match ArrayView size"); |
| 170 } | 174 } |
| 171 | 175 |
| 172 // (Only if size is fixed.) Construct an ArrayView from any type U that has a | 176 // (Only if size is fixed.) Construct an ArrayView from any type U that has a |
| 173 // static constexpr size() method whose return value is equal to Size, and a | 177 // static constexpr size() method whose return value is equal to Size, and a |
| 174 // data() method whose return value converts implicitly to T*. In particular, | 178 // data() method whose return value converts implicitly to T*. In particular, |
| 175 // this means we allow conversion from ArrayView<T, N> to ArrayView<const T, | 179 // this means we allow conversion from ArrayView<T, N> to ArrayView<const T, |
| 176 // N>, but not the other way around. We also don't allow conversion from | 180 // N>, but not the other way around. We also don't allow conversion from |
| 177 // ArrayView<T> to ArrayView<T, N>, or from ArrayView<T, M> to ArrayView<T, | 181 // ArrayView<T> to ArrayView<T, N>, or from ArrayView<T, M> to ArrayView<T, |
| 178 // N> when M != N. | 182 // N> when M != N. |
| 179 template <typename U, | 183 template < |
| 180 typename std::enable_if< | 184 typename U, |
| 181 Size != impl::kArrayViewVarSize && | 185 typename std::enable_if<Size != impl::kArrayViewVarSize && |
| 182 HasDataAndSize<U, T>::value>::type* = nullptr> | 186 HasDataAndSize<U, T>::value>::type* = nullptr> |
| 183 ArrayView(U& u) : ArrayView(u.data(), u.size()) { | 187 ArrayView(U& u) // NOLINT |
| 188 : ArrayView(u.data(), u.size()) { | |
| 184 static_assert(U::size() == Size, "Sizes must match exactly"); | 189 static_assert(U::size() == Size, "Sizes must match exactly"); |
| 185 } | 190 } |
| 186 | 191 |
| 187 // (Only if size is variable.) Construct an ArrayView from any type U that | 192 // (Only if size is variable.) Construct an ArrayView from any type U that |
| 188 // has a size() method whose return value converts implicitly to size_t, and | 193 // has a size() method whose return value converts implicitly to size_t, and |
| 189 // a data() method whose return value converts implicitly to T*. In | 194 // a data() method whose return value converts implicitly to T*. In |
| 190 // particular, this means we allow conversion from ArrayView<T> to | 195 // particular, this means we allow conversion from ArrayView<T> to |
| 191 // ArrayView<const T>, but not the other way around. Other allowed | 196 // ArrayView<const T>, but not the other way around. Other allowed |
| 192 // conversions include | 197 // conversions include |
| 193 // ArrayView<T, N> to ArrayView<T> or ArrayView<const T>, | 198 // ArrayView<T, N> to ArrayView<T> or ArrayView<const T>, |
| 194 // std::vector<T> to ArrayView<T> or ArrayView<const T>, | 199 // std::vector<T> to ArrayView<T> or ArrayView<const T>, |
| 195 // const std::vector<T> to ArrayView<const T>, | 200 // const std::vector<T> to ArrayView<const T>, |
| 196 // rtc::Buffer to ArrayView<uint8_t> or ArrayView<const uint8_t>, and | 201 // rtc::Buffer to ArrayView<uint8_t> or ArrayView<const uint8_t>, and |
| 197 // const rtc::Buffer to ArrayView<const uint8_t>. | 202 // const rtc::Buffer to ArrayView<const uint8_t>. |
| 198 template < | 203 template < |
| 199 typename U, | 204 typename U, |
| 200 typename std::enable_if<Size == impl::kArrayViewVarSize && | 205 typename std::enable_if<Size == impl::kArrayViewVarSize && |
| 201 HasDataAndSize<U, T>::value>::type* = nullptr> | 206 HasDataAndSize<U, T>::value>::type* = nullptr> |
| 202 ArrayView(U& u) : ArrayView(u.data(), u.size()) {} | 207 ArrayView(U& u) // NOLINT |
| 208 : ArrayView(u.data(), u.size()) {} | |
| 203 | 209 |
| 204 // Indexing and iteration. These allow mutation even if the ArrayView is | 210 // Indexing and iteration. These allow mutation even if the ArrayView is |
| 205 // const, because the ArrayView doesn't own the array. (To prevent mutation, | 211 // const, because the ArrayView doesn't own the array. (To prevent mutation, |
| 206 // use a const element type.) | 212 // use a const element type.) |
| 207 T& operator[](size_t idx) const { | 213 T& operator[](size_t idx) const { |
| 208 RTC_DCHECK_LT(idx, this->size()); | 214 RTC_DCHECK_LT(idx, this->size()); |
| 209 RTC_DCHECK(this->data()); | 215 RTC_DCHECK(this->data()); |
| 210 return this->data()[idx]; | 216 return this->data()[idx]; |
| 211 } | 217 } |
| 212 T* begin() const { return this->data(); } | 218 T* begin() const { return this->data(); } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 243 static_assert(sizeof(ArrayView<int, 17>) == sizeof(int*), ""); | 249 static_assert(sizeof(ArrayView<int, 17>) == sizeof(int*), ""); |
| 244 static_assert(std::is_empty<ArrayView<int, 0>>::value, ""); | 250 static_assert(std::is_empty<ArrayView<int, 0>>::value, ""); |
| 245 | 251 |
| 246 template <typename T> | 252 template <typename T> |
| 247 inline ArrayView<T> MakeArrayView(T* data, size_t size) { | 253 inline ArrayView<T> MakeArrayView(T* data, size_t size) { |
| 248 return ArrayView<T>(data, size); | 254 return ArrayView<T>(data, size); |
| 249 } | 255 } |
| 250 | 256 |
| 251 } // namespace rtc | 257 } // namespace rtc |
| 252 | 258 |
| 253 #endif // WEBRTC_RTC_BASE_ARRAY_VIEW_H_ | 259 #endif // WEBRTC_API_ARRAY_VIEW_H_ |
| OLD | NEW |