// Copyright 2022 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CORE_FXCRT_FIXED_SIZE_DATA_VECTOR_H_
#define CORE_FXCRT_FIXED_SIZE_DATA_VECTOR_H_

#include <stddef.h>

#include <memory>
#include <utility>

#include "core/fxcrt/compiler_specific.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/span.h"

namespace fxcrt {

// A simple data container that has a fixed size.
// Unlike std::vector, it cannot be implicitly copied and its data is only
// accessible using spans.
// It can either initialize its data with zeros, or leave its data
// uninitialized.
template <typename T>
class FixedSizeDataVector {
 public:
  FixedSizeDataVector() = default;

  // Allocates a vector of the given size with uninitialized memory.
  // A CHECK() failure occurs when insufficient memory.
  static FixedSizeDataVector Uninit(size_t size) {
    if (size == 0) {
      return FixedSizeDataVector();
    }
    return FixedSizeDataVector(FX_AllocUninit(T, size), size);
  }

  // Allocates a vector of the given size with zeroed memory.
  // A CHECK() failure occurs when insufficient memory.
  static FixedSizeDataVector Zeroed(size_t size) {
    if (size == 0) {
      return FixedSizeDataVector();
    }
    return FixedSizeDataVector(FX_Alloc(T, size), size);
  }

  // Same as above, but return an empty vector when insufficient memory.
  static FixedSizeDataVector TryZeroed(size_t size) {
    if (size == 0) {
      return FixedSizeDataVector();
    }
    T* ptr = FX_TryAlloc(T, size);
    return FixedSizeDataVector(ptr, ptr ? size : 0u);
  }

  FixedSizeDataVector(const FixedSizeDataVector&) = delete;
  FixedSizeDataVector& operator=(const FixedSizeDataVector&) = delete;

  FixedSizeDataVector(FixedSizeDataVector<T>&& that) noexcept
      : data_(std::move(that.data_)), size_(std::exchange(that.size_, 0)) {}

  FixedSizeDataVector& operator=(FixedSizeDataVector<T>&& that) noexcept {
    data_ = std::move(that.data_);
    size_ = std::exchange(that.size_, 0);
    return *this;
  }

  ~FixedSizeDataVector() = default;

  bool empty() const { return size_ == 0; }
  size_t size() const { return size_; }

  // Implicit access to data via span.
  operator pdfium::span<T>() { return span(); }
  operator pdfium::span<const T>() const { return span(); }

  // Explicit access to data via span.
  pdfium::span<T> span() {
    // SAFETY: size_ describes size of data_.
    return UNSAFE_BUFFERS(pdfium::make_span(data_.get(), size_));
  }
  pdfium::span<const T> span() const {
    // SAFETY: size_ describes size of data_.
    return UNSAFE_BUFFERS(pdfium::make_span(data_.get(), size_));
  }

  // Convenience methods to slice the vector into spans.
  pdfium::span<T> subspan(size_t offset,
                          size_t count = pdfium::dynamic_extent) {
    return span().subspan(offset, count);
  }
  pdfium::span<const T> subspan(size_t offset,
                                size_t count = pdfium::dynamic_extent) const {
    return span().subspan(offset, count);
  }

  pdfium::span<T> first(size_t count) { return span().first(count); }
  pdfium::span<const T> first(size_t count) const {
    return span().first(count);
  }

  pdfium::span<T> last(size_t count) { return span().last(count); }
  pdfium::span<const T> last(size_t count) const { return span().last(count); }

 private:
  FixedSizeDataVector(T* ptr, size_t size) : data_(ptr), size_(size) {}

  std::unique_ptr<T, FxFreeDeleter> data_;
  size_t size_ = 0;
};

}  // namespace fxcrt

using fxcrt::FixedSizeDataVector;

#endif  // CORE_FXCRT_FIXED_SIZE_DATA_VECTOR_H_
