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

#ifndef SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_PREALLOCATED_VECTOR_H_
#define SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_PREALLOCATED_VECTOR_H_

#include <lib/stdcompat/span.h>

#include <new>
#include <optional>
#include <string_view>
#include <type_traits>

namespace elfldltl {

// elfldltl::PreallocatedVector<T> wraps a previously allocated but
// uninitialized span of T with a container interface that looks like a
// std::vector but provides the container.h API for the allocating methods.
// For an allocation failure, the Diagnostics object's ResourceLimit<N> method
// will be called with the error string (the std::string_view parameter).  The
// methods that usually return void (push_back, emplace_back) instead return
// bool, with false indicating allocation failure.  The methods that usually
// return an iterator (emplace, insert) instead return std::optional<iterator>,
// with std::nullopt indicating allocation failure.
//
// This can be default-constructed (with zero capacity) and then move-assigned
// from another object constructed with storage.  It's usually constructed via
// the deduction guide with any cpp20::span argument.
template <typename T, size_t N = cpp20::dynamic_extent>
class PreallocatedVector {
 public:
  using value_type = T;
  using pointer = T*;
  using const_pointer = const T*;
  using reference = T&;
  using const_reference = const T&;
  using iterator = typename cpp20::span<T>::iterator;
  using const_iterator = typename cpp20::span<const T, N>::iterator;
  using reverse_iterator = typename cpp20::span<T, N>::reverse_iterator;
  using const_reverse_iterator = typename cpp20::span<const T, N>::reverse_iterator;

  constexpr PreallocatedVector() = default;

  constexpr PreallocatedVector(PreallocatedVector&&) noexcept = default;

  template <size_t OtherN>
  constexpr explicit PreallocatedVector(PreallocatedVector<T, OtherN>&& other) noexcept
      : PreallocatedVector(other.storage_) {
    static_assert(N == cpp20::dynamic_extent || OtherN == N);
  }

  constexpr explicit PreallocatedVector(cpp20::span<T, N> storage) : storage_(storage) {}

  constexpr PreallocatedVector& operator=(PreallocatedVector&&) noexcept = default;

  template <size_t OtherN>
  constexpr PreallocatedVector& operator=(PreallocatedVector<T, OtherN>&& other) noexcept {
    static_assert(N == cpp20::dynamic_extent || OtherN == N);
    *this = PreallocatedVector(other.storage_);
    return *this;
  }

  ~PreallocatedVector() { clear(); }

  // All the basic std::vector methods that don't need to allocate are here.

  static constexpr size_t max_size() { return N; }

  constexpr size_t capacity() const { return storage_.size(); }

  constexpr cpp20::span<T> as_span() { return storage_.subspan(0, size_); }
  constexpr cpp20::span<const T> as_span() const { return storage_.subspan(0, size_); }

  constexpr pointer data() { return as_span().data(); }
  constexpr const_pointer data() const { return as_span().data(); }

  constexpr size_t size() const { return as_span().size(); }

  constexpr bool empty() const { return as_span().empty(); }

  constexpr iterator begin() { return as_span().begin(); }
  constexpr iterator end() { return as_span().end(); }

  constexpr const_iterator begin() const { return as_span().begin(); }
  constexpr const_iterator end() const { return as_span().end(); }

  constexpr const_iterator cbegin() const { return as_span().begin(); }
  constexpr const_iterator cend() const { return as_span().end(); }

  constexpr reverse_iterator rbegin() { return as_span().rbegin(); }
  constexpr reverse_iterator rend() { return as_span().rend(); }

  constexpr const_reverse_iterator rbegin() const { return crbegin(); }
  constexpr const_reverse_iterator rend() const { return crend(); }

  constexpr const_reverse_iterator crbegin() const { return as_span().rbegin(); }
  constexpr const_reverse_iterator crend() const { return as_span().rend(); }

  constexpr reference at(size_t pos) { return as_span()[pos]; }
  constexpr const_reference at(size_t pos) const { return as_span()[pos]; }

  constexpr reference operator[](size_t pos) { return at(pos); }
  constexpr const_reference operator[](size_t pos) const { return at(pos); }

  constexpr reference front() { return *begin(); }
  constexpr const_reference front() const { return *begin(); }

  constexpr reference back() { return *std::prev(end()); }
  constexpr const_reference back() const { return *std::prev(end()); }

  constexpr void pop_back() {
    assert(size_ > 0);
    back().~T();
    --size_;
  }

  constexpr void clear() {
    while (!empty()) {
      pop_back();
    }
  }

  constexpr iterator erase(iterator pos) { return erase(pos, pos); }

  constexpr iterator erase(const_iterator pos) { return erase(pos, pos); }

  constexpr iterator erase(iterator first, iterator last) {
    iterator out = first;
    for (iterator in = std::next(last); in != end(); ++in) {
      *out++ = std::move(*in);
    }
    while (out != end()) {
      pop_back();
    }
    return first;
  }

  constexpr iterator erase(const_iterator first, const_iterator last) {
    return erase(begin() + (first - cbegin()), begin() + (last - cbegin()));
  }

  constexpr void resize(size_t new_size) {
    assert(new_size <= size_);
    while (new_size < size_) {
      pop_back();
    }
  }

  // The cases that require allocation are only supported via the methods
  // that use the diagnostics.h API to report failures.

  template <class Diagnostics>
  constexpr bool resize(Diagnostics& diagnostics, std::string_view error, size_t new_size) {
    if (new_size > capacity()) [[unlikely]] {
      ResourceLimit(diagnostics, error, new_size);
      return false;
    }
    if (new_size < size_) {
      resize(new_size);
      return true;
    }

    // Default-construct the new elements.
    size_t old_size = size_;
    size_ = new_size;
    for (auto& elt : cpp20::span(data(), capacity()).subspan(old_size)) {
      new (&elt) T();
    }
    return true;
  }

  template <class Diagnostics>
  constexpr bool push_back(Diagnostics& diagnostics, std::string_view error, const T& elt) {
    return emplace_back(diagnostics, error, elt);
  }

  template <class Diagnostics>
  constexpr bool push_back(Diagnostics& diagnostics, std::string_view error, T&& elt) {
    return emplace_back(diagnostics, error, std::move(elt));
  }

  template <class Diagnostics, typename... Args>
  constexpr bool emplace_back(Diagnostics& diagnostics, std::string_view error, Args&&... args) {
    if (size_ >= capacity()) [[unlikely]] {
      ResourceLimit(diagnostics, error, capacity() + 1);
      return false;
    }
    new (std::addressof(data()[size_++])) T{std::forward<Args>(args)...};
    return true;
  }

  template <class Diagnostics, typename... Args>
  constexpr std::optional<iterator> emplace(Diagnostics& diagnostics, std::string_view error,
                                            const_iterator it, Args&&... args) {
    if (size_ >= capacity()) [[unlikely]] {
      ResourceLimit(diagnostics, error, capacity() + 1);
      return std::nullopt;
    }

    // The new element will go where the existing elements are now.
    iterator write = MoveElements(it, 1);

    // Construct the new element.
    new (std::addressof(*write)) T{std::forward<Args>(args)...};

    // Return the iterator to where it was written.
    return write;
  }

  template <class Diagnostics>
  constexpr std::optional<iterator> insert(Diagnostics& diagnostics, std::string_view error,
                                           const_iterator it, const T& value) {
    return emplace(diagnostics, error, it, value);
  }

  template <class Diagnostics>
  constexpr std::optional<iterator> insert(Diagnostics& diagnostics, std::string_view error,
                                           const_iterator it, T&& value) {
    return emplace(diagnostics, error, it, std::move(value));
  }

  template <class Diagnostics, typename InputIt>
  constexpr std::optional<iterator> insert(Diagnostics& diagnostics, std::string_view error,
                                           const_iterator it, InputIt first, InputIt last) {
    const size_t count = std::distance(first, last);
    if (capacity() - size_ < count) [[unlikely]] {
      ResourceLimit(diagnostics, error, size_ + count);
      return std::nullopt;
    }

    // The new elements will go where the existing elements are now.
    iterator write = MoveElements(it, count);
    iterator ret = write;

    // Copy/move-construct the new elements.
    while (first != last) {
      new (std::addressof(*write++)) T{*first++};
    }

    // Return the iterator to the beginning where they were written.
    return ret;
  }

 private:
  template <class Diagnostics, typename... Args>
  constexpr void ResourceLimit(Diagnostics& diag, Args... args) {
    if constexpr (N != cpp20::dynamic_extent) {
      diag.template ResourceLimit<N>(args...);
    } else {
      diag.ResourceLimit(capacity(), args...);
    }
  }

  template <typename OtherT, size_t OtherN>
  friend class PreallocatedVector;

  // Return it+count after increasing size by count and moving all the
  // elements at [it, it+count) up.
  constexpr iterator MoveElements(const_iterator it, size_t count) {
    iterator ret = begin() + (it - cbegin());
    for (iterator write = (end() - 1 + count); write - count >= ret; write--) {
      *write = std::move(*(write - count));
    }

    // Now advance end() to include the new slots.
    size_ += count;

    return ret;
  }

  size_t size_ = 0;
  cpp20::span<T, N> storage_;
};

// Deduction guide.
template <typename T, size_t N>
PreallocatedVector(cpp20::span<T, N>) -> PreallocatedVector<T, N>;

}  // namespace elfldltl

#endif  // SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_PREALLOCATED_VECTOR_H_
