diff options
Diffstat (limited to 'third_party/libwebrtc/rtc_base/bounded_inline_vector.h')
-rw-r--r-- | third_party/libwebrtc/rtc_base/bounded_inline_vector.h | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/bounded_inline_vector.h b/third_party/libwebrtc/rtc_base/bounded_inline_vector.h new file mode 100644 index 0000000000..f8b7eb3d86 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/bounded_inline_vector.h @@ -0,0 +1,155 @@ +/* + * Copyright 2020 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_BASE_BOUNDED_INLINE_VECTOR_H_ +#define RTC_BASE_BOUNDED_INLINE_VECTOR_H_ + +#include <stdint.h> + +#include <memory> +#include <type_traits> +#include <utility> + +#include "rtc_base/bounded_inline_vector_impl.h" +#include "rtc_base/checks.h" + +namespace webrtc { + +// A small std::vector-like type whose capacity is a compile-time constant. It +// stores all data inline and never heap allocates (beyond what its element type +// requires). Trying to grow it beyond its constant capacity is an error. +// +// TODO(bugs.webrtc.org/11391): Comparison operators. +// TODO(bugs.webrtc.org/11391): Methods for adding and deleting elements. +template <typename T, int fixed_capacity> +class BoundedInlineVector { + static_assert(!std::is_const<T>::value, "T may not be const"); + static_assert(fixed_capacity > 0, "Capacity must be strictly positive"); + + public: + using size_type = int; + using value_type = T; + using const_iterator = const T*; + + BoundedInlineVector() = default; + BoundedInlineVector(const BoundedInlineVector&) = default; + BoundedInlineVector(BoundedInlineVector&&) = default; + BoundedInlineVector& operator=(const BoundedInlineVector&) = default; + BoundedInlineVector& operator=(BoundedInlineVector&&) = default; + ~BoundedInlineVector() = default; + + // This constructor is implicit, to make it possible to write e.g. + // + // BoundedInlineVector<double, 7> x = {2.72, 3.14}; + // + // and + // + // BoundedInlineVector<double, 7> GetConstants() { + // return {2.72, 3.14}; + // } + template <typename... Ts, + typename std::enable_if_t< + bounded_inline_vector_impl::AllConvertible<T, Ts...>::value>* = + nullptr> + BoundedInlineVector(Ts&&... elements) // NOLINT(runtime/explicit) + : storage_(std::forward<Ts>(elements)...) { + static_assert(sizeof...(Ts) <= fixed_capacity, ""); + } + + template < + int other_capacity, + typename std::enable_if_t<other_capacity != fixed_capacity>* = nullptr> + BoundedInlineVector(const BoundedInlineVector<T, other_capacity>& other) { + RTC_DCHECK_LE(other.size(), fixed_capacity); + bounded_inline_vector_impl::CopyElements(other.data(), other.size(), + storage_.data, &storage_.size); + } + + template < + int other_capacity, + typename std::enable_if_t<other_capacity != fixed_capacity>* = nullptr> + BoundedInlineVector(BoundedInlineVector<T, other_capacity>&& other) { + RTC_DCHECK_LE(other.size(), fixed_capacity); + bounded_inline_vector_impl::MoveElements(other.data(), other.size(), + storage_.data, &storage_.size); + } + + template < + int other_capacity, + typename std::enable_if_t<other_capacity != fixed_capacity>* = nullptr> + BoundedInlineVector& operator=( + const BoundedInlineVector<T, other_capacity>& other) { + bounded_inline_vector_impl::DestroyElements(storage_.data, storage_.size); + RTC_DCHECK_LE(other.size(), fixed_capacity); + bounded_inline_vector_impl::CopyElements(other.data(), other.size(), + storage_.data, &storage_.size); + return *this; + } + + template < + int other_capacity, + typename std::enable_if_t<other_capacity != fixed_capacity>* = nullptr> + BoundedInlineVector& operator=( + BoundedInlineVector<T, other_capacity>&& other) { + bounded_inline_vector_impl::DestroyElements(storage_.data, storage_.size); + RTC_DCHECK_LE(other.size(), fixed_capacity); + bounded_inline_vector_impl::MoveElements(other.data(), other.size(), + storage_.data, &storage_.size); + return *this; + } + + bool empty() const { return storage_.size == 0; } + int size() const { return storage_.size; } + constexpr int capacity() const { return fixed_capacity; } + + // Resizes the BoundedInlineVector to the given size, which must not exceed + // its constant capacity. If the size is increased, the added elements are + // default constructed. + void resize(int new_size) { + RTC_DCHECK_GE(new_size, 0); + RTC_DCHECK_LE(new_size, fixed_capacity); + if (new_size > storage_.size) { + bounded_inline_vector_impl::DefaultInitializeElements( + storage_.data + storage_.size, new_size - storage_.size); + } else if (new_size < storage_.size) { + bounded_inline_vector_impl::DestroyElements(storage_.data + new_size, + storage_.size - new_size); + } + storage_.size = new_size; + } + + const T* data() const { return storage_.data; } + T* data() { return storage_.data; } + + const T& operator[](int index) const { + RTC_DCHECK_GE(index, 0); + RTC_DCHECK_LT(index, storage_.size); + return storage_.data[index]; + } + T& operator[](int index) { + RTC_DCHECK_GE(index, 0); + RTC_DCHECK_LT(index, storage_.size); + return storage_.data[index]; + } + + T* begin() { return storage_.data; } + T* end() { return storage_.data + storage_.size; } + const T* begin() const { return storage_.data; } + const T* end() const { return storage_.data + storage_.size; } + const T* cbegin() const { return storage_.data; } + const T* cend() const { return storage_.data + storage_.size; } + + private: + bounded_inline_vector_impl::Storage<T, fixed_capacity> storage_; +}; + +} // namespace webrtc + +#endif // RTC_BASE_BOUNDED_INLINE_VECTOR_H_ |