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> |
| 15 #include <type_traits> |
13 | 16 |
14 #include "webrtc/rtc_base/checks.h" | 17 #include "webrtc/rtc_base/checks.h" |
15 #include "webrtc/rtc_base/type_traits.h" | 18 #include "webrtc/rtc_base/type_traits.h" |
16 | 19 |
17 namespace rtc { | 20 namespace rtc { |
18 | 21 |
| 22 // tl;dr: rtc::ArrayView is the same thing as gsl::span from the Guideline |
| 23 // Support Library. |
| 24 // |
19 // Many functions read from or write to arrays. The obvious way to do this is | 25 // Many functions read from or write to arrays. The obvious way to do this is |
20 // to use two arguments, a pointer to the first element and an element count: | 26 // to use two arguments, a pointer to the first element and an element count: |
21 // | 27 // |
22 // bool Contains17(const int* arr, size_t size) { | 28 // bool Contains17(const int* arr, size_t size) { |
23 // for (size_t i = 0; i < size; ++i) { | 29 // for (size_t i = 0; i < size; ++i) { |
24 // if (arr[i] == 17) | 30 // if (arr[i] == 17) |
25 // return true; | 31 // return true; |
26 // } | 32 // } |
27 // return false; | 33 // return false; |
28 // } | 34 // } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 : impl::ArrayViewBase<T, Size>::ArrayViewBase(data, size) { | 154 : impl::ArrayViewBase<T, Size>::ArrayViewBase(data, size) { |
149 RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data()); | 155 RTC_DCHECK_EQ(size == 0 ? nullptr : data, this->data()); |
150 RTC_DCHECK_EQ(size, this->size()); | 156 RTC_DCHECK_EQ(size, this->size()); |
151 RTC_DCHECK_EQ(!this->data(), | 157 RTC_DCHECK_EQ(!this->data(), |
152 this->size() == 0); // data is null iff size == 0. | 158 this->size() == 0); // data is null iff size == 0. |
153 } | 159 } |
154 | 160 |
155 // Construct an empty ArrayView. Note that fixed-size ArrayViews of size > 0 | 161 // Construct an empty ArrayView. Note that fixed-size ArrayViews of size > 0 |
156 // cannot be empty. | 162 // cannot be empty. |
157 ArrayView() : ArrayView(nullptr, 0) {} | 163 ArrayView() : ArrayView(nullptr, 0) {} |
158 ArrayView(std::nullptr_t) : ArrayView() {} | 164 ArrayView(std::nullptr_t) // NOLINT |
| 165 : ArrayView() {} |
159 ArrayView(std::nullptr_t, size_t size) | 166 ArrayView(std::nullptr_t, size_t size) |
160 : ArrayView(static_cast<T*>(nullptr), size) { | 167 : ArrayView(static_cast<T*>(nullptr), size) { |
161 static_assert(Size == 0 || Size == impl::kArrayViewVarSize, ""); | 168 static_assert(Size == 0 || Size == impl::kArrayViewVarSize, ""); |
162 RTC_DCHECK_EQ(0, size); | 169 RTC_DCHECK_EQ(0, size); |
163 } | 170 } |
164 | 171 |
165 // Construct an ArrayView from an array. | 172 // Construct an ArrayView from an array. |
166 template <typename U, size_t N> | 173 template <typename U, size_t N> |
167 ArrayView(U (&array)[N]) : ArrayView(array, N) { | 174 ArrayView(U (&array)[N]) // NOLINT |
| 175 : ArrayView(array, N) { |
168 static_assert(Size == N || Size == impl::kArrayViewVarSize, | 176 static_assert(Size == N || Size == impl::kArrayViewVarSize, |
169 "Array size must match ArrayView size"); | 177 "Array size must match ArrayView size"); |
170 } | 178 } |
171 | 179 |
172 // (Only if size is fixed.) Construct an ArrayView from any type U that has a | 180 // (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 | 181 // 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, | 182 // 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, | 183 // 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 | 184 // 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, | 185 // ArrayView<T> to ArrayView<T, N>, or from ArrayView<T, M> to ArrayView<T, |
178 // N> when M != N. | 186 // N> when M != N. |
179 template <typename U, | 187 template < |
180 typename std::enable_if< | 188 typename U, |
181 Size != impl::kArrayViewVarSize && | 189 typename std::enable_if<Size != impl::kArrayViewVarSize && |
182 HasDataAndSize<U, T>::value>::type* = nullptr> | 190 HasDataAndSize<U, T>::value>::type* = nullptr> |
183 ArrayView(U& u) : ArrayView(u.data(), u.size()) { | 191 ArrayView(U& u) // NOLINT |
| 192 : ArrayView(u.data(), u.size()) { |
184 static_assert(U::size() == Size, "Sizes must match exactly"); | 193 static_assert(U::size() == Size, "Sizes must match exactly"); |
185 } | 194 } |
186 | 195 |
187 // (Only if size is variable.) Construct an ArrayView from any type U that | 196 // (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 | 197 // 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 | 198 // a data() method whose return value converts implicitly to T*. In |
190 // particular, this means we allow conversion from ArrayView<T> to | 199 // particular, this means we allow conversion from ArrayView<T> to |
191 // ArrayView<const T>, but not the other way around. Other allowed | 200 // ArrayView<const T>, but not the other way around. Other allowed |
192 // conversions include | 201 // conversions include |
193 // ArrayView<T, N> to ArrayView<T> or ArrayView<const T>, | 202 // ArrayView<T, N> to ArrayView<T> or ArrayView<const T>, |
194 // std::vector<T> to ArrayView<T> or ArrayView<const T>, | 203 // std::vector<T> to ArrayView<T> or ArrayView<const T>, |
195 // const std::vector<T> to ArrayView<const T>, | 204 // const std::vector<T> to ArrayView<const T>, |
196 // rtc::Buffer to ArrayView<uint8_t> or ArrayView<const uint8_t>, and | 205 // rtc::Buffer to ArrayView<uint8_t> or ArrayView<const uint8_t>, and |
197 // const rtc::Buffer to ArrayView<const uint8_t>. | 206 // const rtc::Buffer to ArrayView<const uint8_t>. |
198 template < | 207 template < |
199 typename U, | 208 typename U, |
200 typename std::enable_if<Size == impl::kArrayViewVarSize && | 209 typename std::enable_if<Size == impl::kArrayViewVarSize && |
201 HasDataAndSize<U, T>::value>::type* = nullptr> | 210 HasDataAndSize<U, T>::value>::type* = nullptr> |
202 ArrayView(U& u) : ArrayView(u.data(), u.size()) {} | 211 ArrayView(U& u) // NOLINT |
| 212 : ArrayView(u.data(), u.size()) {} |
203 | 213 |
204 // Indexing and iteration. These allow mutation even if the ArrayView is | 214 // Indexing and iteration. These allow mutation even if the ArrayView is |
205 // const, because the ArrayView doesn't own the array. (To prevent mutation, | 215 // const, because the ArrayView doesn't own the array. (To prevent mutation, |
206 // use a const element type.) | 216 // use a const element type.) |
207 T& operator[](size_t idx) const { | 217 T& operator[](size_t idx) const { |
208 RTC_DCHECK_LT(idx, this->size()); | 218 RTC_DCHECK_LT(idx, this->size()); |
209 RTC_DCHECK(this->data()); | 219 RTC_DCHECK(this->data()); |
210 return this->data()[idx]; | 220 return this->data()[idx]; |
211 } | 221 } |
212 T* begin() const { return this->data(); } | 222 T* begin() const { return this->data(); } |
(...skipping 30 matching lines...) Expand all Loading... |
243 static_assert(sizeof(ArrayView<int, 17>) == sizeof(int*), ""); | 253 static_assert(sizeof(ArrayView<int, 17>) == sizeof(int*), ""); |
244 static_assert(std::is_empty<ArrayView<int, 0>>::value, ""); | 254 static_assert(std::is_empty<ArrayView<int, 0>>::value, ""); |
245 | 255 |
246 template <typename T> | 256 template <typename T> |
247 inline ArrayView<T> MakeArrayView(T* data, size_t size) { | 257 inline ArrayView<T> MakeArrayView(T* data, size_t size) { |
248 return ArrayView<T>(data, size); | 258 return ArrayView<T>(data, size); |
249 } | 259 } |
250 | 260 |
251 } // namespace rtc | 261 } // namespace rtc |
252 | 262 |
253 #endif // WEBRTC_RTC_BASE_ARRAY_VIEW_H_ | 263 #endif // WEBRTC_API_ARRAY_VIEW_H_ |
OLD | NEW |