/*
 *  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 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; }

  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_
