//===-- vector.h ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef SCUDO_VECTOR_H_
#define SCUDO_VECTOR_H_

#include "common.h"

#include <string.h>

namespace scudo {

// A low-level vector based on map. May incur a significant memory overhead for
// small vectors. The current implementation supports only POD types.
template <typename T> class VectorNoCtor {
public:
  void init(uptr InitialCapacity) {
    CapacityBytes = 0;
    Size = 0;
    Data = nullptr;
    reserve(InitialCapacity);
  }
  void destroy() {
    if (Data)
      unmap(Data, CapacityBytes);
  }
  T &operator[](uptr I) {
    DCHECK_LT(I, Size);
    return Data[I];
  }
  const T &operator[](uptr I) const {
    DCHECK_LT(I, Size);
    return Data[I];
  }
  void push_back(const T &Element) {
    DCHECK_LE(Size, capacity());
    if (Size == capacity()) {
      const uptr NewCapacity = roundUpToPowerOfTwo(Size + 1);
      reallocate(NewCapacity);
    }
    memcpy(&Data[Size++], &Element, sizeof(T));
  }
  T &back() {
    DCHECK_GT(Size, 0);
    return Data[Size - 1];
  }
  void pop_back() {
    DCHECK_GT(Size, 0);
    Size--;
  }
  uptr size() const { return Size; }
  const T *data() const { return Data; }
  T *data() { return Data; }
  uptr capacity() const { return CapacityBytes / sizeof(T); }
  void reserve(uptr NewSize) {
    // Never downsize internal buffer.
    if (NewSize > capacity())
      reallocate(NewSize);
  }
  void resize(uptr NewSize) {
    if (NewSize > Size) {
      reserve(NewSize);
      memset(&Data[Size], 0, sizeof(T) * (NewSize - Size));
    }
    Size = NewSize;
  }

  void clear() { Size = 0; }
  bool empty() const { return size() == 0; }

  const T *begin() const { return data(); }
  T *begin() { return data(); }
  const T *end() const { return data() + size(); }
  T *end() { return data() + size(); }

private:
  void reallocate(uptr NewCapacity) {
    DCHECK_GT(NewCapacity, 0);
    DCHECK_LE(Size, NewCapacity);
    const uptr NewCapacityBytes =
        roundUpTo(NewCapacity * sizeof(T), getPageSizeCached());
    T *NewData =
        reinterpret_cast<T *>(map(nullptr, NewCapacityBytes, "scudo:vector"));
    if (Data) {
      memcpy(NewData, Data, Size * sizeof(T));
      unmap(Data, CapacityBytes);
    }
    Data = NewData;
    CapacityBytes = NewCapacityBytes;
  }

  T *Data;
  uptr CapacityBytes;
  uptr Size;
};

template <typename T> class Vector : public VectorNoCtor<T> {
public:
  Vector() { VectorNoCtor<T>::init(1); }
  explicit Vector(uptr Count) {
    VectorNoCtor<T>::init(Count);
    this->resize(Count);
  }
  ~Vector() { VectorNoCtor<T>::destroy(); }
  // Disallow copies and moves.
  Vector(const Vector &) = delete;
  Vector &operator=(const Vector &) = delete;
  Vector(Vector &&) = delete;
  Vector &operator=(Vector &&) = delete;
};

} // namespace scudo

#endif // SCUDO_VECTOR_H_
