blob: 4b9bf4541ad7b182efa28afe0ecfc0316aa1069c [file] [log] [blame] [edit]
//===-- lib/runtime/array.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 FLANG_RT_RUNTIME_ARRAY_H_
#define FLANG_RT_RUNTIME_ARRAY_H_
#include "flang-rt/runtime/memory.h"
#include "flang-rt/runtime/terminator.h"
namespace Fortran::runtime {
// A simple dynamic array that only supports appending to avoid std::vector.
template <typename T> struct DynamicArray {
~DynamicArray() {
for (std::size_t i = 0; i < size_; ++i) {
data_[i].~T();
}
FreeMemory(data_);
}
void emplace_back(T &&value) {
if (size_ == capacity_) {
reserve(capacity_ ? capacity_ * 2 : 4);
}
new (data_ + size_) T(std::move(value));
++size_;
}
void reserve(std::size_t newCap) {
if (newCap <= capacity_) {
return;
}
T *new_data = static_cast<T *>(
AllocateMemoryOrCrash(terminator_, newCap * sizeof(T)));
for (std::size_t i = 0; i < size_; ++i) {
new (new_data + i) T(std::move(data_[i]));
data_[i].~T();
}
FreeMemory(data_);
data_ = new_data;
capacity_ = newCap;
}
T *begin() const { return data_; }
T *end() const { return data_ + size_; }
private:
T *data_ = nullptr;
std::size_t size_ = 0;
std::size_t capacity_ = 0;
Terminator terminator_{__FILE__, __LINE__};
};
} // namespace Fortran::runtime
#endif // FLANG_RT_RUNTIME_ARRAY_H_